/// <summary> /// Returns the winning move, or -1 if there isn't one - Deprecated /// </summary> /// <param name="game"></param> /// <returns></returns> private int GetWinningMove(Game game) { Game attempt = new Game(); Array.Copy(game.Board, attempt.Board, game.Board.Length); for (int x = 0; x < Game.NCOLS; x++) { // Reset board & turn Array.Copy(game.Board, attempt.Board, game.Board.Length); attempt.Turn = game.Turn; // And try a row & see if it wins attempt.MakeMove(x); if (attempt.DetectWinner()) { return(x); } } return(-1); }
/// <summary> /// Get a game in a current state and do an intelligent move /// </summary> /// <param name="game"></param> /// <returns></returns> public int GetSmartMove(Game game) { Dictionary <int, List <int> > MoveAndItsEvaluation = new Dictionary <int, List <int> >(); // Attempted move (column) and its value results (its score) for (int n1 = 0; n1 < Game.NCOLS; n1++) { MoveAndItsEvaluation.Add(n1, new List <int>()); // Reset state to game.Board Game attempt = new Game(); Array.Copy(game.Board, attempt.Board, game.Board.Length); attempt.Turn = game.Turn; int cpuValue = 100; // Base value for CPU // A full column would be the worst move if (!attempt.ColHasSpace(n1)) { cpuValue = -1000000; } attempt.MakeMove(n1); // Evaluate it if (attempt.DetectWinner()) { cpuValue += 100000; // We will win with this move } cpuValue += 50 * Detect3(attempt); cpuValue += 15 * Detect2(attempt); attempt.ShiftTurns(); for (int n2 = 0; n2 < Game.NCOLS; n2++) { // From this situation, calculate the best move player can make, on top of the attempt.MakeMove // Reset state to attempt.Board Game playerAttempt = new Game(); Array.Copy(attempt.Board, playerAttempt.Board, attempt.Board.Length); playerAttempt.Turn = attempt.Turn; int playerValue = 100; // Same base value for Player playerAttempt.MakeMove(n2); // Evaluate it if (playerAttempt.DetectWinner()) { playerValue += 5000; // He will win this one, worth less than CPU win because it's his turn } playerValue += 50 * Detect3(playerAttempt); playerValue += 15 * Detect2(playerAttempt); // Compare cpu value to player value and store it in Dict int realValue = cpuValue - playerValue; MoveAndItsEvaluation[n1].Add(realValue); } } int[] sums = new int[Game.NCOLS]; // Make sum of all evaluations for moves - the highest result is the best move foreach (KeyValuePair <int, List <int> > kvp in MoveAndItsEvaluation) { for (int i = 0; i < kvp.Value.Count; i++) { sums[kvp.Key] += kvp.Value.ElementAt(i); } } int biggest = sums.Max(); // Get all equally good moves List <int> bestMoves = new List <int>(); for (int i = 0; i < sums.Length; i++) { if (sums[i] == biggest) { bestMoves.Add(i); } } int aBestMove = bestMoves[new Random().Next(0, bestMoves.Count)]; // One random move of equally good moves, to have less stale AI return(aBestMove); }