public int MINIMAX_DECISION(Game game) { _stopwatch = new System.Diagnostics.Stopwatch(); _stopwatch.Start(); int maxValue = int.MinValue; List<int> colOptions = new List<int>(); List<int> actions = ACTIONS(game); int iterationCounter = 0; foreach (int column in actions) { iterationCounter++; int v = MIN_VALUE(RESULT(game, column, _max), 1); if (v > maxValue) { maxValue = v; colOptions.Clear(); colOptions.Add(column); } else if (v == maxValue) { colOptions.Add(column); } if (_stopwatch.Elapsed.Seconds > (game.TimeLimitSeconds - 1)) break; } int c = colOptions[_rnd.Next(colOptions.Count)]; Console.WriteLine("Column selection: {0} / Elapsed: {1} / Total Actions: {2} / Actions Evaluated: {3}", c, _stopwatch.Elapsed, actions.Count, iterationCounter); return c; }
public int MIN_VALUE(Game game, int depth) { if (TERMINAL_TEST(game, depth)) return UTILITY(game); int value = int.MaxValue; foreach (int column in ACTIONS(game)) { value = Math.Min(value, MAX_VALUE(RESULT(game, column, _min), ++depth)); } return value; }
static void PlayGame(System.IO.StreamWriter writer) { Game g = new Game() { Rows = 6, Columns = 7, PiecesToWin = 4, TimeLimitSeconds = 30 }; g.Initialize(); Player p1 = new MinimaxPlayer(Players.Black, Players.Red, "MINIMAX (1)"); p1.SetGameInfo(g.Rows, g.Columns, g.PiecesToWin, 0, g.TimeLimitSeconds); Player p2 = new Player(Players.Red, Players.Black, "SIMPLE (2)"); p2.SetGameInfo(g.Rows, g.Columns, g.PiecesToWin, 1, g.TimeLimitSeconds); GameValueCalculator calc = new GameValueCalculator(g); GameResult result = GameResult.InProgress; while (result == GameResult.InProgress) { int move = p1.GetNextMove(); g.AcceptMove(p1.ID, move); result = calc.EvaluateGameState(); p2.NoteOpponentsMove(move); if (result == GameResult.WinBlack || result == GameResult.WinRed) break; move = p2.GetNextMove(); g.AcceptMove(p2.ID, move); result = calc.EvaluateGameState(); p1.NoteOpponentsMove(move); } Console.WriteLine(string.Format(" --- {0} --- ", result)); g.DisplayBoard(); writer.WriteLine(string.Format(" --- {0} --- ", result)); g.DisplayBoard(writer); }
static void DiagnoseFdUpMoves() { Game g = new Game() { Rows = 6, Columns = 7, PiecesToWin = 4, TimeLimitSeconds = 30000 }; g.Initialize(); g.AcceptMove(Players.Black, 3); g.AcceptMove(Players.Red, 4); g.AcceptMove(Players.Black, 3); g.AcceptMove(Players.Red, 3); MinimaxCs.Minimax m = new MinimaxCs.Minimax(Players.Black); int col = m.MINIMAX_DECISION(g); }
public Game Clone() { Game clone = new Game() { Rows = this.Rows, Columns = this.Columns, PiecesToWin = this.PiecesToWin, TimeLimitSeconds = this.TimeLimitSeconds }; clone.Initialize(); for (int r = 0; r < this.Rows; r++) { for (int c = 0; c < this.Columns; c++) { clone.Board[r, c] = this.Board[r, c]; } } return clone; }
int UTILITY(Game game) { GameValueCalculator calc = new GameValueCalculator(game); return calc.CalculateValues(_max).NormalizedValue; }
bool TERMINAL_TEST(Game game, int depth) { if (_stopwatch.Elapsed.Seconds > (game.TimeLimitSeconds - 2)) return true; if (depth >= MAX_DEPTH) return true; GameValueCalculator calc = new GameValueCalculator(game); if (calc.IsGameComplete()) return true; return false; }
List<int> ACTIONS(Game game) { List<int> actions = new List<int>(); for (int c = 0; c < game.Columns; c++) { if (game.Board[0, c] == (int)Players.None) actions.Add(c); } return actions; }
public Game RESULT(Game game, int column, Players playerId) { Game newState = game.Clone(); newState.AcceptMove(playerId, column); return newState; }
public GameValueCalculator(Game game) { _game = game; }