Example #1
0
        public static OthelloBoard CreateStartingBoard()
        {
            OthelloBoard board = new OthelloBoard(SquareState.Black);

            board.SetToStartingPosition();
            return(board);
        }
Example #2
0
        public override PlayerResult GetMove(OthelloBoard board)
        {
            ArrayList    moves     = board.GetValidMoves();
            int          moveIndex = rand.Next(moves.Count);
            PlayerResult result    = new PlayerResult();

            result.Move = (OthelloMove)moves[moveIndex];
            return(result);
        }
Example #3
0
        /* returns the difference of possible moves for the players */
        private int Mobility(OthelloBoard board)
        {
            int ret = board.CountValidMoves();

            board.CurrentPlayer = board.OtherPlayer;
            ret -= board.CountValidMoves();
            board.CurrentPlayer = board.OtherPlayer;

            return(ret);
        }
Example #4
0
        public virtual object Clone()
        {
            OthelloBoard ret = new OthelloBoard();

            ret._squares         = (SquareState[, ]) this._squares.Clone();
            ret.CurrentPlayer    = this._currentPlayer;
            ret._playerSquares   = this._playerSquares;
            ret._opponentSquares = this._opponentSquares;
            return(ret);
        }
Example #5
0
        /* Value of the X-squares */
        private int XSquareValue(OthelloBoard board)
        {
            int       ret            = 0;
            const int XSquarePenalty = 10;

            if (board[0, 0] == SquareState.Empty)
            {
                if (board[1, 1] == board.CurrentPlayer)
                {
                    ret -= XSquarePenalty;
                }
                else if (board[1, 1] == board.OtherPlayer)
                {
                    ret += XSquarePenalty;
                }
            }

            if (board[7, 0] == SquareState.Empty)
            {
                if (board[6, 1] == board.CurrentPlayer)
                {
                    ret -= XSquarePenalty;
                }
                else if (board[6, 1] == board.OtherPlayer)
                {
                    ret += XSquarePenalty;
                }
            }

            if (board[0, 7] == SquareState.Empty)
            {
                if (board[1, 6] == board.CurrentPlayer)
                {
                    ret -= XSquarePenalty;
                }
                else if (board[1, 6] == board.OtherPlayer)
                {
                    ret += XSquarePenalty;
                }
            }

            if (board[7, 7] == SquareState.Empty)
            {
                if (board[6, 6] == board.CurrentPlayer)
                {
                    ret -= XSquarePenalty;
                }
                else if (board[6, 6] == board.OtherPlayer)
                {
                    ret += XSquarePenalty;
                }
            }

            return(ret);
        }
Example #6
0
        protected override int GetBoardValue(OthelloBoard board)
        {
            int ret = 0;

            /************** X-SQUARE VALUE *******/
            ret += XSquareValue(board);
            ret += SquareValue(board);

            /************** MOBILITY ***********/
            ret += Mobility(board);

            return(ret);
        }
Example #7
0
 private void DoPostMoveProcessing(SquareState previousPlayerColor)
 {
     if (_board.GameOver)
     {
         MessageBox.Show("Game over!  Black: " + _board.BlackSquares +
                         " White: " + _board.WhiteSquares);
     }
     else if (_board.CurrentPlayer == previousPlayerColor)
     {
         MessageBox.Show("No moves for " + OthelloBoard.ColorNameFromSquareState(
                             _board.OtherPlayer));
     }
     PlayNextMove();
 }
Example #8
0
        private int SquareValue(OthelloBoard board)
        {
            int       ret           = 0;
            const int SquarePenalty = 10;

            if (board[0, 0] == board.CurrentPlayer)
            {
                ret += SquarePenalty;
            }
            else if (board[0, 0] == board.OtherPlayer)
            {
                ret -= SquarePenalty;
            }

            if (board[7, 0] == board.CurrentPlayer)
            {
                ret += SquarePenalty;
            }
            else if (board[7, 0] == board.OtherPlayer)
            {
                ret -= SquarePenalty;
            }

            if (board[0, 7] == board.CurrentPlayer)
            {
                ret += SquarePenalty;
            }
            else if (board[0, 7] == board.OtherPlayer)
            {
                ret -= SquarePenalty;
            }

            if (board[7, 7] == board.CurrentPlayer)
            {
                ret += SquarePenalty;
            }
            else if (board[7, 7] == board.OtherPlayer)
            {
                ret -= SquarePenalty;
            }

            return(ret);
        }
