public BoardSpace[][] updateBoard(BoardSpace[][] previousBoard, KeyValuePair <int, int> move, uint turnNumber)
    {
        BoardSpace[][] newBoard = previousBoard.Select(x => x.ToArray()).ToArray();
        if (turnNumber % 2 == 0)
        {
            newBoard[move.Key][move.Value] = BoardSpace.BLACK;
        }
        else
        {
            newBoard[move.Key][move.Value] = BoardSpace.WHITE;
        }
        List <KeyValuePair <int, int> > updatedMoves = BoardScript.GetPointsChangedFromMove(newBoard, turnNumber, move.Value, move.Key);

        foreach (KeyValuePair <int, int> action in updatedMoves)
        {
            if (turnNumber % 2 == 0)
            {
                newBoard[action.Key][action.Value] = BoardSpace.BLACK;
            }
            else
            {
                newBoard[action.Key][action.Value] = BoardSpace.WHITE;
            }
        }
        ++turnNumber;
        return(newBoard);
    }
Exemple #2
0
    public BoardSpace[][] createNewBoard(BoardSpace[][] board, KeyValuePair <int, int> move, bool isBlack)
    {
        BoardSpace[][] newBoard = new BoardSpace[8][];
        //Copy board
        for (int i = 0; i < 8; i++)
        {
            newBoard[i] = new BoardSpace[8];
            for (int j = 0; j < 8; j++)
            {
                newBoard[i][j] = board[i][j];
            }
        }

        newBoard[move.Key][move.Value] = isBlack ? BoardSpace.BLACK : BoardSpace.WHITE;

        //Update Moves
        List <KeyValuePair <int, int> > changedSpots = BoardScript.GetPointsChangedFromMove(newBoard, isBlack ? ((uint)2) : ((uint)1), move.Value, move.Key);

        foreach (KeyValuePair <int, int> change in changedSpots)
        {
            newBoard[change.Key][change.Value] = isBlack ? BoardSpace.BLACK : BoardSpace.WHITE;
        }

        return(newBoard);
    }
    private int negamax(BoardSpace[][] node, uint depth, int color)
    {
        //Debug.Log("negamax function start");
        if (depth == maxDepth - 2)
        {
            int retVal = -1000000;
            List <KeyValuePair <int, int> > moves = BoardScript.GetValidMoves(node, BoardScript.GetTurnNumber() + maxDepth);

            foreach (KeyValuePair <int, int> n in moves)
            {
                int temp = rateMoveSelect(moves, n);
                if (temp > retVal)
                {
                    retVal = temp;
                }
            }
            return(retVal);
        }
        else
        {
            int value = -100000;
            //go through each valid move for this board state
            foreach (KeyValuePair <int, int> n in BoardScript.GetValidMoves(node, BoardScript.GetTurnNumber()))
            {
                BoardSpace[][] nodeCopy = new BoardSpace[8][];
                for (int x = 0; x < 8; x++)
                {
                    nodeCopy[x] = new BoardSpace[8];
                    System.Array.Copy(node[x], nodeCopy[x], 8);
                }
                if (color == -1)
                {
                    nodeCopy[n.Value][n.Key] = BoardSpace.BLACK;
                }
                else
                {
                    nodeCopy[n.Value][n.Key] = BoardSpace.WHITE;
                }

                //simulate the changes each move would result in
                List <KeyValuePair <int, int> > simulatedChanges = BoardScript.GetPointsChangedFromMove(nodeCopy, BoardScript.GetTurnNumber() + depth, n.Key, n.Value);
                foreach (KeyValuePair <int, int> spot in simulatedChanges)
                {
                    if (nodeCopy[spot.Value][spot.Key] == BoardSpace.BLACK)
                    {
                        nodeCopy[spot.Value][spot.Key] = BoardSpace.WHITE;
                    }
                    else
                    {
                        nodeCopy[spot.Value][spot.Key] = BoardSpace.BLACK;
                    }
                }
                //recurse
                value = Mathf.Max(value, -1 * negamax(nodeCopy, depth + 1, -1 * color));
            }
            return(value);
        }
    }
    public override KeyValuePair <int, int> makeMove(List <KeyValuePair <int, int> > availableMoves, BoardSpace[][] currBoard)
    {
        board = currBoard;

        if (color == BoardSpace.BLACK)
        {
            colorNum = -1;
        }
        else
        {
            colorNum = 1;
        }
        KeyValuePair <int, int> best;
        int bestScore = -100000000;

        foreach (KeyValuePair <int, int> n in availableMoves)
        {
            Debug.Log("iteration start");
            BoardSpace[][] nodeCopy = new BoardSpace[8][];
            for (int x = 0; x < 8; x++)
            {
                nodeCopy[x] = new BoardSpace[8];
                System.Array.Copy(currBoard[x], nodeCopy[x], 8);
            }
            if (colorNum == -1)
            {
                nodeCopy[n.Value][n.Key] = BoardSpace.BLACK;
            }
            else
            {
                nodeCopy[n.Value][n.Key] = BoardSpace.WHITE;
            }

            //simulate the changes the move would result in
            List <KeyValuePair <int, int> > simulatedChanges = BoardScript.GetPointsChangedFromMove(nodeCopy, BoardScript.GetTurnNumber(), n.Key, n.Value);
            //Debug.Log(simulatedChanges);
            foreach (KeyValuePair <int, int> spot in simulatedChanges)
            {
                if (nodeCopy[n.Value][n.Key] == BoardSpace.BLACK)
                {
                    nodeCopy[n.Value][n.Key] = BoardSpace.WHITE;
                }
                else
                {
                    nodeCopy[n.Value][n.Key] = BoardSpace.BLACK;
                }
            }
            //Debug.Log("starting negamax traversal");
            int value = negamax(nodeCopy, 0, colorNum);
            if (value >= bestScore)
            {
                best = n;
            }
        }
        Debug.Log("best is x:" + best.Value + " y:" + best.Key);
        return(best);
    }
