Exemple #1
0
        static List<int> Greedy(Board board, int player)
        {
            List<int> greedyReturn = new List<int>(); // 0: points after move, 1: move X, 2: move Y, 3: helper X, 4: helper Y
            greedyReturn.Add(board.Evaluate(player));
            greedyReturn.Add(-1);
            greedyReturn.Add(-1);
            greedyReturn.Add(-1);
            greedyReturn.Add(-1);

            List<List<int>> possibilities = board.GetPossibleMoves(player);

            if (possibilities.Count == 0)
            {
                return greedyReturn;
            }

            Board newBoard;

            foreach (List<int> move in board.GetPossibleMoves(player))
            {
                // Get new board configuration
                newBoard = board.MakeMove(move, player);

                if (newBoard.Evaluate(player) > greedyReturn[0])//if better than last possible move
                {
                    greedyReturn.Clear();//clear the last one
                    greedyReturn.Add(newBoard.Evaluate(player));
                    foreach (int val in move)
                        greedyReturn.Add(val);
                }
            }
            return greedyReturn;
        }
 public void FlipPiece_PositiveTest()
 {
     m_board = new Board(8);
     m_board.SetFieldValue(FieldValue.Black, new Coords(0, 0));
     m_board.FlipPiece(new Coords(0, 0));
     Assert.AreEqual(FieldValue.White, m_board.GetFieldValue(new Coords(0, 0)));
 }
 public MainWindow()
 {
     InitializeComponent();
     m_board = new Board(8);
     m_game = new OthelloGame(m_board);
     Board.SetBoard(m_board);// DataContext = m_guiboard;
     Board.BoardClickedEvent += BoardClicked;
 }
 public void ClearBoard_PositiveTest()
 {
     m_board = new Board(8);
     m_board.SetFieldValue(FieldValue.Black, new Coords(3, 2));
     m_board.ClearBoard();
     var numNotEmpty = m_board.CountBlacks + m_board.CountWhites;
     Assert.AreEqual(0, numNotEmpty);
 }
 public void CountByFieldValue_PositiveTest()
 {
     m_board = new Board(8);
     m_board.SetStartValues();
     m_board.SetFieldValue(FieldValue.Black, new Coords(0, 0));
     Assert.AreEqual(3, m_board.CountByFieldValue(FieldValue.Black));
     Assert.AreEqual(59, m_board.CountByFieldValue(FieldValue.Empty));
 }
        public void GetFieldValue_NegativeTest()
        {
            m_board = new Board(8);
            bool exceptionThrown = false;

            try { m_board.GetFieldValue(new Coords(0, -1)); }
            catch (ArgumentOutOfRangeException) { exceptionThrown = true; }

            Assert.IsTrue(exceptionThrown);
            exceptionThrown = false;

            try { m_board.GetFieldValue(new Coords(-1, -1)); }
            catch (ArgumentOutOfRangeException) {exceptionThrown = true;}

            Assert.IsTrue(exceptionThrown);
            exceptionThrown = false;

            try { m_board.GetFieldValue(new Coords(-1, 0)); }
            catch (ArgumentOutOfRangeException) { exceptionThrown = true; }

            Assert.IsTrue(exceptionThrown);
            exceptionThrown = false;

            try { m_board.GetFieldValue(new Coords(8, 0)); }
            catch (ArgumentOutOfRangeException) { exceptionThrown = true; }

            Assert.IsTrue(exceptionThrown);
            exceptionThrown = false;

            try { m_board.GetFieldValue(new Coords(0, 8)); }
            catch (ArgumentOutOfRangeException) { exceptionThrown = true; }

            Assert.IsTrue(exceptionThrown);
            exceptionThrown = false;

            try { m_board.GetFieldValue(new Coords(8, 8)); }
            catch (ArgumentOutOfRangeException) { exceptionThrown = true; }

            Assert.IsTrue(exceptionThrown);
            exceptionThrown = false;

            try { m_board.GetFieldValue(new Coords(8, -1)); }
            catch (ArgumentOutOfRangeException) { exceptionThrown = true; }

            Assert.IsTrue(exceptionThrown);
            exceptionThrown = false;

            try { m_board.GetFieldValue(new Coords(-1, 8)); }
            catch (ArgumentOutOfRangeException) { exceptionThrown = true; }

            Assert.IsTrue(exceptionThrown);
        }
        public void IsValidMove_PositiveTest()
        {
            var board = new Board(8);

            board.SetFieldValue(FieldValue.Black, new Coords(0, 0));
            board.SetFieldValue(FieldValue.White, new Coords(1, 0));

            var valid = OthelloRules.IsValidMove(FieldValue.Black, new Coords(2, 0), board);
            Assert.IsTrue(valid);

            board.SetFieldValue(FieldValue.White, new Coords(1, 1));
            valid = OthelloRules.IsValidMove(FieldValue.Black, new Coords(2, 2), board);
            Assert.IsTrue(valid);
        }
        /// <summary>
        /// Sets the board that should be shown in the GUI.
        /// 
        /// TODO: Remove listener for old board.
        /// </summary>
        public void SetBoard(Board board)
        {
            Rows = new ObservableCollection<ObservableCollection<GUIField>>();
                m_board = board;

                //Listen for new board
                m_board.BoardChanged += BoardChanged;

                for (int row = 0; row < m_board.Size; row++)
                {
                    var columns = new ObservableCollection<GUIField>();
                    for (int col = 0; col < m_board.Size; col++)
                    {
                        var coords = new Coords(col, row);
                        var field = new GUIField(board.GetFieldValue(coords), coords);
                        columns.Add(field);
                    }

                    Rows.Add(columns);
                }

                this.DataContext = Rows;
        }
