aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--main.go10
-rw-r--r--tris/core.go71
-rw-r--r--tris/lines.go17
3 files changed, 74 insertions, 24 deletions
diff --git a/main.go b/main.go
index b075825..faa48c3 100644
--- a/main.go
+++ b/main.go
@@ -31,11 +31,11 @@ func npos(l, c int, f tris.Field) {
}
}
-func render(r [10]bool, block, empty string) string {
+func render(r []int, block, empty string) string {
var s string
for _, c := range r {
- if c {
- s += block
+ if c > 0 {
+ s += fmt.Sprintf("\033[%dm%s\033[0m", c, block)
} else {
s += empty
}
@@ -63,7 +63,7 @@ func main() {
rand.Seed(time.Now().UnixNano()) // to start with truly random pieces
- var f tris.Field // the playing field (10x20)
+ f := tris.NewField(20, 10) // the playing field (10x20)
var floor, topout, harddrop bool // state machine variables to check special situations
// define outside of game loop to avoid accidental resets of position
@@ -90,7 +90,7 @@ func main() {
slines := fmt.Sprintf("lines %d", linescleared)
if !harddrop {
fpos(0, 0, f.Add(p))
- var next tris.Field
+ next := tris.NewField(20, 4)
b, next = b.Next(5)
npos(0, 24, next)
ppos(1, 32, sscore)
diff --git a/tris/core.go b/tris/core.go
index 087203e..e0ae111 100644
--- a/tris/core.go
+++ b/tris/core.go
@@ -50,10 +50,10 @@ type Placement struct {
// Collide checks if any squares of the Placement and the Field overlap
func (p Placement) Collide(f Field) bool {
- pf, ok := p.Field()
- for x := 0; x < 10; x++ {
- for y := 0; y < 20; y++ {
- if f[y][x] && pf[y][x] {
+ pf, ok := p.Field(f.H(), f.W())
+ for x := 0; x < f.W(); x++ {
+ for y := 0; y < f.H(); y++ {
+ if f[y][x] > 0 && pf[y][x] > 0 {
return true
}
}
@@ -63,22 +63,42 @@ func (p Placement) Collide(f Field) bool {
// Field translates the Placement into a Field format
// When it gets out of the board, we return that to the caller with a bool
-func (p Placement) Field() (Field, bool) {
- var f Field
+func (p Placement) Field(h, w int) (Field, bool) {
+ f := NewField(h, w)
ok := true
for _, point := range p.Points() {
- if point.X < 0 || point.X > 9 || point.Y > 19 {
+ if point.X < 0 || point.X >= f.W() || point.Y >= f.H() {
ok = false
continue
}
if point.Y < 0 { // above the playing field we count the piece as on the board
continue
}
- f[point.Y][point.X] = true
+ f[point.Y][point.X] = p.Color()
}
return f, ok
}
+func (p Placement) Color() int {
+ switch p.piece {
+ case IPiece:
+ return 36
+ case JPiece:
+ return 34
+ case LPiece:
+ return 37
+ case OPiece:
+ return 33
+ case SPiece:
+ return 32
+ case TPiece:
+ return 35
+ case ZPiece:
+ return 31
+ }
+ return 0
+}
+
// Points transforms the piece to a list of coordinates
func (p Placement) Points() []Point {
piece := p.piece[p.Rot]
@@ -118,26 +138,49 @@ func (b Bag) Pick() (Bag, Placement) {
return b, piece
}
-type Field [20][10]bool
+type Field [][]int
+
+func NewField(h, w int) Field {
+ f := make(Field, h)
+ for i := range f {
+ f[i] = make([]int, w)
+ }
+ return f
+}
+
+func (f Field) H() int {
+ return len(f)
+}
+
+func (f Field) W() int {
+ if f.H() == 0 {
+ return 0
+ }
+ return len(f[0])
+}
// Add merges the Field and Piece together
func (f Field) Add(p Placement) Field {
- fn := f
+ fn := NewField(f.H(), f.W())
+ for i, row := range fn {
+ for j := range row {
+ fn[i][j] = f[i][j]
+ }
+ }
for _, point := range p.Points() {
- if point.Y < 0 || point.Y > 19 || point.X < 0 || point.X > 9 {
+ if point.Y < 0 || point.Y > f.H() || point.X < 0 || point.X > f.W() {
continue
}
- fn[point.Y][point.X] = true
+ fn[point.Y][point.X] = p.Color()
}
return fn
}
-// The command line tool uses this representation as the actual playing field
func (f Field) String() (output string) {
for _, row := range f {
for _, block := range row {
- if block {
+ if block != 0 {
output += "\u2588\u2589"
} else {
output += "\u2591\u2591"
diff --git a/tris/lines.go b/tris/lines.go
index 7c7026b..37ec35c 100644
--- a/tris/lines.go
+++ b/tris/lines.go
@@ -2,14 +2,21 @@ package tris
// Lines counts the number of lines that is completed and returns a Field with them removed
func (f Field) Lines() (int, Field) {
- full := [10]bool{true, true, true, true, true, true, true, true, true, true}
- empty := [10]bool{false, false, false, false, false, false, false, false, false, false}
var n int
- var nf [][10]bool
+ var nf [][]int
+
+ full := func(line []int) bool {
+ for _, el := range line {
+ if el == 0 {
+ return false
+ }
+ }
+ return true
+ }
// count and collect
for _, line := range f {
- if line == full {
+ if full(line) {
n++
} else {
nf = append(nf, line)
@@ -19,7 +26,7 @@ func (f Field) Lines() (int, Field) {
// compress
for i := 0; i < 20; i++ {
if i < n {
- f[i] = empty
+ f[i] = make([]int, len(f[0]))
} else {
f[i] = nf[i-n]
}