Exemple #1
0
        public static void Print(this Playground playground)
        {
            ConsoleColor foreground = Console.ForegroundColor;

            for (var r = 0; r < 3; r++)
            {
                Console.WriteLine("+---+---+---+");
                for (var c = 0; c < 3; c++)
                {
                    Field field = playground.Fields[r * 3 + c];

                    Console.Write("| ");

                    Console.ForegroundColor = field.IsEmpty ? ConsoleColor.Gray : ConsoleColor.Green;
                    Console.Write(GetFieldValue(field));
                    Console.ForegroundColor = foreground;

                    Console.Write(" ");
                }

                Console.WriteLine("|");
            }

            Console.WriteLine("+---+---+---+");
        }
        public static IEnumerable <Field> EmptyFields(this Playground playground)
        {
            if (playground == null)
            {
                throw new ArgumentNullException(nameof(playground));
            }

            return(playground.Fields.Where(f => f.IsEmpty));
        }
Exemple #3
0
        /// <summary>
        /// Calculates the best move for given playground state.
        /// </summary>
        /// <param name="playground">Game playground.</param>
        /// <returns>
        /// Returns index of field of the best move for player.
        /// </returns>
        public (bool CanTurn, int Index) CalulateBestMove(Playground playground)
        {
            if (playground == null)
            {
                throw new ArgumentNullException(nameof(playground));
            }

            FieldScore result = MiniMax(playground, true);

            return(result.Index > 0
                ? (true, result.Index)
                : (false, 0));
        }
Exemple #4
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());
        }
Exemple #5
0
        static void Main(string[] args)
        {
            var p1 = new Player('X');
            var p2 = new Player('O');

            var s1 = new Solver(p1, p2);
            var s2 = new Solver(p2, p1);

            var playground = new Playground();

            playground = playground.Turn(s1.CalulateBestMove(playground).Index, p1);
            playground.Print();

            playground = playground.Turn(s2.CalulateBestMove(playground).Index, p2);
            playground.Print();

            playground = playground.Turn(s1.CalulateBestMove(playground).Index, p1);
            playground.Print();

            playground = playground.Turn(s2.CalulateBestMove(playground).Index, p2);
            playground.Print();

            playground = playground.Turn(s1.CalulateBestMove(playground).Index, p1);
            playground.Print();

            playground = playground.Turn(s2.CalulateBestMove(playground).Index, p2);
            playground.Print();

            playground = playground.Turn(s1.CalulateBestMove(playground).Index, p1);
            playground.Print();

            playground = playground.Turn(s2.CalulateBestMove(playground).Index, p2);
            playground.Print();

            playground = playground.Turn(s2.CalulateBestMove(playground).Index, p1);
            playground.Print();

            Debugger.Break();
        }