Added comments
This commit is contained in:
parent
ebcc296976
commit
0ad9733f01
3
ai.go
3
ai.go
|
@ -4,6 +4,7 @@ import (
|
||||||
"github.com/nsf/termbox-go"
|
"github.com/nsf/termbox-go"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// NewAi creates a new AI
|
||||||
func NewAi() *Ai {
|
func NewAi() *Ai {
|
||||||
ai := Ai{}
|
ai := Ai{}
|
||||||
queue := make([]rune, 1)
|
queue := make([]rune, 1)
|
||||||
|
@ -12,6 +13,7 @@ func NewAi() *Ai {
|
||||||
return &ai
|
return &ai
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ProcessQueue checks AI queue and process key moments
|
||||||
func (ai *Ai) ProcessQueue() {
|
func (ai *Ai) ProcessQueue() {
|
||||||
if ai.newQueue != nil {
|
if ai.newQueue != nil {
|
||||||
ai.queue = ai.newQueue
|
ai.queue = ai.newQueue
|
||||||
|
@ -38,6 +40,7 @@ func (ai *Ai) ProcessQueue() {
|
||||||
view.RefreshScreen()
|
view.RefreshScreen()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetBestQueue gets the best queue
|
||||||
func (ai *Ai) GetBestQueue() {
|
func (ai *Ai) GetBestQueue() {
|
||||||
bestScore := -9999999
|
bestScore := -9999999
|
||||||
bestQueue := make([]rune, 0, 0)
|
bestQueue := make([]rune, 0, 0)
|
||||||
|
|
29
board.go
29
board.go
|
@ -7,11 +7,13 @@ import (
|
||||||
"github.com/nsf/termbox-go"
|
"github.com/nsf/termbox-go"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// NewBoard creates a new clear board
|
||||||
func NewBoard() {
|
func NewBoard() {
|
||||||
board = &Board{}
|
board = &Board{}
|
||||||
board.Clear()
|
board.Clear()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Clear clears the board
|
||||||
func (board *Board) Clear() {
|
func (board *Board) Clear() {
|
||||||
board.width = len(boards[board.boardsIndex].colors)
|
board.width = len(boards[board.boardsIndex].colors)
|
||||||
board.height = len(boards[board.boardsIndex].colors[0])
|
board.height = len(boards[board.boardsIndex].colors[0])
|
||||||
|
@ -29,6 +31,7 @@ func (board *Board) Clear() {
|
||||||
board.currentMino = NewMino()
|
board.currentMino = NewMino()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// PreviousBoard switchs to previous board
|
||||||
func (board *Board) PreviousBoard() {
|
func (board *Board) PreviousBoard() {
|
||||||
board.boardsIndex--
|
board.boardsIndex--
|
||||||
if board.boardsIndex < 0 {
|
if board.boardsIndex < 0 {
|
||||||
|
@ -38,6 +41,7 @@ func (board *Board) PreviousBoard() {
|
||||||
board.Clear()
|
board.Clear()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NextBoard switchs to next board
|
||||||
func (board *Board) NextBoard() {
|
func (board *Board) NextBoard() {
|
||||||
board.boardsIndex++
|
board.boardsIndex++
|
||||||
if board.boardsIndex == len(boards) {
|
if board.boardsIndex == len(boards) {
|
||||||
|
@ -47,6 +51,7 @@ func (board *Board) NextBoard() {
|
||||||
board.Clear()
|
board.Clear()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MinoMoveLeft moves mino left
|
||||||
func (board *Board) MinoMoveLeft() {
|
func (board *Board) MinoMoveLeft() {
|
||||||
board.dropDistance = 0
|
board.dropDistance = 0
|
||||||
mino := board.currentMino.CloneMoveLeft()
|
mino := board.currentMino.CloneMoveLeft()
|
||||||
|
@ -56,6 +61,7 @@ func (board *Board) MinoMoveLeft() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MinoMoveRight moves mino right
|
||||||
func (board *Board) MinoMoveRight() {
|
func (board *Board) MinoMoveRight() {
|
||||||
board.dropDistance = 0
|
board.dropDistance = 0
|
||||||
mino := board.currentMino.CloneMoveRight()
|
mino := board.currentMino.CloneMoveRight()
|
||||||
|
@ -65,6 +71,7 @@ func (board *Board) MinoMoveRight() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MinoRotateRight rotates mino right
|
||||||
func (board *Board) MinoRotateRight() {
|
func (board *Board) MinoRotateRight() {
|
||||||
board.dropDistance = 0
|
board.dropDistance = 0
|
||||||
mino := board.currentMino.CloneRotateRight()
|
mino := board.currentMino.CloneRotateRight()
|
||||||
|
@ -88,6 +95,7 @@ func (board *Board) MinoRotateRight() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MinoRotateLeft rotates mino right
|
||||||
func (board *Board) MinoRotateLeft() {
|
func (board *Board) MinoRotateLeft() {
|
||||||
board.dropDistance = 0
|
board.dropDistance = 0
|
||||||
mino := board.currentMino.CloneRotateLeft()
|
mino := board.currentMino.CloneRotateLeft()
|
||||||
|
@ -111,6 +119,7 @@ func (board *Board) MinoRotateLeft() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MinoMoveDown moves mino down
|
||||||
func (board *Board) MinoMoveDown() {
|
func (board *Board) MinoMoveDown() {
|
||||||
mino := board.currentMino.CloneMoveDown()
|
mino := board.currentMino.CloneMoveDown()
|
||||||
if mino.ValidLocation(false) {
|
if mino.ValidLocation(false) {
|
||||||
|
@ -128,6 +137,7 @@ func (board *Board) MinoMoveDown() {
|
||||||
board.nextMino()
|
board.nextMino()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MinoDrop dropps mino
|
||||||
func (board *Board) MinoDrop() {
|
func (board *Board) MinoDrop() {
|
||||||
board.dropDistance = 0
|
board.dropDistance = 0
|
||||||
mino := board.currentMino.CloneMoveDown()
|
mino := board.currentMino.CloneMoveDown()
|
||||||
|
@ -150,6 +160,7 @@ func (board *Board) MinoDrop() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// StartLockDelayIfBottom if at bottom, starts lock delay
|
||||||
func (board *Board) StartLockDelayIfBottom() bool {
|
func (board *Board) StartLockDelayIfBottom() bool {
|
||||||
mino := board.currentMino.CloneMoveDown()
|
mino := board.currentMino.CloneMoveDown()
|
||||||
if mino.ValidLocation(false) {
|
if mino.ValidLocation(false) {
|
||||||
|
@ -159,6 +170,7 @@ func (board *Board) StartLockDelayIfBottom() bool {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// nextMino gets next mino
|
||||||
func (board *Board) nextMino() {
|
func (board *Board) nextMino() {
|
||||||
engine.AddScore(board.dropDistance)
|
engine.AddScore(board.dropDistance)
|
||||||
|
|
||||||
|
@ -180,6 +192,7 @@ func (board *Board) nextMino() {
|
||||||
engine.ResetTimer(0)
|
engine.ResetTimer(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// deleteCheck checks if there are any lines on the board that can be deleted
|
||||||
func (board *Board) deleteCheck() {
|
func (board *Board) deleteCheck() {
|
||||||
lines := board.fullLines()
|
lines := board.fullLines()
|
||||||
if len(lines) < 1 {
|
if len(lines) < 1 {
|
||||||
|
@ -194,6 +207,7 @@ func (board *Board) deleteCheck() {
|
||||||
engine.AddDeleteLines(len(lines))
|
engine.AddDeleteLines(len(lines))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// fullLines returns the line numbers that have full lines
|
||||||
func (board *Board) fullLines() []int {
|
func (board *Board) fullLines() []int {
|
||||||
fullLines := make([]int, 0, 1)
|
fullLines := make([]int, 0, 1)
|
||||||
for j := 0; j < board.height; j++ {
|
for j := 0; j < board.height; j++ {
|
||||||
|
@ -204,6 +218,7 @@ func (board *Board) fullLines() []int {
|
||||||
return fullLines
|
return fullLines
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// isFullLine checks if line is full
|
||||||
func (board *Board) isFullLine(j int) bool {
|
func (board *Board) isFullLine(j int) bool {
|
||||||
for i := 0; i < board.width; i++ {
|
for i := 0; i < board.width; i++ {
|
||||||
if board.colors[i][j] == blankColor {
|
if board.colors[i][j] == blankColor {
|
||||||
|
@ -213,6 +228,7 @@ func (board *Board) isFullLine(j int) bool {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// deleteLine deletes the line
|
||||||
func (board *Board) deleteLine(line int) {
|
func (board *Board) deleteLine(line int) {
|
||||||
for i := 0; i < board.width; i++ {
|
for i := 0; i < board.width; i++ {
|
||||||
board.colors[i][line] = blankColor
|
board.colors[i][line] = blankColor
|
||||||
|
@ -228,11 +244,13 @@ func (board *Board) deleteLine(line int) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetColor sets the color and rotation of board location
|
||||||
func (board *Board) SetColor(x int, y int, color termbox.Attribute, rotation int) {
|
func (board *Board) SetColor(x int, y int, color termbox.Attribute, rotation int) {
|
||||||
board.colors[x][y] = color
|
board.colors[x][y] = color
|
||||||
board.rotation[x][y] = rotation
|
board.rotation[x][y] = rotation
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ValidBlockLocation checks if block location is vaild
|
||||||
func (board *Board) ValidBlockLocation(x int, y int, mustBeOnBoard bool) bool {
|
func (board *Board) ValidBlockLocation(x int, y int, mustBeOnBoard bool) bool {
|
||||||
if x < 0 || x >= board.width || y >= board.height {
|
if x < 0 || x >= board.width || y >= board.height {
|
||||||
return false
|
return false
|
||||||
|
@ -254,10 +272,12 @@ func (board *Board) ValidBlockLocation(x int, y int, mustBeOnBoard bool) bool {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ValidDisplayLocation checks if vaild display location
|
||||||
func ValidDisplayLocation(x int, y int) bool {
|
func ValidDisplayLocation(x int, y int) bool {
|
||||||
return x >= 0 && x < board.width && y >= 0 && y < board.height
|
return x >= 0 && x < board.width && y >= 0 && y < board.height
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DrawBoard draws the board with help from view
|
||||||
func (board *Board) DrawBoard() {
|
func (board *Board) DrawBoard() {
|
||||||
for i := 0; i < board.width; i++ {
|
for i := 0; i < board.width; i++ {
|
||||||
for j := 0; j < board.height; j++ {
|
for j := 0; j < board.height; j++ {
|
||||||
|
@ -268,14 +288,17 @@ func (board *Board) DrawBoard() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DrawPreviewMino draws the preview mino
|
||||||
func (board *Board) DrawPreviewMino() {
|
func (board *Board) DrawPreviewMino() {
|
||||||
board.previewMino.DrawMino(MinoPreview)
|
board.previewMino.DrawMino(MinoPreview)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DrawCurrentMino draws the current mino
|
||||||
func (board *Board) DrawCurrentMino() {
|
func (board *Board) DrawCurrentMino() {
|
||||||
board.currentMino.DrawMino(MinoCurrent)
|
board.currentMino.DrawMino(MinoCurrent)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DrawDropMino draws the drop mino
|
||||||
func (board *Board) DrawDropMino() {
|
func (board *Board) DrawDropMino() {
|
||||||
mino := board.currentMino.CloneMoveDown()
|
mino := board.currentMino.CloneMoveDown()
|
||||||
if !mino.ValidLocation(false) {
|
if !mino.ValidLocation(false) {
|
||||||
|
@ -288,7 +311,7 @@ func (board *Board) DrawDropMino() {
|
||||||
mino.DrawMino(MinoDrop)
|
mino.DrawMino(MinoDrop)
|
||||||
}
|
}
|
||||||
|
|
||||||
// for debuging
|
// printDebugBoard is for printing board in text for debuging
|
||||||
func (board *Board) printDebugBoard() {
|
func (board *Board) printDebugBoard() {
|
||||||
for j := 0; j < board.height; j++ {
|
for j := 0; j < board.height; j++ {
|
||||||
for i := 0; i < board.width; i++ {
|
for i := 0; i < board.width; i++ {
|
||||||
|
@ -317,7 +340,7 @@ func (board *Board) printDebugBoard() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// for debuging
|
// getDebugBoard returns board as string for debuging and testing
|
||||||
func (board *Board) getDebugBoard() []string {
|
func (board *Board) getDebugBoard() []string {
|
||||||
lines := make([]string, board.height)
|
lines := make([]string, board.height)
|
||||||
for j := 0; j < board.height; j++ {
|
for j := 0; j < board.height; j++ {
|
||||||
|
@ -347,7 +370,7 @@ func (board *Board) getDebugBoard() []string {
|
||||||
return lines
|
return lines
|
||||||
}
|
}
|
||||||
|
|
||||||
// for debuging
|
// getDebugBoardWithMino returns board with mino placed on it
|
||||||
func (board *Board) getDebugBoardWithMino(mino *Mino) []string {
|
func (board *Board) getDebugBoardWithMino(mino *Mino) []string {
|
||||||
lines := make([]string, board.height)
|
lines := make([]string, board.height)
|
||||||
for j := 0; j < board.height; j++ {
|
for j := 0; j < board.height; j++ {
|
||||||
|
|
95
boards.go
95
boards.go
|
@ -1082,5 +1082,100 @@ func init() {
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
||||||
}},
|
}},
|
||||||
|
|
||||||
|
// 20 x 20 pumpkin
|
||||||
|
Boards{
|
||||||
|
colors: [][]termbox.Attribute{
|
||||||
|
[]termbox.Attribute{blankColor, blankColor, blankColor, blankColor, blankColor, blankColor, blankColor, blankColor, blankColor, blankColor,
|
||||||
|
blankColor, blankColor, blankColor, blankColor, blankColor, blankColor, blankColor, blankColor, blankColor, blankColor},
|
||||||
|
[]termbox.Attribute{blankColor, blankColor, blankColor, blankColor, blankColor, blankColor, blankColor, blankColor, blankColor, blankColor,
|
||||||
|
blankColor, blankColor, blankColor, blankColor, blankColor, blankColor, blankColor, blankColor, blankColor, blankColor},
|
||||||
|
[]termbox.Attribute{blankColor, blankColor, blankColor, blankColor, blankColor, blankColor, blankColor, blankColor, blankColor, blankColor,
|
||||||
|
blankColor, blankColor, blankColor, blankColor, blankColor, blankColor, blankColor, blankColor, blankColor, blankColor},
|
||||||
|
|
||||||
|
[]termbox.Attribute{blankColor, blankColor, blankColor, blankColor, blankColor, blankColor, blankColor, blankColor, blankColor, termbox.ColorWhite,
|
||||||
|
termbox.ColorWhite, termbox.ColorWhite, blankColor, blankColor, blankColor, blankColor, blankColor, blankColor, blankColor, blankColor},
|
||||||
|
[]termbox.Attribute{blankColor, blankColor, blankColor, blankColor, blankColor, blankColor, blankColor, blankColor, termbox.ColorRed, termbox.ColorRed,
|
||||||
|
termbox.ColorMagenta, termbox.ColorWhite, termbox.ColorYellow, termbox.ColorYellow, blankColor, blankColor, blankColor, blankColor, blankColor, blankColor},
|
||||||
|
[]termbox.Attribute{blankColor, blankColor, blankColor, blankColor, blankColor, blankColor, blankColor, termbox.ColorRed, termbox.ColorRed, termbox.ColorMagenta,
|
||||||
|
termbox.ColorMagenta, termbox.ColorMagenta, termbox.ColorYellow, termbox.ColorYellow, termbox.ColorBlue, blankColor, blankColor, blankColor, blankColor, blankColor},
|
||||||
|
[]termbox.Attribute{blankColor, blankColor, blankColor, blankColor, blankColor, blankColor, blankColor, termbox.ColorWhite, termbox.ColorWhite, termbox.ColorWhite,
|
||||||
|
termbox.ColorCyan, termbox.ColorCyan, termbox.ColorCyan, termbox.ColorCyan, termbox.ColorBlue, blankColor, blankColor, blankColor, blankColor, blankColor},
|
||||||
|
[]termbox.Attribute{blankColor, blankColor, blankColor, blankColor, blankColor, blankColor, blankColor, termbox.ColorGreen, termbox.ColorGreen, termbox.ColorWhite,
|
||||||
|
termbox.ColorWhite, termbox.ColorWhite, termbox.ColorRed, termbox.ColorRed, termbox.ColorBlue, termbox.ColorBlue, blankColor, blankColor, blankColor, blankColor},
|
||||||
|
|
||||||
|
[]termbox.Attribute{blankColor, blankColor, blankColor, blankColor, blankColor, blankColor, blankColor, blankColor, termbox.ColorGreen, termbox.ColorGreen,
|
||||||
|
termbox.ColorWhite, termbox.ColorRed, termbox.ColorRed, termbox.ColorCyan, termbox.ColorCyan, termbox.ColorCyan, termbox.ColorCyan, blankColor, blankColor, blankColor},
|
||||||
|
[]termbox.Attribute{blankColor, blankColor, blankColor, blankColor, blankColor, blankColor, blankColor, blankColor, termbox.ColorBlue, termbox.ColorBlue,
|
||||||
|
termbox.ColorWhite, termbox.ColorGreen, termbox.ColorGreen, termbox.ColorMagenta, termbox.ColorMagenta, termbox.ColorMagenta, termbox.ColorRed, termbox.ColorRed, blankColor, blankColor},
|
||||||
|
[]termbox.Attribute{blankColor, blankColor, blankColor, blankColor, blankColor, blankColor, blankColor, blankColor, termbox.ColorGreen, termbox.ColorBlue,
|
||||||
|
termbox.ColorYellow, termbox.ColorYellow, termbox.ColorGreen, termbox.ColorGreen, termbox.ColorMagenta, termbox.ColorRed, termbox.ColorRed, blankColor, blankColor, blankColor},
|
||||||
|
|
||||||
|
[]termbox.Attribute{blankColor, blankColor, blankColor, blankColor, blankColor, blankColor, blankColor, termbox.ColorGreen, termbox.ColorGreen, termbox.ColorBlue,
|
||||||
|
termbox.ColorYellow, termbox.ColorYellow, termbox.ColorYellow, termbox.ColorYellow, termbox.ColorWhite, termbox.ColorWhite, blankColor, blankColor, blankColor, blankColor},
|
||||||
|
[]termbox.Attribute{blankColor, blankColor, blankColor, blankColor, blankColor, blankColor, blankColor, termbox.ColorGreen, termbox.ColorRed, termbox.ColorRed,
|
||||||
|
termbox.ColorGreen, termbox.ColorGreen, termbox.ColorYellow, termbox.ColorYellow, termbox.ColorWhite, blankColor, blankColor, blankColor, blankColor, blankColor},
|
||||||
|
[]termbox.Attribute{blankColor, blankColor, blankColor, blankColor, blankColor, blankColor, blankColor, termbox.ColorRed, termbox.ColorRed, termbox.ColorMagenta,
|
||||||
|
termbox.ColorBlue, termbox.ColorGreen, termbox.ColorGreen, termbox.ColorBlue, termbox.ColorWhite, blankColor, blankColor, blankColor, blankColor, blankColor},
|
||||||
|
[]termbox.Attribute{blankColor, blankColor, blankColor, blankColor, blankColor, blankColor, blankColor, blankColor, termbox.ColorMagenta, termbox.ColorMagenta,
|
||||||
|
termbox.ColorBlue, termbox.ColorBlue, termbox.ColorBlue, termbox.ColorBlue, blankColor, blankColor, blankColor, blankColor, blankColor, blankColor},
|
||||||
|
[]termbox.Attribute{blankColor, blankColor, blankColor, blankColor, blankColor, blankColor, blankColor, blankColor, blankColor, termbox.ColorMagenta,
|
||||||
|
termbox.ColorBlue, termbox.ColorBlue, blankColor, blankColor, blankColor, blankColor, blankColor, blankColor, blankColor, blankColor},
|
||||||
|
|
||||||
|
[]termbox.Attribute{blankColor, blankColor, blankColor, blankColor, blankColor, blankColor, blankColor, blankColor, blankColor, blankColor,
|
||||||
|
blankColor, blankColor, blankColor, blankColor, blankColor, blankColor, blankColor, blankColor, blankColor, blankColor},
|
||||||
|
[]termbox.Attribute{blankColor, blankColor, blankColor, blankColor, blankColor, blankColor, blankColor, blankColor, blankColor, blankColor,
|
||||||
|
blankColor, blankColor, blankColor, blankColor, blankColor, blankColor, blankColor, blankColor, blankColor, blankColor},
|
||||||
|
[]termbox.Attribute{blankColor, blankColor, blankColor, blankColor, blankColor, blankColor, blankColor, blankColor, blankColor, blankColor,
|
||||||
|
blankColor, blankColor, blankColor, blankColor, blankColor, blankColor, blankColor, blankColor, blankColor, blankColor},
|
||||||
|
[]termbox.Attribute{blankColor, blankColor, blankColor, blankColor, blankColor, blankColor, blankColor, blankColor, blankColor, blankColor,
|
||||||
|
blankColor, blankColor, blankColor, blankColor, blankColor, blankColor, blankColor, blankColor, blankColor, blankColor},
|
||||||
|
},
|
||||||
|
rotation: [][]int{
|
||||||
|
[]int{0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
||||||
|
[]int{0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
||||||
|
[]int{0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
||||||
|
|
||||||
|
[]int{0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
||||||
|
[]int{0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
2, 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
||||||
|
[]int{0, 0, 0, 0, 0, 0, 0, 0, 0, 2,
|
||||||
|
2, 2, 0, 0, 2, 0, 0, 0, 0, 0},
|
||||||
|
[]int{0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
2, 2, 2, 2, 2, 0, 0, 0, 0, 0},
|
||||||
|
[]int{0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
2, 2, 0, 0, 2, 2, 0, 0, 0, 0},
|
||||||
|
|
||||||
|
[]int{0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
2, 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
||||||
|
[]int{0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
2, 0, 0, 0, 0, 0, 2, 2, 0, 0},
|
||||||
|
[]int{0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
2, 2, 0, 0, 0, 2, 2, 0, 0, 0},
|
||||||
|
|
||||||
|
[]int{0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
2, 2, 0, 0, 2, 2, 0, 0, 0, 0},
|
||||||
|
[]int{0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
2, 2, 0, 0, 2, 0, 0, 0, 0, 0},
|
||||||
|
[]int{0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
2, 2, 2, 2, 2, 0, 0, 0, 0, 0},
|
||||||
|
[]int{0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
2, 2, 2, 2, 0, 0, 0, 0, 0, 0},
|
||||||
|
[]int{0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
2, 2, 0, 0, 0, 0, 0, 0, 0, 0},
|
||||||
|
|
||||||
|
[]int{0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
||||||
|
[]int{0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
||||||
|
[]int{0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
||||||
|
[]int{0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
||||||
|
}},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
16
engine.go
16
engine.go
|
@ -6,6 +6,7 @@ import (
|
||||||
"github.com/nsf/termbox-go"
|
"github.com/nsf/termbox-go"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// NewEngine creates new engine
|
||||||
func NewEngine() {
|
func NewEngine() {
|
||||||
engine = &Engine{
|
engine = &Engine{
|
||||||
chanStop: make(chan struct{}, 1),
|
chanStop: make(chan struct{}, 1),
|
||||||
|
@ -15,6 +16,7 @@ func NewEngine() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Run runs the engine
|
||||||
func (engine *Engine) Run() {
|
func (engine *Engine) Run() {
|
||||||
logger.Println("Engine Run start")
|
logger.Println("Engine Run start")
|
||||||
|
|
||||||
|
@ -56,6 +58,7 @@ loop:
|
||||||
logger.Println("Engine Run end")
|
logger.Println("Engine Run end")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Stop stops the engine
|
||||||
func (engine *Engine) Stop() {
|
func (engine *Engine) Stop() {
|
||||||
logger.Println("Engine Stop start")
|
logger.Println("Engine Stop start")
|
||||||
|
|
||||||
|
@ -69,6 +72,7 @@ func (engine *Engine) Stop() {
|
||||||
logger.Println("Engine Stop end")
|
logger.Println("Engine Stop end")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Pause pauses the engine
|
||||||
func (engine *Engine) Pause() {
|
func (engine *Engine) Pause() {
|
||||||
if !engine.timer.Stop() {
|
if !engine.timer.Stop() {
|
||||||
select {
|
select {
|
||||||
|
@ -85,6 +89,7 @@ func (engine *Engine) Pause() {
|
||||||
engine.paused = true
|
engine.paused = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// UnPause resumes running the engine
|
||||||
func (engine *Engine) UnPause() {
|
func (engine *Engine) UnPause() {
|
||||||
engine.timer.Reset(engine.tickTime)
|
engine.timer.Reset(engine.tickTime)
|
||||||
if engine.aiEnabled {
|
if engine.aiEnabled {
|
||||||
|
@ -93,10 +98,12 @@ func (engine *Engine) UnPause() {
|
||||||
engine.paused = false
|
engine.paused = false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// PreviewBoard sets previewBoard to true
|
||||||
func (engine *Engine) PreviewBoard() {
|
func (engine *Engine) PreviewBoard() {
|
||||||
engine.previewBoard = true
|
engine.previewBoard = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NewGame resets board and starts a new game
|
||||||
func (engine *Engine) NewGame() {
|
func (engine *Engine) NewGame() {
|
||||||
logger.Println("Engine NewGame start")
|
logger.Println("Engine NewGame start")
|
||||||
|
|
||||||
|
@ -125,6 +132,7 @@ loop:
|
||||||
logger.Println("Engine NewGame end")
|
logger.Println("Engine NewGame end")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ResetTimer resets the time for lock delay or tick time
|
||||||
func (engine *Engine) ResetTimer(duration time.Duration) {
|
func (engine *Engine) ResetTimer(duration time.Duration) {
|
||||||
if !engine.timer.Stop() {
|
if !engine.timer.Stop() {
|
||||||
select {
|
select {
|
||||||
|
@ -141,6 +149,7 @@ func (engine *Engine) ResetTimer(duration time.Duration) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AiGetBestQueue calls AI to get best queue
|
||||||
func (engine *Engine) AiGetBestQueue() {
|
func (engine *Engine) AiGetBestQueue() {
|
||||||
if !engine.aiEnabled {
|
if !engine.aiEnabled {
|
||||||
return
|
return
|
||||||
|
@ -148,11 +157,13 @@ func (engine *Engine) AiGetBestQueue() {
|
||||||
go engine.ai.GetBestQueue()
|
go engine.ai.GetBestQueue()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// tick move mino down and refreshes screen
|
||||||
func (engine *Engine) tick() {
|
func (engine *Engine) tick() {
|
||||||
board.MinoMoveDown()
|
board.MinoMoveDown()
|
||||||
view.RefreshScreen()
|
view.RefreshScreen()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AddDeleteLines adds deleted lines to score
|
||||||
func (engine *Engine) AddDeleteLines(lines int) {
|
func (engine *Engine) AddDeleteLines(lines int) {
|
||||||
engine.deleteLines += lines
|
engine.deleteLines += lines
|
||||||
if engine.deleteLines > 999999 {
|
if engine.deleteLines > 999999 {
|
||||||
|
@ -175,6 +186,7 @@ func (engine *Engine) AddDeleteLines(lines int) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AddScore adds to score
|
||||||
func (engine *Engine) AddScore(add int) {
|
func (engine *Engine) AddScore(add int) {
|
||||||
engine.score += add
|
engine.score += add
|
||||||
if engine.score > 9999999 {
|
if engine.score > 9999999 {
|
||||||
|
@ -182,6 +194,7 @@ func (engine *Engine) AddScore(add int) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// LevelUp goes up a level
|
||||||
func (engine *Engine) LevelUp() {
|
func (engine *Engine) LevelUp() {
|
||||||
if engine.level >= 30 {
|
if engine.level >= 30 {
|
||||||
return
|
return
|
||||||
|
@ -205,6 +218,7 @@ func (engine *Engine) LevelUp() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GameOver pauses engine and sets to game over
|
||||||
func (engine *Engine) GameOver() {
|
func (engine *Engine) GameOver() {
|
||||||
logger.Println("Engine GameOver start")
|
logger.Println("Engine GameOver start")
|
||||||
|
|
||||||
|
@ -228,12 +242,14 @@ loop:
|
||||||
logger.Println("Engine GameOver end")
|
logger.Println("Engine GameOver end")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// EnabledAi enables the AI
|
||||||
func (engine *Engine) EnabledAi() {
|
func (engine *Engine) EnabledAi() {
|
||||||
engine.aiEnabled = true
|
engine.aiEnabled = true
|
||||||
go engine.ai.GetBestQueue()
|
go engine.ai.GetBestQueue()
|
||||||
engine.aiTimer.Reset(engine.tickTime / 6)
|
engine.aiTimer.Reset(engine.tickTime / 6)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DisableAi disables the AI
|
||||||
func (engine *Engine) DisableAi() {
|
func (engine *Engine) DisableAi() {
|
||||||
engine.aiEnabled = false
|
engine.aiEnabled = false
|
||||||
if !engine.aiTimer.Stop() {
|
if !engine.aiTimer.Stop() {
|
||||||
|
|
23
globals.go
23
globals.go
|
@ -13,16 +13,23 @@ const (
|
||||||
boardYOffset = 2
|
boardYOffset = 2
|
||||||
rankingFileName = "/tetris.db"
|
rankingFileName = "/tetris.db"
|
||||||
|
|
||||||
|
// MinoPreview is for the preview mino
|
||||||
MinoPreview MinoType = iota
|
MinoPreview MinoType = iota
|
||||||
MinoCurrent = iota
|
// MinoCurrent is for the current mino
|
||||||
MinoDrop = iota
|
MinoCurrent = iota
|
||||||
|
// MinoDrop is for the drop mino
|
||||||
|
MinoDrop = iota
|
||||||
)
|
)
|
||||||
|
|
||||||
type (
|
type (
|
||||||
MinoType int
|
// MinoType is the type of mino
|
||||||
MinoBlocks [][]termbox.Attribute
|
MinoType int
|
||||||
|
// MinoBlocks is the blocks of the mino
|
||||||
|
MinoBlocks [][]termbox.Attribute
|
||||||
|
// MinoRotation is the rotation of the mino
|
||||||
MinoRotation [4]MinoBlocks
|
MinoRotation [4]MinoBlocks
|
||||||
|
|
||||||
|
// Mino is a mino
|
||||||
Mino struct {
|
Mino struct {
|
||||||
x int
|
x int
|
||||||
y int
|
y int
|
||||||
|
@ -31,12 +38,14 @@ type (
|
||||||
minoRotation MinoRotation
|
minoRotation MinoRotation
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Minos is a bag of minos
|
||||||
Minos struct {
|
Minos struct {
|
||||||
minoBag [7]MinoRotation
|
minoBag [7]MinoRotation
|
||||||
bagRand []int
|
bagRand []int
|
||||||
bagIndex int
|
bagIndex int
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Board is the Tetris board
|
||||||
Board struct {
|
Board struct {
|
||||||
boardsIndex int
|
boardsIndex int
|
||||||
width int
|
width int
|
||||||
|
@ -48,30 +57,36 @@ type (
|
||||||
dropDistance int
|
dropDistance int
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Boards holds all the premade boards
|
||||||
Boards struct {
|
Boards struct {
|
||||||
colors [][]termbox.Attribute
|
colors [][]termbox.Attribute
|
||||||
rotation [][]int
|
rotation [][]int
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// KeyInput is the key input engine
|
||||||
KeyInput struct {
|
KeyInput struct {
|
||||||
stopped bool
|
stopped bool
|
||||||
chanStop chan struct{}
|
chanStop chan struct{}
|
||||||
chanKeyInput chan *termbox.Event
|
chanKeyInput chan *termbox.Event
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// View is the display engine
|
||||||
View struct {
|
View struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Ai is the AI engine
|
||||||
Ai struct {
|
Ai struct {
|
||||||
queue *[]rune
|
queue *[]rune
|
||||||
newQueue *[]rune
|
newQueue *[]rune
|
||||||
index int
|
index int
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Ranking holds the ranking scores
|
||||||
Ranking struct {
|
Ranking struct {
|
||||||
scores []uint64
|
scores []uint64
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Engine is the Tetirs game engine
|
||||||
Engine struct {
|
Engine struct {
|
||||||
stopped bool
|
stopped bool
|
||||||
chanStop chan struct{}
|
chanStop chan struct{}
|
||||||
|
|
|
@ -6,6 +6,7 @@ import (
|
||||||
"github.com/nsf/termbox-go"
|
"github.com/nsf/termbox-go"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// NewKeyInput creates a new KeyInput
|
||||||
func NewKeyInput() *KeyInput {
|
func NewKeyInput() *KeyInput {
|
||||||
return &KeyInput{
|
return &KeyInput{
|
||||||
chanStop: make(chan struct{}, 1),
|
chanStop: make(chan struct{}, 1),
|
||||||
|
@ -13,6 +14,7 @@ func NewKeyInput() *KeyInput {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Run starts the KeyInput engine
|
||||||
func (keyInput *KeyInput) Run() {
|
func (keyInput *KeyInput) Run() {
|
||||||
logger.Println("KeyInput Run start")
|
logger.Println("KeyInput Run start")
|
||||||
|
|
||||||
|
@ -36,6 +38,7 @@ loop:
|
||||||
logger.Println("KeyInput Run end")
|
logger.Println("KeyInput Run end")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ProcessEvent process the key input event
|
||||||
func (keyInput *KeyInput) ProcessEvent(event *termbox.Event) {
|
func (keyInput *KeyInput) ProcessEvent(event *termbox.Event) {
|
||||||
if event.Key == termbox.KeyCtrlI {
|
if event.Key == termbox.KeyCtrlI {
|
||||||
// Ctrl l (lower case L) to log stack trace
|
// Ctrl l (lower case L) to log stack trace
|
||||||
|
|
18
mino.go
18
mino.go
|
@ -6,6 +6,7 @@ import (
|
||||||
"github.com/nsf/termbox-go"
|
"github.com/nsf/termbox-go"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// NewMino creates a new Mino
|
||||||
func NewMino() *Mino {
|
func NewMino() *Mino {
|
||||||
minoRotation := minos.minoBag[minos.bagRand[minos.bagIndex]]
|
minoRotation := minos.minoBag[minos.bagRand[minos.bagIndex]]
|
||||||
minos.bagIndex++
|
minos.bagIndex++
|
||||||
|
@ -22,32 +23,38 @@ func NewMino() *Mino {
|
||||||
return mino
|
return mino
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CloneMoveLeft creates copy of the mino and moves it left
|
||||||
func (mino *Mino) CloneMoveLeft() *Mino {
|
func (mino *Mino) CloneMoveLeft() *Mino {
|
||||||
newMino := *mino
|
newMino := *mino
|
||||||
newMino.MoveLeft()
|
newMino.MoveLeft()
|
||||||
return &newMino
|
return &newMino
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MoveLeft moves the mino left
|
||||||
func (mino *Mino) MoveLeft() {
|
func (mino *Mino) MoveLeft() {
|
||||||
mino.x--
|
mino.x--
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CloneMoveRight creates copy of the mino and moves it right
|
||||||
func (mino *Mino) CloneMoveRight() *Mino {
|
func (mino *Mino) CloneMoveRight() *Mino {
|
||||||
newMino := *mino
|
newMino := *mino
|
||||||
newMino.MoveRight()
|
newMino.MoveRight()
|
||||||
return &newMino
|
return &newMino
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MoveRight moves the mino right
|
||||||
func (mino *Mino) MoveRight() {
|
func (mino *Mino) MoveRight() {
|
||||||
mino.x++
|
mino.x++
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CloneRotateRight creates copy of the mino and rotates it right
|
||||||
func (mino *Mino) CloneRotateRight() *Mino {
|
func (mino *Mino) CloneRotateRight() *Mino {
|
||||||
newMino := *mino
|
newMino := *mino
|
||||||
newMino.RotateRight()
|
newMino.RotateRight()
|
||||||
return &newMino
|
return &newMino
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// RotateRight rotates the mino right
|
||||||
func (mino *Mino) RotateRight() {
|
func (mino *Mino) RotateRight() {
|
||||||
mino.rotation++
|
mino.rotation++
|
||||||
if mino.rotation > 3 {
|
if mino.rotation > 3 {
|
||||||
|
@ -55,12 +62,14 @@ func (mino *Mino) RotateRight() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CloneRotateLeft creates copy of the mino and rotates it left
|
||||||
func (mino *Mino) CloneRotateLeft() *Mino {
|
func (mino *Mino) CloneRotateLeft() *Mino {
|
||||||
newMino := *mino
|
newMino := *mino
|
||||||
newMino.RotateLeft()
|
newMino.RotateLeft()
|
||||||
return &newMino
|
return &newMino
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// RotateLeft rotates the mino left
|
||||||
func (mino *Mino) RotateLeft() {
|
func (mino *Mino) RotateLeft() {
|
||||||
if mino.rotation < 1 {
|
if mino.rotation < 1 {
|
||||||
mino.rotation = 3
|
mino.rotation = 3
|
||||||
|
@ -69,20 +78,24 @@ func (mino *Mino) RotateLeft() {
|
||||||
mino.rotation--
|
mino.rotation--
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CloneMoveDown creates copy of the mino and moves it down
|
||||||
func (mino *Mino) CloneMoveDown() *Mino {
|
func (mino *Mino) CloneMoveDown() *Mino {
|
||||||
newMino := *mino
|
newMino := *mino
|
||||||
newMino.MoveDown()
|
newMino.MoveDown()
|
||||||
return &newMino
|
return &newMino
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MoveDown moves the mino down
|
||||||
func (mino *Mino) MoveDown() {
|
func (mino *Mino) MoveDown() {
|
||||||
mino.y++
|
mino.y++
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MoveUp moves the mino up
|
||||||
func (mino *Mino) MoveUp() {
|
func (mino *Mino) MoveUp() {
|
||||||
mino.y--
|
mino.y--
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ValidLocation check if the mino is in a valid location
|
||||||
func (mino *Mino) ValidLocation(mustBeOnBoard bool) bool {
|
func (mino *Mino) ValidLocation(mustBeOnBoard bool) bool {
|
||||||
minoBlocks := mino.minoRotation[mino.rotation]
|
minoBlocks := mino.minoRotation[mino.rotation]
|
||||||
for i := 0; i < mino.length; i++ {
|
for i := 0; i < mino.length; i++ {
|
||||||
|
@ -97,6 +110,7 @@ func (mino *Mino) ValidLocation(mustBeOnBoard bool) bool {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetOnBoard attaches mino to the board
|
||||||
func (mino *Mino) SetOnBoard() {
|
func (mino *Mino) SetOnBoard() {
|
||||||
minoBlocks := mino.minoRotation[mino.rotation]
|
minoBlocks := mino.minoRotation[mino.rotation]
|
||||||
for i := 0; i < mino.length; i++ {
|
for i := 0; i < mino.length; i++ {
|
||||||
|
@ -108,6 +122,7 @@ func (mino *Mino) SetOnBoard() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DrawMino draws the mino on the board
|
||||||
func (mino *Mino) DrawMino(minoType MinoType) {
|
func (mino *Mino) DrawMino(minoType MinoType) {
|
||||||
minoBlocks := mino.minoRotation[mino.rotation]
|
minoBlocks := mino.minoRotation[mino.rotation]
|
||||||
for i := 0; i < mino.length; i++ {
|
for i := 0; i < mino.length; i++ {
|
||||||
|
@ -128,6 +143,7 @@ func (mino *Mino) DrawMino(minoType MinoType) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// minoOverlap check if a mino overlaps anohter mino
|
||||||
func (mino *Mino) minoOverlap(mino1 *Mino) bool {
|
func (mino *Mino) minoOverlap(mino1 *Mino) bool {
|
||||||
minoBlocks := mino.minoRotation[mino.rotation]
|
minoBlocks := mino.minoRotation[mino.rotation]
|
||||||
for i := 0; i < mino.length; i++ {
|
for i := 0; i < mino.length; i++ {
|
||||||
|
@ -142,6 +158,7 @@ func (mino *Mino) minoOverlap(mino1 *Mino) bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// isMinoAtLocation check if a mino block is in a location
|
||||||
func (mino *Mino) isMinoAtLocation(x int, y int) bool {
|
func (mino *Mino) isMinoAtLocation(x int, y int) bool {
|
||||||
xIndex := x - mino.x
|
xIndex := x - mino.x
|
||||||
yIndex := y - mino.y
|
yIndex := y - mino.y
|
||||||
|
@ -157,6 +174,7 @@ func (mino *Mino) isMinoAtLocation(x int, y int) bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// getMinoColorAtLocation gets the mino color at a location
|
||||||
func (mino *Mino) getMinoColorAtLocation(x int, y int) termbox.Attribute {
|
func (mino *Mino) getMinoColorAtLocation(x int, y int) termbox.Attribute {
|
||||||
xIndex := x - mino.x
|
xIndex := x - mino.x
|
||||||
yIndex := y - mino.y
|
yIndex := y - mino.y
|
||||||
|
|
2
minos.go
2
minos.go
|
@ -6,6 +6,7 @@ import (
|
||||||
"github.com/nsf/termbox-go"
|
"github.com/nsf/termbox-go"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// NewMinos creates the minos and minoBag
|
||||||
func NewMinos() {
|
func NewMinos() {
|
||||||
minoI := MinoBlocks{
|
minoI := MinoBlocks{
|
||||||
[]termbox.Attribute{blankColor, termbox.ColorCyan, blankColor, blankColor},
|
[]termbox.Attribute{blankColor, termbox.ColorCyan, blankColor, blankColor},
|
||||||
|
@ -85,6 +86,7 @@ func NewMinos() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// minosCloneRotateRight clones a mino and rotates the mino to the right
|
||||||
func minosCloneRotateRight(minoBlocks MinoBlocks) MinoBlocks {
|
func minosCloneRotateRight(minoBlocks MinoBlocks) MinoBlocks {
|
||||||
length := len(minoBlocks)
|
length := len(minoBlocks)
|
||||||
newMinoBlocks := make(MinoBlocks, length, length)
|
newMinoBlocks := make(MinoBlocks, length, length)
|
||||||
|
|
|
@ -8,6 +8,7 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// NewRanking create a new ranking
|
||||||
func NewRanking() *Ranking {
|
func NewRanking() *Ranking {
|
||||||
ranking := &Ranking{
|
ranking := &Ranking{
|
||||||
scores: make([]uint64, 9),
|
scores: make([]uint64, 9),
|
||||||
|
@ -41,6 +42,7 @@ func NewRanking() *Ranking {
|
||||||
return ranking
|
return ranking
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Save saves the rankings to a file
|
||||||
func (ranking *Ranking) Save() {
|
func (ranking *Ranking) Save() {
|
||||||
var buffer bytes.Buffer
|
var buffer bytes.Buffer
|
||||||
|
|
||||||
|
@ -54,6 +56,7 @@ func (ranking *Ranking) Save() {
|
||||||
ioutil.WriteFile(baseDir+rankingFileName, buffer.Bytes(), 0644)
|
ioutil.WriteFile(baseDir+rankingFileName, buffer.Bytes(), 0644)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// InsertScore inserts a score into the rankings
|
||||||
func (ranking *Ranking) InsertScore(newScore uint64) {
|
func (ranking *Ranking) InsertScore(newScore uint64) {
|
||||||
for index, score := range ranking.scores {
|
for index, score := range ranking.scores {
|
||||||
if newScore > score {
|
if newScore > score {
|
||||||
|
@ -64,6 +67,7 @@ func (ranking *Ranking) InsertScore(newScore uint64) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// slideScores slides the scores down to make room for a new score
|
||||||
func (ranking *Ranking) slideScores(index int) {
|
func (ranking *Ranking) slideScores(index int) {
|
||||||
for i := len(ranking.scores) - 1; i > index; i-- {
|
for i := len(ranking.scores) - 1; i > index; i-- {
|
||||||
ranking.scores[i] = ranking.scores[i-1]
|
ranking.scores[i] = ranking.scores[i-1]
|
||||||
|
|
15
view.go
15
view.go
|
@ -8,6 +8,7 @@ import (
|
||||||
"github.com/nsf/termbox-go"
|
"github.com/nsf/termbox-go"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// NewView creates a new view
|
||||||
func NewView() {
|
func NewView() {
|
||||||
err := termbox.Init()
|
err := termbox.Init()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -18,6 +19,7 @@ func NewView() {
|
||||||
view = &View{}
|
view = &View{}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Stop stops the view
|
||||||
func (view *View) Stop() {
|
func (view *View) Stop() {
|
||||||
logger.Println("View Stop start")
|
logger.Println("View Stop start")
|
||||||
|
|
||||||
|
@ -26,6 +28,7 @@ func (view *View) Stop() {
|
||||||
logger.Println("View Stop end")
|
logger.Println("View Stop end")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// RefreshScreen refreshs the updated view to the screen
|
||||||
func (view *View) RefreshScreen() {
|
func (view *View) RefreshScreen() {
|
||||||
termbox.Clear(termbox.ColorDefault, termbox.ColorDefault)
|
termbox.Clear(termbox.ColorDefault, termbox.ColorDefault)
|
||||||
|
|
||||||
|
@ -50,6 +53,7 @@ func (view *View) RefreshScreen() {
|
||||||
termbox.Flush()
|
termbox.Flush()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// drawBackground draws the background
|
||||||
func (view *View) drawBackground() {
|
func (view *View) drawBackground() {
|
||||||
// playing board
|
// playing board
|
||||||
xOffset := boardXOffset
|
xOffset := boardXOffset
|
||||||
|
@ -85,6 +89,7 @@ func (view *View) drawBackground() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// drawTexts draws the text
|
||||||
func (view *View) drawTexts() {
|
func (view *View) drawTexts() {
|
||||||
xOffset := boardXOffset + board.width*2 + 8
|
xOffset := boardXOffset + board.width*2 + 8
|
||||||
yOffset := boardYOffset + 7
|
yOffset := boardYOffset + 7
|
||||||
|
@ -124,6 +129,7 @@ func (view *View) drawTexts() {
|
||||||
view.drawText(xOffset, yOffset, "q - quit", termbox.ColorWhite, termbox.ColorBlack)
|
view.drawText(xOffset, yOffset, "q - quit", termbox.ColorWhite, termbox.ColorBlack)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DrawPreviewMinoBlock draws the preview mino
|
||||||
func (view *View) DrawPreviewMinoBlock(x int, y int, color termbox.Attribute, rotation int, length int) {
|
func (view *View) DrawPreviewMinoBlock(x int, y int, color termbox.Attribute, rotation int, length int) {
|
||||||
var char1 rune
|
var char1 rune
|
||||||
var char2 rune
|
var char2 rune
|
||||||
|
@ -139,6 +145,7 @@ func (view *View) DrawPreviewMinoBlock(x int, y int, color termbox.Attribute, ro
|
||||||
termbox.SetCell(xOffset+1, y+boardYOffset+2, char2, color, color^termbox.AttrBold)
|
termbox.SetCell(xOffset+1, y+boardYOffset+2, char2, color, color^termbox.AttrBold)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DrawBlock draws a block
|
||||||
func (view *View) DrawBlock(x int, y int, color termbox.Attribute, rotation int) {
|
func (view *View) DrawBlock(x int, y int, color termbox.Attribute, rotation int) {
|
||||||
var char1 rune
|
var char1 rune
|
||||||
var char2 rune
|
var char2 rune
|
||||||
|
@ -159,11 +166,13 @@ func (view *View) DrawBlock(x int, y int, color termbox.Attribute, rotation int)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// drawPaused draws Paused
|
||||||
func (view *View) drawPaused() {
|
func (view *View) drawPaused() {
|
||||||
yOffset := (board.height+1)/2 + boardYOffset
|
yOffset := (board.height+1)/2 + boardYOffset
|
||||||
view.drawTextCenter(yOffset, "Paused", termbox.ColorWhite, termbox.ColorBlack)
|
view.drawTextCenter(yOffset, "Paused", termbox.ColorWhite, termbox.ColorBlack)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// drawGameOver draws GAME OVER
|
||||||
func (view *View) drawGameOver() {
|
func (view *View) drawGameOver() {
|
||||||
yOffset := boardYOffset + 2
|
yOffset := boardYOffset + 2
|
||||||
view.drawTextCenter(yOffset, " GAME OVER", termbox.ColorWhite, termbox.ColorBlack)
|
view.drawTextCenter(yOffset, " GAME OVER", termbox.ColorWhite, termbox.ColorBlack)
|
||||||
|
@ -181,6 +190,7 @@ func (view *View) drawGameOver() {
|
||||||
view.drawTextCenter(yOffset, "→next board", termbox.ColorWhite, termbox.ColorBlack)
|
view.drawTextCenter(yOffset, "→next board", termbox.ColorWhite, termbox.ColorBlack)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// drawRankingScores draws the ranking scores
|
||||||
func (view *View) drawRankingScores() {
|
func (view *View) drawRankingScores() {
|
||||||
yOffset := boardYOffset + 10
|
yOffset := boardYOffset + 10
|
||||||
for index, line := range engine.ranking.scores {
|
for index, line := range engine.ranking.scores {
|
||||||
|
@ -188,12 +198,14 @@ func (view *View) drawRankingScores() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// drawText draws the provided text
|
||||||
func (view *View) drawText(x int, y int, text string, fg termbox.Attribute, bg termbox.Attribute) {
|
func (view *View) drawText(x int, y int, text string, fg termbox.Attribute, bg termbox.Attribute) {
|
||||||
for index, char := range text {
|
for index, char := range text {
|
||||||
termbox.SetCell(x+index, y, rune(char), fg, bg)
|
termbox.SetCell(x+index, y, rune(char), fg, bg)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// drawTextCenter draws text in the center of the board
|
||||||
func (view *View) drawTextCenter(y int, text string, fg termbox.Attribute, bg termbox.Attribute) {
|
func (view *View) drawTextCenter(y int, text string, fg termbox.Attribute, bg termbox.Attribute) {
|
||||||
xOffset := board.width - (len(text)+1)/2 + boardXOffset + 2
|
xOffset := board.width - (len(text)+1)/2 + boardXOffset + 2
|
||||||
for index, char := range text {
|
for index, char := range text {
|
||||||
|
@ -201,6 +213,7 @@ func (view *View) drawTextCenter(y int, text string, fg termbox.Attribute, bg te
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ShowDeleteAnimation draws the delete animation
|
||||||
func (view *View) ShowDeleteAnimation(lines []int) {
|
func (view *View) ShowDeleteAnimation(lines []int) {
|
||||||
view.RefreshScreen()
|
view.RefreshScreen()
|
||||||
|
|
||||||
|
@ -216,6 +229,7 @@ func (view *View) ShowDeleteAnimation(lines []int) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ShowGameOverAnimation draws one randomily picked gave over animation
|
||||||
func (view *View) ShowGameOverAnimation() {
|
func (view *View) ShowGameOverAnimation() {
|
||||||
logger.Println("View ShowGameOverAnimation start")
|
logger.Println("View ShowGameOverAnimation start")
|
||||||
|
|
||||||
|
@ -283,6 +297,7 @@ func (view *View) ShowGameOverAnimation() {
|
||||||
logger.Println("View ShowGameOverAnimation end")
|
logger.Println("View ShowGameOverAnimation end")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// colorizeLine changes the color of a line
|
||||||
func (view *View) colorizeLine(y int, color termbox.Attribute) {
|
func (view *View) colorizeLine(y int, color termbox.Attribute) {
|
||||||
for x := 0; x < board.width; x++ {
|
for x := 0; x < board.width; x++ {
|
||||||
termbox.SetCell(x*2+boardXOffset+2, y+boardYOffset+1, ' ', termbox.ColorDefault, color)
|
termbox.SetCell(x*2+boardXOffset+2, y+boardYOffset+1, ' ', termbox.ColorDefault, color)
|
||||||
|
|
Loading…
Reference in New Issue