예제 #1
0
        /// <summary>
        /// Gets playground state identifying whether there's winning player.
        /// </summary>
        /// <returns>
        /// Playground state.
        /// </returns>
        public PlaygroundState GetState()
        {
            if (_emptyFields > MinimumFieldsToWin)
            {
                return(PlaygroundState.NotComplete);
            }

            bool FieldEqual(Field f1, Field f2)
            {
                return(!Player.IsNullOrBlank(f1.Player) && f1.Player.Equals(f2.Player));
            }

            foreach (int[] wc in WinningCoords)
            {
                int a = wc[0];
                int b = wc[1];
                int c = wc[2];
                if (FieldEqual(_fields[a], _fields[b]) && FieldEqual(_fields[b], _fields[c]))
                {
                    return(PlaygroundState.Winner(_fields[a].Player));
                }
            }

            return(_emptyFields == 0
                ? PlaygroundState.Tie
                : PlaygroundState.NotComplete);
        }
예제 #2
0
        /// <summary>
        /// Evaluate every possible move using minimax algorithm.
        /// </summary>
        /// <param name="playground">Game playground.</param>
        /// <param name="isMaximizing"><c>true</c> if player's move, <c>false</c> if opponent's move.</param>
        /// <returns>
        /// Returns field-score.
        /// </returns>
        private FieldScore MiniMax(Playground playground, bool isMaximizing)
        {
            PlaygroundState state = playground.GetState();

            // board is in final state, return score immediately
            // (since we are not aware of previous move (chosen field)
            //  we return only score part)
            if (state.State != GameState.NotComplete)
            {
                return(state.State == GameState.Tie
                    ? new FieldScore {
                    Score = 0
                }
                    : _player.Equals(state.Player)
                        ? new FieldScore {
                    Score = 1
                }
                        : new FieldScore {
                    Score = -1
                });
            }

            Player currentPlayer = isMaximizing
                ? _player
                : _opponent;

            // calculate scores for each possible move
            // (NB! recursion is about to happen)
            IEnumerable <FieldScore> moves = playground.EmptyFields()
                                             .Select(
                f => new FieldScore
            {
                Index = f.Index,
                Score = MiniMax(playground.Turn(f.Index, currentPlayer), !isMaximizing).Score
            });

            // captain obvious to the service:
            // player - get the highest score (ORDER BY score DESC)
            // opponent - get the lowest score (ORDER BY score ASC)
            moves = isMaximizing
                ? moves.OrderByDescending(m => m.Score)
                : moves.OrderBy(m => m.Score);

            return(moves.First());
        }