コード例 #1
0
        public GameTree GetNode(UltimateTicTacToeBoard data)
        {
            if (Data.Equals(data))
            {
                return(this);
            }
            if (Children == null || Children.Count < 1)
            {
                return(null);
            }
            var nodes = new List <GameTree>();

            nodes.AddRange(Children);

            for (var i = 0; i < nodes.Count; i++)
            {
                if (nodes[i].Data.ToString().Equals(data.ToString()))
                {
                    return(nodes[i]);
                }
                if (nodes[i].Children != null && nodes[i].Children.Count >= 1)
                {
                    nodes.AddRange(nodes[i].Children);
                }
            }
            return(null);
        }
コード例 #2
0
        private static short CountWins(Player player, UltimateTicTacToeBoard board)
        {
            var wins = (short)(CanWin(player, board, new[] { 0, 1, 2 }) ? 1 : 0);

            wins += (short)(CanWin(player, board, new[] { 3, 4, 5 }) ? 1 : 0);
            wins += (short)(CanWin(player, board, new[] { 6, 7, 8 }) ? 1 : 0);
            wins += (short)(CanWin(player, board, new[] { 0, 3, 6 }) ? 1 : 0);
            wins += (short)(CanWin(player, board, new[] { 1, 4, 7 }) ? 1 : 0);
            wins += (short)(CanWin(player, board, new[] { 2, 5, 8 }) ? 1 : 0);
            wins += (short)(CanWin(player, board, new[] { 0, 4, 8 }) ? 1 : 0);
            wins += (short)(CanWin(player, board, new[] { 2, 4, 6 }) ? 1 : 0);
            return(wins);
        }
コード例 #3
0
        UltimateTicTacToeMove ITicTacToePlayer.TakeTurn(UltimateTicTacToeBoard ticTacToeBoard)
        {
            byte outerCell;

            if (ticTacToeBoard.RequiredOuterCell == null)
            {
                var validCells = ticTacToeBoard.GetValidOuterCells();
                outerCell = validCells[new Random().Next(0, validCells.Count)];
            }
            else
            {
                outerCell = ticTacToeBoard.RequiredOuterCell.Value;
            }

            var validInnerCells = ticTacToeBoard.GetValidInnerCells(outerCell);
            var innerCell       = validInnerCells[new Random().Next(0, validInnerCells.Count)];

            return(new UltimateTicTacToeMove(Player, outerCell, innerCell));
        }
コード例 #4
0
        public UltimateTicTacToeMove TakeTurn(UltimateTicTacToeBoard ticTacToeBoard)
        {
            _taunt("Planning My Move...");
            GameTree currentTree = _gameTree?.GetNode(ticTacToeBoard);

            Debug.WriteLine($"There were {_gameTree?.GetNodeCount()} nodes in the tree prior to this move.");

            //Taunt the player if they played well!
            if (_gameTree?.Children != null && _gameTree.Children.Count != 0)
            {
                var lowScore         = _gameTree.Children.Min(node => node.Score);
                var highScore        = _gameTree.Children.Max(node => node.Score);
                var bestMove         = Player == Player.O ? highScore : lowScore;
                var worstMove        = Player == Player.X ? highScore : lowScore;
                var bestPlayedMoves  = _gameTree.Children.Where(child => child.Score == bestMove);
                var worstPlayedMoves = _gameTree.Children.Where(child => child.Score == worstMove);
                var playedMoves      = bestPlayedMoves as IList <GameTree> ?? bestPlayedMoves.ToList();
                if (playedMoves.Contains(currentTree) && playedMoves.Count == 1 && Math.Abs(bestMove - worstMove) > 250)
                {
                    _taunt("Nice Move Kiddums!");
                    Thread.Sleep(timeout: new TimeSpan(0, 0, 5));
                }
                else if (worstPlayedMoves.Contains(currentTree) && Math.Abs(bestMove - worstMove) > 250)
                {
                    _taunt("What are you thinking?");
                    Thread.Sleep(timeout: new TimeSpan(0, 0, 5));
                }
            }

            _gameTree = currentTree ?? new GameTree(data: ticTacToeBoard.Clone());
            Debug.WriteLine($"Tree Triming reduced it to {_gameTree.GetNodeCount()} nodes.");
            Debug.WriteLine($"Memory Used {GC.GetTotalMemory(false)}");
            GC.Collect();
            GC.WaitForPendingFinalizers();
            Debug.WriteLine($"Memory Used {GC.GetTotalMemory(false)}");
            PopulateTree();
            Debug.WriteLine($"Memory Used {GC.GetTotalMemory(false)}");
            Debug.WriteLine($"Tree population increased it to {_gameTree.GetNodeCount()} nodes at a depth of {_gameTree.GetTreeDepth()}.");
            var move = MinMax();

            return(move);
        }
