Example #1
0
        private void TakeTurn(GameState gameState, bool beginningPlayer)
        {
            var board = Board.Parse(gameState.BoardData.ToByteArray(), (int)gameState.BoardWidth, (int)gameState.BoardHeight, beginningPlayer);

            Console.WriteLine("Opponent played:");
            board.Display();

            int tilesTotal  = board.Width * board.Height;
            int tilesPlaced = gameState.BoardData.Count(b => b != (byte)'0');
            int tilesFree   = tilesTotal - tilesPlaced;
            int depth       = 3;


            /*
             * int tilesToWin = Math.Min((int)board.Width - maxPlayerScore[0], (int)board.Height - maxPlayerScore[1]);
             * if(tilesToWin <= 6)
             * {
             *  depth = 3;
             * }
             */


            int boardFillAmount = gameState.BoardData.Count(b => b != (byte)'0');
            int boardSize       = gameState.BoardData.Length;
            int tilesLeft       = boardSize - boardFillAmount;

            Console.WriteLine("My turn! Calculating...");

            Children.Clear();
            var root = GameTree(board, null, beginningPlayer, int.MinValue, int.MaxValue, depth, 0, true);

            Node bestChild = null;

            if (beginningPlayer)
            {
                bestChild = Children.Aggregate((best, cur) => cur.Evaluation > best.Evaluation ? cur : best);
            }
            else
            {
                bestChild = Children.Aggregate((best, cur) => cur.Evaluation < best.Evaluation ? cur : best);
            }

            var end = System.DateTime.Now;

            Console.WriteLine("Seconds taken for turn: " + Stopwatch.Elapsed.TotalSeconds);

            var bestMove = new GameTurn()
            {
                X1 = bestChild.X1,
                Y1 = bestChild.Y1,
                X2 = bestChild.X2,
                Y2 = bestChild.Y2,
            };

            SubmitTurn(bestMove);

            Console.WriteLine("Move taken (Eval: " + bestChild.Evaluation + "): ");
            board.Display(bestMove);
            Console.WriteLine("---");
        }
Example #2
0
        public void Display(GameTurn myTurn = null)
        {
            string firstPlayerMarker  = (myToken == 'X' ? green : red) + 'X';
            string secondPlayerMarker = (myToken == 'O' ? green : red) + 'O';

            var rawToDisplayCharacter = new Dictionary <byte, string>()
            {
                { (byte)'0', white + '.' },
                { (byte)'1', firstPlayerMarker },
                { (byte)'2', secondPlayerMarker }
            };

            StringBuilder sb = new StringBuilder();

            for (int y = 0; y < Height; y++)
            {
                for (int x = 0; x < Width; x++)
                {
                    if (myTurn != null && (x == myTurn.X1 && y == myTurn.Y1 || x == myTurn.X2 && y == myTurn.Y2))
                    {
                        sb.Append(yellow + myToken);
                    }
                    else
                    {
                        sb.Append(rawToDisplayCharacter[Data[x, y]]);
                    }
                }
                sb.AppendLine();
            }
            sb.Append(white);
            Console.WriteLine(sb.ToString());
        }
Example #3
0
        public static Board DeepCopyAndAddMove(Board other, GameTurn move, byte b)
        {
            var newBoard = DeepCopy(other);

            newBoard.Data[move.X1, move.Y1] = b;
            newBoard.Data[move.X2, move.Y2] = b;
            return(newBoard);
        }
Example #4
0
 public Node(int eval, GameTurn move)
 {
     Evaluation = eval;
     if (move == null)
     {
         return;
     }
     X1 = move.X1;
     Y1 = move.Y1;
     X2 = move.X2;
     Y2 = move.Y2;
 }
Example #5
0
        public void SubmitTurn(GameTurn turn)
        {
            var cToken  = new System.Threading.CancellationToken();
            var request = new TurnRequest()
            {
                MatchId     = matchID,
                DomGameTurn = turn
            };
            var response = client.SubmitTurn(request, null, null, cToken);

            if (response.TurnStatus == TurnStatus.InvalidTurn)
            {
                Console.WriteLine("Ooops, invalid turn!");
                AbortMatch();
            }
        }