Exemple #9
0
        static List<int> Human(Board board, int player)
        {
            List<int> humanReturn = new List<int>();
            humanReturn.Add(board.Evaluate(player));
            humanReturn.Add(-1);
            humanReturn.Add(-1);
            humanReturn.Add(-1);
            humanReturn.Add(-1);

            if (board.GetPossibleMoves(player).Count == 0)
            {
                return humanReturn;
            }

            while (true)
            {
                Console.Write("enter x-position:");
                humanReturn[1] = int.Parse(Console.ReadLine());
                Console.WriteLine();
                Console.Write("enter y-position:");
                humanReturn[2] = int.Parse(Console.ReadLine());
                Console.WriteLine();

                foreach (List<int> move in board.GetPossibleMoves(player))
                {
                    if (humanReturn[1] == move[0] && humanReturn[2] == move[1])
                    {
                        Board newBoard = board.MakeMove(move, player);
                        humanReturn[3] = move[2];
                        humanReturn[4] = move[3];
                        return humanReturn;
                    }
                }
                Console.WriteLine("invalid move!");
            }
        }
Exemple #10
0
 public Game(int i_BoardSize)
 {
     m_Board = new Board(i_BoardSize);
 }
Exemple #11
0
 private void InitBoard()
 {
     label5.Text = "";
     board = new Board(false);
     panel1.Width = 8 * Board.WIDTH;
     panel1.Height = 8 * Board.WIDTH;
 }