Exemple #5
0
    private float ABnegaMax(BoardSpace[][] currentBoard, int current_depth, int Max_depth, uint turn_number, float alpha, float beta)
    {
        BoardSpace enemyColor     = turn_number % 2 == 0 ? BoardSpace.WHITE : BoardSpace.BLACK;
        BoardSpace ourColor       = turn_number % 2 == 0 ? BoardSpace.BLACK : BoardSpace.WHITE;
        uint       current_player = turn_number % 2;
        List <KeyValuePair <int, int> > possible_moves = BoardScript.GetValidMoves(currentBoard, turn_number);

        if (current_depth >= Max_depth || possible_moves.Count == 0)
        {
            return(Evaluation(currentBoard, turn_number));
        }
        List <float> score = new List <float>();

        //Debug.Log("current depth: " + current_depth + " move size: " + possible_moves.Count);
        foreach (KeyValuePair <int, int> move in possible_moves)
        {
            BoardSpace[][] newer_board = new BoardSpace[8][];
            for (int i = 0; i < 8; ++i)
            {
                newer_board[i] = new BoardSpace[8];
                for (int j = 0; j < 8; ++j)
                {
                    newer_board[i][j] = currentBoard[i][j];
                }
            }
            newer_board[move.Key][move.Value] = ourColor;
            List <KeyValuePair <int, int> > changed = BoardScript.GetPointsChangedFromMove(newer_board, turn_number, move.Value, move.Key);
            //Debug.Log("changed: " + string.Join(",", changed));
            foreach (KeyValuePair <int, int> change in changed)
            {
                newer_board[change.Key][change.Value] = ourColor;
            }
            //add a variable that stores alpha
            //instead of compiling scores, compare with beta. if >=, just return
            //negaMax w/ alpha and beta being -beta, -<variable>
            float value = (-ABnegaMax(newer_board, current_depth + 1, Max_depth, turn_number + 1, -beta, -alpha));
            score.Add(value);
            if (value >= beta)
            {
                break;
            }
            if (value >= alpha)
            {
                alpha = value;
            }
        }
        //Debug.Log("score: " + string.Join(",", score));
        return(score.Max());
    }
