From 4230a3ce04f5df957986d0ca06fcb84fa53e1ffb Mon Sep 17 00:00:00 2001 From: MichaelS11 Date: Fri, 25 May 2018 19:02:00 -0700 Subject: [PATCH] Improved AI Removed unneeded rotations --- ai.go | 41 ++++++++++++++++++++++++++++++----------- ai_test.go | 25 +++++++++++++++++++++++++ board.go | 2 +- mino.go | 2 +- tetris.go | 1 - 5 files changed, 57 insertions(+), 14 deletions(-) diff --git a/ai.go b/ai.go index e199427..3cecbda 100644 --- a/ai.go +++ b/ai.go @@ -1,5 +1,9 @@ package main +import ( + "github.com/nsf/termbox-go" +) + func NewAi() *Ai { ai := Ai{} queue := make([]rune, 1) @@ -38,10 +42,25 @@ func (ai *Ai) GetBestQueue() { bestScore := -9999999 bestQueue := make([]rune, 0, 0) currentMino := *board.currentMino + rotations1 := 5 + rotations2 := 5 + + switch currentMino.minoRotation[0][1][1] { + case termbox.ColorCyan, termbox.ColorGreen, termbox.ColorRed: + rotations1 = 2 + case termbox.ColorYellow: + rotations1 = 1 + } + switch board.previewMino.minoRotation[0][1][1] { + case termbox.ColorCyan, termbox.ColorGreen, termbox.ColorRed: + rotations2 = 2 + case termbox.ColorYellow: + rotations2 = 1 + } for slide1 := 0; slide1 < 5; slide1++ { for move1 := board.width; move1 >= 0; move1-- { - for rotate1 := 0; rotate1 < 5; rotate1++ { + for rotate1 := 0; rotate1 < rotations1; rotate1++ { queue, mino1 := board.getMovesforMino(rotate1, move1, slide1, ¤tMino, nil) if mino1 == nil { @@ -50,7 +69,7 @@ func (ai *Ai) GetBestQueue() { for slide2 := 0; slide2 < 5; slide2++ { for move2 := board.width; move2 >= 0; move2-- { - for rotate2 := 0; rotate2 < 5; rotate2++ { + for rotate2 := 0; rotate2 < rotations2; rotate2++ { _, mino2 := board.getMovesforMino(rotate2, move2, slide2, board.previewMino, mino1) if mino2 == nil { @@ -158,17 +177,16 @@ func (board *Board) getMovesforMino(rotate int, move int, slide int, mino1 *Mino func (board *Board) boardStatsWithMinos(mino1 *Mino, mino2 *Mino) (fullLines int, holes int, bumpy int) { // fullLines - fullLinesY := make(map[int]bool, 2) + fullLinesY := make([]bool, board.height) for j := 0; j < board.height; j++ { - isFullLine := true + fullLinesY[j] = true for i := 0; i < board.width; i++ { if board.colors[i][j] == blankColor && !mino1.isMinoAtLocation(i, j) && !mino2.isMinoAtLocation(i, j) { - isFullLine = false + fullLinesY[j] = false break } } - if isFullLine { - fullLinesY[j] = true + if fullLinesY[j] { fullLines++ } } @@ -179,7 +197,7 @@ func (board *Board) boardStatsWithMinos(mino1 *Mino, mino2 *Mino) (fullLines int index := board.height indexOffset := 0 for j := 0; j < board.height; j++ { - if _, found := fullLinesY[j]; found { + if fullLinesY[j] { indexOffset++ } else { if board.colors[i][j] != blankColor || mino1.isMinoAtLocation(i, j) || mino2.isMinoAtLocation(i, j) { @@ -209,11 +227,12 @@ func (board *Board) boardStatsWithMinos(mino1 *Mino, mino2 *Mino) (fullLines int return } -func (ai *Ai) getScoreFromBoardStats(fullLines int, holes int, bumpy int) (score int) { +func (ai *Ai) getScoreFromBoardStats(fullLines int, holes int, bumpy int) int { + score := 0 if fullLines == 4 { score += 512 } - score -= 75 * holes - score -= 25 * bumpy + score -= 80 * holes + score -= 20 * bumpy return score } diff --git a/ai_test.go b/ai_test.go index a41e986..7d4907c 100644 --- a/ai_test.go +++ b/ai_test.go @@ -84,6 +84,16 @@ func TestAI(t *testing.T) { testMinoStruct{minoRotation: minos.minoBag[6], x: 3, y: 18}, // minoZ testMinoStruct{minoRotation: minos.minoBag[6], x: 6, y: 18}, // minoZ }, fullLines: 0, holes: 3, bumpy: 6}, + {info: "holes 4x minoT 2x minoI 2x minoO", minos: []testMinoStruct{ + testMinoStruct{minoRotation: minos.minoBag[5], x: 0, y: 18}, // minoT + testMinoStruct{minoRotation: minos.minoBag[5], x: 7, y: 18}, // minoT + testMinoStruct{minoRotation: minos.minoBag[3], x: 0, y: 16}, // minoO + testMinoStruct{minoRotation: minos.minoBag[5], x: 3, y: 16}, // minoT + testMinoStruct{minoRotation: minos.minoBag[5], x: 7, y: 16}, // minoT + testMinoStruct{minoRotation: minos.minoBag[3], x: 0, y: 14}, // minoO + testMinoStruct{minoRotation: minos.minoBag[0], x: 2, y: 14}, // minoI + testMinoStruct{minoRotation: minos.minoBag[0], x: 6, y: 14}, // minoI + }, fullLines: 1, holes: 9, bumpy: 16}, {info: "bumpy 2x minoT - 1", minos: []testMinoStruct{ testMinoStruct{minoRotation: minos.minoBag[5], x: 0, y: 18}, // minoT testMinoStruct{minoRotation: minos.minoBag[5], x: 5, y: 18}, // minoT @@ -194,6 +204,21 @@ func TestBigBoardAI(t *testing.T) { testMinoStruct{minoRotation: minos.minoBag[6], x: 12, y: 18}, // minoZ testMinoStruct{minoRotation: minos.minoBag[6], x: 16, y: 18}, // minoZ }, fullLines: 0, holes: 5, bumpy: 18}, + {info: "holes 6x minoT 2x minoO 5x minoI", minos: []testMinoStruct{ + testMinoStruct{minoRotation: minos.minoBag[5], x: 0, y: 18}, // minoT + testMinoStruct{minoRotation: minos.minoBag[5], x: 6, y: 18}, // minoT + testMinoStruct{minoRotation: minos.minoBag[5], x: 12, y: 18}, // minoT + testMinoStruct{minoRotation: minos.minoBag[3], x: 18, y: 18}, // minoO + testMinoStruct{minoRotation: minos.minoBag[5], x: 3, y: 16}, // minoT + testMinoStruct{minoRotation: minos.minoBag[5], x: 9, y: 16}, // minoT + testMinoStruct{minoRotation: minos.minoBag[5], x: 15, y: 16}, // minoT + testMinoStruct{minoRotation: minos.minoBag[3], x: 18, y: 16}, // minoO + testMinoStruct{minoRotation: minos.minoBag[0], x: 0, y: 14}, // minoI + testMinoStruct{minoRotation: minos.minoBag[0], x: 4, y: 14}, // minoI + testMinoStruct{minoRotation: minos.minoBag[0], x: 8, y: 14}, // minoI + testMinoStruct{minoRotation: minos.minoBag[0], x: 12, y: 14}, // minoI + testMinoStruct{minoRotation: minos.minoBag[0], x: 16, y: 14}, // minoI + }, fullLines: 1, holes: 18, bumpy: 23}, {info: "bumpy 4x minoJ - 1", minos: []testMinoStruct{ testMinoStruct{minoRotation: minos.minoBag[1], x: 0, y: 18}, // minoJ testMinoStruct{minoRotation: minos.minoBag[1], x: 5, y: 18}, // minoJ diff --git a/board.go b/board.go index e1e1637..f2b8b3c 100644 --- a/board.go +++ b/board.go @@ -233,7 +233,7 @@ func (board *Board) SetColor(x int, y int, color termbox.Attribute, rotation int board.rotation[x][y] = rotation } -func 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 { return false } diff --git a/mino.go b/mino.go index 5b63df3..68a7f62 100644 --- a/mino.go +++ b/mino.go @@ -88,7 +88,7 @@ func (mino *Mino) ValidLocation(mustBeOnBoard bool) bool { for i := 0; i < mino.length; i++ { for j := 0; j < mino.length; j++ { if minoBlocks[i][j] != blankColor { - if !ValidBlockLocation(mino.x+i, mino.y+j, mustBeOnBoard) { + if !board.ValidBlockLocation(mino.x+i, mino.y+j, mustBeOnBoard) { return false } } diff --git a/tetris.go b/tetris.go index 3fce15a..6336541 100644 --- a/tetris.go +++ b/tetris.go @@ -10,7 +10,6 @@ import ( ) func main() { - baseDir, _ = filepath.Abs(filepath.Dir(os.Args[0])) logger = log15.New() if baseDir != "" {