Hi,

I'm currently creating a pool game which is nearly complete but I want to have it as a 2 player (human vs human) game. All that I want the program to perform is that when the game begins then the two players are asked to enter their names (I have got this working) and when the game begins the first players name is displayed on the screen (this is also working, but needs adjusting). The issue I am having though is making the names alternate after a shot is missed. I am not worried at this point about assigning a specific colour to a player or awarding two shots when the white is potted. I just want the names to change when a ball is not potted or the cue ball is potted.

I have declared a first and second player variable at the start of my applet class:

String player1, player2;

Within my start() method I have added the code for the players to enter their names:

player1 = JOptionPane.showInputDialog("Please enter the name of Player 1: ");
player2 = JOptionPane.showInputDialog("Please enter the name of Player 2: ");

For displaying the first players name to the screen I have written a method called playersTurn() in which I have the following code:

public void playerTurn(Ball b[], Graphics g)
    {
        for(int i = 0; i < b.length; i++)

            if(b[i].isPotted() != true)
            {
                String firstPlayer = player1;
                Font font = new Font("Serif", Font.BOLD, 18);
                g.setFont(font);
                g.setColor(Color.BLACK);
                g.drawString(firstPlayer, getWidth() - 101, 26);
                g.setColor(Color.BLUE);
                g.drawString(firstPlayer, getWidth() - 100, 25);
            }

            else{

                String secondPlayer = player2;
                Font font = new Font("Serif", Font.BOLD, 18);
                g.setFont(font);
                g.setColor(Color.BLACK);
                g.drawString(secondPlayer, getWidth() - 101, 26);
                g.setColor(Color.BLUE);
                g.drawString(secondPlayer, getWidth() - 100, 25);
            }
    }

I understand that this is probably a way off the mark so any help I can get would be much appreciated. I have a boolean variable in my Ball class called isPotted() initially set to false this is changed to true in my ballPotted() method in my Vector class as follows:

private void ballPotted(Ball b[], Ball p[])
    {
            for(int i = 0; i < b.length; i++) 
            {
                for(int j = 0; j < p.length; j ++)
                {
                    double yPosDifference = p[j].getY() - b[i].getY();
                    double xPosDifference = p[j].getX() - b[i].getX();
                    double pot = Ball.getRadius()*1.5 + Ball.getRadius()*1.5;
                    double centres = Math.sqrt((yPosDifference * yPosDifference) + (xPosDifference * xPosDifference));

                    if(centres <= pot && (b[i].getVelocity()).magnitude() > 0)
                    {
                        System.out.println("Pot has occurred for ball at position (" + b[i].getX() + ", " +
                                b[i].getY() + ") and pocket position (" + p[j].getX() + ", " + p[j].getY() + ")");

                        performRemoval(b[i], p[j]);
                        b[i].setPotted(true);

                        if(b[0].isPotted())
                        {
                            b[0].setDeltaX(0);
                            b[0].setDeltaY(0);
                            b[0].setX(200);
                            b[0].setY(425);
                        }
                    }
                }
            }
        blackPotted(b);
    }

I am at a bit of a loss at the moment so any help or advice as to how I should go about this would be greatly welcomed. Thanks in advance and if you have any questions or would like to see more code please let me know.

What exactly is your question? does your existing method work and you would like a more effecient way to do the name switching when balls are sunk? or does it not work?

Hi,

The playerTurn() method works in as much as when a ball is sunk then the isPotted() method returns to true and the second players name appears behind the first players name. So the first players name should be removed after a miss.

What I want it to do is to display the first players name at the beginning then when a shot is missed to remove the first players name and display the second players name until they too miss a shot at which point the names reverse again. This should continue until all balls are potted.

Thanks for the reply

maybe something like

String p1,p2,currentPlayer;
...
p1="name1";
p2="name2"
currentPlayer=p1;//player 1 always starts I guess :)

while(!gameOver) {//loop for the game span

    if(!isPotted(..)) {
    //if a ball is not sunk we change the names
    //if the currentPlayer name is the same as player1 name we switch the currentPlayer name to the opposite of course

    /*if(currentPlayer.equals(p1)) {currentPlayer=p2;}else {currentPlayer=p1;}*/

        switch(currentPlayer) {
            p1: currentPlayer=p2;
                break;
            p2: currentPlayer=p1;
                break;
            default:
                currentPlayer=p1;
        }
    }else {
    //The ball was potted by the same player so no name changes take place
    }
}

Edited 4 Years Ago by DavidKroukamp

This is great. Thank you very much. I have put it into my playerTurn() method. I have an error saying that a case is expected after the first curly brace. I left out the while loop and used a for loop. should I put this in the run() method or am I ok to leave it in the playerTurn() method and use a while loop. This is what I have added so far. Thank you very much.

String player1, player2, currentPlayer; //I declared these variables at the start

player1 = JOptionPane.showInputDialog("Please enter the name of Player 1: ");
player2 = JOptionPane.showInputDialog("Please enter the name of Player 2: ");
currentPlayer = player1; //These were added in the start() method