Example #9
0
        public Game()
        {
            this.DataContext = this;

            p1         = new Player(0, NAME_PLAYER_1, new BitmapImage(uriWhite));
            p2         = new Player(1, NAME_PLAYER_2, new BitmapImage(uriBlack));
            this.board = new OthelloBoard("Board", BOARD_WIDTH, BOARD_HEIGHT); //TODO : Change name dynamically, using save name !

            stackUndo = new Stack <Tuple <int[], bool> >();
            stackRedo = new Stack <Tuple <int[], bool> >();

            InitializeComponent();

            GridGeneration(BOARD_HEIGHT, BOARD_WIDTH);

            UpdateScore();

            initTimer();
        }
Example #10
0
        public static OthelloBoard LoadFromFile(string path)
        {
            StreamReader reader = new StreamReader(path);

            string       s             = reader.ReadLine();
            SquareState  currentPlayer = SquareStateFromChar(s[0]);
            OthelloBoard ret           = new OthelloBoard(currentPlayer);

            for (int y = 0; y < 8; y++)
            {
                s = reader.ReadLine();
                for (int x = 0; x < 8; x++)
                {
                    ret[x, y] = SquareStateFromChar(s[x]);
                }
            }

            reader.Close();

            return(ret);
        }
Example #11
0
        public override bool Equals(object o)
        {
            OthelloBoard other = (OthelloBoard)o;

            if (other.CurrentPlayer != this.CurrentPlayer)
            {
                return(false);
            }

            for (int y = 0; y < 8; y++)
            {
                for (int x = 0; x < 8; x++)
                {
                    if (other[x, y] != this[x, y])
                    {
                        return(false);
                    }
                }
            }

            return(true);
        }
Example #12
0
        public Game(int[] values, bool isWhiteTurn, long timeSaveWhite, long timeSaveBlack, Stack <Tuple <int[], bool> > stackUndo, Stack <Tuple <int[], bool> > stackRedo)
        {
            this.DataContext = this;

            p1         = new Player(0, NAME_PLAYER_1, new BitmapImage(uriWhite));
            p2         = new Player(1, NAME_PLAYER_2, new BitmapImage(uriBlack));
            this.board = new OthelloBoard("Board", BOARD_WIDTH, BOARD_HEIGHT, values, isWhiteTurn);

            this.isWhiteTurn   = isWhiteTurn;
            this.timeSaveWhite = timeSaveWhite;
            this.timeSaveBlack = timeSaveBlack;
            this.stackUndo     = stackUndo;
            this.stackRedo     = stackRedo;

            InitializeComponent();

            GridGeneration(BOARD_HEIGHT, BOARD_WIDTH);

            UpdateScore();

            initTimer();
        }
Example #13
0
 public void SetBoard(OthelloBoard board)
 {
     _board = board;
 }
Example #14
0
 public abstract PlayerResult GetMove(OthelloBoard board);
Example #15
0
        static void ReadBook()
        {
#if USE_TRANSPOSITION_TABLE
            StreamReader reader = null;

            try
            {
                reader = new StreamReader("book.txt");
            }
            catch
            {
                // No opening book, oh well...
                return;
            }

            // Each line is a game, and looks like: +d3-c3+c4-e3+c2-b3+d2...-a5+a7-a8+b8-b7: -04 10
            // -04 is the final score for black.  10 is always there and should be ignored
            for (int x = 0; ; x++)
            {
                string s = reader.ReadLine();
                if (s == null)
                {
                    break;
                }

                OthelloBoard board = OthelloBoard.CreateStartingBoard();

                int i;
                i = s.LastIndexOf(':');
                int val = int.Parse(s.Substring(i + 2, 3));
                if (val < 0)
                {
                    val -= 500;
                }
                else if (val > 0)
                {
                    val += 500;
                }

                // Only use the first 10 moves to limit size
                for (i = 0; i < (10 * 3); i += 3)
                {
                    if (s[i] == ':')
                    {
                        break;
                    }
                    OthelloMove move = new OthelloMove((s[i + 1] - 'a'), (s[i + 2] - '1'));
                    board.PlayMove(move);
                    board.FixUpCurrentPlayer();
                    _transpositionTable.AddEntry(board.GetHashCode(), 60 /*ply*/,
                                                 (board.CurrentPlayer == SquareState.Black) ? val : -val,
                                                 TranspositionTableElementType.Exact, -1, -1);
                    move = null;
                }

                board.FixUpCurrentPlayer();

                /*
                 * int expectedVal = board.BlackSquares - board.WhiteSquares;
                 * Debug.Assert(val == expectedVal);
                 * Debug.Assert(board.GameOver);
                 */
                board = null;
            }

            reader.Close();
#endif
        }
