I've looked around and I can't see why I'm having this problem. Basically, I'm passing an array of player objects but after passing them I can't access the details correctly.
Code:
for(int i = 0; i <= 2;i++){
players[i] = new Player(names[i], chipCount);
System.out.println(players[i].getName());
}
This for loop is in my main method. I have another for loop that sets up three players (Player is an object that requires a name and a number of chips, and has two methods - getName() and getChips()). The players are "Bob" "Billy" and "Barney" and in the above loop they get printed out fine, however when I pass the array of players over to my 'Game' class, attempting to print the player's names in the same way as above just prints "Barney Barney Barney" instead.
Code for Game class:
public class Game {
Player[] players;
int pot = 0;
public Game(Player[] player){
this.players = player;
}
public void startGame(int rounds){
int roundNumber = 1;
while(roundNumber != rounds){
System.out.println("Starting round " + roundNumber);
System.out.print("Players: ");
for(int i = 0; i <= 2; i++){
System.out.print(players[i].getName() + " ");
}
System.out.println("");
roundNumber = rounds;
}
}
}
And how I'm calling Game:
Game game = new Game(players);
Anyone know why it's not printing out the names correctly? Am I passing the array incorrectly?
Thanks
My bet is that the fields (name and chips) in Player are static. They shouldn't.
Read the Java tutorial about instance and static members.
Related
I am making a guessing game where you are supposed to guess the capital of x country, the user is supposed to be prompted each time if they want to guess again there is an array of 15 CountryCards which I need to read through in a random order, I also cannot use the same card twice. When I run my current code I get through 14 iterations of the array and then the last one just gets stuck on the very start of the while loop (after inputting 1 into yesNo nothing happens) Here is the relevant code, any help is appreciated:
while (CountryCard.instances < 30) {
System.out.println("Would you like to guess the capital of a country?"
+ " Hit 1 for yes, or 2 for no (Case sensitive)");
yesNo = input.nextInt();
if (yesNo == 2) {
return;
}
Random generator = new Random();
int randomNumber = generator.nextInt(game.length);
while (game[randomNumber].used == true && CountryCard.uses < 15) {
randomNumber = generator.nextInt(game.length);
}
System.out.println("What is the Capital of "
+ game[randomNumber].getName() + "?");
game[randomNumber].usedCard(1);
guess = input.next();
if (guess.equals(game[randomNumber].getCapital())) {
System.out.println("Correct! :)");
} else {
System.out.println("Incorrect! :(");
}
}//end of while
System.out.println("Thanks for playing :)");
Why not just shuffle your CountryCard list in place with Collections.shuffle each time you play the game?
Something like:
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Scanner;
class Game {
private static final List<CountryCard> countryCards = new ArrayList<>(
Arrays.asList(
new CountryCard("Canada", "Ottawa"),
new CountryCard("USA", "Washington, D.C."),
new CountryCard("France", "Paris"),
new CountryCard("Germany", "Berlin"),
new CountryCard("Spain", "Madrid"),
new CountryCard("Turkey", "Ankara"),
new CountryCard("Sudan", "Khartoum"),
new CountryCard("Brazil", "Brasilia")
// TODO add more countries as needed
));
private Scanner input = new Scanner(System.in);
public void play() {
// shuffle the country card list before playing
Collections.shuffle(countryCards);
for (CountryCard randomCountryCard: countryCards) {
System.out.println("What is the capital of " + randomCountryCard.getName() + "?");
String guess = input.next();
if (randomCountryCard.getCapital().equalsIgnoreCase(guess)) {
System.out.println("Correct!");
} else {
System.out.println("Incorrect!");
}
System.out.println("Answer: " + randomCountryCard.getCapital() + "\n");
}
}
public static void main(String[] args) {
Game game = new Game();
game.play();
}
}
class CountryCard {
private String name;
private String capital;
CountryCard(String name, String capital) {
this.name = name;
this.capital = capital;
}
public String getName() {
return name;
}
public String getCapital() {
return capital;
}
}
If your collection/array has only 15 elements you can just use Collections.shuffle() and then iterate it.
If you don't want to change the initial array you can generate the collection with indexes (from zero to array.length) and then shuffle it.
I previously mentioned in a comment that because you are randomly generating numbers in a while loop while looking for the last 1/15 number, it is very difficult to do. What you could do is implement open addressing collision handling. Of this, you can utilise either linear probing or double hashing.
Linear probing:
if random generated number is x, x is already used, instead of generating new random num, take x+1. If x+1 is used, take x+2 and so on.
double hashing:
if random generated number x is not used, continue as normal, but if it is used, utilise a hash to add a variable constant value to your x.
If it works only 14 times, then issue will be in the loop condition.
Try changing CountryCard.uses<15 to CountryCard.uses<=15
Also check the value of game.length
I have designed the battleship game to only have one ship hidden and now I have to implement another ship into the game. I am new to Java and was wondering if anybody could offer me a simple way to go about this. Do I need to create another method or just adjust the display river method?
public static void displayRiver(int[] river, boolean showShip) {
System.out.println();
System.out.print("|");
for (int val : river) {
switch (val) {
case -1: // No Ship
System.out.print("x");
break;
case 0: // Unknown
System.out.print(" ");
break;
case 1: // Ship Found
System.out.print(showShip ? "Y" : " ");
break;
}//switch
System.out.print("|");
}//for
System.out.println();
System.out.println();
}//displayRiver
// main method
public static void main(String[] arg) {
int riverLength = promptForInt("Please, enter the river lenght");
int [] shipArray = new int[riverLength];
int randomBattleshipLocation = new Random().nextInt(riverLength);
shipArray[randomBattleshipLocation] = 1;
boolean showShip = false ;
int userGuess;
do
{
displayRiver (shipArray, false);
userGuess = promptForInt(String.format("Guess, enter a location from 1 to " + riverLength));
userGuess = userGuess -1;
if(shipArray[userGuess] == 1)
{
System.out.println("Boom! ");
showShip = true;
displayRiver(shipArray, true);
}
else if(shipArray[userGuess] == -1)
{
System.out.println("Location was already hit, try again! ");
}
else if(shipArray[userGuess] == 0)
{
System.out.println("Splash...");
shipArray[userGuess] = -1 ;
}
} while(!showShip);
System.exit(0);
}
}
Your logic seems to be that an 1 in the array indicates a ship, and your ships apparently are never more than one in width.
You currently use the following to create one ship
int randomBattleshipLocation = new Random().nextInt(riverLength);
shipArray[randomBattleshipLocation] = 1;
So you could turn that into a method that creates a battleship, then call that as many times as you want for multiple ships. Just make sure that you don't assign a ship on top of another ship, or make another logical error (like trying to put 5 ships into a river of size 4, and it will loop forever trying to find space for ships).
Pseudo-code and not-so-pseudo-code:
for(int i = 0;i < shipsToAdd; i++) {
addShip(shipArray);
}
// Use a shared class-level Random object, don't do new Random().nextInt();
private static Random rnd = new Random();
private static addShip(int[] array) {
// Here you should loop to check if the array is already full of ships
// otherwise it's a design flaw that will result in an infinite loop with bad input
// loop until we find a shipless array index
int index = rnd.nextInt(array);
while(array[index] == 1)
index = rnd.nextInt(array);
array[index] = 1;
}
I am almost finished creating a hangman game in Java, although I am having difficulty with one last part. I want to make it so the program checks if all the letters of the word have been guessed correctly and if so, the game prints a message saying they have won, the game ends and the program goes to the do while loop in the main class asking if they would like to play again. If not however, the game continues until this point or if all 5 guesses have been used - to which again, it is sent to the do while loop in order to restart the game and not simply terminate the program.
The problem is I am unsure how and where exactly to structure the if and else statements in order to do so.
Any help would be greatly appreciated, if I can provide further information to help narrow anything down please ask too, thank you in advance.
Instantiable Class
public class Hangman {
private char letterGuess;
private int numberLives;
private String outputWord, endMessage;
private final String hiddenWord;
private final StringBuffer swapBuffer = new StringBuffer();
public Hangman() {
letterGuess = ' ';
numberLives = 5;
hiddenWord = "java";
outputWord = "";
endMessage = "";
for (int i = 0; i < hiddenWord.length(); i++) {
swapBuffer.append("*");
}
}
public void setLetterGuess(char letterGuess) {
this.letterGuess = letterGuess;
}
public void compute() {
boolean letterFound = false;
for (int i = 0; i < hiddenWord.length(); i++) {
if (letterGuess == hiddenWord.charAt(i)) {
swapBuffer.setCharAt(i, letterGuess);
letterFound = true;
}
}
if (!letterFound) numberLives--;
outputWord = swapBuffer.toString();
}
public int getNumberLives() {
return numberLives;
}
public String getHiddenWord() {
return hiddenWord;
}
public String getOutputWord() {
return outputWord;
}
public String getEndMessage() {
return endMessage;
}
}
Main Class
import javax.swing.*;
public class HangmanApp {
public static void main(String[] args) {
char letterGuess;
int numberLives;
String hiddenWord, outputWord, endMessage, restartGame;
do {
Hangman myHangman = new Hangman();
JOptionPane.showMessageDialog(null, "Welcome to Java Hangman!");
JOptionPane.showMessageDialog(null, "In this game, a word will be printed to you in asterisks - each letter will be revealed upon a correct guess!");
JOptionPane.showMessageDialog(null, "You have 5 lives for the game, the game will end if you make too many incorrect guesses!");
for (int i = 0; i < 10; i++) {
hiddenWord = myHangman.getHiddenWord();
numberLives = myHangman.getNumberLives();
JOptionPane.showMessageDialog(null, "You currently have " +numberLives+ " lives!");
letterGuess = JOptionPane.showInputDialog(null, "Now, please enter a letter : ").charAt(0);
myHangman.setLetterGuess(letterGuess);
myHangman.compute();
outputWord = myHangman.getOutputWord();
JOptionPane.showMessageDialog(null, "The word so far is : " +outputWord);
}
numberLives = myHangman.getNumberLives();
JOptionPane.showMessageDialog(null, "You have finished the game with : " +numberLives+ " lives!");
restartGame = JOptionPane.showInputDialog(null, "Would you like to play again?");
}
while (restartGame.equalsIgnoreCase("Yes"));
}
}
Here's the way I see it. After you call myHangman.compute();, you want to check to see if the player has either won the game or run out of lives. Each of these is a separate test using an if expression. There is no else part because if the test fails, the game just goes on.
If one of these conditions is recognized, then you want to display a message, and then you want to exit the current game loop so the user will be asked if they want to play another game. The way to do this is with the break statement.
One issue you have is that you don't have a way in your main game loop to ask the Hangman class if the user has guessed the whole word. To be able to do this, you can add this method to the bottom of your Hangman class:
public boolean getAllLettersFound() {
return outputWord.indexOf('*') < 0;
}
This method checks to see if there are any * in outputWord. If not, then the user has guessed all the letters. So with this method added, the main loop can query the Hangman object to find out if the player has won.
To put this all together, you need to add the two condition checks to your main game loop, right after you call myHangman.compute();. Here are those two if blocks:
if (myHangman.getAllLettersFound()) {
JOptionPane.showMessageDialog(null, "You Won!!!!");
break;
}
if (myHangman.getNumberLives() == 0) {
JOptionPane.showMessageDialog(null, "You Ran Out Of Guesses");
break;
}
That should do it. Happy coding!
I'm taking a programming II class in which we've been working on programming classes. Now we've been assigned homework to write a driver class to incorporate these classes. The homework states
Using the die, dice, and player classes completed in class, write a
driver class to have three players taking turns rolling the dice.
First player to accumulate a total score of 35 or more is the winner."
For example, if player 1 rolls a 3, their score is 3. Then player 2
rolls. Then player 3. As each player rolls, their roll is added to
their previous score.
I've started writing it, but have been given the error that several items in my program cannot be resolved to a type. I also have absolutely no idea how to even begin creating a loop to do what is being asked. This is what I have so far:
import java.util.Scanner;
public class DiceRace {
public static void main(String[] args){
Player player1;
Player player2;
Player player3;
Dice dice;
Scanner keyboard;
keyboard=new Scanner(System.in);
dice=new Dice();
System.out.print("First player's name: ");
player1=keyboard.next();
System.out.print("Second player's name: ");
player2=keyboard.next();
System.out.print("Third player's name: ");
player3=keyboard.next();
}//Ending bracket of method main
}//Ending bracket of class DiceRace
You can create 3 methods, for each player, and a method that plays the game. In each player's method, it first calls the play method with a parameter containing the player name, and the play method prints it out so that the player knows who's turn it is. once the play method is done, it will call the next player method, then the player after that, and finally back to player 1.
It looks like you're a beginner. You should do some tutorials or stuff like that to know the basics :) Also, if you start getting familiar with an IDE (like Eclipse) then programming will be far more easy for you as IDEs can give you detailed descriptions of errors, even while writing the code.
In your above example you need to create two classes by yourself Dice and Player, as they are not in Java by default.
The method keyboard.next() reads an input from the console and returns it as object of the type String, not Player. Thus, you can not assign the variable player1 the result, a String.
What you probably want is a Player object having a member variable String name. Here's an example:
public final class Player {
private String mName;
public Player(final String name) {
mName = name;
}
public String getName() {
return mName;
}
}
Then you can do something like this in your main-method:
player1 = new Player(keyboard.next());
System.out.println("Name of player1 is: " + player1.getName());
Next you probably want a Dice to have a roll method:
public final class Dice() {
private Random mRandom;
public Dice() {
mRandom = new Random();
}
public int roll() {
// Returns a random number between 1 and 6 (inclusive)
return mRandom.nextInt(6) + 1;
}
}
Then, in your main you can do:
Dice dice = new Dice();
System.out.println("Let's roll the dice: " dice.roll());
Now to the games logic, let's keep it very simple, beginner friendly:
int player1Score = 0;
int player2Score = 0;
int player3Score = 0;
boolean finished = false;
boolean player1One = false;
boolean player2One = false;
boolean player3One = false;
// 0 is first player, 1 second and 2 third
int currentPlayer = 0;
while(!finished) {
int rollValue = dice.roll();
if (currentPlayer == 0) {
player1Score += rollValue;
} else if (currentPlayer == 1) {
player2Score += rollValue;
} else {
player3Score += rollValue;
}
player1One = player1Score >= 35;
player2One = player2Score >= 35;
player3One = player3Score >= 35;
finished = player1One || player2One || player3One;
// Increment and modulo 3 (numbers between 0 and 2)
currentPlayer = ((currentPlayer + 1) % 3);
}
Good luck :)
Trying to create a blackjack game, and I'm having some trouble figuring out how to print out and array of cards.
So after the player has seen their first two cards, they can choose to either hit or stand.
When they choose to hit, I want it to print a random card from the array I've created and add the integer value of the card (using .rank to get int) to a variable to count their score.
Here I made a loop that filled two arrays with cards.
Card[] dealerDeck = new Card[21];
Card[] playerDeck = new Card[21];
for (int i = 0; i < 21; i++)
{
dealerDeck[i] = deck.cards[i+11];
playerDeck[i] = deck.cards[i+30];
}
How do I get it to print some random card from the array using a for-loop?
String temp;
int userChoice = 0;
while (score < 21 || userChoice != 1)
{
System.out.println("Do you want to HIT or STAND?");
temp = scanner.nextLine();
if (temp.contains("H") || temp.contains ("h"))
{
System.out.println(" "); //This is for aesthetics
System.out.println("The dealer gave you a ");
//you can use .printCard(); to print the card out
// as King of Hearts, Four of Spades, etc.
}
else if (temp.contains("S") || temp.contains ("s"))
{
System.out.println(" ");
System.out.println("Your final score is "+score+".");
userChoice++;
}
}
Sorry if this a bit confusing, English is my first language.
I think I have it all in my head, I just need to get what's in my head into code.
Thanks in advance!
First, you'll need to change your arrays to an ArrayList as shown:
ArrayList<Card> dealerDeck = new ArrayList<Card>();
ArrayList<Card> playerDeck = new ArrayList<Card>();
This will enable you to remove cards from the Card arrays and modify them more easily. To pick a random card, use this:
Random rand = new Random();
void addRandomCard() {
int randIndex = rand.nextInt(dealerDeck.size());
dealerDeck.remove(randIndex);
playerDeck.add(randIndex);
}
Is this what you were looking for?