1
0
Fork 0
tetris-go/game/grid.go

91 lines
1.6 KiB
Go

package game
import (
"slices"
"tetris/engine/graphics"
)
const (
GRID_WIDTH = 10
GRID_HEIGHT = 16
)
type Grid [GRID_WIDTH * GRID_HEIGHT]Block
func (Grid) Width() int32 {
return GRID_WIDTH
}
func (Grid) Height() int32 {
return GRID_HEIGHT
}
func (g Grid) At(x, y byte) Block {
return g[uint16(x)+(uint16(y)*GRID_WIDTH)]
}
func (g Grid) Tile(x, y byte) graphics.Tile {
return g.At(x, y).Tile()
}
func (g *Grid) Set(x, y byte, c Block) {
(*g)[uint16(x)+(uint16(y)*GRID_WIDTH)] = c
}
func (g *Grid) ClearFullRows() byte {
completed := byte(0)
for y := int(g.Height() - 1); y >= 0; y-- {
if g.IsRowFull(byte(y)) {
completed++
g.ClearRow(byte(y))
} else if completed > 0 {
g.MoveRowDown(byte(y), completed)
}
}
return completed
}
func (g *Grid) FullRows() []byte {
rows := []byte{}
for y := byte(0); y < byte(g.Height()); y++ {
if g.IsRowFull(y) {
rows = append(rows, y)
}
}
return rows
}
func (g *Grid) IsRowFull(y byte) bool {
for x := range byte(g.Width()) {
if g.At(x, y) == BLOCK_EMPTY {
return false
}
}
return true
}
func (g *Grid) MoveRowsDown(rows ...byte) {
completed := byte(0)
for y := int(g.Height() - 1); y >= 0; y-- {
if slices.Contains(rows, byte(y)) {
completed++
} else if completed > 0 {
g.MoveRowDown(byte(y), completed)
}
}
}
func (g *Grid) MoveRowDown(y, num_rows byte) {
w := uint16(g.Width())
src := uint16(y) * w
dst := uint16(y+num_rows) * w
copy(g[dst:dst+w], g[src:src+w])
clear(g[src : src+w])
}
func (g *Grid) ClearRow(y byte) {
w := uint16(g.Width())
n := uint16(y) * w
clear(g[n : n+w])
}