Example #16
0
        private int GetBoardValueRecursive(OthelloBoard board, int ply,
                                           int notStuck, int alpha, int beta)
        {
            //MyTrace(ply, "left="+board.EmptySquares+" alpha="+alpha+" beta="+beta);

            /* If the game is over */
            if (notStuck == 0 || board.EmptySquares == 0)
            {
                _finalEvaluations++;
                int squareDifference = board.PlayerSquares - board.OpponentSquares;

                if (squareDifference > 0)
                {
                    return(squareDifference + 1000);
                }
                if (squareDifference < 0)
                {
                    return(squareDifference - 1000);
                }

                // Tie
                return(0);
            }

#if USE_TRANSPOSITION_TABLE
            int  moveToTryFirst_X = -1, moveToTryFirst_Y = -1;
            bool needToTryFirstMove = false;
            int  boardHashCode      = board.GetHashCode();
            int  transpositionValue = _transpositionTable.LookupEntry(boardHashCode, ply,
                                                                      alpha, beta, ref moveToTryFirst_X, ref moveToTryFirst_Y);

            if (transpositionValue != AlphaBetaOthelloPlayer.INVALID_MOVE)
            {
                _transpositionHits++;
                return(transpositionValue);
            }

            if (moveToTryFirst_X >= 0)
            {
                needToTryFirstMove = true;
            }

            TranspositionTableElementType elementType = TranspositionTableElementType.Alpha;
            OthelloMoveWithData           bestMove    = null;
#endif

            if (ply == 0)
            {
                _boardEvaluations++;
                int val = GetBoardValue(board);
#if USE_TRANSPOSITION_TABLE
                _transpositionTable.AddEntry(boardHashCode, 0, val,
                                             TranspositionTableElementType.Exact, -1, -1);
#endif
                return(val);
            }

            int count = 0;
            for (int y = 0; y < 8; y++)
            {
                for (int x = 0; x < 8; x++)
                {
                    OthelloMoveWithData move;

#if USE_TRANSPOSITION_TABLE
                    if (needToTryFirstMove)
                    {
                        move = board.GetMoveInfoIfValid(moveToTryFirst_X, moveToTryFirst_Y);
                        needToTryFirstMove = false;

                        // Set x to -1 to make sure that (0,0) gets process next time around
                        x = -1;

                        // This could happen if we found an incorrect entry in the table
                        if (move == null)
                        {
                            continue;
                        }
                    }
                    else
                    {
                        // Skip this move if we've already tried it
                        if (x == moveToTryFirst_X && y == moveToTryFirst_Y)
                        {
                            continue;
                        }

                        move = board.GetMoveInfoIfValid(x, y);
                        if (move == null)
                        {
                            continue;
                        }
                    }
#else
                    move = board.GetMoveInfoIfValid(x, y);
                    if (move == null)
                    {
                        continue;
                    }
#endif

                    count++;

                    /* perform the move */
                    board.PlayMove(move);

                    //MyTrace(ply, move.X + "," + move.Y + " alpha="+alpha+" beta="+beta);
                    int val = (-GetBoardValueRecursive(board, ply - 1, 2, -beta, -alpha));
                    //MyTrace(ply, move.X + "," + move.Y + " alpha="+alpha+" beta="+beta+" val="+val);

                    board.UnplayMove(move);

                    if (val >= beta)
                    {
#if USE_TRANSPOSITION_TABLE
                        _transpositionTable.AddEntry(boardHashCode, ply, beta,
                                                     TranspositionTableElementType.Beta, move.X, move.Y);
#endif
                        return(BEST_MOVE);
                    }

                    if (val > alpha)
                    {
                        alpha = val;
#if USE_TRANSPOSITION_TABLE
                        elementType = TranspositionTableElementType.Exact;
                        bestMove    = move;
#endif
                    }
                }
            }

            if (count == 0)
            {        /* if no possible move */
                board.SwitchPlayer();
                int val = -GetBoardValueRecursive(board, ply, notStuck - 1, -beta, -alpha);
                board.SwitchPlayer();
                return(val);
            }

#if USE_TRANSPOSITION_TABLE
            if (bestMove != null)
            {
                _transpositionTable.AddEntry(boardHashCode, ply, alpha, elementType, bestMove.X, bestMove.Y);
            }
            else
            {
                _transpositionTable.AddEntry(boardHashCode, ply, alpha, elementType, -1, -1);
            }
#endif

            return(alpha);
        }