コード例 #5
0
        public UltimateTicTacToeBoard Clone(bool cloneMoves = false)
        {
            var clonedBoard = new UltimateTicTacToeBoard();

            if (cloneMoves)
            {
                foreach (var move in _moves)
                {
                    clonedBoard._moves.AddLast(move);
                }
            }
            else if (_moves.Count >= 1)
            {
                clonedBoard._moves.AddLast(_moves.Last.Value);
            }
            clonedBoard.WinningMove = WinningMove;
            clonedBoard.State       = State;
            for (int i = 0; i < 9; i++)
            {
                clonedBoard._grid[i] = _grid[i].Clone();
            }
            return(clonedBoard);
        }
コード例 #6
0
 public void AddChild(UltimateTicTacToeBoard data)
 {
     Children.Add(new GameTree(data));
 }
コード例 #7
0
 public GameTree(UltimateTicTacToeBoard data)
 {
     Data     = data;
     Children = new List <GameTree>();
 }
コード例 #8
0
        private static bool CanWin(Player player, UltimateTicTacToeBoard board, IEnumerable <int> cells)
        {
            var winState = player == Player.X ? GameState.Xwin : GameState.Owin;

            return(cells.All(cell => board.GameBoard.ElementAt(cell).State == GameState.Open || board.GameBoard.ElementAt(cell).State == winState));
        }
コード例 #9
0
ファイル: Program.cs プロジェクト: sonnemad/UltimateTicTacToe
        private static void PlayGame()
        {
            var board = new UltimateTicTacToeBoard();

            ITicTacToePlayer player1 = new HumanConsolePlayer(Player.X);
            ITicTacToePlayer player2 = new HumanConsolePlayer(Player.O);

            Console.SetWindowSize(80, 48);
            Console.WriteLine("Ultimate Tic Tac Toe!!!");

            bool correctPlayers = false;

            while (!correctPlayers)
            {
                Console.Write("How Many Players? ");
                int players;
                correctPlayers = int.TryParse(Console.ReadLine(), out players);
                if (correctPlayers)
                {
                    if (players == 2)
                    {
                        player1 = new HumanConsolePlayer(Player.X);
                        player2 = new HumanConsolePlayer(Player.O);
                    }
                    else if (players == 1)
                    {
                        Console.WriteLine("Do you want to play as X or O?");
                        var response = Console.ReadLine();
                        if (response?.StartsWith("x", StringComparison.InvariantCultureIgnoreCase) == true)
                        {
                            player1 = new HumanConsolePlayer(Player.X);
                            player2 = new MinMaxAIPlayer(Player.O);
                        }
                        else if (response?.StartsWith("o", StringComparison.InvariantCultureIgnoreCase) == true)
                        {
                            player1 = new MinMaxAIPlayer(Player.X);
                            player2 = new HumanConsolePlayer(Player.O);
                        }
                        else
                        {
                            correctPlayers = false;
                        }
                    }
                    else if (players == 0)
                    {
                        player1 = new MinMaxAIPlayer(Player.X);
                        player2 = new MinMaxAIPlayer(Player.O);
                    }
                    else
                    {
                        correctPlayers = false;
                    }
                }
                if (!correctPlayers)
                {
                    Console.WriteLine("Sorry kiddums, try again!");
                }
            }

            var startTime = DateTime.UtcNow;

            string[] player1LastTaunt = { "" };
            Taunt    p1Taunt          = delegate(string msg)
            {
                if (player1LastTaunt[0].Equals(msg))
                {
                    return;
                }
                player1LastTaunt[0] = msg;
                Console.WriteLine(msg);
            };

            player1.SetTauntDelegate(p1Taunt);
            string[] player2LastTaunt = { "" };
            Taunt    p2Taunt          = delegate(string msg)
            {
                if (player2LastTaunt[0].Equals(msg))
                {
                    return;
                }
                player2LastTaunt[0] = msg;
                Console.WriteLine(msg);
            };

            player2.SetTauntDelegate(p2Taunt);

            var playerTurn = Player.X;

            while (board.State == GameState.Open)
            {
                player1LastTaunt[0] = "";
                player2LastTaunt[0] = "";
                var validMove = false;
                while (!validMove)
                {
                    var move = playerTurn == Player.X ? player1.TakeTurn(board.Clone(cloneMoves: true)) : player2.TakeTurn(board.Clone(cloneMoves: true));

                    validMove = board.MakeMove(playerTurn, move.OuterCell, move.InnerCell);
                    if (!validMove)
                    {
                        Console.WriteLine("Sorry kiddums, try again!");
                    }
                    else
                    {
                        Console.Clear();
                        Console.WriteLine(GetCurrentGameStats(DateTime.UtcNow.Subtract(startTime)));
                        Console.WriteLine();
                        Console.WriteLine(board.ToString());
                    }
                }
                playerTurn = playerTurn == Player.X ? Player.O : Player.X;
            }

            var gameTime = DateTime.UtcNow.Subtract(startTime);

            _playtime      = _playtime.Add(gameTime);
            _totalPlaytime = _totalPlaytime.Add(gameTime);

            string stateStr = null;

            switch (board.State)
            {
            case GameState.Xwin:
                _xWins++;
                stateStr = "Player X Wins!";
                break;

            case GameState.Owin:
                _oWins++;
                stateStr = "Player O Wins!";
                break;

            case GameState.Open:
                break;

            case GameState.Draw:
                _draws++;
                stateStr = "DRAW!";
                break;

            default:
                throw new ArgumentOutOfRangeException();
            }

            Console.Clear();
            Console.WriteLine(GetGameStats());
            Console.WriteLine();
            Console.WriteLine(board.ToString());
            Console.WriteLine("Game has Ended: " + stateStr);
        }
