Esempio n. 1
0
        public OthelloMoveWithData[] GetValidMovesWithData()
        {
            int count = 0;

            for (int y = 0; y < 8; y++)
            {
                for (int x = 0; x < 8; x++)
                {
                    OthelloMoveWithData move = GetMoveInfoIfValid(x, y);
                    if (move != null)
                    {
                        _tempMoveWithDataArray[count++] = move;
                    }
                }
            }

            if (count == 0)
            {
                return(null);
            }

            OthelloMoveWithData[] validMoves = new OthelloMoveWithData[count];
            for (int i = 0; i < count; i++)
            {
                validMoves[i] = _tempMoveWithDataArray[i];
            }

            return(validMoves);
        }
Esempio n. 2
0
        /*
         * OthelloMoveWithData qqq(int x, int y) {
         * int i=1;
         * if (i==0)
         *  throw new Exception("Bogus exception just to prevent method inlining");
         *
         * OthelloMoveWithData moveInfo = new OthelloMoveWithData(x, y);
         * moveInfo.CurrentPlayer = this.CurrentPlayer;
         * moveInfo.PlayerSquares = this._playerSquares;
         * moveInfo.OpponentSquares = this._opponentSquares;
         * return moveInfo;
         * }
         */

        public OthelloMoveWithData GetMoveInfoIfValid(int x, int y)
        {
            if (_squares[x, y] != SquareState.Empty)
            {
                return(null);
            }

            OthelloMoveWithData moveInfo = null;

            for (int dir = 0; dir < 8; dir++)
            {
                int num = NumToTakeInDirection(
                    x, y, _directions[dir, 0], _directions[dir, 1]);
                if (num > 0)
                {
                    if (moveInfo == null)
                    {
                        moveInfo = new OthelloMoveWithData(x, y);
                        moveInfo.CurrentPlayer   = this.CurrentPlayer;
                        moveInfo.PlayerSquares   = this._playerSquares;
                        moveInfo.OpponentSquares = this._opponentSquares;
                    }
                    moveInfo.CaptureInDirection[dir] = num;
                }
            }

            return(moveInfo);
        }
Esempio n. 3
0
        public void UnplayMove(OthelloMoveWithData move)
        {
            this.CurrentPlayer    = move.CurrentPlayer;
            this._playerSquares   = move.PlayerSquares;
            this._opponentSquares = move.OpponentSquares;
            _gameOver             = false;

            for (int dir = 0; dir < 8; dir++)
            {
                int captureInDirection = move.CaptureInDirection[dir];
                if (captureInDirection > 0)
                {
                    UntakeInDirection(move.X, move.Y, _directions[dir, 0],
                                      _directions[dir, 1], move.CaptureInDirection[dir]);
                }
            }

            this[move.X, move.Y] = SquareState.Empty;
        }
Esempio n. 4
0
        public void PlayMove(OthelloMoveWithData move)
        {
            for (int dir = 0; dir < 8; dir++)
            {
                int captureInDirection = move.CaptureInDirection[dir];
                if (captureInDirection > 0)
                {
                    TakeInDirection(move.X, move.Y, _directions[dir, 0],
                                    _directions[dir, 1], move.CaptureInDirection[dir]);
                }
            }

            this[move.X, move.Y] = CurrentPlayer;

            SwitchPlayer();

            if (EmptySquares == 0)
            {
                _gameOver = true;
                return;
            }
        }
Esempio n. 5
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);
        }