Exemple #6
0
    /// <summary>
    /// This shows how to override the abstract definition of makeMove. All this one
    /// does is stupidly a random, yet legal, move.
    /// </summary>
    /// <param name="availableMoves"></param>
    /// <param name="currentBoard"></param>
    /// <returns></returns>

    public override KeyValuePair <int, int> makeMove(List <KeyValuePair <int, int> > availableMoves, BoardSpace[][] currentBoard, uint turn_number)
    {
        //Debug.Log(string.Join(",", availableMoves));
        BoardSpace enemyColor = turn_number % 2 == 0 ? BoardSpace.WHITE : BoardSpace.BLACK;
        BoardSpace ourColor   = turn_number % 2 == 0 ? BoardSpace.BLACK : BoardSpace.WHITE;
        KeyValuePair <int, int>         result;
        List <KeyValuePair <int, int> > result_candidates = new List <KeyValuePair <int, int> >();
        float score = float.NegativeInfinity;

        foreach (KeyValuePair <int, int> move in availableMoves)
        {
            BoardSpace[][] newer_board = new BoardSpace[8][];
            for (int i = 0; i < 8; ++i)
            {
                newer_board[i] = new BoardSpace[8];
                for (int j = 0; j < 8; ++j)
                {
                    newer_board[i][j] = currentBoard[i][j];
                }
            }
            //Debug.Log(move.Key + "," + move.Value);
            newer_board[move.Key][move.Value] = ourColor;
            List <KeyValuePair <int, int> > changed = BoardScript.GetPointsChangedFromMove(newer_board, turn_number, move.Value, move.Key);
            //Debug.Log(string.Join(",", changed));
            foreach (KeyValuePair <int, int> change in changed)
            {
                newer_board[change.Key][change.Value] = ourColor;
            }
            float candidate = ABnegaMax(newer_board, 1, Maxdepth, turn_number + 1, float.NegativeInfinity, float.PositiveInfinity);
            //Debug.Log("candidate: " + candidate);
            if (candidate >= score)
            {
                if (candidate > score)
                {
                    result_candidates.Clear();
                    result = new KeyValuePair <int, int>(move.Key, move.Value);
                    score  = candidate;
                    result_candidates.Add(result);
                }
                else
                {
                    result_candidates.Add(result);
                }
            }
        }
        //Debug.Log("turn number: " + turn_number);
        //Debug.Log("final score: " + score);
        return(result_candidates[Random.Range(0, result_candidates.Count)]);
    }
Exemple #7
0
    public override KeyValuePair <int, int> makeMove(List <KeyValuePair <int, int> > availableMoves, BoardSpace[][] currentBoard)
    {
        if (color == BoardSpace.BLACK)
        {
            colorNum = 1;
        }
        else
        {
            colorNum = -1;
        }
        KeyValuePair <int, int> best;
        int bestScore = -100000000;

        foreach (KeyValuePair <int, int> n in availableMoves)
        {
            BoardSpace[][] nodeCopy = (BoardSpace[][])currentBoard.Clone();
            if (colorNum == 1)
            {
                nodeCopy[n.Key][n.Value] = BoardSpace.BLACK;
            }
            else
            {
                nodeCopy[n.Key][n.Value] = BoardSpace.WHITE;
            }

            //simulate the changes the move would result in
            List <KeyValuePair <int, int> > simulatedChanges = BoardScript.GetPointsChangedFromMove(nodeCopy, BoardScript.GetTurnNumber(), n.Key, n.Value);
            foreach (KeyValuePair <int, int> spot in simulatedChanges)
            {
                if (nodeCopy[spot.Key][spot.Value] == BoardSpace.BLACK)
                {
                    nodeCopy[spot.Key][spot.Value] = BoardSpace.WHITE;
                }
                else
                {
                    nodeCopy[spot.Key][spot.Value] = BoardSpace.BLACK;
                }
            }
            int value = negamax(nodeCopy, maxDepth, colorNum);
            if (value >= bestScore)
            {
                best = n;
            }
        }
        return(best);
    }
Exemple #8
0
    private int negamax(BoardSpace[][] node, uint depth, int color)
    {
        if (depth == maxDepth /* || node.Count == 1*/)
        {
            //return SEF(node)
            return(1);
        }
        else
        {
            int value = -100000;
            //go through each valid move for this board state
            foreach (KeyValuePair <int, int> n in BoardScript.GetValidMoves(node, BoardScript.GetTurnNumber()))
            {
                BoardSpace[][] nodeCopy = (BoardSpace[][])node.Clone();
                if (color == 1)
                {
                    nodeCopy[n.Key][n.Value] = BoardSpace.BLACK;
                }
                else
                {
                    nodeCopy[n.Key][n.Value] = BoardSpace.WHITE;
                }

                //simulate the changes each move would result in
                List <KeyValuePair <int, int> > simulatedChanges = BoardScript.GetPointsChangedFromMove(nodeCopy, BoardScript.GetTurnNumber() + depth, n.Key, n.Value);
                foreach (KeyValuePair <int, int> spot in simulatedChanges)
                {
                    if (nodeCopy[spot.Key][spot.Value] == BoardSpace.BLACK)
                    {
                        nodeCopy[spot.Key][spot.Value] = BoardSpace.WHITE;
                    }
                    else
                    {
                        nodeCopy[spot.Key][spot.Value] = BoardSpace.BLACK;
                    }
                }
                //recurse
                value = Mathf.Max(value, -1 * negamax(nodeCopy, depth + 1, -1 * color));
            }
            return(value);
        }
    }
Exemple #9
0
    BoardSpace[][][] GetChildrenNodes(BoardSpace[][] node, BoardSpace color)   // find all the nodes that are children of this one
    {
        List <KeyValuePair <int, int> > validMoves = BoardScript.GetValidMoves(node, color == BoardSpace.BLACK ? 0u : 1u);

        BoardSpace[][][] childrenNodes = new BoardSpace[validMoves.Count][][];

        for (int i = 0; i < validMoves.Count; ++i)
        {
            childrenNodes[i] = CopyBoard(node);
            childrenNodes[i][validMoves[i].Key][validMoves[i].Value] = color;
            List <KeyValuePair <int, int> > changedSpaces = BoardScript.GetPointsChangedFromMove(childrenNodes[i], color == BoardSpace.BLACK ? 0u : 1u, validMoves[i].Value, validMoves[i].Key);

            foreach (KeyValuePair <int, int> changed in changedSpaces)
            {
                childrenNodes[i][changed.Key][changed.Value] = color;
            }
        }


        return(childrenNodes);
    }
Exemple #10
0
    private int negamaxAB(BoardSpace[][] node, uint depth, int alpha, int beta, int color)

    {
        //Debug.Log("negamax function start");

        if (depth == maxDepth - 2)

        {
            int retVal = -1000000;

            List <KeyValuePair <int, int> > moves = BoardScript.GetValidMoves(node, BoardScript.GetTurnNumber() + depth);



            foreach (KeyValuePair <int, int> n in moves)

            {
                int temp = -1000;
                if (ai == 1)
                {
                    temp = rateMoveSelect(moves, n);
                }
                else if (ai == 3)
                {
                    temp = NaiveRateMoveSelect(moves, n);
                }

                if (temp > retVal)
                {
                    retVal = temp;
                }
            }

            return(retVal);
        }

        else

        {
            int value = -100000;

            //go through each valid move for this board state

            List <KeyValuePair <int, int> > possibleMoves = BoardScript.GetValidMoves(node, BoardScript.GetTurnNumber() + depth);

            foreach (KeyValuePair <int, int> n in possibleMoves)

            {
                BoardSpace[][] nodeCopy = new BoardSpace[8][];

                for (int x = 0; x < 8; x++)

                {
                    nodeCopy[x] = new BoardSpace[8];

                    System.Array.Copy(node[x], nodeCopy[x], 8);
                }

                if (color == -1)
                {
                    nodeCopy[n.Value][n.Key] = BoardSpace.BLACK;
                }

                else
                {
                    nodeCopy[n.Value][n.Key] = BoardSpace.WHITE;
                }



                //simulate the changes each move would result in

                List <KeyValuePair <int, int> > simulatedChanges = BoardScript.GetPointsChangedFromMove(nodeCopy, BoardScript.GetTurnNumber() + depth, n.Key, n.Value);

                foreach (KeyValuePair <int, int> spot in simulatedChanges)

                {
                    if (nodeCopy[spot.Value][spot.Key] == BoardSpace.BLACK)
                    {
                        nodeCopy[spot.Value][spot.Key] = BoardSpace.WHITE;
                    }

                    else
                    {
                        nodeCopy[spot.Value][spot.Key] = BoardSpace.BLACK;
                    }
                }

                //recurse
                int temp = -1 * negamaxAB(nodeCopy, depth + 1, -1 * alpha, -1 * beta, -1 * color);
                //value = Mathf.Max(value, -1 * negamaxAB(nodeCopy, depth + 1, -1 * alpha, -1 * beta, -1 * color));

                if (Mathf.Abs(temp - value) <= 30)
                {
                    if (Random.value < .5)
                    {
                        value = temp;
                    }
                }
                else if (temp >= value)
                {
                    value = temp;
                }

                int a = alpha;

                a = Mathf.Max(a, value);

                if (a >= beta)
                {
                    break;
                }
            }

            return(value);
        }
    }