Exemple #12
0
        static void Main(string[] args)
        {
            // Maximum depth the algorithm should search to
            int maxDepth = 4;
            // Board attributes for its size
            int boardRows = 8, boardCols = 8;
            // Default empty square value - BE SURE ITS THE SAME HERE AND IN BOARD CLASS
            int emptySquare = 7;
            // Containers for the miniMax return values
            List<int> miniMaxValues = new List<int>();
            // Container to store and pass on only the move returned by miniMax
            List<int> chosenMove = new List<int>();
            // Initial values for blackPoint and whitePoints
            int blackPoints = 0, whitePoints = 0;
            // String to say who won the game
            string winner = "None";

            #region Create Start
            // Create rows
            int[][] startState = new int[boardRows][];
            // Create cols
            for (int i = 0; i < boardRows; ++i)
                startState[i] = new int[boardCols];

            // fill in the board with start state
            for (int r = 0; r < boardRows; ++r)
            {
                for (int c = 0; c < boardCols; ++c)
                {
                    if (r == 3 && c == 3)
                        startState[r][c] = 1;
                    else if (r == 3 && c == 4)
                        startState[r][c] = 0;
                    else if (r == 4 && c == 3)
                        startState[r][c] = 0;
                    else if (r == 4 && c == 4)
                        startState[r][c] = 1;
                    else
                        startState[r][c] = emptySquare;
                }
            }
            #endregion

            Board board = new Board(startState, 1);

            board.DisplayBoard();

            #region MiniMax Driver Section
            while (true)
            {
                // Player 1 (Black) Moves first

                miniMaxValues = MiniMax(board, 1, 1, maxDepth, 0);
                //miniMaxValues = MiniMaxMove(board, 1, 1, maxDepth, 0);
                //miniMaxValues = Unpredictable(board, 1);
                //miniMaxValues = Greedy(board, 1);
                //miniMaxValues = Human(board, 1);

                if (((miniMaxValues[1] == -1 || miniMaxValues[2] == -1 || miniMaxValues[3] == -1 || miniMaxValues[4] == -1) &&
                    board.IsGameOver(0)) || //other player cannot move also
                    (board.Evaluate(1) == 0) || (board.Evaluate(0) == 0)// one player or the other have 0 point
                    )
                {
                    blackPoints = board.Evaluate(1);
                    whitePoints = board.Evaluate(0);
                    break;
                }
                else if(miniMaxValues[1] != -1 && miniMaxValues[2] != -1 && miniMaxValues[3] != -1 && miniMaxValues[4] != -1)
                {
                    // New move coordinates
                    bool skip = true;
                    chosenMove.Clear();
                    foreach (int val in miniMaxValues)
                    {
                        if (skip)
                        {
                            skip = false;
                            continue;
                        }
                        chosenMove.Add(val);
                    }
                    board = board.MakeMove(chosenMove, 1);
                    board.DisplayBoard();
                }

                // Player 2 (White) Moves second

                //miniMaxValues = MiniMax(board, 0, 0, maxDepth, 0);
                //miniMaxValues = MiniMaxMove(board, 0, 0, maxDepth, 0);
                //miniMaxValues = Unpredictable(board, 0);
                miniMaxValues = Greedy(board, 0);
                //miniMaxValues = Human(board, 0);

                if (((miniMaxValues[1] == -1 || miniMaxValues[2] == -1 || miniMaxValues[3] == -1 || miniMaxValues[4] == -1) &&
                    board.IsGameOver(1)) || //other player cannot move also
                    (board.Evaluate(1) == 0) || (board.Evaluate(0) == 0)// one player or the other have 0 point
                    )
                {
                    blackPoints = board.Evaluate(1);
                    whitePoints = board.Evaluate(0);
                    break;
                }
                else if (miniMaxValues[1] != -1 && miniMaxValues[2] != -1 && miniMaxValues[3] != -1 && miniMaxValues[4] != -1)
                {
                    // New move coordinates
                    bool skip = true;
                    chosenMove.Clear();
                    foreach (int val in miniMaxValues)
                    {
                        if (skip)
                        {
                            skip = false;
                            continue;
                        }
                        chosenMove.Add(val);
                    }
                    board = board.MakeMove(chosenMove, 0);
                    board.DisplayBoard();
                }
            }
            #endregion

            // End game output
            if (blackPoints > whitePoints)
                winner = "Black Wins!";
            else if (whitePoints > blackPoints)
                winner = "White Wins!";
            else
                winner = "It's a Draw!";

            Console.WriteLine("Game Over!");
            Console.WriteLine("Black: " + blackPoints + "   White: " + whitePoints);
            Console.WriteLine(winner);

            #region System("pause") Equivalent
            Console.WriteLine();
            Console.Write("Press Enter To Exit");
            Console.ReadLine();
            #endregion
        }
Exemple #13
0
        //randomly choose a move
        static List<int> Unpredictable(Board board, int player)
        {
            List<int> UnpredictableReturn = new List<int>(); // 0: points after move, 1: move X, 2: move Y, 3: helper X, 4: helper Y

            List<List<int>> possibilities = board.GetPossibleMoves(player);

            if (possibilities.Count == 0)
            {
                UnpredictableReturn.Add(board.Evaluate(player));
                UnpredictableReturn.Add(-1);
                UnpredictableReturn.Add(-1);
                UnpredictableReturn.Add(-1);
                UnpredictableReturn.Add(-1);

                return UnpredictableReturn;
            }

            Random random = new Random();
            int randomMove = random.Next(0, possibilities.Count);
            List<int> move = possibilities[randomMove];

            UnpredictableReturn.Add(board.MakeMove(move, player).Evaluate(player));
            foreach (int val in move)
                UnpredictableReturn.Add(val);

            return UnpredictableReturn;
        }
