aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--main.go28
-rw-r--r--tris/core.go8
-rw-r--r--tris/lines.go1
-rw-r--r--tris/move.go4
4 files changed, 32 insertions, 9 deletions
diff --git a/main.go b/main.go
index c212e5b..6bc8ce0 100644
--- a/main.go
+++ b/main.go
@@ -22,17 +22,23 @@ func GetKey() []byte {
}
func main() {
- rand.Seed(time.Now().UnixNano())
- var f tris.Field
- var floor, topout, harddrop bool
+ rand.Seed(time.Now().UnixNano()) // to start with truly random pieces
+ var f tris.Field // 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
+ // x, y and rot are the values calculated to feed to Move
+ // which then checks collisions and does the wall kicks
var x, y int
var rot tris.Rotation
- var key []byte
+
+ // init variable for pressed key - MUST be initialized 3 long to avoid crash, GetKey() does this
+ key := GetKey()
+
fmt.Print("\033[2J") // Clear screen
b := tris.NewBag()
b, p := b.Pick()
t := time.Tick(time.Second)
- key = GetKey()
for {
x, y, rot = p.X, p.Y, p.Rot
if !harddrop {
@@ -76,19 +82,23 @@ func main() {
y = p.Y + 1
}
}
- p, floor, topout = p.Move(f, rot, x, y)
+ p, floor, topout = p.Move(f, rot, x, y) // Check if the piece can move, then do it and communicate back for housekeeping
+
+ // Give some time before actually locking in to enable tucks
+ // This code runs when the time is over
if floor && p.Lock.Add(tris.LockDelay).Before(time.Now()) {
harddrop = false
var l int
f = f.Add(p)
- l, f = f.Lines()
+ l, f = f.Lines() // count and remove full lines
if l > 0 {
- fmt.Println(l, " lines removed!")
+ fmt.Println(l, "lines removed!")
time.Sleep(time.Second)
}
fmt.Print("\033[2J") // Clear screen
- b, p = b.Pick()
+ b, p = b.Pick() // ... and pick a new piece from the bag
}
+ // when not touching a piece or floor below yet, reset lock delay
if !floor {
p.Lock = time.Now()
}
diff --git a/tris/core.go b/tris/core.go
index 8a9c16b..087203e 100644
--- a/tris/core.go
+++ b/tris/core.go
@@ -38,6 +38,8 @@ const (
CounterClockwise
)
+// a placement is the combination of a piece and where it exactly is on the board
+// we use this both for the actual piece and for checking hypothetical positions
type Placement struct {
piece Piece
X int
@@ -46,6 +48,7 @@ type Placement struct {
Lock time.Time
}
+// 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++ {
@@ -58,6 +61,8 @@ func (p Placement) Collide(f Field) bool {
return !ok
}
+// 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
ok := true
@@ -74,6 +79,7 @@ func (p Placement) Field() (Field, bool) {
return f, ok
}
+// Points transforms the piece to a list of coordinates
func (p Placement) Points() []Point {
piece := p.piece[p.Rot]
var points []Point
@@ -114,6 +120,7 @@ func (b Bag) Pick() (Bag, Placement) {
type Field [20][10]bool
+// Add merges the Field and Piece together
func (f Field) Add(p Placement) Field {
fn := f
for _, point := range p.Points() {
@@ -126,6 +133,7 @@ func (f Field) Add(p Placement) Field {
}
+// 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 {
diff --git a/tris/lines.go b/tris/lines.go
index 5cb6981..7c7026b 100644
--- a/tris/lines.go
+++ b/tris/lines.go
@@ -1,5 +1,6 @@
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}
diff --git a/tris/move.go b/tris/move.go
index 127ce06..c5ba1ef 100644
--- a/tris/move.go
+++ b/tris/move.go
@@ -3,6 +3,7 @@ package tris
// As at the bottom of https://tetris.fandom.com/wiki/SRS but Y inverse because we start Y at the top
type Kicks map[Rotation][]Point
+// Kics for all pieces except I and O pieces
var K3CW = Kicks{
0: {{X:0, Y:0}, {X:-1, Y:0}, {X:-1, Y: -1}, {X:0, Y:2}, {X:-1, Y:2}},
1: {{X:0, Y:0}, {X:1, Y:0}, {X:1, Y: 1}, {X:0, Y:-2}, {X:1, Y:-2}},
@@ -10,6 +11,7 @@ var K3CW = Kicks{
3: {{X:0, Y:0}, {X:-1, Y:0}, {X:-1, Y: 1}, {X:0, Y:-2}, {X:-1, Y:-2}},
}
+// Long Bar (I piece) Kicks
var LCW = Kicks{
0: {{X:0, Y:0}, {X:-2, Y:0}, {X:1, Y: 0}, {X:-2, Y:1}, {X:1, Y:-2}},
1: {{X:0, Y:0}, {X:-1, Y:0}, {X:2, Y: 0}, {X:-1, Y:-2}, {X:2, Y:1}},
@@ -17,6 +19,7 @@ var LCW = Kicks{
3: {{X:0, Y:0}, {X:1, Y:0}, {X:-2, Y: 0}, {X:1, Y:2}, {X:-2, Y:-1}},
}
+// Try all possible kicks
func (ks Kicks) Try(rot Rotation, reverse bool, p Placement, f Field) (np Placement) {
orot := (rot + 3)%4
if reverse { // for going backwards, you start from one more
@@ -38,6 +41,7 @@ func (ks Kicks) Try(rot Rotation, reverse bool, p Placement, f Field) (np Placem
return p
}
+// Floor checks if the piece touches something underneath it
func (p Placement) Floor(f Field) bool {
fp := p
fp.Y++