Exemple #1
0
        // Gets move at row turn in file and makes it
        public override Move getInput(Board B)
        {
            System.Threading.Thread.Sleep(sleepTime);

            uint turn = B.getTurn() - 1;
            if (turn <= moves.Count) {
                Move move = moves.ElementAt((int) turn);
                return move;
            }
            return new Move();
        }
Exemple #2
0
        // Gets move at row turn in file and makes it
        public override Move getInput(Board B)
        {
            System.Threading.Thread.Sleep(sleepTime);

            uint turn = B.getTurn() - 1;

            if (turn <= moves.Count)
            {
                Move move = moves.ElementAt((int)turn);
                return(move);
            }
            return(new Move());
        }
Exemple #3
0
        // Reset the game
        public void reset()
        {
            // Stop the game
            running = false;
            paused  = false;

            // Create a new board and update the GUI
            board = new Board();
            gui.updateBoard(board);

            // White allways starts
            turnWhite = true;

            // Update GUI fields
            gui.putPlayerTurn(turnWhite);
            gui.putTurn(board.getTurn());
            gui.putScore(0);
        }
Exemple #4
0
        // --- The main game loop ---

        // The game is powered by an infinite loop that works as this:
        // 1) Get move from active player.
        // 2) Check validity of move, and make move if valid.
        // 3) Allow the GUI to run all events as to not freeze the program.
        // 4) If the move was legal:
        //    * Save move if playback saving is enabled.
        //    * Update the GUI with the new board state.
        //    * Check if the game is over, either by a win or remi.
        //    * Update the GUI with new turn, score, etc.
        //    * Save the current state to a file.
        // 5) Check if the current state file has been manualy changed.
        // 6) Allow the GUI to run all events (again) as to not freeze the program.
        //
        // The reason we use a loop to control the game instead of a compleatly event
        // driven design is the we do not want the game to know the differens between
        // a human player and an AI (which is a requirement of the program).
        // In an event driven design the AI would either have to be activated be a
        // human player each turn, or be activated by a very fast timer event, or the
        // AI would have to run in a different thread. The first two options are not
        // very nice, and the last would prevent the AI from interacting with the GUI,
        // because WinForms controls can only be accessed from the thread that created them.
        // With our loop solutions, none of these issues exist, which is why we feel it is
        // the best option.
        public void run()
        {
            Move selectedMove = null;
            bool oldTurnWhite = turnWhite;

            while (running)
            {
                if (paused)
                {
                    // Run the program at 10 fps if it is paused.
                    Thread.Sleep(100);
                }
                else
                {
                    // gets a new move from the active player
                    if (turnWhite)
                    {
                        selectedMove = white.getInput(board);
                    }
                    else
                    {
                        selectedMove = black.getInput(board);
                    }

                    // Makes the move and switches player if it was a legal move
                    if (Rules.movePossible(board, selectedMove, (turnWhite ? "white" : "black")))
                    {
                        board.makeMove((turnWhite ? "white" : "black"), selectedMove);
                        turnWhite = !turnWhite;
                    }

                    // Run everything else
                    Application.DoEvents();

                    // New move accepted, update GUI and check for winner.
                    if (oldTurnWhite != turnWhite)
                    {
                        // Print accepted move
                        gui.putString(selectedMove.ToString());

                        // Save move to file
                        if (gui.getPlaybackEnabled())
                        {
                            string name = gui.getFileName();
                            if (!name.Equals(""))
                            {
                                SaveManager.saveMove(selectedMove, name);
                            }
                        }

                        // Update graphics
                        gui.updateBoard(board);

                        // Check if game over
                        if (checkGameOver())
                        {
                            return;
                        }

                        // Update turn GUI
                        board.updateTurn();
                        oldTurnWhite = turnWhite;
                        gui.putPlayerTurn(turnWhite);
                        gui.putTurn(board.getTurn());
                        gui.putScore(board.getScore("white"));

                        // Save current state
                        fileMonitor.ignoreFor(500);
                        SaveManager.saveCurrent(board);
                    }

                    // Check file monitor
                    checkFileChanged();
                }
                Application.DoEvents();
            }
        }