Example #6
0
        public Node GameTree(Board oldBoard, GameTurn move, bool maximizer, int alpha, int beta, int remainingDepth, int depth, bool presort)
        {
            Board board;

            if (move != null)
            {
                byte b = maximizer ? (byte)'2' : (byte)'1';
                board = Board.DeepCopyAndAddMove(oldBoard, move, b);
            }
            else
            {
                board = oldBoard;
            }

            //board.Display();
            //curNode.Board = board;

            if (GameOver(board))
            {
                if (move == null)
                {
                    maximizer = !maximizer;
                }
                //board.Display();
                var eval = (maximizer ? int.MinValue : int.MaxValue) - (maximizer ? (-depth) : (depth));
                //Console.WriteLine("^Game Over^ -> " + curNode.Evaluation);
                return(new Node(eval, move));
            }

            if (remainingDepth == 0)
            {
                return(new Node(Heuristic(board, depth), move));
            }

            IEnumerable <GameTurn> possibleMoves;

            if (presort)
            {
                // presort children based on shallow tree
                Children.Clear();
                var tmpRoot = GameTree(oldBoard, move, maximizer, int.MinValue, int.MaxValue, 2, 0, false);
                possibleMoves = Children.OrderBy(c => c.Evaluation).Select(c => new GameTurn()
                {
                    X1 = c.X1, X2 = c.X2, Y1 = c.Y1, Y2 = c.Y2
                }).ToArray();
                if (possibleMoves.Count() < 100)
                {
                    remainingDepth++;
                }
                if (possibleMoves.Count() < 50)
                {
                    remainingDepth++;
                }
                Console.WriteLine("Depth: " + remainingDepth);
                Children.Clear();
            }
            else
            {
                possibleMoves = GetPossibleMoves(board).OrderBy(p => Math.Abs(p.X1 - p.Y1));
            }

            if (!possibleMoves.Any())
            {
                return(new Node(0, move));
            }

            var curNode = new Node(0, move);

            foreach (var newMove in possibleMoves)
            {
                if (Stopwatch.Elapsed.TotalSeconds > 350)
                {
                    break;
                }

                var child = GameTree(board, newMove, !maximizer, alpha, beta, remainingDepth - 1, depth + 1, false);

                if (depth == 0)
                {
                    Children.Add(child);
                }

                if (maximizer)
                {
                    alpha = Math.Max(alpha, child.Evaluation);
                }
                else
                {
                    beta = Math.Min(beta, child.Evaluation);
                }

                if (beta <= alpha)
                {
                    curNode.Evaluation = maximizer ? beta : alpha;;
                    return(curNode);
                }
            }

            curNode.Evaluation = maximizer ? alpha : beta;
            return(curNode);
        }
Example #7
0
        public static void ManualPlay(int width, int height, int depth)
        {
            var rawBoard = new byte[width * height];

            Array.Fill(rawBoard, (byte)'0');
            var startingBoard = Board.Parse(rawBoard, width, height, true);

            var dummyGame = new DominectGame();

            dummyGame.InitInternals((int)width, (int)height);

            string line = "";

            do
            {
                //System.GC.Collect();
                //GC.WaitForPendingFinalizers();
                //System.GC.Collect();

                line = Console.ReadLine();

                if (line.Length == 0)
                {
                    break;
                }

                var  coords = line.Split(' ');
                uint x1     = uint.Parse(coords[0]);
                uint y1     = uint.Parse(coords[1]);
                uint x2     = uint.Parse(coords[2]);
                uint y2     = uint.Parse(coords[3]);

                startingBoard.Data[x1, y1] = (byte)'1';
                startingBoard.Data[x2, y2] = (byte)'1';

                var playerMove = new GameTurn
                {
                    X1 = x1,
                    Y1 = y1,
                    X2 = x2,
                    Y2 = y2
                };

                dummyGame.Stopwatch.Restart();
                dummyGame.Children.Clear();
                var start = System.DateTime.Now;
                var root  = dummyGame.GameTree(startingBoard, null, false, int.MinValue, int.MaxValue, depth, 0, true);
                var end   = System.DateTime.Now;
                Console.WriteLine("Final root value: " + root.Evaluation + " (" + (end - start).TotalSeconds + "s)");

                var bestChild = dummyGame.Children.Aggregate((best, cur) => cur.Evaluation < best.Evaluation ? cur : best);
                var bestMove  = new GameTurn()
                {
                    X1 = bestChild.X1,
                    Y1 = bestChild.Y1,
                    X2 = bestChild.X2,
                    Y2 = bestChild.Y2,
                };

                startingBoard.Data[bestChild.X1, bestChild.Y1] = (byte)'2';
                startingBoard.Data[bestChild.X2, bestChild.Y2] = (byte)'2';
                //startingBoard.Data[x1, y1] = (byte)'1';
                //startingBoard.Data[x2, y2] = (byte)'1';

                startingBoard.Display(bestMove);
                bestChild = null;
                root      = null;
            } while (line.Length > 0);
        }