Example #1
0
    public void ResolveMove(StoneMove _move)
    {
        if (state[_move.startPos] == TileState.WhitePiece && _move.endPos < 4)
        {
            state[_move.startPos] = TileState.WhiteKing;
        }
        else if (state[_move.startPos] == TileState.BlackPiece && _move.endPos > 30)
        {
            state[_move.startPos] = TileState.BlackKing;
        }
        else if (_move.endState != TileState.Empty)
        {
            state[_move.startPos] = _move.endState;
        }

        state[_move.endPos]   = state[_move.startPos];
        state[_move.startPos] = TileState.Empty;

        if (_move.stoneCaptured)
        {
            foreach (int pos in _move.capturedStones)
            {
                state[pos] = TileState.Empty;
            }
        }
    }
Example #2
0
    public void AttemptMove(StoneMove _move)
    {
        if (validMoves.Contains(_move))
        {
            bool captureFound = false;
            bool furtherCaps  = true;

            List <StoneMove> moveCheck = new List <StoneMove>();

            boardState.ResolveMove(_move);

            if (_move.stoneCaptured)
            {
                foreach (int pos in _move.capturedStones)
                {
                    AI.FindValidMoves(boardState, _move.endPos, ref captureFound, ref furtherCaps, moveCheck, false);
                }

                int blackRemaining = 0, whiteRemaining = 0;
                for (int i = 0; i < 35; i++)
                {
                    TileState s = boardState.state[i];

                    if (s == TileState.BlackKing || s == TileState.BlackPiece)
                    {
                        blackRemaining++;
                    }
                    else if (s == TileState.WhiteKing || s == TileState.WhitePiece)
                    {
                        whiteRemaining++;
                    }
                }
                if (blackRemaining == 0)
                {
                    winner = 2;
                    EventManager.TriggerEvent("gameOver");
                }
                else if (whiteRemaining == 0)
                {
                    winner = 1;
                    EventManager.TriggerEvent("gameOver");
                }
            }

            if (captureFound)
            {
                validMoves = moveCheck;
            }
            else
            {
                turnComplete = true;
            }

            EventManager.TriggerEvent("boardUpdated");
        }
    }
Example #3
0
 public BoardNode(Board _boardState, int _activePlayer, StoneMove _moveMade)
 {
     boardState      = _boardState.Clone();
     activePlayer    = _activePlayer;
     childNodes      = new List <BoardNode>();
     validMoves      = AI.FindAllValidMoves(boardState, activePlayer, true);
     endNode         = true;
     moveMade        = _moveMade;
     valueCalculated = false;
 }
Example #4
0
        public EstimateMoveNode AddChild(StoneMove move)
        {
            var child = new EstimateMoveNode(this, move);

            lock (_lock)
            {
                this._Children.Add(child);
            }

            return(child);
        }
Example #5
0
 public BoardNode(Board _boardState, int _activePlayer, bool _shuffleMoves)
 {
     boardState   = _boardState.Clone();
     activePlayer = _activePlayer;
     childNodes   = new List <BoardNode>();
     validMoves   = AI.FindAllValidMoves(boardState, activePlayer, true);
     System.Random rnd = new System.Random();
     validMoves      = validMoves.OrderBy(item => rnd.Next()).ToList();
     endNode         = true;
     moveMade        = null;
     valueCalculated = false;
 }
Example #6
0
        private EstimateMoveNode(EstimateMoveNode parent, StoneMove move)
        {
            if (null == parent)
            {
                throw new ArgumentNullException("parent is null.");
            }
            if (null == move)
            {
                throw new ArgumentNullException("move is null.");
            }

            this.Parent    = parent;
            this.Depth     = Parent.Depth + 1;
            this.Move      = move;
            this._Children = new List <EstimateMoveNode>();

            InitializeState();
        }
Example #7
0
 public void AttemptMove(StoneMove _move)
 {
     model.AttemptMove(_move);
 }
