Added comments

This commit is contained in:
MichaelS11 2018-10-02 18:21:08 -07:00
parent ebcc296976
commit 0ad9733f01
10 changed files with 201 additions and 7 deletions

3
ai.go
View File

@ -4,6 +4,7 @@ import (
"github.com/nsf/termbox-go"
)
// NewAi creates a new AI
func NewAi() *Ai {
ai := Ai{}
queue := make([]rune, 1)
@ -12,6 +13,7 @@ func NewAi() *Ai {
return &ai
}
// ProcessQueue checks AI queue and process key moments
func (ai *Ai) ProcessQueue() {
if ai.newQueue != nil {
ai.queue = ai.newQueue
@ -38,6 +40,7 @@ func (ai *Ai) ProcessQueue() {
view.RefreshScreen()
}
// GetBestQueue gets the best queue
func (ai *Ai) GetBestQueue() {
bestScore := -9999999
bestQueue := make([]rune, 0, 0)

View File

@ -7,11 +7,13 @@ import (
"github.com/nsf/termbox-go"
)
// NewBoard creates a new clear board
func NewBoard() {
board = &Board{}
board.Clear()
}
// Clear clears the board
func (board *Board) Clear() {
board.width = len(boards[board.boardsIndex].colors)
board.height = len(boards[board.boardsIndex].colors[0])
@ -29,6 +31,7 @@ func (board *Board) Clear() {
board.currentMino = NewMino()
}
// PreviousBoard switchs to previous board
func (board *Board) PreviousBoard() {
board.boardsIndex--
if board.boardsIndex < 0 {
@ -38,6 +41,7 @@ func (board *Board) PreviousBoard() {
board.Clear()
}
// NextBoard switchs to next board
func (board *Board) NextBoard() {
board.boardsIndex++
if board.boardsIndex == len(boards) {
@ -47,6 +51,7 @@ func (board *Board) NextBoard() {
board.Clear()
}
// MinoMoveLeft moves mino left
func (board *Board) MinoMoveLeft() {
board.dropDistance = 0
mino := board.currentMino.CloneMoveLeft()
@ -56,6 +61,7 @@ func (board *Board) MinoMoveLeft() {
}
}
// MinoMoveRight moves mino right
func (board *Board) MinoMoveRight() {
board.dropDistance = 0
mino := board.currentMino.CloneMoveRight()
@ -65,6 +71,7 @@ func (board *Board) MinoMoveRight() {
}
}
// MinoRotateRight rotates mino right
func (board *Board) MinoRotateRight() {
board.dropDistance = 0
mino := board.currentMino.CloneRotateRight()
@ -88,6 +95,7 @@ func (board *Board) MinoRotateRight() {
}
}
// MinoRotateLeft rotates mino right
func (board *Board) MinoRotateLeft() {
board.dropDistance = 0
mino := board.currentMino.CloneRotateLeft()
@ -111,6 +119,7 @@ func (board *Board) MinoRotateLeft() {
}
}
// MinoMoveDown moves mino down
func (board *Board) MinoMoveDown() {
mino := board.currentMino.CloneMoveDown()
if mino.ValidLocation(false) {
@ -128,6 +137,7 @@ func (board *Board) MinoMoveDown() {
board.nextMino()
}
// MinoDrop dropps mino
func (board *Board) MinoDrop() {
board.dropDistance = 0
mino := board.currentMino.CloneMoveDown()
@ -150,6 +160,7 @@ func (board *Board) MinoDrop() {
}
}
// StartLockDelayIfBottom if at bottom, starts lock delay
func (board *Board) StartLockDelayIfBottom() bool {
mino := board.currentMino.CloneMoveDown()
if mino.ValidLocation(false) {
@ -159,6 +170,7 @@ func (board *Board) StartLockDelayIfBottom() bool {
return true
}
// nextMino gets next mino
func (board *Board) nextMino() {
engine.AddScore(board.dropDistance)
@ -180,6 +192,7 @@ func (board *Board) nextMino() {
engine.ResetTimer(0)
}
// deleteCheck checks if there are any lines on the board that can be deleted
func (board *Board) deleteCheck() {
lines := board.fullLines()
if len(lines) < 1 {
@ -194,6 +207,7 @@ func (board *Board) deleteCheck() {
engine.AddDeleteLines(len(lines))
}
// fullLines returns the line numbers that have full lines
func (board *Board) fullLines() []int {
fullLines := make([]int, 0, 1)
for j := 0; j < board.height; j++ {
@ -204,6 +218,7 @@ func (board *Board) fullLines() []int {
return fullLines
}
// isFullLine checks if line is full
func (board *Board) isFullLine(j int) bool {
for i := 0; i < board.width; i++ {
if board.colors[i][j] == blankColor {
@ -213,6 +228,7 @@ func (board *Board) isFullLine(j int) bool {
return true
}
// deleteLine deletes the line
func (board *Board) deleteLine(line int) {
for i := 0; i < board.width; i++ {
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) {
board.colors[x][y] = color
board.rotation[x][y] = rotation
}
// ValidBlockLocation checks if block location is vaild
func (board *Board) ValidBlockLocation(x int, y int, mustBeOnBoard bool) bool {
if x < 0 || x >= board.width || y >= board.height {
return false
@ -254,10 +272,12 @@ func (board *Board) ValidBlockLocation(x int, y int, mustBeOnBoard bool) bool {
return true
}
// ValidDisplayLocation checks if vaild display location
func ValidDisplayLocation(x int, y int) bool {
return x >= 0 && x < board.width && y >= 0 && y < board.height
}
// DrawBoard draws the board with help from view
func (board *Board) DrawBoard() {
for i := 0; i < board.width; i++ {
for j := 0; j < board.height; j++ {
@ -268,14 +288,17 @@ func (board *Board) DrawBoard() {
}
}
// DrawPreviewMino draws the preview mino
func (board *Board) DrawPreviewMino() {
board.previewMino.DrawMino(MinoPreview)
}
// DrawCurrentMino draws the current mino
func (board *Board) DrawCurrentMino() {
board.currentMino.DrawMino(MinoCurrent)
}
// DrawDropMino draws the drop mino
func (board *Board) DrawDropMino() {
mino := board.currentMino.CloneMoveDown()
if !mino.ValidLocation(false) {
@ -288,7 +311,7 @@ func (board *Board) DrawDropMino() {
mino.DrawMino(MinoDrop)
}
// for debuging
// printDebugBoard is for printing board in text for debuging
func (board *Board) printDebugBoard() {
for j := 0; j < board.height; j++ {
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 {
lines := make([]string, board.height)
for j := 0; j < board.height; j++ {
@ -347,7 +370,7 @@ func (board *Board) getDebugBoard() []string {
return lines
}
// for debuging
// getDebugBoardWithMino returns board with mino placed on it
func (board *Board) getDebugBoardWithMino(mino *Mino) []string {
lines := make([]string, board.height)
for j := 0; j < board.height; j++ {

View File

@ -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},
}},
// 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},
}},
}
}

View File

@ -6,6 +6,7 @@ import (
"github.com/nsf/termbox-go"
)
// NewEngine creates new engine
func NewEngine() {
engine = &Engine{
chanStop: make(chan struct{}, 1),
@ -15,6 +16,7 @@ func NewEngine() {
}
}
// Run runs the engine
func (engine *Engine) Run() {
logger.Println("Engine Run start")
@ -56,6 +58,7 @@ loop:
logger.Println("Engine Run end")
}
// Stop stops the engine
func (engine *Engine) Stop() {
logger.Println("Engine Stop start")
@ -69,6 +72,7 @@ func (engine *Engine) Stop() {
logger.Println("Engine Stop end")
}
// Pause pauses the engine
func (engine *Engine) Pause() {
if !engine.timer.Stop() {
select {
@ -85,6 +89,7 @@ func (engine *Engine) Pause() {
engine.paused = true
}
// UnPause resumes running the engine
func (engine *Engine) UnPause() {
engine.timer.Reset(engine.tickTime)
if engine.aiEnabled {
@ -93,10 +98,12 @@ func (engine *Engine) UnPause() {
engine.paused = false
}
// PreviewBoard sets previewBoard to true
func (engine *Engine) PreviewBoard() {
engine.previewBoard = true
}
// NewGame resets board and starts a new game
func (engine *Engine) NewGame() {
logger.Println("Engine NewGame start")
@ -125,6 +132,7 @@ loop:
logger.Println("Engine NewGame end")
}
// ResetTimer resets the time for lock delay or tick time
func (engine *Engine) ResetTimer(duration time.Duration) {
if !engine.timer.Stop() {
select {
@ -141,6 +149,7 @@ func (engine *Engine) ResetTimer(duration time.Duration) {
}
}
// AiGetBestQueue calls AI to get best queue
func (engine *Engine) AiGetBestQueue() {
if !engine.aiEnabled {
return
@ -148,11 +157,13 @@ func (engine *Engine) AiGetBestQueue() {
go engine.ai.GetBestQueue()
}
// tick move mino down and refreshes screen
func (engine *Engine) tick() {
board.MinoMoveDown()
view.RefreshScreen()
}
// AddDeleteLines adds deleted lines to score
func (engine *Engine) AddDeleteLines(lines int) {
engine.deleteLines += lines
if engine.deleteLines > 999999 {
@ -175,6 +186,7 @@ func (engine *Engine) AddDeleteLines(lines int) {
}
}
// AddScore adds to score
func (engine *Engine) AddScore(add int) {
engine.score += add
if engine.score > 9999999 {
@ -182,6 +194,7 @@ func (engine *Engine) AddScore(add int) {
}
}
// LevelUp goes up a level
func (engine *Engine) LevelUp() {
if engine.level >= 30 {
return
@ -205,6 +218,7 @@ func (engine *Engine) LevelUp() {
}
}
// GameOver pauses engine and sets to game over
func (engine *Engine) GameOver() {
logger.Println("Engine GameOver start")
@ -228,12 +242,14 @@ loop:
logger.Println("Engine GameOver end")
}
// EnabledAi enables the AI
func (engine *Engine) EnabledAi() {
engine.aiEnabled = true
go engine.ai.GetBestQueue()
engine.aiTimer.Reset(engine.tickTime / 6)
}
// DisableAi disables the AI
func (engine *Engine) DisableAi() {
engine.aiEnabled = false
if !engine.aiTimer.Stop() {

View File

@ -13,16 +13,23 @@ const (
boardYOffset = 2
rankingFileName = "/tetris.db"
// MinoPreview is for the preview mino
MinoPreview MinoType = iota
MinoCurrent = iota
MinoDrop = iota
// MinoCurrent is for the current mino
MinoCurrent = iota
// MinoDrop is for the drop mino
MinoDrop = iota
)
type (
MinoType int
MinoBlocks [][]termbox.Attribute
// MinoType is the type of mino
MinoType int
// MinoBlocks is the blocks of the mino
MinoBlocks [][]termbox.Attribute
// MinoRotation is the rotation of the mino
MinoRotation [4]MinoBlocks
// Mino is a mino
Mino struct {
x int
y int
@ -31,12 +38,14 @@ type (
minoRotation MinoRotation
}
// Minos is a bag of minos
Minos struct {
minoBag [7]MinoRotation
bagRand []int
bagIndex int
}
// Board is the Tetris board
Board struct {
boardsIndex int
width int
@ -48,30 +57,36 @@ type (
dropDistance int
}
// Boards holds all the premade boards
Boards struct {
colors [][]termbox.Attribute
rotation [][]int
}
// KeyInput is the key input engine
KeyInput struct {
stopped bool
chanStop chan struct{}
chanKeyInput chan *termbox.Event
}
// View is the display engine
View struct {
}
// Ai is the AI engine
Ai struct {
queue *[]rune
newQueue *[]rune
index int
}
// Ranking holds the ranking scores
Ranking struct {
scores []uint64
}
// Engine is the Tetirs game engine
Engine struct {
stopped bool
chanStop chan struct{}

View File

@ -6,6 +6,7 @@ import (
"github.com/nsf/termbox-go"
)
// NewKeyInput creates a new KeyInput
func NewKeyInput() *KeyInput {
return &KeyInput{
chanStop: make(chan struct{}, 1),
@ -13,6 +14,7 @@ func NewKeyInput() *KeyInput {
}
}
// Run starts the KeyInput engine
func (keyInput *KeyInput) Run() {
logger.Println("KeyInput Run start")
@ -36,6 +38,7 @@ loop:
logger.Println("KeyInput Run end")
}
// ProcessEvent process the key input event
func (keyInput *KeyInput) ProcessEvent(event *termbox.Event) {
if event.Key == termbox.KeyCtrlI {
// Ctrl l (lower case L) to log stack trace

18
mino.go
View File

@ -6,6 +6,7 @@ import (
"github.com/nsf/termbox-go"
)
// NewMino creates a new Mino
func NewMino() *Mino {
minoRotation := minos.minoBag[minos.bagRand[minos.bagIndex]]
minos.bagIndex++
@ -22,32 +23,38 @@ func NewMino() *Mino {
return mino
}
// CloneMoveLeft creates copy of the mino and moves it left
func (mino *Mino) CloneMoveLeft() *Mino {
newMino := *mino
newMino.MoveLeft()
return &newMino
}
// MoveLeft moves the mino left
func (mino *Mino) MoveLeft() {
mino.x--
}
// CloneMoveRight creates copy of the mino and moves it right
func (mino *Mino) CloneMoveRight() *Mino {
newMino := *mino
newMino.MoveRight()
return &newMino
}
// MoveRight moves the mino right
func (mino *Mino) MoveRight() {
mino.x++
}
// CloneRotateRight creates copy of the mino and rotates it right
func (mino *Mino) CloneRotateRight() *Mino {
newMino := *mino
newMino.RotateRight()
return &newMino
}
// RotateRight rotates the mino right
func (mino *Mino) RotateRight() {
mino.rotation++
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 {
newMino := *mino
newMino.RotateLeft()
return &newMino
}
// RotateLeft rotates the mino left
func (mino *Mino) RotateLeft() {
if mino.rotation < 1 {
mino.rotation = 3
@ -69,20 +78,24 @@ func (mino *Mino) RotateLeft() {
mino.rotation--
}
// CloneMoveDown creates copy of the mino and moves it down
func (mino *Mino) CloneMoveDown() *Mino {
newMino := *mino
newMino.MoveDown()
return &newMino
}
// MoveDown moves the mino down
func (mino *Mino) MoveDown() {
mino.y++
}
// MoveUp moves the mino up
func (mino *Mino) MoveUp() {
mino.y--
}
// ValidLocation check if the mino is in a valid location
func (mino *Mino) ValidLocation(mustBeOnBoard bool) bool {
minoBlocks := mino.minoRotation[mino.rotation]
for i := 0; i < mino.length; i++ {
@ -97,6 +110,7 @@ func (mino *Mino) ValidLocation(mustBeOnBoard bool) bool {
return true
}
// SetOnBoard attaches mino to the board
func (mino *Mino) SetOnBoard() {
minoBlocks := mino.minoRotation[mino.rotation]
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) {
minoBlocks := mino.minoRotation[mino.rotation]
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 {
minoBlocks := mino.minoRotation[mino.rotation]
for i := 0; i < mino.length; i++ {
@ -142,6 +158,7 @@ func (mino *Mino) minoOverlap(mino1 *Mino) bool {
return false
}
// isMinoAtLocation check if a mino block is in a location
func (mino *Mino) isMinoAtLocation(x int, y int) bool {
xIndex := x - mino.x
yIndex := y - mino.y
@ -157,6 +174,7 @@ func (mino *Mino) isMinoAtLocation(x int, y int) bool {
return false
}
// getMinoColorAtLocation gets the mino color at a location
func (mino *Mino) getMinoColorAtLocation(x int, y int) termbox.Attribute {
xIndex := x - mino.x
yIndex := y - mino.y

View File

@ -6,6 +6,7 @@ import (
"github.com/nsf/termbox-go"
)
// NewMinos creates the minos and minoBag
func NewMinos() {
minoI := MinoBlocks{
[]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 {
length := len(minoBlocks)
newMinoBlocks := make(MinoBlocks, length, length)

View File

@ -8,6 +8,7 @@ import (
"strings"
)
// NewRanking create a new ranking
func NewRanking() *Ranking {
ranking := &Ranking{
scores: make([]uint64, 9),
@ -41,6 +42,7 @@ func NewRanking() *Ranking {
return ranking
}
// Save saves the rankings to a file
func (ranking *Ranking) Save() {
var buffer bytes.Buffer
@ -54,6 +56,7 @@ func (ranking *Ranking) Save() {
ioutil.WriteFile(baseDir+rankingFileName, buffer.Bytes(), 0644)
}
// InsertScore inserts a score into the rankings
func (ranking *Ranking) InsertScore(newScore uint64) {
for index, score := range ranking.scores {
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) {
for i := len(ranking.scores) - 1; i > index; i-- {
ranking.scores[i] = ranking.scores[i-1]

15
view.go
View File

@ -8,6 +8,7 @@ import (
"github.com/nsf/termbox-go"
)
// NewView creates a new view
func NewView() {
err := termbox.Init()
if err != nil {
@ -18,6 +19,7 @@ func NewView() {
view = &View{}
}
// Stop stops the view
func (view *View) Stop() {
logger.Println("View Stop start")
@ -26,6 +28,7 @@ func (view *View) Stop() {
logger.Println("View Stop end")
}
// RefreshScreen refreshs the updated view to the screen
func (view *View) RefreshScreen() {
termbox.Clear(termbox.ColorDefault, termbox.ColorDefault)
@ -50,6 +53,7 @@ func (view *View) RefreshScreen() {
termbox.Flush()
}
// drawBackground draws the background
func (view *View) drawBackground() {
// playing board
xOffset := boardXOffset
@ -85,6 +89,7 @@ func (view *View) drawBackground() {
}
// drawTexts draws the text
func (view *View) drawTexts() {
xOffset := boardXOffset + board.width*2 + 8
yOffset := boardYOffset + 7
@ -124,6 +129,7 @@ func (view *View) drawTexts() {
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) {
var char1 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)
}
// DrawBlock draws a block
func (view *View) DrawBlock(x int, y int, color termbox.Attribute, rotation int) {
var char1 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() {
yOffset := (board.height+1)/2 + boardYOffset
view.drawTextCenter(yOffset, "Paused", termbox.ColorWhite, termbox.ColorBlack)
}
// drawGameOver draws GAME OVER
func (view *View) drawGameOver() {
yOffset := boardYOffset + 2
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)
}
// drawRankingScores draws the ranking scores
func (view *View) drawRankingScores() {
yOffset := boardYOffset + 10
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) {
for index, char := range text {
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) {
xOffset := board.width - (len(text)+1)/2 + boardXOffset + 2
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) {
view.RefreshScreen()
@ -216,6 +229,7 @@ func (view *View) ShowDeleteAnimation(lines []int) {
}
}
// ShowGameOverAnimation draws one randomily picked gave over animation
func (view *View) ShowGameOverAnimation() {
logger.Println("View ShowGameOverAnimation start")
@ -283,6 +297,7 @@ func (view *View) ShowGameOverAnimation() {
logger.Println("View ShowGameOverAnimation end")
}
// colorizeLine changes the color of a line
func (view *View) colorizeLine(y int, color termbox.Attribute) {
for x := 0; x < board.width; x++ {
termbox.SetCell(x*2+boardXOffset+2, y+boardYOffset+1, ' ', termbox.ColorDefault, color)