예제 #1
0
        private void startAIComputing(object sender, DoWorkEventArgs e)
        {
            // run ai with its own desk, while computing the desk is modified
            Desk aiDesk = new Desk(rules.getDeskSize(), rules.getPiecesPerPlayer());

            aiDesk.setPlayerPieces(desk.getPlayerFields(GameVar.PLAYER_WHITE), GameVar.PLAYER_WHITE);
            aiDesk.setPlayerPieces(desk.getPlayerFields(GameVar.PLAYER_BLACK), GameVar.PLAYER_BLACK);
            aiDesk.setCurrentPlayer(desk.getCurrentPlayer());

            aiMove = engine.getBestMove(aiDesk, rules);
        }
예제 #2
0
        public bool isGameEnd(Desk desk)
        {
            int fieldsBlackCnt = desk.getPlayerFields(GameVar.PLAYER_BLACK).Count;
            int fieldsWhiteCnt = desk.getPlayerFields(GameVar.PLAYER_WHITE).Count;

            if (fieldsBlackCnt == 0 || fieldsWhiteCnt == 0)
            {
                return(true);
            }
            if (getPossibleMoves(desk, GameVar.PLAYER_WHITE, true).Count > 0)
            {
                return(false);
            }
            if (getPossibleMoves(desk, GameVar.PLAYER_BLACK, true).Count > 0)
            {
                return(false);
            }
            return(true);
        }
예제 #3
0
        public int getGameEvaluation(Desk desk, short player)
        {
            int whitePiecesCnt = desk.getPlayerFields(GameVar.PLAYER_WHITE).Count;
            int blackPiecesCnt = desk.getPlayerFields(GameVar.PLAYER_BLACK).Count;
            int piecesDifference = 0, piecesPositionVal = 0, x, y;

            //white player
            if (player == GameVar.PLAYER_WHITE)
            {
                if (evalPiecePosition)
                {
                    piecesPositionVal += getPiecesPositionEvaluation(desk.getPlayerFields(GameVar.PLAYER_WHITE));
                }
                if (blackPiecesCnt == 0 && whitePiecesCnt > 0)
                {
                    return(int.MaxValue);
                }
                if (whitePiecesCnt == 0 && blackPiecesCnt > 0)
                {
                    return(int.MinValue);
                }
                piecesDifference = whitePiecesCnt - blackPiecesCnt;
            }
            else       //black player
            {
                if (evalPiecePosition)
                {
                    piecesPositionVal += getPiecesPositionEvaluation(desk.getPlayerFields(GameVar.PLAYER_BLACK));
                }
                if (whitePiecesCnt == 0 && blackPiecesCnt > 0)
                {
                    return(int.MaxValue);
                }
                if (blackPiecesCnt == 0 && whitePiecesCnt > 0)
                {
                    return(int.MinValue);
                }
                piecesDifference = blackPiecesCnt - whitePiecesCnt;
            }
            return(piecesDifference * piecesDifferenceWeight + piecesPositionVal * piecesPositionWeight);
        }