Example #8
0
    public override bool PerformTurn(Board _currentBoard, int _aiPlayer, PlayerType otherPlayer, bool _firstTurn, out StoneMove _move, int presetFirstMove)
    {
        ADRASMoveList.Clear();

        if (boardNodes == null)
        {
            boardNodes = new List <BoardNode>();
        }

        _move = new StoneMove();

        List <StoneMove> possibleMoves = FindAllValidMoves(_currentBoard, _aiPlayer, true);

        System.Random    rnd          = new System.Random();
        List <StoneMove> shuffledList = possibleMoves.OrderBy(item => rnd.Next()).ToList();

        if (shuffledList.Count > 0)
        {
            StoneMove selectedMove      = possibleMoves[0];
            float     selectedMoveValue = -Mathf.Infinity;

            if (_firstTurn)
            {
                FFData temp;
                float  boardVal = GetBoardRating(_currentBoard, _aiPlayer, out temp);
                InitBoardVal[_aiPlayer - 1] = boardVal;
                if (_aiPlayer == 1)
                {
                    if (presetFirstMove >= 0 && presetFirstMove < possibleMoves.Count && !GameManager.DEMO)
                    {
                        _move = possibleMoves[presetFirstMove];
                    }
                    else
                    {
                        _move = shuffledList.First();
                    }
                    return(true);
                }
            }
            else
            {
                bool      existingNodeFound = false;
                BoardNode baseNode          = new BoardNode(_currentBoard, _aiPlayer);

                if (boardNodes.Count > 0)
                {
                    for (int i = 0; i < boardNodes.Count; i++)
                    {
                        if (boardNodes[i].boardState == _currentBoard)
                        {
                            existingNodeFound = true;
                            baseNode          = boardNodes[i];
                            break;
                        }
                    }
                }

                boardNodes = new List <BoardNode>();

                if (existingNodeFound && !baseNode.IsEndNode())
                {
                    boardNodes.AddRange(baseNode.GetChildren());
                }
                else
                {
                    foreach (StoneMove m in shuffledList)
                    {
                        Board testBoard = _currentBoard.Clone();
                        testBoard.ResolveMove(m);
                        BoardNode bn = new BoardNode(testBoard, 3 - _aiPlayer, m);
                        boardNodes.Add(bn);
                    }
                }

                foreach (BoardNode bn in boardNodes)
                {
                    bool prevStateFound = false;
                    foreach (Board b in CheckersMain.prevStates)
                    {
                        if (b == bn.boardState)
                        {
                            prevStateFound = true;
                        }
                    }

                    float moveValue = Mathf.NegativeInfinity;
                    if (!prevStateFound)
                    {
                        moveValue = Search.TraverseNodeList(bn, searchDepth - 1, Mathf.NegativeInfinity, Mathf.Infinity, _aiPlayer, false, this, 0);
                    }

                    if (moveValue >= 1 - accuracyMod)
                    {
                        ADRASMoveList.Add(bn);
                    }

                    if (moveValue > selectedMoveValue)
                    {
                        selectedMove      = bn.GetMoveMade();
                        selectedMoveValue = moveValue;
                    }
                }

                if (otherPlayer == PlayerType.Human)
                {
                    List <BoardNode> newNodeList = new List <BoardNode>(0);
                    foreach (BoardNode bn in boardNodes)
                    {
                        if (!bn.IsEndNode())
                        {
                            newNodeList.AddRange(bn.GetChildren());
                        }
                    }
                    boardNodes = newNodeList;
                }
            }

            if (selectedMoveValue > 1 - accuracyMod)
            {
                selectedMove = ADRASMoveList.OrderBy(item => rnd.Next()).First().GetMoveMade();
            }

            _move = selectedMove;
            return(true);
        }
        else
        {
            FFData data;
            GetBoardRating(_currentBoard, _aiPlayer, out data);
            return(false);
        }
    }
