91 lines
1.6 KiB
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) ClearFullLines() byte {
|
|
completed := byte(0)
|
|
for y := int(g.Height() - 1); y >= 0; y-- {
|
|
if g.IsLineFull(byte(y)) {
|
|
completed++
|
|
g.ClearLine(byte(y))
|
|
} else if completed > 0 {
|
|
g.MoveLineDown(byte(y), completed)
|
|
}
|
|
}
|
|
return completed
|
|
}
|
|
|
|
func (g *Grid) FullLines() []byte {
|
|
lines := []byte{}
|
|
for y := byte(0); y < byte(g.Height()); y++ {
|
|
if g.IsLineFull(y) {
|
|
lines = append(lines, y)
|
|
}
|
|
}
|
|
return lines
|
|
}
|
|
|
|
func (g *Grid) IsLineFull(y byte) bool {
|
|
for x := range byte(g.Width()) {
|
|
if g.At(x, y) == BLOCK_EMPTY {
|
|
return false
|
|
}
|
|
}
|
|
return true
|
|
}
|
|
|
|
func (g *Grid) MoveLinesDown(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.MoveLineDown(byte(y), completed)
|
|
}
|
|
}
|
|
}
|
|
|
|
func (g *Grid) MoveLineDown(y, num_lines byte) {
|
|
w := uint16(g.Width())
|
|
src := uint16(y) * w
|
|
dst := uint16(y+num_lines) * w
|
|
copy(g[dst:dst+w], g[src:src+w])
|
|
clear(g[src : src+w])
|
|
}
|
|
|
|
func (g *Grid) ClearLine(y byte) {
|
|
w := uint16(g.Width())
|
|
n := uint16(y) * w
|
|
clear(g[n : n+w])
|
|
}
|