1

I am having troubles with programming a game called "Coup" and to explain what the problem is, i need to briefly explain what the game is about. Coup is a card game where players try to eliminate each other and be the last player left. To do this, players can choose a number of actions but they can also lie to other players. In this game, other players can call "bullshit" or block another players action. Because of this, i need to make Response windows which will let other players respond with a challenge, a block or do nothing. The result of the action is then dependent on the responses. For example, a player tries to get foreign aid. I can decide to block his action or to let him continue. There are consequences if i block but that isnt the problem here.

The real problem is this: I want to give all my players a chance to give a response (Block or do nothing) via a JFrame and I use a while loop to wait for all players responses. However, this while loop doesnt do anything except keep the method from progressing since the result depends on players reactions. With the while loop, the JFrame I constructed appears white and doesnt contain the two buttons i made. At this point i can even press the close button and it wont respond due to the while loop I made which is dependent on my responseless window. Is there anyway to fix this?

if (turnCount == players[currentPlayerNum].getPlayerNum()){
        for(int i=0; i<players.length;i++){
            //If it is not the players turn and they have one or two lives, make response window
            if (players[i].getPlayerNum() != turnCount){
                if (players[i].getLives() != 0){
                    //foreignAidBlock constructs the response window   
                    players[i].foreignAidBlock(turnCount);
                }

                else{
                //Not applicable since out of game/not in game
                players[i].setResponse("NA");
                }
            }
            else{
            //Not applicable since out of game/not in game
            players[i].setResponse("NA");
            }
        }

        //Idea: PAUSE TILL RESPONSES COME IN
        while(players[0].getResponse() != null  || players[1].getResponse() != null || players[2].getResponse() != null || players[3].getResponse() != null)
        {
            System.out.println(players[0].getResponse());
            System.out.println(players[1].getResponse());
            System.out.println(players[2].getResponse());
            System.out.println(players[3].getResponse());
        }

The result i get from running this part of the code is: "NA null NA NA" continuously. I use a null to represent a player that hasnt answered yet. At the end of the method, I reset all of my players abilities back to null.

All my response window will do is change the response of the player from null to "B" or "N". But without access to the buttons I cannot do this. Does anybody have any tips on how to use something to "pause" my thread besides using a while loop?

HTVS
  • 11
  • 1
  • You could force the JFrame to remain open and on top, therefore preventing other action from continuing. Like a JOptionPane maybe – OneCricketeer May 30 '16 at 20:00
  • Change the structure of the code. Do not *loop* on for a condition: this blocks the UI, and it cannot do it's own things such as rendering. Instead, use events to *react* to a change-state and then check the condition and "do the next appropriate thing" - the "blocking" is then logical but independent of the flow within a particular function. – user2864740 May 30 '16 at 20:05

2 Answers2

1

As Abdul Fatir mentioned, it is because the UI thread is being blocked.

I would however not reccomend directly messing with threads. There is a SwingWorker class exactly for this scenario and it is reccommended you use this.

For more info check this blog article - Swing Worker Example

You can also find some useful info in the following SO question - How do I use SwingWorker in Java


Here is quick use example from the official javadoc:

Say we want to find the "Meaning of Life" and display the result in a JLabel.

   final JLabel label;
   class MeaningOfLifeFinder extends SwingWorker<String, Object> {
       @Override
       public String doInBackground() {
           return findTheMeaningOfLife();
       }

       @Override
       protected void done() {
           try {
               label.setText(get());
           } catch (Exception ignore) {
           }
       }
   }

   (new MeaningOfLifeFinder()).execute();
Glorfindel
  • 21,988
  • 13
  • 81
  • 109
Vojtech Ruzicka
  • 16,384
  • 15
  • 63
  • 66
0

The while loop is blocking your UI Thread. Perform your while loop checks in a different Thread.

Thread t = new Thread(new Runnable(){...});
t.start();  

This way your UI won't be blocked and controls will remain responsive.

Abdul Fatir
  • 6,159
  • 5
  • 31
  • 58