Example #9
0
    public virtual bool PerformTurn(Board _currentBoard, int _aiPlayer, PlayerType otherPlayer, bool _firstTurn, out StoneMove _move, int _presetFirstMove)
    {
        //initialize board node list if it isn't already
        if (boardNodes == null)
        {
            boardNodes = new List <BoardNode>();
        }

        //Placeholder move in case no valid moves are found
        _move = new StoneMove();

        //Generate list of possible moves for board state
        List <StoneMove> possibleMoves = FindAllValidMoves(_currentBoard, _aiPlayer, true);

        //Shuffle the list
        System.Random    rnd          = new System.Random();
        List <StoneMove> shuffledList = possibleMoves.OrderBy(item => rnd.Next()).ToList();

        if (shuffledList.Count > 0)
        {
            //set selected move to first move in the list & the value to infinity, this will likely be overwritten immediately.
            StoneMove selectedMove      = possibleMoves[0];
            float     selectedMoveValue = -Mathf.Infinity;

            //If its the first turn, run some extra processing
            if (_firstTurn)
            {
                FFData temp;
                //Find the initial board value for the player. This is used for dynamic difficulty AI's
                float boardVal = GetBoardRating(_currentBoard, _aiPlayer, out temp);
                InitBoardVal[_aiPlayer - 1] = boardVal;
                //If player is black, select the preset first move from the list and exit.
                if (_aiPlayer == 1)
                {
                    if (_presetFirstMove >= 0 && _presetFirstMove < possibleMoves.Count && !GameManager.DEMO)
                    {
                        _move = possibleMoves[_presetFirstMove];
                    }
                    else
                    {
                        _move = shuffledList.First();
                    }
                    return(true);
                }
            }
            //Main body
            else
            {
                bool      existingNodeFound = false;
                BoardNode baseNode          = new BoardNode(_currentBoard, _aiPlayer);
                //If we already have a list of board nodes to use the attempt to locate the current board in the list.
                if (boardNodes.Count > 0)
                {
                    for (int i = 0; i < boardNodes.Count; i++)
                    {
                        if (boardNodes[i].boardState == _currentBoard)
                        {
                            existingNodeFound = true;
                            baseNode          = boardNodes[i];
                            break;
                        }
                    }
                }
                //Refresh board node list
                boardNodes = new List <BoardNode>();
                //If we found a node, add the nodes children to the board node list
                if (existingNodeFound && !baseNode.IsEndNode())
                {
                    boardNodes.AddRange(baseNode.GetChildren());
                }
                //otherwise, generate a new node from this board and add that nodes children to the list
                else
                {
                    foreach (StoneMove m in shuffledList)
                    {
                        Board testBoard = _currentBoard.Clone();
                        testBoard.ResolveMove(m);
                        BoardNode bn = new BoardNode(testBoard, 3 - _aiPlayer, m);
                        boardNodes.Add(bn);
                    }
                }

                //Go through the board nodes and begin search
                foreach (BoardNode bn in boardNodes)
                {
                    bool prevStateFound = false;
                    foreach (Board b in CheckersMain.prevStates)
                    {
                        if (b == bn.boardState)
                        {
                            prevStateFound = true;
                        }
                    }

                    float moveValue = Mathf.NegativeInfinity;
                    if (!prevStateFound)
                    {
                        moveValue = Search.TraverseNodeList(bn, searchDepth - 1, Mathf.NegativeInfinity, Mathf.Infinity, _aiPlayer, false, this, 0);
                    }


                    if (moveValue > selectedMoveValue)
                    {
                        selectedMove      = bn.GetMoveMade();
                        selectedMoveValue = moveValue;
                    }
                }
                //If the other player is human. Then the next board state will be skipped, so next board node list has to be 2 ply away.
                if (otherPlayer == PlayerType.Human)
                {
                    List <BoardNode> newNodeList = new List <BoardNode>(0);
                    foreach (BoardNode bn in boardNodes)
                    {
                        if (!bn.IsEndNode())
                        {
                            newNodeList.AddRange(bn.GetChildren());
                        }
                    }
                    boardNodes = newNodeList;
                }
            }

            _move = selectedMove;
            return(true);
        }
        else
        {
            FFData data;
            GetBoardRating(_currentBoard, _aiPlayer, out data);
            return(false);
        }
    }
Example #10
0
    //Tests for any further captures that are possible and returns list of all further necessary captures.
    static private bool TestFurtherMoves(Board _board, int _activePlayer, StoneMove _initialMove, ref List <StoneMove> _foundMoves)
    {
        Board tempBoard = _board.Clone();

        tempBoard.ResolveMove(_initialMove);

        int newPos = _initialMove.endPos;

        TileState state = tempBoard.state[newPos];

        int enemyPlayer = 3 - _activePlayer;

        List <int> tempCaps = new List <int>();
        bool       moveFound = false;
        int        enemyPos, nextPos;

        for (int i = 4; i <= 5; i++)
        {
            if (state == TileState.BlackKing || state == TileState.BlackPiece || state == TileState.WhiteKing)
            {
                enemyPos = newPos + i;
                nextPos  = enemyPos + i;
                if (tempBoard.GetOwner(enemyPos) == enemyPlayer && tempBoard.GetOwner(nextPos) == 0)
                {
                    moveFound = true;

                    tempCaps.Clear();
                    tempCaps.AddRange(_initialMove.capturedStones);
                    tempCaps.Add(enemyPos);
                    StoneMove newMove = new StoneMove(_initialMove.startPos, nextPos, true, tempCaps, state);

                    if (!TestFurtherMoves(_board, _activePlayer, newMove, ref _foundMoves))
                    {
                        _foundMoves.Add(newMove);
                    }
                }
            }

            if (state == TileState.BlackKing || state == TileState.WhitePiece || state == TileState.WhiteKing)
            {
                enemyPos = newPos - i;
                nextPos  = enemyPos - i;

                if (tempBoard.GetOwner(enemyPos) == enemyPlayer && tempBoard.GetOwner(nextPos) == 0)
                {
                    moveFound = true;

                    tempCaps.Clear();
                    tempCaps.AddRange(_initialMove.capturedStones);
                    tempCaps.Add(enemyPos);
                    StoneMove newMove = new StoneMove(_initialMove.startPos, nextPos, true, tempCaps, state);

                    if (!TestFurtherMoves(_board, _activePlayer, newMove, ref _foundMoves))
                    {
                        _foundMoves.Add(newMove);
                    }
                }
            }
        }

        if (!moveFound)
        {
            return(false);
        }
        else
        {
            return(true);
        }
    }
Example #11
0
    protected static bool TestMove(Board _board, int _owner, int _startPos, int _movePos, ref bool _captureFound, ref bool _firstCap, List <StoneMove> _moves, bool _capChains)
    {
        //First ensure target position is within the bounds of the board.
        if (_movePos > 34 || _movePos < 0 || _movePos == 8 || _movePos == 17 || _movePos == 26)
        {
            return(false);
        }

        TileState targetState = _board.state[_movePos];

        //If target tile is occupied by a stone owned by the same player, move is not valid.
        if (_owner == 1 && (targetState == TileState.BlackKing || targetState == TileState.BlackPiece) ||
            _owner == 2 && (targetState == TileState.WhiteKing || targetState == TileState.WhitePiece))
        {
            return(false);
        }

        //If target tile is empty then move is allowed.
        if (targetState == TileState.Empty)
        {
            if (_captureFound)
            {
                return(false);
            }
            _moves.Add(new StoneMove(_startPos, _movePos, false, 0));
            return(true);
        }

        //If we have gotten this far then the tile must be occupied by an enemy! Now we test if there is an unoccupied tile behind them
        int endPos = _movePos + (_movePos - _startPos);

        //Double check we're still within the board bounds.
        if (endPos > 34 || endPos < 0 || endPos == 8 || endPos == 17 || endPos == 26)
        {
            return(false);
        }

        //Final check, if the tile beyond the enemy is empty then they are capturable! But we have to check for further captures that are possible
        if (_board.state[endPos] == TileState.Empty)
        {
            _captureFound = true;
            if (_firstCap)
            {
                _moves.Clear();
                _firstCap = false;
            }
            StoneMove _move = new StoneMove(_startPos, endPos, true, _movePos);

            if (!_capChains)
            {
                _moves.Add(_move);
            }
            else if (!TestFurtherMoves(_board, _owner, _move, ref _moves))
            {
                _moves.Add(_move);
            }

            return(true);
        }

        //If we get this far then there are no more checks to do. It is not a valid move.
        return(false);
    }
 // Use this for initialization
 void Start()
 {
     objectalpha = stoneRef.GetComponent <StoneMove>();
     this.GetComponent <Image>().color = new Color(1.0f, 1.0f, 1.0f, 0.0f);
 }