Example #1
0
        public Move getBestMove(Desk desk, GameRules rules)
        {
            movesInspected = 0;
            int       topMoveScore     = int.MinValue;
            int       currentScore     = 0;
            short     currentPlayer    = desk.getCurrentPlayer();
            short     oppositePlayer   = rules.getOppositePlayer(currentPlayer);
            bool      maximizingPlayer = false;
            ArrayList topMoves         = new ArrayList();

            //check game end - both players have some fields and at least one can move
            if (rules.isGameEnd(desk))
            {
                return(null);
            }

            ArrayList possiblePlayerMoves = rules.getPossibleMoves(desk, currentPlayer);

            if (possiblePlayerMoves.Count == 0)        //no possible moves for current player, switch to another player
            {
                possiblePlayerMoves = rules.getPossibleMoves(desk, oppositePlayer);
                oppositePlayer      = currentPlayer;
                maximizingPlayer    = !maximizingPlayer;
            }

            //loop possible moves
            foreach (Move move in possiblePlayerMoves)
            {
                //try the move and run minimax
                desk.makeMove(move);
                currentScore = minimax(desk, rules, depthMax, oppositePlayer, maximizingPlayer);
                desk.undoMove(move);

                if (currentScore > topMoveScore)     //new top move found
                {
                    topMoveScore = currentScore;
                    topMoves.Clear();
                    topMoves.Add(move);
                }
                else if (currentScore == topMoveScore)    //more moves with same value found
                {
                    topMoves.Add(move);
                }
            }

            if (!randomMoveSelection)
            {
                return((Move)topMoves[0]);
            }

            //pick randomly one of the top moves
            Random r = new Random();

            return((Move)topMoves[r.Next(0, topMoves.Count)]);
        }
Example #2
0
        private void handlePieceClick(Object sender, EventArgs e)
        {
            if (!pieceClickListening)
            {
                return;
            }

            bool setAIButtons = false;

            cancelAIComputing(setAIButtons);    // AI computing "show best move" could be in progress

            PictureBox pieceClicked = (PictureBox)sender;

            int[] coords = Coords.getPieceCoordsFromName(pieceClicked.Name);

            if (isPieceSelectError)
            {
                tableDesk.Refresh();
                isPieceSelected    = false;
                isPieceSelectError = false;
            }

            if (wasClickedOnOwnPiece(desk.getCurrentPlayer(), coords))      // start piece of move
            {
                // clean previously highlighted pieces
                tableDesk.Refresh();
                piecesSelected.Clear();

                pieceFocused    = pieceClicked;
                isPieceSelected = true;
                if (showPossibleMoves)
                {
                    highlightPossibleMovesFromPiece(pieceFocused, piecesSelected);
                }
                else
                {
                    drawPictureBoxControl(pieceClicked, Properties.Resources.piece_control_select);
                }
            }
            else if (isPieceSelected)                                          // following pieces of move
            {
                if (isPartialMove(pieceFocused, pieceClicked, piecesSelected)) // move cannot be made yet, clicked piece is not end piece
                {
                    piecesSelected.Add(pieceClicked);
                    if (showPossibleMoves)
                    {
                        highlightPossibleMovesFromPiece(pieceFocused, piecesSelected);
                    }
                    else
                    {
                        drawPictureBoxControl(pieceClicked, Properties.Resources.piece_control_select);
                    }
                    return;
                }
                try
                {
                    makeHumanMove(pieceFocused, pieceClicked, piecesSelected);
                }
                catch       // selected move isn't possible
                {
                    bool      cleanOutput   = true;
                    ArrayList possibleMoves = rules.getPossibleMoves(desk, desk.getCurrentPlayer());
                    Random    r             = new Random();
                    Move      randomMove    = (Move)possibleMoves[r.Next(0, possibleMoves.Count)];
                    drawPictureBoxControl(pieceClicked, Properties.Resources.piece_control_error);
                    addGameNotice("you could play for example " + Coords.getCoordsStr(randomMove), cleanOutput);
                    addGameNotice("move " + Coords.getCoordsStr(pieceFocused) + " " + Coords.getCoordsStr(pieceClicked) + " is not possible");
                }
                isPieceSelectError = true;
            }
            else    // clicked on some piece without possibility of making move
            {
                tableDesk.Refresh();
                isPieceSelected = false;
            }
        }
Example #3
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);
        }