Exemple #5
0
        // Returns a list of all possible moves
        public static List<Tuple<uint, uint>> getPossibleMoves(Board board, Piece piece)
        {
            List<Tuple<uint, uint>> tmpList = new List<Tuple<uint, uint>>();
            short yMod;
            short passantRow;
            if (piece.getColour() == "white")
            {
                yMod = 1;
                passantRow = 4;
            }
            else
            {
                yMod = -1;
                passantRow = 3;
            }

            // Take left
            if (board.withinBoard((int) piece.getX() - 1, (int) piece.getY() + yMod))
            {
                Piece P = board.getPieceAt((uint)(piece.getX() - 1), (uint)(piece.getY() + yMod));
                if (P != null)
                {
                    if (!piece.isSameColour(P))
                    {
                        tmpList.Add(new Tuple<uint, uint>((uint)(piece.getX() - 1), (uint)(piece.getY() + yMod)));
                    }
                }
            }

            //Take right
            if (board.withinBoard((int)piece.getX() + 1, (int)piece.getY() + yMod))
            {
                Piece P = board.getPieceAt((uint)(piece.getX() + 1), (uint)(piece.getY() + yMod));
                if (P != null)
                {
                    if (!piece.isSameColour(P))
                    {
                        tmpList.Add(new Tuple<uint, uint>((uint)(piece.getX() + 1), (uint)(piece.getY() + yMod)));
                    }
                }
            }

            //Move 1
            if (board.withinBoard((int)piece.getX(), (int)piece.getY() + yMod))
            {
                Piece P = board.getPieceAt(piece.getX(), (uint)(piece.getY() + yMod));
                if (P == null)
                {
                    tmpList.Add(new Tuple<uint, uint>(piece.getX(), (uint)(piece.getY() + yMod)));
                }
            }

            //Move 2 (Only first move)
            if (!piece.movedFromInit())
            {
                if (board.withinBoard((int)piece.getX(), (int)piece.getY() + 2 * yMod))
                {
                    Piece P = board.getPieceAt(piece.getX(), (uint)(piece.getY() + 2 * yMod));
                    Piece P2 = board.getPieceAt(piece.getX(), (uint)(piece.getY() + yMod));
                    if (P == null && P2 == null)
                    {
                        tmpList.Add(new Tuple<uint, uint>(piece.getX(), (uint)(piece.getY() + 2 * yMod)));
                        //((Pawn)piece).setDoubleStepTurn(board.getTurn());
                    }
                }
            }

            //En Passant
            if (piece.getY() == passantRow)
            {
                if ((piece.getX() + 1) < Board.BOARD_SIZE_X)
                {
                    Piece P1 = board.getPieceAt(piece.getX() + 1, piece.getY());

                    if (P1 != null)
                    {
                        if (P1 is Pawn)
                            if (((Pawn)P1).getDoubleStepTurn() == board.getTurn() - 1)
                                tmpList.Add(new Tuple<uint, uint>(piece.getX() + 1, (uint)(piece.getY() + yMod)));
                    }
                }

                if ((int)piece.getX() - 1 >= 0)
                {
                    Piece P2 = board.getPieceAt(piece.getX() - 1, piece.getY());
                    if (P2 != null)
                    {
                        if (P2 is Pawn)
                            if (((Pawn)P2).getDoubleStepTurn() == board.getTurn() - 1)
                                tmpList.Add(new Tuple<uint, uint>(piece.getX() - 1, (uint)(piece.getY() + yMod)));
                    }
                }

            }

            // Filter for check situations
            CommonRules.checkFilter(ref tmpList, board, piece);

            return tmpList;
        }
Exemple #6
0
        // Reset the game
        public void reset()
        {
            // Stop the game
            running = false;
            paused = false;

            // Create a new board and update the GUI
            board = new Board();
            gui.updateBoard(board);

            // White allways starts
            turnWhite = true;

            // Update GUI fields
            gui.putPlayerTurn(turnWhite);
            gui.putTurn(board.getTurn());
            gui.putScore(0);
        }
Exemple #7
0
        public Tuple<Move, int> runMinMax(Board board, string activePlayer, uint depth, bool max, int alpha, int beta, putScore put)
        {
            // Prints number of searched moves
            put(1);

            string nonActivePlayer = "";
            if (activePlayer == "white")
            {
                nonActivePlayer = "black";
            }
            else
            {
                nonActivePlayer = "white";
            }

            // First check if this is leaf node
            if (depth <= 0)
            {
                return new Tuple<Move, int>(null, (max ? board.getScore(activePlayer) : board.getScore(nonActivePlayer)));
            }

            // Not a leaf node, branch out

            List<Move> moves = new List<Move>();

            // Get moves from active player
            if (activePlayer == "white")
            {
                moves = ChessForms.rules.Rules.getWhiteMoves(board);
            }
            else
            {
                moves = ChessForms.rules.Rules.getBlackMoves(board);
            }

            // Check if no legal moves
            if (moves.Count == 0)
            {
                return new Tuple<Move, int>(null, (max ? MINIMUM : MAXIMUM));
            }

            // Assume horrible best
            int bestScore = (max ? MINIMUM : MAXIMUM);
            Tuple<Move, int> bestResult = new Tuple<Move, int>(null, bestScore);

            // Loop through all moves and minmax them
            Board nextBoard = new Board(board.getTurn());
            Tuple<Move, int> nextResult;
            foreach (Move move in moves)
            {
                nextBoard.Copy(board);
                nextBoard.makeMove(activePlayer, move);
                nextResult = runMinMax(nextBoard, nonActivePlayer, depth - 1, !max, alpha, beta, put);

                // If new best result, then change bestResult.
                if ((nextResult.Item2 > bestResult.Item2 && max) ||
                    (nextResult.Item2 < bestResult.Item2 && !max))
                {
                    bestResult = new Tuple<Move, int>(move, nextResult.Item2);
                }

                // Alpha-Beta pruning
                if (max)
                {
                    alpha = Math.Max(alpha, bestResult.Item2);
                }
                else
                {
                    beta = Math.Min(beta, bestResult.Item2);
                }
                if (beta <= alpha)
                {
                    // Need not explore subtree.
                    break;
                }

                // Run events to not stall the entire application while searching.
                Application.DoEvents();
            }
            return bestResult;
        }