コード例 #10
0
        UltimateTicTacToeMove ITicTacToePlayer.TakeTurn(UltimateTicTacToeBoard ticTacToeBoard)
        {
            Console.Clear();

            Console.WriteLine(ticTacToeBoard.ToString());
            Console.WriteLine();
            if (ticTacToeBoard.LastMove != null)
            {
                Console.WriteLine($"{ticTacToeBoard.LastMove.Player} made the move [{BoardToCell(ticTacToeBoard.LastMove.OuterCell)}:{BoardToCell(ticTacToeBoard.LastMove.InnerCell)}]");
                Console.WriteLine("");
            }
            Console.WriteLine($"Player {Player}'s, Please make your move!");
            byte outerCell;

            if (ticTacToeBoard.RequiredOuterCell == null)
            {
                Console.WriteLine("You get to play anywhere, choose wisely!");
                Console.Write("Outer Cell 1-9: ");
                byte.TryParse(Console.ReadLine(), out outerCell);
                outerCell = CellToBoard(outerCell);
                Console.WriteLine();
            }
            else
            {
                outerCell = ticTacToeBoard.RequiredOuterCell.Value;
            }

            var msg = "You are now playing in the ";

            switch (outerCell)
            {
            case 0:
                msg += "upper left cell";
                break;

            case 1:
                msg += "upper middle cell";
                break;

            case 2:
                msg += "upper right cell";
                break;

            case 3:
                msg += "middle left cell";
                break;

            case 4:
                msg += "center cell";
                break;

            case 5:
                msg += "middle right cell";
                break;

            case 6:
                msg += "lower left cell";
                break;

            case 7:
                msg += "lower center cell";
                break;

            case 8:
                msg += "lower right cell";
                break;

            default:
                msg += "DEFAULT ERROR";
                break;
            }
            Console.WriteLine();
            Console.WriteLine(msg);
            Console.WriteLine();

            Console.Write("Inner Cell 1-9: ");
            byte innerCell;

            byte.TryParse(Console.ReadLine(), out innerCell);
            innerCell = CellToBoard(innerCell);

            ticTacToeBoard.MakeMove(Player, outerCell, innerCell);
            Console.Clear();
            Console.WriteLine(ticTacToeBoard.ToString());

            return(new UltimateTicTacToeMove(Player, outerCell, innerCell));
        }