for(int i = 0; i < b.length; i++) //Finally this is what I added to the playerTurn() method. 

            if(b[i].isPotted() != true)
            { 
                switch(currentPlayer)
                { //This is where I am getting the error
                player1: currentPlayer = player2;
                break;
                p2: currentPlayer = player1;
                break;
                default: currentPlayer = player1;
                }
            }
            else
            {

            }

Edited 4 Years Ago by lj81

David's post has incorrect syntax for a switch - it's missing the "case" keyword. Check the official doc for the correct version.
ps: A switch using a String is only available from Java 1.7 onwards.

Comments
thank you my mistake

Thanks I have changed the switch around. I sort of guessed that but hadn't used it with Strings. I have updated it now so it looks as follows:

public void playerTurn(Ball b[], Graphics g)
    {
        for(int i = 0; i < b.length; i++)

            if(b[i].isPotted() != true)
            {
                switch(currentPlayer)
                {
                case "player1": currentPlayer = player1;
                                break;
                case "player2": currentPlayer = player2;
                                break;
                default: currentPlayer = player1;
                         break;
                }
            }
            else
            {

            }
    }       

However the names are not changing when a shot is missed. Only the name of player1 is appearing. What exactly am I missing here in my code that I should have written?

I also want to display it to the screen now actually on the applet itself and not as a println(). How would I go about it? Can I still use the same idea as in my first post which was:

String playerName = currentPlayer;
Font font = new Font("Serif", Font.BOLD, 18);
g.setFont(font);
g.setColor(Color.BLACK);
g.drawString(currentPlayer, getWidth() - 101, 26);
g.setColor(Color.BLUE);
g.drawString(currentPlayer, getWidth() - 100, 25);

or is there a better more efficient way of displaying the current players name?

Edited 4 Years Ago by lj81

why do you have:

                case "player1": currentPlayer = player1;
                                break;
                case "player2": currentPlayer = player2;
                                break;
                default: currentPlayer = player1;
                         break;

do this

                case player1: currentPlayer = player2;
                                break;
                case player2: currentPlayer = player1;
                                break;
                default: currentPlayer = player1;
                         break;

as we want to compare the 'currentplayer' var to the 2 player name variables

I had the comments around the player1 and player2 because I'm getting an error saying that "case expressions must be constant expressions" without them. Anywhere I have looked that is the way it is written when using a string in a switch statement. I understand that the currentPlayer variables should be compared but not sure why this is appearing.

Like the message says, the case expressions must be constants, and player1/2 are variables. Looks like David was having a bad day when he posted that. :)
You could make player1/2 values of an enum, then you could use them in switches etc.

Comments

Thats alright so. I thought it was something I was missing:) Thanks very much. If I change them to enums will I have to change the switch method and also would I be better off not allowing the players to enter their names

there are many other ways than a switch to simply switch the currentPlayer value to the other player name.

a simple if structure would be the easiest to understand, i personaly like using ternary operators for such small tasks...

something in the likes of :

currentPlayer = (currentPlayer == player1 ? player2 : player1);

Something like, but not exactly...
those variablea are all Strings, so for safety you need equals(...), not == (in this particular case there's a good chance that == will work because there are probably only two String ionstances underlying all those variables, but sooner or later somethiong's going to break that.)
Personally my immediate instinct is to make Player a class - yes it's going to be a small simple class, but in the end it's going to make everything clearer and safer.

Edited 4 Years Ago by JamesCherrill

Hey guys I used the ternary operator which was suggested and it is starting to take shape. Here is what I have added:

String player1, player2,currentPlayer; //my variables
....

player1 = JOptionPane.showInputDialog("Please enter the name of Player 1: ");
player2 = JOptionPane.showInputDialog("Please enter the name of Player 2: ");
currentPlayer = player1; //my name entries, in my start() method, which are working and being displayed on the screen
....

public void playerTurn(Ball b[], Graphics g) //this is my method for switching the names.
    {
        for(int i = 0; i < b.length; i++)

            if(b[i].isPotted() != true)
            {
                currentPlayer = (currentPlayer.equals(player1) ? player2 : player1);
            }   

        String Player = currentPlayer;
        Font font = new Font("Serif", Font.BOLD, 18);
        g.setFont(font);
        g.setColor(Color.BLACK);
        g.drawString(Player, getWidth() - 101, 26);
        g.setColor(Color.BLUE);
        g.drawString(Player, getWidth() - 100, 25);
    }

The code above is working in as far as when the game starts and the players enter their respective names. The name of player1 is displayed on the screen as it should be. However the name of player1 continues to appear on the screen until a ball is potted at which point the name of player2 appears and the names of both players continue to switch back and forth constantly. Am I right in saying that it is something to do with the if statement I have written? Obviously isPotted() is going to be false all the time until a ball has been potted. At least the names are changing now:)

ah , my bad on the == on strings, wasn't quite woken up when i wrote that cause that certainly is an issue i would usualy spot! thanks for pointing it out :)

This question has already been answered. Start a new discussion instead.