예제 #4
0
        public ArrayList getPossibleMoves(Desk desk, short currentPlayer, bool firstMoveOnly = false)
        {
            int[,] fields = desk.getFields();
            int       x, y, size = desk.getSize();
            ArrayList possibleMoves = new ArrayList();
            bool      forcedMoves   = false;
            short     opositePlayer = getOppositePlayer(currentPlayer);

            ArrayList playerFields     = null;
            ArrayList playerFieldsCopy = new ArrayList();

            //get current player fields
            if (currentPlayer == GameVar.PLAYER_WHITE)
            {
                playerFields = desk.getPlayerFields(GameVar.PLAYER_WHITE);
            }
            else if (currentPlayer == GameVar.PLAYER_BLACK)
            {
                playerFields = desk.getPlayerFields(GameVar.PLAYER_BLACK);
            }

            //make player_fields_copy, because while move inspected player_fields change
            foreach (var field in playerFields)
            {
                playerFieldsCopy.Add(field);
            }

            int playerFieldsCnt = playerFieldsCopy.Count;

            for (int i = 0; i < playerFieldsCnt; i++)           //loop player fields
            {
                x = (int)(playerFieldsCopy[i] as Array).GetValue(0);
                y = (int)(playerFieldsCopy[i] as Array).GetValue(1);

                //get possible jumps
                ArrayList possible_jumps = getPossibleJumps(desk, x, y, currentPlayer);
                if (possible_jumps.Count > 0)
                {
                    if (!forcedMoves)      //forced jump found, do not inspect normal moves anymore
                    {
                        possibleMoves.Clear();
                        forcedMoves = true;
                    }
                    foreach (Move jump in possible_jumps)
                    {
                        addMove(possibleMoves, jump);      //add jump move to results
                    }
                    if (firstMoveOnly)
                    {
                        return(possibleMoves);
                    }
                }

                if (!forcedMoves)      //inspect normal moves only when no forced jump found
                {
                    int newX = 0;
                    int newY = 0;

                    //loop normal moves directions
                    for (int k = 0; k < directionsNormal[currentPlayer].Length; k++)
                    {
                        if (directionsNormal[currentPlayer][k] == GameVar.DIR_UP)
                        {
                            newX = x;
                            newY = y + 1;
                        }
                        else if (directionsNormal[currentPlayer][k] == GameVar.DIR_UP_LEFT)
                        {
                            newX = x - 1;
                            newY = y + 1;
                        }
                        else if (directionsNormal[currentPlayer][k] == GameVar.DIR_UP_RIGHT)
                        {
                            newX = x + 1;
                            newY = y + 1;
                        }
                        else if (directionsNormal[currentPlayer][k] == GameVar.DIR_DOWN)
                        {
                            newX = x;
                            newY = y - 1;
                        }
                        else if (directionsNormal[currentPlayer][k] == GameVar.DIR_DOWN_LEFT)
                        {
                            newX = x - 1;
                            newY = y - 1;
                        }
                        else if (directionsNormal[currentPlayer][k] == GameVar.DIR_DOWN_RIGHT)
                        {
                            newX = x + 1;
                            newY = y - 1;
                        }
                        if (GameVar.isValidField(newX, newY, deskSize) && fields[newX, newY] == GameVar.FIELD_EMPTY)
                        {
                            addMove(possibleMoves, x, y, newX, newY);      //add normal move to results

                            if (firstMoveOnly)
                            {
                                return(possibleMoves);
                            }
                        }
                    }
                }
            }
            return(possibleMoves);
        }
예제 #5
0
        private int minimax(Desk desk, GameRules rules, int depth, short currentPlayer, bool maximizingPlayer)
        {
            movesInspected++;
            short oppositePlayer = rules.getOppositePlayer(currentPlayer);

            if (rules.isGameEnd(desk))      //check game end - both players have some fields and at least one can move
            {
                short nextPlayer = rules.getNextPlayer(desk);
                if (desk.getPlayerFields(GameVar.PLAYER_WHITE).Count != 0 && desk.getPlayerFields(GameVar.PLAYER_BLACK).Count != 0 && nextPlayer == -1)
                {
                    return(0);       //draw, neither of players can move
                }
                if (maximizingPlayer)
                {
                    return(int.MinValue + depthMax - depth);
                }
                return(int.MaxValue - depthMax + depth);
            }

            if (depth == 0)     //check depth level, return eval of current position
            {
                if (maximizingPlayer)
                {
                    return(-rules.getGameEvaluation(desk, oppositePlayer));
                }
                return(rules.getGameEvaluation(desk, oppositePlayer));
            }

            //get new possible moves, make the moves and call recursively minmax
            ArrayList possibleMoves = rules.getPossibleMoves(desk, currentPlayer);
            int       bestVal       = 0;
            int       currentVal    = 0;

            //current player has no possible moves, play "nothing" and call minimax
            if (possibleMoves.Count == 0)
            {
                if (maximizingPlayer)
                {
                    bestVal    = int.MinValue;
                    currentVal = minimax(desk, rules, depth, oppositePlayer, false);
                    bestVal    = Math.Max(bestVal, currentVal);
                }
                else
                {
                    bestVal    = int.MaxValue;
                    currentVal = minimax(desk, rules, depth, oppositePlayer, true);
                    bestVal    = Math.Min(bestVal, currentVal);
                }
                return(bestVal);
            }

            if (maximizingPlayer)      //current player's best move, looking for the highest rating move
            {
                bestVal = int.MinValue;
                foreach (Move move in possibleMoves)
                {
                    desk.makeMove(move);
                    currentVal = minimax(desk, rules, depth - 1, oppositePlayer, false);
                    desk.undoMove(move);
                    bestVal = Math.Max(bestVal, currentVal);
                }
            }
            else                  //opposite player's best move - the worst move for current player, looking for the lowest rating move
            {
                bestVal = int.MaxValue;
                foreach (Move move in possibleMoves)
                {
                    desk.makeMove(move);
                    currentVal = minimax(desk, rules, depth - 1, oppositePlayer, true);
                    desk.undoMove(move);
                    bestVal = Math.Min(bestVal, currentVal);
                }
            }
            return(bestVal);
        }