Exemplo n.º 1
0
        /// <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);
        }