简体   繁体   中英

How should I make my getMove() method interact with my GUI in my chess application?

I'm developing an application in Java to help me land my first job as a junior developer. It's a chess game with a GUI that both human players click on from the same machine.

When it's, say, white's turn to move, the application calls white's getMove(Interface interaction) method until a valid MoveAttempt is returned. Here's the getMove(Interface interaction) method of HumanPlayer :

public MoveAttempt getMove(Interface interaction) {
    while(!interaction.selectionMade()) {

    }

    byte pieceFile = interaction.getPenultimateFile();
    byte pieceRank = interaction.getPenultimateRank();
    byte toFile = interaction.getUltimateFile();
    byte toRank = interaction.getUltimateRank();
    return new MoveAttempt(pieceFile, pieceRank, toFile, toRank, getIsWhite());
}

penultimateFile , penultimateRank , ultimateFile and ultimateRank are supposed to store the file (column) and rank (row) of the last two chess tiles clicked. This is achieved through this actionPerformed(ActionEvent event) which Interface has because it implements ActionListener

public void actionPerformed(ActionEvent event) {
    LocalizedButton button = (LocalizedButton) event.getSource();

    if(penultimateFile == -1) {
       penultimateFile = button.getFile();
       penultimateRank = button.getRank();
    }
    else {
        ultimateFile = button.getFile();
        ultimateRank = button.getRank();
    }
}

and by calling this method before each call to getMove(Interface interaction)

public void resetClicks() {
    penultimateFile = -1;
    penultimateRank = -1;
    ultimateFile = -1;
    ultimateRank = -1;
}

So the idea is that a move attempt is not made until someone has clicked on two chess squares which is why I have a while loop indefinitely calling selectionMade() :

public boolean selectionMade() {
    return penultimateFile != -1 && penultimateRank != -1 && ultimateFile != -1 && ultimateRank != -1;
}

This didn't work---pieces didn't move---so in an attempt to see what was happening I put this print statement

System.out.println(interaction.getPenultimateFile() + ", " +
                interaction.getPenultimateRank() + ", " +
                interaction.getUltimateFile() + ", " +
                interaction.getUltimateRank());

into the while loop to see what was going on and now it works---pieces move---except I may have encountered times in which it didn't work but I last I tried I couldn't get it to fail.

I don't want to print anything to the console; what should I do in lieu of having this while loop?

Edit: Putting boolean lol = 0 just above the loop and lol = !lol in the loop doesn't allow the code to work. Neither does calling doNothing() .

Edit: Here's the source code: https://github.com/JosephBGriffith/Chess Right now only the pawns work because I have other bugs that I need to fix. En passant works except the opponent piece doesn't get eliminated.

I would invert the control, so that the UI pushes moves to the game, rather than the game trying to pull moves from the UI.

So your game class might have:

class Game {
  boolean move(int fromFile, int fromRank, int toFile, int toRank) { ... }
  ...
}

If the move wasn't legal (eg if it was the other player's turn) then move returns false and the move doesn't occur. That is, the internal state of the Game is unchanged.

And your actionPerformed method becomes:

public void actionPerformed(ActionEvent event) {
    LocalizedButton button = (LocalizedButton) event.getSource();

    if(penultimateFile == -1) {
       penultimateFile = button.getFile();
       penultimateRank = button.getRank();
    }
    else {
        game.move(penultimateFile, penultimateRank, button.getFile(), button.getRank());
        penultimateFile = -1;
    }
}

You could use the return value of move to provide some feedback to the user if the move is illegal.

Something to note about this suggestion is that move is executed on the Swing event thread. In theory this is bad practice, although unless your move method is very slow it won't matter.

Read https://docs.oracle.com/javase/tutorial/uiswing/concurrency/index.html and consider whether you want to use invokeLater .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM