Example #1
0
    int EvaluationFunction(BoardSpace[][] currentBoard, BoardSpace color, bool isGameCompleted)
    {
        int totalDifference = 0;

        foreach (BoardSpace[] row in currentBoard)
        {
            foreach (BoardSpace space in row)
            {
                if (space == color)
                {
                    totalDifference++;
                }
                else if (space != BoardSpace.EMPTY)
                {
                    totalDifference--;
                }
            }
        }
        if (isGameCompleted)
        {
            if (totalDifference > 0)
            {
                return(currentBoard.Length * currentBoard[0].Length);
            }
            if (totalDifference < 0)
            {
                return(currentBoard.Length * currentBoard[0].Length * -1);
            }
        }
        return(BoardScript.GetValidMoves(currentBoard, color == BoardSpace.BLACK ? 0u : 1u).Count);
    }
Example #2
0
    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);
        }
    }
Example #3
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());
    }
Example #4
0
    private KeyValuePair <float, KeyValuePair <int, int> > AlphaBetaNegamax(BoardSpace[][] curBoard, List <KeyValuePair <int, int> > availableMoves, int curDepth, float alpha, float beta, uint turnNumber)
    {
        turnNumber++;
        KeyValuePair <int, int> bestMove;
        float bestScore = int.MinValue;;
        KeyValuePair <float, KeyValuePair <int, int> > bestPair;
        List <KeyValuePair <int, int> > actions = BoardScript.GetValidMoves(curBoard, turnNumber);

        if (curDepth <= 0 || actions.Count == 0)
        {
            float score = betterEvaluationFunction(curBoard);
            //float score = bestEvaluationFunction(curBoard); // Doesn't work as I hoped :/

            if (score < bestScore)
            {
                return(new KeyValuePair <float, KeyValuePair <int, int> >(bestScore, bestMove));
            }
            else
            {
                KeyValuePair <int, int> lastAction = new KeyValuePair <int, int>(7, 7);
                return(new KeyValuePair <float, KeyValuePair <int, int> >(score, lastAction));
            }
        }
        foreach (KeyValuePair <int, int> action in actions)
        {
            BoardSpace[][] successor = updateBoard(curBoard, action, turnNumber);
            KeyValuePair <float, KeyValuePair <int, int> > currentMove = AlphaBetaNegamax(successor, availableMoves, curDepth - 1, -beta, -alpha, turnNumber);
            float value        = currentMove.Key;
            float currentScore = -value;

            if (currentScore >= bestScore)
            {
                bestScore = currentScore;
                bestMove  = action;
            }
            if (alpha < currentScore)
            {
                alpha = currentScore;
            }
            if (alpha >= beta)
            {
                break;
            }
        }
        bestPair = new KeyValuePair <float, KeyValuePair <int, int> >(bestScore, bestMove);
        return(bestPair);
    }
Example #5
0
    public int Negamax(BoardSpace[][] board, int depth, bool isBlack)
    {
        //Generate List of possible moves
        List <KeyValuePair <int, int> > possibleMoves = BoardScript.GetValidMoves(board, isBlack ? ((uint)2) : ((uint)1));

        //If hit end, bubble up
        if (depth <= 0 || possibleMoves.Count == 0)
        {
            if (BoardScript.betterSEF)
            {
                return(BetterSEF(board));
            }
            else
            {
                return(UniformSEF(board));
            }
        }

        if (isBlack)
        {
            int maxScore = -9999;
            foreach (KeyValuePair <int, int> move in possibleMoves)
            {
                BoardSpace[][] newBoard     = createNewBoard(board, move, isBlack);
                int            currentScore = Negamax(newBoard, depth - 1, false);
                if (currentScore > maxScore)
                {
                    maxScore = currentScore;
                }
            }
            return(maxScore);
        }
        else
        {
            int minScore = 9999;
            foreach (KeyValuePair <int, int> move in possibleMoves)
            {
                BoardSpace[][] newBoard     = createNewBoard(board, move, isBlack);
                int            currentScore = Negamax(newBoard, depth - 1, true);
                if (currentScore < minScore)
                {
                    minScore = currentScore;
                }
            }
            return(minScore);
        }
    }
Example #6
0
    public float MaxValue(BoardSpace[][] curBoard, int curDepth, float alpha, float beta, uint turnNumber)
    {
        float value = Mathf.NegativeInfinity;
        List <KeyValuePair <int, int> > actions = BoardScript.GetValidMoves(curBoard, turnNumber);

        foreach (KeyValuePair <int, int> action in actions)
        {
            BoardSpace[][] successor      = updateBoard(curBoard, action, turnNumber);
            float          newActionScore = Value(successor, (curDepth - 1), alpha, beta, turnNumber++);
            value = Mathf.Max(value, newActionScore);
            alpha = Mathf.Max(alpha, value);
            if (alpha >= beta)
            {
                break;
            }
        }
        return(value);
    }
Example #7
0
    /************************************************* AlphaBeta Minimax implementation /*************************************************/

    public float Value(BoardSpace[][] curBoard, int curDepth, float alpha, float beta, uint turnNumber)
    {
        turnNumber++;
        List <KeyValuePair <int, int> > actions = BoardScript.GetValidMoves(curBoard, turnNumber);

        if (curDepth <= 0 || actions.Count == 0)
        {
            return(betterEvaluationFunction(curBoard));
        }
        if (turnNumber % 2 == 0)
        {
            return(MaxValue(curBoard, curDepth, alpha, beta, turnNumber));
        }
        else
        {
            return(MinValue(curBoard, curDepth, alpha, beta, turnNumber));
        }
    }
Example #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);
        }
    }
Example #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);
    }
Example #10
0
    private int[] HMinimizeOpponentsMoves(List <KeyValuePair <int, int> > availableMoves)
    {
        List <Vector2> enemyMoves = new List <Vector2>();

        int[] retval = new int[availableMoves.Count];

        for (int i = 0; i < availableMoves.Count; i++)
        {
            KeyValuePair <int, int> temp = availableMoves[i];
            int            tempKey       = temp.Key;
            int            tempValue     = temp.Value;
            BoardSpace[][] tempBoard     = board;

            //Debug.Log(BoardScript.GetTurnNumber());
            tempBoard[tempKey][tempValue] = getColor(BoardScript.GetTurnNumber());
            enemyMoves.Add(new Vector2(i, BoardScript.GetValidMoves(tempBoard, BoardScript.GetTurnNumber() + 1).Count));
            retval[i] = enemyMoves.Count;
            //Debug.Log(enemyMoves[i].x + " " + enemyMoves[i].y);
            tempBoard[tempKey][tempValue] = BoardSpace.EMPTY;
        }

        return(retval);
    }
Example #11
0
 //determines if theres no more valid possible moves for either player
 bool IsGameCompleted(BoardSpace[][] node)
 {
     return(BoardScript.GetValidMoves(node, 0).Count == 0 && BoardScript.GetValidMoves(node, 1).Count == 0);
 }
Example #12
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);
        }
    }