示例#1
0
        public void OutcomeTest()
        {
            TicTacToePosition board = TicTacToePosition.Build(
                "a1", "a2", "a3", "b2", "b1", "c1", "b3", "c3", "c2");

            Assert.IsTrue(board.Outcome == GameOutcome.Draw);
        }
示例#2
0
        public void MoveExpectancyIllegal()
        {
            TicTacToePosition board = TicTacToePosition.Set(
                crosses: new TicTacToeLocation[] { "a3", "c1" },
                naughts: new TicTacToeLocation[] { "b2", "c3" });

            Assert.IsTrue(board.MoveDegree("a3") == TicTacToe.MoveExpectancy.Illegal, "Must be illegal move");
        }
示例#3
0
        public void MoveExpectancy()
        {
            TicTacToePosition board = TicTacToePosition.Set(
                crosses: new TicTacToeLocation[] { "a3", "c1" },
                naughts: new TicTacToeLocation[] { "b2", "c3" });

            Assert.IsTrue(board.MoveDegree("a1") == TicTacToe.MoveExpectancy.Win, "Must be winning move");
            Assert.IsTrue(board.MoveDegree("a2") == TicTacToe.MoveExpectancy.Lose, "Must be losing move");
        }
示例#4
0
        /// <summary>
        /// Expected Winner
        /// </summary>
        public static GameOutcome ExpectedWinner(this TicTacToePosition position)
        {
            if (position is null)
            {
                return(GameOutcome.Illegal);
            }

            return(s_Outcomes.TryGetValue(position, out var result)
        ? result
        : GameOutcome.Illegal);
        }
示例#5
0
        /// <summary>
        /// Move quality
        ///   -1 worst move
        ///    0 illegal move
        ///   +1 best move
        /// </summary>
        public static int MoveQuality(this TicTacToePosition position, string cell)
        {
            var match = Regex.Match(cell, @"^\s*(?<rank>[A-Ca-c])\s*(?<file>[1-3])\s*$");

            if (!match.Success)
            {
                return(0);
            }

            return(MoveQuality(position,
                               '3' - match.Groups["file"].Value[0],
                               match.Groups["rank"].Value.ToUpper()[0] - 'A'));
        }
示例#6
0
        public void BestMovesTest()
        {
            TicTacToePosition board = TicTacToePosition.Empty.MakeMoves(
                "a1", "a2", "a3", "b3"
                );

            var bestMoves = board.BestMoves(); // .OrderBy(move => move);

            TicTacToeLocation[] expected = new TicTacToeLocation[] {
                "b2", "c1"
            };

            Assert.IsTrue(bestMoves.SequenceEqual(expected), string.Join(" ", bestMoves.AsEnumerable()));
        }
示例#7
0
        /// <summary>
        /// Move Expectation
        /// </summary>
        public static GameOutcome MoveExpectation(this TicTacToePosition position, int index)
        {
            if (position is null)
            {
                return(GameOutcome.Illegal);
            }

            if (position[index] != Mark.None)
            {
                return(GameOutcome.Illegal);
            }
            else if (index < 1 || index > 9)
            {
                return(GameOutcome.Illegal);
            }

            return(ExpectedWinner(position.MakeMove(index)));
        }
示例#8
0
        /// <summary>
        /// Move Expectation
        /// </summary>
        public static GameOutcome MoveExpectation(this TicTacToePosition position, string cell)
        {
            if (cell is null)
            {
                return(GameOutcome.Illegal);
            }

            var match = Regex.Match(cell, @"^\s*(?<rank>[A-Ca-c])\s*(?<file>[1-3])\s*$");

            if (!match.Success)
            {
                return(GameOutcome.Illegal);
            }

            return(MoveExpectation(position,
                                   '3' - match.Groups["file"].Value[0],
                                   match.Groups["rank"].Value.ToUpper()[0] - 'A'));
        }
示例#9
0
        /// <summary>
        /// Move Expectation
        /// </summary>
        public static GameOutcome MoveExpectation(this TicTacToePosition position, int line, int column)
        {
            if (position is null)
            {
                return(GameOutcome.Illegal);
            }

            if (position[line, column] != Mark.None)
            {
                return(GameOutcome.Illegal);
            }
            else if (line < 0 || line > 2 || column < 0 || column > 2)
            {
                return(GameOutcome.Illegal);
            }

            return(ExpectedWinner(position.MakeMove(line, column)));
        }
示例#10
0
        /// <summary>
        /// Move quality
        ///   -1 worst move
        ///    0 illegal move
        ///   +1 best move
        /// </summary>
        public static int MoveQuality(this TicTacToePosition position, int index)
        {
            var actual = MoveExpectation(position, index);

            if (actual == GameOutcome.Illegal)
            {
                return(0);
            }

            var best = ExpectedWinner(position);

            if (best == actual)
            {
                return(1);
            }
            else
            {
                return(-1);
            }
        }
示例#11
0
        private static void CoreUpdate()
        {
            s_Outcomes = TicTacToePosition
                         .AllLegalPositions()
                         .ToDictionary(p => p, p => GameOutcome.None);

            var data = s_Outcomes
                       .Keys
                       .OrderByDescending(key => key.MarkCount);

            foreach (var position in data)
            {
                if (position.Outcome != GameOutcome.None)
                {
                    s_Outcomes[position] = position.Outcome;

                    continue;
                }

                var onMove = position.WhoIsOnMove;

                GameOutcome bestOutcome = onMove == Mark.Cross
          ? GameOutcome.SecondWin
          : GameOutcome.FirstWin;

                foreach (var next in position.AvailablePositions())
                {
                    GameOutcome outcome = s_Outcomes[next];

                    bestOutcome = onMove == Mark.Cross
            ? bestOutcome.BestForFirst(outcome)
            : bestOutcome.BestForSecond(outcome);
                }

                s_Outcomes[position] = bestOutcome;
            }
        }
示例#12
0
        public void Expectations()
        {
            TicTacToePosition board = TicTacToePosition.Build("a1", "a2", "a3", "b3");

            Assert.IsTrue(board.ExpectedWinner() == GameOutcome.FirstWin, board.DrawPosition());
        }
示例#13
0
        /// <summary>
        /// Best Moves (all winning moves or, if the position drawish, all draw moves)
        /// </summary>
        public static IEnumerable <(int line, int column, int index, string cell)> BestMoves(this TicTacToePosition position)
        {
            if (position is null)
            {
                yield break;
            }

            foreach (var move in position.AvailableMoves())
            {
                if (MoveQuality(position, move.index) == 1)
                {
                    yield return(move);
                }
            }
        }