Example #17
0
 protected abstract int GetBoardValue(OthelloBoard board);
Example #18
0
 private void LoadGame_Click(object sender, System.EventArgs e)
 {
     _board          = OthelloBoard.LoadFromFile("game.txt");
     _lastPlayedMove = null;
     SyncBoardToUI();
 }
Example #19
0
 private void CreateDefaultBoard()
 {
     _board = OthelloBoard.CreateStartingBoard();
 }
Example #20
0
        public override PlayerResult GetMove(OthelloBoard board)
        {
            StringBuilder statusString = new StringBuilder();;

            _finalEvaluations = 0;
            _boardEvaluations = 0;
#if USE_TRANSPOSITION_TABLE
            _transpositionHits = 0;
            _transpositionTable._wrongEntriesFound      = 0;
            _transpositionTable._tooShallowEntriesFound = 0;
#endif
            DateTime startTime = DateTime.Now;

            OthelloMoveWithData[] moves          = board.GetValidMovesWithData();
            MoveWithValue[]       movesWithValue = new MoveWithValue[moves.Length];
            for (int i = 0; i < moves.Length; i++)
            {
                movesWithValue[i]      = new MoveWithValue();
                movesWithValue[i].Move = moves[i];
            }

            int currentPly;
#if USE_ITERATIVE_DEEPENING
            for (currentPly = 0; ; currentPly++)
            {
                //for (currentPly = 0; currentPly<2; currentPly++) {
#else
            for (int currentPly = ply - 1; currentPly < ply; currentPly++)
            {
#endif

                statusString.Length = 0;
                DateTime startIterationTime = DateTime.Now;

                statusString.Append("Depth " + (currentPly + 1).ToString() + ": ");

                // Should we do a final search
                if (board.EmptySquares <= 15 && currentPly > 5)
                {
                    currentPly = board.EmptySquares;
                }

                int alpha = WORST_MOVE;
                int beta  = BEST_MOVE;
                foreach (MoveWithValue move in movesWithValue)
                {
                    board.PlayMove(move.Move);

                    statusString.Append(move.Move.ToString());
                    this.PostStatus(statusString.ToString());

                    move.Value = (-GetBoardValueRecursive(board, currentPly, 2, -beta, -alpha));

                    if (move.Value != BEST_MOVE && move.Value != WORST_MOVE)
                    {
                        statusString.Append("(" + move.Value.ToString() + ")");
                    }
                    statusString.Append(" ");
                    this.PostStatus(statusString.ToString());

                    board.UnplayMove(move.Move);

                    if (move.Value > alpha)
                    {
                        alpha = move.Value;
                    }
                    if (alpha >= beta)
                    {
                        break;
                    }
                }

                Array.Sort(movesWithValue);

                // If we've already search to the end, we're done
                if (currentPly == board.EmptySquares)
                {
                    break;
                }

                if (movesWithValue[0].Value < -500 || movesWithValue[0].Value > 500)
                {
                    break;
                }

                TimeSpan t = DateTime.Now - startTime;
                if (t.TotalSeconds >= 3)
                {
                    break;
                }
            }

            PlayerResult result = new PlayerResult();
            result.Move = movesWithValue[0].Move;
            TimeSpan processingTime = DateTime.Now - startTime;
            statusString.Append("\r\nEvals: " + _boardEvaluations + " Final evals: " + _finalEvaluations + "\r\n");
#if USE_TRANSPOSITION_TABLE
            /*
             * statusString.Append("Transp: " + _transpositionHits +
             *  " wrong hits: " + _transpositionTable._wrongEntriesFound +
             *  " shallow hits: " + _transpositionTable._tooShallowEntriesFound + "\r\n");
             */
#endif
            statusString.Append("Score: " + movesWithValue[0].Value + " (" + processingTime + ")");
            result.Status = statusString.ToString();
            return(result);
        }