Exemple #14
0
 private void ResetBoard()
 {
     label5.Text = "";
     board = new Board(true);
 }
Exemple #15
0
        //MiniMax base on number of moves
        static List<int> MiniMaxMove(Board board, int player, int callingPlayer, int maxDepth, int currentDepth)
        {
            // This array contains: bestScore, bestMoveX, bestMoveY in that order
            List<int> miniMaxReturn = new List<int>();
            // This array contains: bestScore, bestMoveX, bestMoveY in that order
            List<int> currentReturn = new List<int>();

            // Check for recursion end
            if (board.IsGameOver(player) || currentDepth == maxDepth)
            {
                miniMaxReturn.Add(board.GetPossibleMoves(callingPlayer).Count);
                miniMaxReturn.Add(-1);
                miniMaxReturn.Add(-1);
                miniMaxReturn.Add(-1);
                miniMaxReturn.Add(-1);

                return miniMaxReturn;
            }

            // Depending on the player we choose a starting bestScore
            // Negative if currentPlayer so we always chose a higher scored board
            if (board.GetCurrentPlayer() == player)
                miniMaxReturn.Add(-int.MaxValue);
            // Positive for opponent so that they always choose a lower scored
            // board
            else
                miniMaxReturn.Add(int.MaxValue);

            // Contains default moveX, moveY
            miniMaxReturn.Add(-1);
            miniMaxReturn.Add(-1);
            miniMaxReturn.Add(-1);
            miniMaxReturn.Add(-1);

            Board newBoard;
            // Recurse for each move
            foreach (List<int> move in board.GetPossibleMoves(player))
            {
                // Get new board configuration
                newBoard = board.MakeMove(move, player);

                // Recurse till return
                currentReturn = MiniMaxMove(newBoard, 1 - player, callingPlayer, maxDepth, currentDepth + 1);

                // Update the best score based on which player is playing
                if (board.GetCurrentPlayer() == player)
                {
                    if (currentReturn[0] > miniMaxReturn[0])
                    {
                        miniMaxReturn.Clear();
                        miniMaxReturn.Add(currentReturn[0]);
                        //miniMaxReturn[0] = currentReturn[0];
                        foreach(int val in move)
                            miniMaxReturn.Add(val);
                    }
                }
                else
                {
                    if (currentReturn[0] < miniMaxReturn[0])
                    {
                        miniMaxReturn.Clear();
                        miniMaxReturn.Add(currentReturn[0]);
                        //miniMaxReturn[0] = currentReturn[0];
                        foreach (int val in move)
                            miniMaxReturn.Add(val);
                    }
                }
            }

            return miniMaxReturn;
        }
Exemple #16
0
        /// <summary>
        /// Tìm nước đi tốt nhất (MiniMax)
        /// </summary>
        /// <param name="piece"></param>
        /// <param name="alpha"></param>
        /// <param name="depth">Độ sâu</param>
        /// <param name="board"></param>
        /// <param name="panel"></param>
        /// <returns></returns>
        public static int GetBestStep(int piece, int alpha, int depth, int difficulty, Board board, Panel panel)
        {
            // Giới hạn độ sâu
            if (depth > difficulty || board.WhiteCount + board.BlackCount == 64)
            {
                int k = board.GetValue();
                return k;
            }

            // List các nước đi có thể xảy ra
            List<int[]> EnableStepsList = board.GetEnableSteps(piece);

            if (EnableStepsList.Count == 0 && piece == WHITE)
                return -Int32.MaxValue;

            int bestvalue = Int32.MaxValue;

            foreach (int[] s in EnableStepsList)
            {
                if (AlphaBetaPruning(alpha, bestvalue, depth))
                {
                    return alpha;
                }

                Board boardcopy = board.Copy();
                boardcopy.Move(s[1], s[0], piece, true);

                // đệ quy tiếp, tăng độ sâu lên 1
                int cur_value = GetBestStep(-piece, alpha, depth + 1, difficulty, boardcopy, panel);

                bestvalue = MinMaxValue(cur_value, -bestvalue, depth);
            }

            return bestvalue;
        }
