void NewGame(int size) { _fileName = null; _gameRecord.Tags.Clear(); _gameRecord.MoveNotations.Clear(); _game = GameState.NewGame(size); _ai = new TakAI(_game.Size); _evaluator = new TakAI.Evaluator(_game.Size); _boardView.Game = _game; PrepareTurn(); }
protected override void OnLoad(EventArgs e) { base.OnLoad(e); _game = GameState.NewGame(5); _ai = new TakAI(_game.Size); _evaluator = new TakAI.Evaluator(_game.Size); _boardView = new BoardView(); _boardView.Dock = DockStyle.Fill; _boardView.Game = _game; this.Controls.Add(_boardView); //_boardView.MouseOverSpotChanged += boardView_MouseOverSpotChanged; }
private void miFileOpen_Click(object sender, EventArgs e) { if (dlgOpen.ShowDialog(this) != DialogResult.OK) { return; } try { var database = TakEngine.Notation.TakPGN.LoadFromFile(dlgOpen.FileName); if (database.Games.Count != 1) { throw new ApplicationException("File must contain exactly 1 game"); } _gameRecord = database.Games[0]; _game = GameState.NewGame(_gameRecord.BoardSize); _ai = new TakAI(_game.Size); _evaluator = new TakAI.Evaluator(_game.Size); _boardView.Game = _game; foreach (var notation in _gameRecord.MoveNotations) { _tempMoveList.Clear(); TakAI.EnumerateMoves(_tempMoveList, _game, _ai.NormalPositions); var move = notation.MatchLegalMove(_tempMoveList); if (null == move) { throw new ApplicationException("Illegal move: " + notation.Text); } move.MakeMove(_game); _movesOfNotation[notation] = move; _navigating = true; if (_historyForm != null) { _historyForm.AddPly(notation.Text); } _navigating = false; _game.Ply++; } _fileName = dlgOpen.FileName; PrepareTurn(); } catch (Exception ex) { MessageBox.Show(this, ex.Message, "Failed to open file", MessageBoxButtons.OK, MessageBoxIcon.Error); } }
static void GameLoop() { var fullauto = new bool[] { false, false }; var game = GameState.NewGame(5); var ai = new TakAI(game.Size, maxDepth: 3); var evaluator = new TakAI.Evaluator(game.Size); bool gameOver; int eval; var recentMoves = new Stack <IMove>(); var recentStates = new Stack <GameState>(); while (true) { // print board PrintBoard(game, previous: recentStates.Count > 0 ? recentStates.Peek() : null); evaluator.Evaluate(game, out eval, out gameOver); if (gameOver) { Console.Write("Game over, "); if (eval == 0) { Console.WriteLine("Tie"); } else if (eval > 0) { Console.WriteLine("X wins"); } else { Console.WriteLine("O wins"); } } Console.Write("[T{0}, {1}]: ", game.Ply, (game.Ply & 1) == 0 ? 'X' : 'O'); string cmd; if (fullauto[game.Ply & 1] && !gameOver) { cmd = "ai"; Console.WriteLine(cmd); } else { cmd = Console.ReadLine().Trim(); } if (string.IsNullOrEmpty(cmd) || cmd == "q") { break; } else if (cmd == "help") { Console.ForegroundColor = ConsoleColor.Cyan; Console.WriteLine("==Global commands"); Console.ForegroundColor = ConsoleColor.Gray; Console.WriteLine("ai AI will choose a move for this player"); Console.WriteLine("ai on This player will become completely controlled by the AI"); Console.WriteLine("ai N Set AI difficulty to N [2-9], default is 4."); Console.WriteLine("ai off Disable AI control for all players"); Console.WriteLine("undo Undo last move, including the AI's response (if any)"); Console.WriteLine("list List all legal moves in the current board position"); Console.WriteLine(" Warning: level N+1 is roughly 30 to 50 times slower than N!"); Console.ForegroundColor = ConsoleColor.Cyan; Console.WriteLine("==Move notation"); Console.ForegroundColor = ConsoleColor.DarkGray; Console.WriteLine(" NOTE: XY positions start from 0 in the top-left of the board"); Console.WriteLine(" NOTE: Directions are n,s,e,w (north, south, east, west)"); Console.ForegroundColor = ConsoleColor.Gray; Console.WriteLine("fXY Place flat stone from reserve at position X,Y"); Console.WriteLine("sXY Place standing stone from reserve at position X,Y"); Console.WriteLine("cXY Place cap stone from reserve at position X,Y"); Console.WriteLine("mXY,N,D N1 N2 N3 etc..."); Console.WriteLine(" Move stones by picking up N stones from the top of the stack"); Console.WriteLine(" at X,Y then then traveling in direction D. Drop N1 stones"); Console.WriteLine(" in the first square, N2 in the second, etc..."); Console.WriteLine(" Example: m23,2,n 1 1"); Console.WriteLine(" This would pick up 2 stones from position 2,3 and travel north,"); Console.WriteLine(" dropping 1 stone at 2,2 and then another stone at 2,1"); Console.Write("<Press any key to continue>"); Console.ReadKey(); Console.WriteLine(); } else if (cmd == "undo") { while (recentMoves.Count > 0) { var undoing = recentMoves.Pop(); undoing.TakeBackMove(game); game.Ply--; recentStates.Pop(); if (!fullauto[game.Ply & 1]) { break; } } } else if (cmd == "ai off") { fullauto[0] = fullauto[1] = false; } else if (cmd.StartsWith("ai ") && cmd.Length > 3 && Char.IsDigit(cmd[3])) { int diff = 0; if (!int.TryParse(cmd.Substring(3), out diff)) { diff = 0; } if (diff < 2 || diff > 9) { Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine("Invalid difficulty level. Legal values are 2 thru 9."); Console.ForegroundColor = ConsoleColor.Gray; } else { if (diff == ai.MaxDepth) { Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine("AI difficulty is already set to " + diff.ToString()); } else { Console.ForegroundColor = ConsoleColor.Cyan; ai.MaxDepth = diff; Console.WriteLine("AI difficulty set to " + diff.ToString()); Console.ForegroundColor = ConsoleColor.Gray; } } } else { if (gameOver) { Console.WriteLine("Invalid command"); } else if (cmd == "ai on" || cmd == "ai") { if (cmd == "ai on") { fullauto[game.Ply & 1] = true; } var move = ai.FindGoodMove(game); var restoreColor = Console.ForegroundColor; Console.ForegroundColor = ConsoleColor.DarkGray; Console.WriteLine("ai move => {0}", move.Notate()); Console.ForegroundColor = restoreColor; recentStates.Push(game.DeepCopy()); recentMoves.Push(move); move.MakeMove(game); game.Ply++; } else if (cmd == "list") { var legalMoves = new List <IMove>(); TakAI.EnumerateMoves(legalMoves, game, ai.RandomPositions); foreach (var move in legalMoves) { Console.WriteLine(move.Notate()); } } else { var legalMoves = new List <IMove>(); TakAI.EnumerateMoves(legalMoves, game, ai.RandomPositions); var match = legalMoves.FirstOrDefault(x => x.Notate() == cmd); if (match == null) { Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine("ILLEGAL MOVE OR INVALID MOVE NOTATION. Type 'help' for more information."); Console.ForegroundColor = ConsoleColor.Gray; } else { recentStates.Push(game.DeepCopy()); recentMoves.Push(match); match.MakeMove(game); game.Ply++; } } } } Console.WriteLine("Exiting"); }
public static void RunTest(string appendPath) { var ai = new TakAI(BoardSize); ai.MaxDepth = 4; var evaluator = new TakAI.Evaluator(BoardSize); var movelog = new List <string>(); var durationlog = new List <TimeSpan>(); while (true) { var guid = System.Guid.NewGuid(); PrintTimeStampedMessage("Started new game"); var game = GameState.NewGame(BoardSize); movelog.Clear(); durationlog.Clear(); bool gameOver; int eval; var starttime = DateTime.Now; do { var movestart = DateTime.Now; var move = ai.FindGoodMove(game); var duration = DateTime.Now.Subtract(movestart); var notation = move.Notate(); PrintTimeStampedMessage(string.Concat(game.Ply, ": ", notation)); movelog.Add(notation); durationlog.Add(duration); move.MakeMove(game); game.Ply++; evaluator.Evaluate(game, out eval, out gameOver); } while (!gameOver); string result; if (eval == 0) { result = "Tie"; } else { if (eval > 0) { result = "First player wins"; } else { result = "Second player wins"; } if (eval == Math.Abs(TakAI.Evaluator.FlatWinEval)) { result += " via flats"; } else { result += " via road"; } } PrintTimeStampedMessage(result); using (var writer = System.IO.File.AppendText(appendPath)) { writer.WriteLine("' Game ID {0}", guid); writer.WriteLine("' AI difficulty {0}", ai.MaxDepth); writer.WriteLine("' Started {0}", starttime.ToString(DateFormat)); writer.WriteLine("' Duration {0}", DateTime.Now.Subtract(starttime)); writer.WriteLine("' Moves {0}", movelog.Count); writer.WriteLine("' Result {0}", result); for (int i = 0; i < movelog.Count; i++) { writer.WriteLine("{0}\t{1}\t{2}", i + 1, movelog[i], durationlog[i]); } } } }