From 29c46f4d23028776efa8b8d7c14c84578d13035b Mon Sep 17 00:00:00 2001
From: Vadim Korolik <vkorolik@gmail.com>
Date: Wed, 20 Mar 2019 20:18:24 -0700
Subject: [PATCH] Testing - caching won't work unless we make more compressed
 way to store []Move (OOM)

---
 chessai/game/game.go           |  2 ++
 chessai/player/ai/ai_player.go | 16 ++++++++++------
 chessai/player/ai/minimax.go   |  1 +
 chessai/test/ai_basic_test.go  |  8 +++++---
 4 files changed, 18 insertions(+), 9 deletions(-)

diff --git a/chessai/game/game.go b/chessai/game/game.go
index 7b70894..04ab49f 100644
--- a/chessai/game/game.go
+++ b/chessai/game/game.go
@@ -16,7 +16,9 @@ type Game struct {
 }
 
 func (g *Game) PlayTurn() {
+	start := time.Now()
 	g.Players[g.CurrentTurnColor].MakeMove(g.CurrentBoard)
+	g.PlayTime[g.CurrentTurnColor] += time.Now().Sub(start)
 	g.CurrentTurnColor = (g.CurrentTurnColor + 1) % color.NumColors
 	g.MovesPlayed++
 }
diff --git a/chessai/player/ai/ai_player.go b/chessai/player/ai/ai_player.go
index a21669b..41483c0 100644
--- a/chessai/player/ai/ai_player.go
+++ b/chessai/player/ai/ai_player.go
@@ -109,17 +109,13 @@ func (p *Player) GetBestMove(b *board.Board) *board.Move {
 	} else {
 		var m *ScoredMove
 		if p.Algorithm == AlgorithmMiniMax {
-			m = p.MiniMax(b, 4, p.PlayerColor)
+			m = p.MiniMax(b, 2, p.PlayerColor)
 		} else if p.Algorithm == AlgorithmAlphaBetaWithMemory {
 			m = p.AlphaBetaWithMemory(b, 4, NegInf, PosInf, p.PlayerColor)
 		} else {
 			panic("invalid ai algorithm")
 		}
-		c := "Black"
-		if p.PlayerColor == color.White {
-			c = "White"
-		}
-		fmt.Printf("AI (%s - %s) best move leads to score %d\n", p.Algorithm, c, m.Score)
+		fmt.Printf("%s best move leads to score %d\n", p.Repr(), m.Score)
 		debugBoard := b.Copy()
 		//for i := 0; i < len(m.MoveSequence); i++ {
 		for i := len(m.MoveSequence) - 1; i >= 0; i-- {
@@ -207,3 +203,11 @@ func (p *Player) EvaluateBoard(b *board.Board) *board.Evaluation {
 	p.evaluationMap.Store(&hash, int32(eval.TotalScore))
 	return eval
 }
+
+func (p *Player) Repr() string {
+	c := "Black"
+	if p.PlayerColor == color.White {
+		c = "White"
+	}
+	return fmt.Sprintf("AI (%s - %s)", p.Algorithm, c)
+}
diff --git a/chessai/player/ai/minimax.go b/chessai/player/ai/minimax.go
index 1b20fb4..370b116 100644
--- a/chessai/player/ai/minimax.go
+++ b/chessai/player/ai/minimax.go
@@ -23,6 +23,7 @@ func (p *Player) MiniMax(b *board.Board, depth int, currentPlayer byte) *ScoredM
 	}
 
 	var best ScoredMove
+	// TODO(Vadim) if depth is odd, flip these?
 	if currentPlayer == p.PlayerColor {
 		// maximizing player
 		best.Score = NegInf
diff --git a/chessai/test/ai_basic_test.go b/chessai/test/ai_basic_test.go
index 8918d7c..e5076f6 100644
--- a/chessai/test/ai_basic_test.go
+++ b/chessai/test/ai_basic_test.go
@@ -12,7 +12,7 @@ import (
 
 func TestBoardAI(t *testing.T) {
 	const MovesToPlay = 100
-	const TimeToPlay = 60 * time.Second
+	const TimeToPlay = 300 * time.Second
 
 	aiPlayerSmart := ai.NewAIPlayer(color.Black)
 	aiPlayerSmart.Algorithm = ai.AlgorithmMiniMax
@@ -30,13 +30,15 @@ func TestBoardAI(t *testing.T) {
 		}
 		g.PlayTurn()
 		fmt.Printf("Move %d\n", g.MovesPlayed)
-		fmt.Println(g.CurrentBoard.Print())
+		fmt.Print(g.CurrentBoard.Print())
+		fmt.Printf("White %s has thought for %s\n", g.Players[color.White].Repr(), g.PlayTime[color.White])
+		fmt.Printf("Black %s has thought for %s\n", g.Players[color.Black].Repr(), g.PlayTime[color.Black])
 	}
 
 	fmt.Println("After moves")
 	fmt.Println(g.CurrentBoard.Print())
 	// comment out printing inside loop for accurate timing
-	fmt.Printf("Played %d moves in %d ms.\n", MovesToPlay, time.Now().Sub(start)/time.Millisecond)
+	fmt.Printf("Played %d moves in %d ms.\n", g.MovesPlayed, time.Now().Sub(start)/time.Millisecond)
 
 	smartScore := aiPlayerSmart.EvaluateBoard(g.CurrentBoard).TotalScore
 	dumbScore := aiPlayerDumb.EvaluateBoard(g.CurrentBoard).TotalScore