Exemple #17
0
 /// <summary>
 /// Copy ma trận bàn cờ
 /// </summary>
 /// <returns>Bàn cờ đã copy</returns>
 public Board Copy()
 {
     Board b = new Board(false);
     for (int i = 0; i < 8; i++)
     {
         for (int j = 0; j < 8; j++)
         {
             b.board[i, j] = board[i, j];
         }
     }
     b.whitecount = this.WhiteCount;
     b.blackcount = this.BlackCount;
     return b;
 }
Exemple #18
0
 public void RestartGame()
 {
     Board.Restart();
     Board.InitNewOthelloGame();
 }
Exemple #19
0
        // This Function makes a move given a certain player,
        // the location the move starts from,
        // and the location the move ends at
        public Board MakeMove(List<int> move, int player)
        {
            // Create temporary board
            int[][] temp = new int[this.board.Length][];
            for (int i = 0; i < this.board[0].Length; ++i)
                temp[i] = new int[this.board[0].Length];

            // Fill it with the current board values
            for (int r = 0; r < this.board.Length; ++r)
            {
                for (int c = 0; c < this.board[r].Length; ++c)
                    temp[r][c] = this.board[r][c];
            }

            // Set new game piece
            temp[move[1]][move[0]] = player;
            bool done = false;
            int indexCtr = 2;

            // Toggle all taken pieces
            int nmx = move[0], nmy = move[1];
            int mx = move[2], my = move[3];
            int incr = 0;
            // This whole section is for toggling the pieces
            // my = move-y          mx = move-x
            // nmy = new-move-y     nmx = new-move-x
            // my is strictly greater than nmy
            while (!done)
            {
                if (my > nmy)
                {
                    // up-left
                    if (mx > nmx)
                    {
                        for (int i = my; i >= nmy; --i)
                        {
                            temp[i][mx + (incr--)] = player;
                        }
                    }
                    // up-right
                    else if (mx < nmx)
                    {
                        for (int i = my; i >= nmy; --i)
                        {
                            temp[i][mx + (incr++)] = player;
                        }
                    }
                    // up
                    else
                    {
                        for (int i = nmy; i <= my; ++i)
                        {
                            for (int j = nmx; j <= mx; ++j)
                                temp[i][j] = player;
                        }
                    }
                }
                // nmy is strictly greater than my
                else if (my < nmy)
                {
                    // down-left
                    if (mx > nmx)
                    {
                        for (int i = my; i <= nmy; ++i)
                        {
                            temp[i][mx + (incr--)] = player;
                        }
                    }
                    // down-right
                    else if (mx < nmx)
                    {
                        for (int i = my; i <= nmy; ++i)
                        {
                            temp[i][mx + (incr++)] = player;
                        }
                    }
                    // down
                    else
                    {
                        for (int i = my; i <= nmy; ++i)
                        {
                            for (int j = mx; j <= nmx; ++j)
                                temp[i][j] = player;
                        }
                    }
                }
                else
                {
                    // Left
                    if (mx > nmx)
                    {
                        for (int j = nmx; j <= mx; ++j)
                            temp[my][j] = player;
                    }
                    // Right
                    else if (mx < nmx)
                    {
                        for (int j = mx; j <= nmx; ++j)
                            temp[my][j] = player;
                    }
                    // This case is a last resort failure case,
                    // should and never does get reached
                    else
                    {
                        Console.WriteLine("Somehow both x and y are the same");
                        Console.WriteLine("DEBUG DAMNIT!");
                        Console.ReadLine();
                    }
                }
                // If there are multiple initial points
                // Increment the index and reset the incr variable
                if (indexCtr < move.Count)
                {
                    mx = move[indexCtr++];
                    my = move[indexCtr++];
                    incr = 0;
                }
                // Else if there are no more initial points, exit loop
                else
                    done = true;
            }

            Board b = new Board(temp, player);
            return b;
        }
 public void SetStartValues_PositiveTest()
 {
     m_board = new Board(8);
     m_board.SetStartValues();
     Assert.AreEqual(2, m_board.CountWhites);
     Assert.AreEqual(2, m_board.CountBlacks);
     Assert.AreEqual(m_board.GetFieldValue(new Coords(4, 4)), m_board.GetFieldValue(new Coords(3, 3)));
     Assert.AreEqual(m_board.GetFieldValue(new Coords(3, 4)), m_board.GetFieldValue(new Coords(4, 3)));
 }