Card Values in BlackJack Java - java

First time posting on here. I've heard many good things about the community. I'm an amateur programmer and have dabbled in C++ and Java so far. Anywhoo, I've been cracking my head open with this BlackJack game in java I've sort of haphazardly put together over the last few days. Basically, I am having an issue with the creating of my deck. I am using an ArrayList to hold the cards, but I cant figure out a way to correctly add a value to each card. As you can see by my code, I am using parseint to get the value from the String and add it to the card sum but the problem is, when values such as "Ace" and "Jack" "King" "Queen" come up, clearly no int can be parsed from there so when the program runs, everything works fine, unless of course one of the previously mentioned cards are pulled. Then I get an error that reads:
(""Exception in thread "main" java.lang.NumberFormatException: For input string: "Queen"
at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
at java.lang.Integer.parseInt(Integer.java:580)
at java.lang.Integer.parseInt(Integer.java:615)
at blackjack.Blackjack.getHumanValue(Blackjack.java:110)
at blackjack.Blackjack.main(Blackjack.java:27)
Java Result: 1
BUILD SUCCESSFUL (total time: 0 seconds)"") .
I've tried looking it up online to see if I can spark some inspiration but all I can find is to use Enums or Switch to build my deck, but the problem is I don't fully understand those techniques yet. Any advice will be greatly appreciated.
Thanks!
public class Blackjack{
ArrayList<card> buildDeck = new ArrayList<card>();
public static void main(String[] args)
{
Blackjack b = new Blackjack();
// Compares both scores. The largest score wins.
if(b.getHumanValue() < b.getRobotValue())
{
System.out.println("ROBOT WINS!!!");
}
else if(b.getRobotValue() > 21 && b.getHumanValue() <=21 )
{
System.out.println("YOU WIN!!!");
}
}
public ArrayList<card> buildDeck(ArrayList<card> buildDeck)
{
String [] suit = {"Spade", "Hearts", "Clubs", "Diamonds"};
String [] cardValue = {"Ace","2","3","4","5","6",
"7","8","9","10","Jack","Queen","King"};
for(int i = 0; i < suit.length; i++)
{
for(int j = 0; j < cardValue.length; j++)
{
card card = new card(suit[i], cardValue[j]);
buildDeck.add(card);
}
}
return buildDeck;
}
// This returns the human score
public int getHumanValue()
{
buildDeck(buildDeck);
Scanner s = new Scanner(System.in);
card value;
int ranCard = 0;
int i = 0;
int aceValue = 0;
int totalValue = 0;
String drawAgain = "";
System.out.println("[[Dealer gives you two cards.]]");
System.out.println("");
while(i < 2)
{
ranCard = 0+(int)(Math.random()*52);
System.out.println("Card " + (i+1) + ":");
System.out.println(buildDeck.get(ranCard));
value = buildDeck.get(ranCard);
while(value.cardValue.equalsIgnoreCase("Ace")) // Ace value; either 1 or 11
{
System.out.println("");
System.out.println("This is an ace.");
System.out.println("It is equal to 1 or 11");
System.out.println("Which number do you prefer?");
System.out.println("");
aceValue = s.nextInt();
s.nextLine();
if(aceValue == 11)
{
totalValue += 11;
totalValue -= 1; // Subtracted 1; was off by one
break;
}
else if(aceValue == 1)
{
totalValue += 1;
totalValue -= 1; // Subtracted 1; was off by one
break;
}
}
totalValue += Integer.parseInt(value.cardValue);
System.out.println("Total Score: " + totalValue);
System.out.println("");
i++;
}
System.out.println("[[Would you like to draw another card? Yes/No]]");
System.out.println("");
drawAgain = s.nextLine();
System.out.println("");
if(drawAgain.equalsIgnoreCase("YES"))
{
ranCard = 0+(int)(Math.random()*52);
System.out.println("Card 3:");
System.out.println(buildDeck.get(ranCard));
value = buildDeck.get(ranCard);
totalValue += Integer.parseInt(value.cardValue);
System.out.println("Total Score: " + totalValue);
System.out.println("");
}
else
{
}
return totalValue;
}
// This returns the robot's score
// Mostly copied from gethumanValue method but more automated
public int getRobotValue()
{
buildDeck(buildDeck);
card value;
int ranCard = 0;
int i = 0;
int totalValue2 = 0;
System.out.println("[[Dealer gives Robot two cards.]]");
System.out.println("");
while(i < 2)
{
ranCard = 0+(int)(Math.random()*52);
System.out.println("Card " + (i+1) + ":");
System.out.println(buildDeck.get(ranCard));
value = buildDeck.get(ranCard);
while(value.cardValue.equalsIgnoreCase("Ace")) // Ace value; either 1 or 11
{
if(totalValue2 < 11)
{
totalValue2 += 11;
totalValue2 -= 1; // Subtracted 1; was off by one
break;
}
else if(totalValue2 > 10)
{
totalValue2 += 1;
totalValue2 -= 1; // Subtracted 1; was off by one
break;
}
}
totalValue2 += Integer.parseInt(value.cardValue);
System.out.println("Total Score: " + totalValue2);
System.out.println("");
i++;
}
if(totalValue2 < 17)
{
ranCard = 0+(int)(Math.random()*52);
System.out.println("Card 3:");
System.out.println(buildDeck.get(ranCard));
value = buildDeck.get(ranCard);
while(value.cardValue.equalsIgnoreCase("Ace")) // Ace value; either 1 or 11
{
if(totalValue2 < 11)
{
totalValue2 += 11;
totalValue2 -= 1; // Subtracted 1; was off by one
break;
}
else if(totalValue2 > 10)
{
totalValue2 += 1;
totalValue2 -= 1; // Subtracted 1; was off by one
break;
}
}
totalValue2 += Integer.parseInt(value.cardValue);
System.out.println("Total Score: " + totalValue2);
System.out.println("");
}
else
{
}
return totalValue2;
}
}
EDIT Sorry, Forgot to include my card class!!!
public class card {
String suit;
String cardValue;
#Override
public String toString() {
return cardValue + " of " + suit;
}
public card(String suit, String cardValue) {
this.suit = suit;
this.cardValue = cardValue;
}
public card(String cardValue) {
this.cardValue = cardValue;
}
public String getSuit() {
return suit;
}
public void setSuit(String suit) {
this.suit = suit;
}

Pay close attention to this call.
totalValue2 += Integer.parseInt(value.cardValue);
It's innocuous enough since it works for any of the integer values you have in cardValue. But, you don't just have integral values there either - you have words, too.
You can't change the word "Queen" to a number. Java doesn't have that capability, since it has no numerical meaning*.
It'd be better to store the value of the card and the name of the card as separate parts of data, since the name of the card would also include the suit information.
You haven't shown us your Card class implementation, but what you can do without changing your external contract is to do a bit of parsing on the inside when you get the String, and return an int instead of a String when you retrieve the cardValue. In the case of an "Ace" type, then depending on the total value of the hand, you should pick the most appropriate value (either 1 or 11). This part I leave as an exercise for the reader.
public Card(String suit, String value) {
this.suit = suit;
switch(value) {
case "Ace":
isAce = true; // conditional logic req'd since Ace can be 1 or 11.
break;
case "Jack":
case "Queen":
case "King":
this.value = 10;
break;
}
this.cardName = value;
}
*: "Queen" does have a value in base 31: 24919187. But that's probably not what you were going for.

Related

Setting a value for one of my instance variables isn't working

I'm trying to write a program that essentially evaluates a 5 card poker hand that is user-generated. One part of the program is that users can choose one variable to randomly change. The issue lies with setting a value for one of my instance variables, right now, my setCards, getCards, and changeOne methods are:
public void setCards(String str) {
this.cards = str;
calculateScore();
history = history + cards + score + changes;
changes++;
}
public String getCards() {
return this.cards;
}
public void changeOne(int pos) {
getCards();
calculateScore();
history = history + cards + score + changes;
randomChar = allCards.charAt((int)(Math.random()*cards.length()));
this.cards = cards.substring(0, pos) + randomChar + cards.substring(pos + 1, cards.length());
changes++;
}
In a separate class, I'm using:
cards = in.nextLine().toUpperCase();
myCards.setCards(cards);
I'm not sure why but whenever I try to use the changeOne method, keeps giving me the error:
Exception in thread "main" java.lang.StringIndexOutOfBoundsException: begin 0, end 3, length 0
Which I assume is because it takes cards to be an empty string. I'm not sure what is happening and why it isn't getting the proper value of cards, help would be greatly appreciated.
Entire code:
First class:
import java.util.Scanner;
public class Assignment4{
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
FiveCards myCards = new FiveCards();
int position;
String choice, cards;
char charChoice;
final char NEW = 'A';
final char CHANGE = 'B';
final char DISPLAY = 'C';
final char QUIT = 'Q';
do {
System.out.println("Choose (A: Make New Cards), (B: Change One Card), (C: Display Data), or (Q: Quit)");
choice = in.next();
charChoice = choice.toUpperCase().charAt(0);
switch(charChoice) {
case NEW:
System.out.println("*** Make New FiveCards ***");
System.out.println("Type five letters without space: ");
in.next();
cards = in.nextLine().toUpperCase();
myCards.setCards(cards);
System.out.println("[Cards] [Score] [Changes]");
myCards.displayData();
break;
case CHANGE:
System.out.println("*** Change One Card ***");
System.out.println("Type one position to change (0-4): ");
position = in.nextInt();
myCards.changeOne(position);
System.out.println("[Cards] [Score] [Changes]");
myCards.displayData();
break;
case DISPLAY:
System.out.println("[Cards] [Score] [Changes]");
myCards.displayData();
break;
case QUIT:
System.out.println("*** End of Program ***");
break;
default:
System.out.println("Invalid input. Try Again");
break;
}
}while(charChoice!=QUIT);
}
}
Second class is:
public class FiveCards {
private String cards, history;
private int score, changes, counter;
private String allCards = "1234567890JQK";
private char randomChar;
public FiveCards() {
}
public void setCards(String str) {
this.cards = str;
calculateScore();
history = history + cards + score + changes;
changes++;
}
public String getCards() {
return this.cards;
}
public void changeOne(int pos) {
calculateScore();
history = history + cards + score + changes;
randomChar = allCards.charAt((int)(Math.random()*cards.length()));
this.cards = cards.substring(0, pos) + randomChar + cards.substring(pos + 1, cards.length());
System.out.println(cards);
changes++;
}
public void calculateScore() {
for(int i = 0; i<cards.length(); i++) {
for(int j = 0; j<cards.length(); j++) {
if((cards.charAt(i) == cards.charAt(j)) && (i != j)) {
counter++;
}
}
}
if(counter == 2) {
score = 1;
}
else if(counter == 4) {
score = 2;
}
else if(counter == 6) {
score = 3;
}
else if(counter == 8) {
score = 4;
}
else {
score = 0;
}
}
public String displayData() {
calculateScore();
history = history + cards + score + changes;
if(cards.length()<=1) {
return cards + " " + score + " " + changes;
}
else {
return "Empty" + " " + score + " " + changes;
}
}
}
First problem:
allCards.charAt(...). In the setCards you assign string to cards, but here you pick character from allCards. What is content of allCards? When it is assigned? I it assigned at all? (your code doesn't show this).
And the second problem:
Math.random()*cards.length()
Valid indexes of characters in the String are from 0 to length() - 1 inclusive, but the way you generate random index, you can give you index from 0 to length() inclusive. Change it to the Math.random()*(cards.length() - 1).

Building card game need same cards to match in value

I am building a war card game for an assignment I have the game built and it is working but I am running into the issue such as card 10 jack of spades is less in value as say card 23 the jack of hearts. Looking for advice about the best way to be able to compare the cards to see if they are equal.
Below is the code I have so far:
import java.util.Random;
import java.util.Scanner;
public class WarGame {
public static void main(String a[]) {
DeckOfCards d = new DeckOfCards();
int input = 0;
int computer = 0;
int you = 0;
Scanner sc = new Scanner(System.in);
System.out.print("\n1.To play\n2.Exit\nEnter the choice:");
input = sc.nextInt();
while (input != 2) {
if (input == 1) {
System.out.print("\n\nEnter the value of the card:");
int card = sc.nextInt();
if (card >= 0 && card <= 51) {
int systemCard = d.computerTurn(card);
System.out.println("Your card - " + d.inputCard(card));
System.out.println("Computer card - " + d.inputCard(systemCard));
if(systemCard > card)
++computer;
else
++you;
System.out.println("The winner is " + (systemCard > card ? "Computer" : "You"));
} else {
System.out.println("Invalid card");
}
}
else {
System.out.println("That is an invalid selection please choose 1 or 2.");
}
System.out.print("\n1.To play\n2.Exit\nEnter the choice:");
input = sc.nextInt();
}
System.out.println("Total Wins by Computer: "+ computer);
System.out.println("Total Wins by You: "+ you);
if (computer > you)
System.out.println("Computer is the champion");
else if (computer == you)
System.out.println("Its a Tie");
else
System.out.println("You are the champion");
}
}
class DeckOfCards {
String suits[] = {"Spades", "Hearts", "Diamonds", "Clubs"};
Random ran = new Random();
int systemWin = 0;
int playerWin = 0;
String inputCard(int card) {
int suit = card / 13; //assigning suit to your card
int rank = card % 13; //Assigning rank to your card
String out = "";
switch (rank) { //Setting up face cards for the cases
case 0:
out = "Ace of " + suits[suit];
break;
case 10:
out = "Jack of " + suits[suit];
break;
case 11:
out = "Queen of " + suits[suit];
break;
case 12:
out = "King of " + suits[suit];
break;
default:
out = rank + 1 + " of " + suits[suit]; //Adding one to remainder so it will go from 2-10 instead of 1-9
break;
}
return out;
}
int computerTurn(int playerRank) { //Keeping track of the wins for computer and player
int systemRank = this.ran.nextInt(51);
if (systemRank > playerRank)
systemWin++;
else
playerWin++;
return systemRank;
}
}
I think you're comparing the index to your deck rather than the card values themselves. If I'm understanding, you want to compare d.inputCard(card) with d.inputCard(systemCard) instead of card with systemCard. But of course, that's a String. Having a hard time following the code :-).

How to compare variables in a loop, java

I have to design a program to simulate players rolling three dice for a number of rounds. Each dice throw is given points. I have to diplay for each round the dice values, and number of points for each player for those values and the winner of each round (the player with the highest points for that round, or no-one if they are the same).
I have implemented the points calculator, but I dont know how to display the winner of each round. Also, I am displaying the output vertically when it is supposed to be horizontally.
I think maybe comparing the values inside the loop in the game class may work. P.S. I am new in java, please make any suggestions to change the code if there is a better solution.
This is waht my program is displaying
round 1--> player 1: 2 4 5 points: 11
round 2--> player 1: 2 3 5 points: 10
round 3--> player 1: 2 4 6 points: 12
round 4--> player 1: 4 4 6 points: 34
round 5--> player 1: 3 4 5 points: 52
.
round 1--> player 2: 3 5 5 points: 33
round 2--> player 2: 3 6 6 points: 35
round 3--> player 2: 2 3 4 points: 49
round 4--> player 2: 1 1 3 points: 25
round 5--> player 2: 1 2 4 points: 7
This is what it is supposed to display
Round 1 Player 1: 1 3 3 points: 27 Player 2: 1 4 5 points: 10 Round winner is player 1
Round 2 Player 1: 1 2 5 points: 8 Player 2: 1 3 6 points: 10 Round winner is player 2
Round 3 Player 1: 1 4 4 points: 29 Player 2: 4 5 6 points: 55 Round winner is player 2
Round 4 Player 1: 1 3 5 points: 9 Player 2: 1 5 5 points: 31 Round winner is player 2
Round 5 Player 1: 3 6 6 points: 35 Player 2: 2 2 4 points: 28 Round winner is player 1
Total wins: Player 1: 2/ Player 2: 3
Total points: Player 1: 108/ Player 2: 134
Average points per round: Player 1: 21.6/ Player 2: 26.8
Overall points winner is player 2.
Main code
import java.util.Scanner;
public class Game {
// ------------------- FIELDS ------------------------
// Create instance of Scanner class
public static Scanner input = new Scanner(System.in);
// variables
public static ThreeDiceScorer thrdiesc;
public static int diceArray [];
// ------------------ METHODS ------------------------
public static void main(String[] args) {
int rounds; // input by user
int players; // input by user
System.out.print("Please input number of rounds (grater or equal than 0) --> ");
rounds = input.nextInt();
System.out.print("\n");
System.out.print("Please input number of rounds (grater or equal than 0) --> ");
players = input.nextInt();
System.out.print("\n");
for (int p = 0; p < players; p++) { //loop for players
for (int r = 0; r < rounds; r++) { // loop for number of rounds
int diceArray [] = new int [3];
for (int i = 0; i < diceArray.length; i++) { // loop for random Array
diceArray [i] = 1 + (int)(6 * Math.random());
}
// Create new ThreeDice and calculator instances
thrdiesc = new ThreeDiceScorer(diceArray [0], diceArray [1], diceArray [2]);
//Calculate
thrdiesc.getDie1();
thrdiesc.getDie2();
thrdiesc.getDie3();
thrdiesc.threeSame();
thrdiesc.runOfThree();
thrdiesc.pair();
thrdiesc.allDifferent();
thrdiesc.calcTotalPoints();
thrdiesc.printResult(p,r);
}
System.out.print("\n");
}
}//end Main Method
}// end Class
ThreeDice class
public class ThreeDice {
// ---------------------- ATTRIBUTES ---------------------
protected int die1;
protected int die2;
protected int die3;
// ------------------ CONSTRUCTOR -------------------
public ThreeDice(int s1, int s2, int s3) {
// This puts the three dice values in ascending order.
int tmp;
if (s2 < s1) {
tmp = s2;
s2 = s1;
s1 = tmp;
}
if (s3 < s2) {
tmp = s3;
s3 = s2;
s2 = tmp;
}
if (s2 < s1) {
tmp = s2;
s2 = s1;
s1 = tmp;
}
die1 = s1;
die2 = s2;
die3 = s3;
}
// --------------------- METHODS ---------------------
// Accessor methods
public int getDie1() {
return die1;
}
public int getDie2() {
return die2;
}
public int getDie3() {
return die3;
}
public boolean threeSame() {
return (die1 == die3);
}
public boolean runOfThree() {
return (( (die1 + 1) == die2) && ( (die2 + 1) == die3));
}
public boolean pair() {
return (((die1 == die2) || (die2 == die3)) && (die1 != die3));
}
public boolean allDifferent() {
return (!runOfThree() && (die1 != die2) && (die2 != die3));
}
public void printResult() {
if (threeSame())
System.out.println("The roll is all the same.");
else if (runOfThree())
System.out.println("The roll is a run.");
else if (pair())
System.out.println("The roll is a pair.");
else if (allDifferent())
System.out.println("The roll is all different.");
}
}
ThreeDiceScorer (Calculator) Class
public class ThreeDiceScorer extends ThreeDice {
int total;
public ThreeDiceScorer(int s1, int s2, int s3) {
super(s1, s2, s3);
}
public void calcTotalPoints() {
int sumOfDice = die1 + die2 + die3;
if (threeSame()){
total= sumOfDice + 60;
}
else if (runOfThree()){
total= sumOfDice + 40;
}
else if (pair()){
total= sumOfDice + 20;
}
else if (allDifferent()){
total= sumOfDice;
}
}
public void printResult(int p,int r) {
System.out.println("round "+ (r+1)+ "--> " + "player "+ (p+1) + " "+ die1 + " " + die2 + " " + die3 + " " + "points: "+ total);
}
}
Sol
Switch player loop and rounds loop.
In each round loop maintain a max and update it with max value and player.
Modify printresult a little to remove round.
Loop and max:
for (int r = 0; r < rounds; r++) { // loop for number of rounds
int max = 0;
int max_p = 0;
System.out.println("Round " + r + ": ");
for (int p = 0; p < players; p++) { //loop for players
int diceArray[] = new int[3];
//...
thrdiesc.printResult(p, r);
if (thrdiesc.total > max) {
max = thrdiesc.total;
max_p = p;
}
}
System.out.println("Winner is player " + (max_p + 1) + "\n");
}
PrintResult Method:
public void printResult(int p, int r) {
System.out.println("player " + (p + 1) + " " + die1 + " " + die2 + " " + die3 + " " + "points: " + total);
}
Misc
Indent Code properly.
Be careful while copying. (See the prompt)
While looking at your code, I have a feeling you might be able to make this much easier for yourself by creating some simple classes, five or six to be exact.
First I would break up some parts into classes. The two main classes I am thinking of are a simple Die class that is simply an immutable Die that when created sets the die value to a random number between 1 and 6. Once you create the Die object it cannot be changed. Your ThreeDice class is narrow and is really unnecessary as the three dice should really be a part of the Player object (next class) as a simple array of 3 Die objects and as an array of Die objects we can sort the dice from low to high.
A sample of a “Die” class is below:
Public final class Die implements Comparable<Die>
{
private int dieNumber;
// default constructor
public Die()
{
RollDie();
}
public int GetDieNumber()
{
return dieNumber;
}
public int compareTo(Die otherDie)
{
return this.dieNumber - otherDie.dieNumber;
}
private void RollDie()
{
dieNumber = 1 + (int)(6 * Math.random());
}
}
The next class to help would be a Player class. The important parts of this class will be a player name, then a Die object array (of size 3 in your case) to hold the players random dice. In this class you could also have methods to get the total value of the 3 dice, along with a method/variable to get the extra points the user gets if the 3 dice are the same number, if there is a pair, etc. Here we can take advantage of the sorting of the dice array from low to high when the dice array is created. This will make checking for straights easier.
A Player class example is below.
public class Player implements Comparable<Player>
{
private String playerName;
private Die[] diceArray;
private int diceTotal = 0;
private int extraPoints = 0;
private int overallTotal = 0;
private String extraPointsString = "";
public Player(String inName, Die[] inDiceArray)
{
playerName = inName;
diceArray = inDiceArray;
SetDiceTotals();
}
public String GetPlayerName()
{
return playerName;
}
public int GetExtraPoints()
{
return extraPoints;
}
public int GetDiceTotal()
{
return diceTotal;
}
public int GetOverallTotal()
{
return overallTotal;
}
public String GetExtraPointsString()
{
return extraPointsString;
}
public Die[] GetDiceArray()
{
return diceArray;
}
public String toString()
{
String playerString = playerName + " Dice values: ";
for (int i = 0; i < diceArray.length; i++)
{
if (i < (diceArray.length - 1))
playerString = playerString + diceArray[i].GetDieNumber() + ", ";
else
playerString = playerString + diceArray[i].GetDieNumber();
}
playerString = playerString + " Total: " + GetDiceTotal();
playerString = playerString + " - Special Points added: " + GetExtraPoints() + " for having " + GetExtraPointsString();
return playerString + " Total Points: " + GetOverallTotal();
}
public int compareTo(Player otherPlayer)
{
int thisTotal = this.GetDiceTotal() + this.GetExtraPoints();
int otherTotal = otherPlayer.GetDiceTotal() + otherPlayer.GetExtraPoints();
return otherTotal - thisTotal;
}
// private internal method to set dice totals, extra points and extra points string
private void SetDiceTotals()
{
int total = 0;
for (int i = 0; i < diceArray.length; i++)
{
total = total + diceArray[i].GetDieNumber();
}
diceTotal = total;
if (is3OfAKind())
{
extraPoints = 60;
extraPointsString = "Three of a Kind";
}
else
{
if (isPair())
{
extraPoints = 40;
extraPointsString = "Pair";
}
else
{
if (isStraight())
{
extraPoints = 20;
extraPointsString = "Straight";
}
else
{
extraPoints = 0;
extraPointsString = "All die are different";
}
}
}
overallTotal = extraPoints + diceTotal;
}
private boolean is3OfAKind()
{
if (diceArray[0].GetDieNumber() == diceArray[1].GetDieNumber() &&
diceArray[0].GetDieNumber() == diceArray[2].GetDieNumber())
return true;
return false;
}
private boolean isPair()
{
if (diceArray[0].GetDieNumber() == diceArray[1].GetDieNumber() ||
diceArray[0].GetDieNumber() == diceArray[2].GetDieNumber() ||
diceArray[1].GetDieNumber() == diceArray[2].GetDieNumber() )
return true;
return false;
}
// this method needs to have the diceArray sorted from low to high
private boolean isStraight()
{
if (diceArray[1].GetDieNumber() == (diceArray[0].GetDieNumber() + 1) &&
diceArray[2].GetDieNumber() == (diceArray[1].GetDieNumber() + 1) )
return true;
return false;
}
}
Then, since you want to keep totals for all the rounds, I figure you may need a Round class. This class will consist of an array of Player objects for a round. Also a round number, total points of the round from all players, an average of points for the round and a string to indicate which player won the round.
A Round class example is below.
public class Round
{
private Player[] playerArray;
private int roundNumber = 0;
private int totalPointsForRound = 0;
private double roundAveragePoints = 0;
private String roundWinnerName = "";
public Round(int inRoundNumber, Player[] inPlayerArray)
{
playerArray = inPlayerArray;
roundNumber = inRoundNumber;
totalPointsForRound = SetAllPointsForRound();
roundAveragePoints = SetAveragePoints();
roundWinnerName = SetRoundWinnerName();
}
public int GetTotalPointsForRound()
{
return totalPointsForRound;
}
public double GetAveragePointsForRound()
{
return roundAveragePoints;
}
public String GetRoundWinnerName()
{
return roundWinnerName;
}
public Player[] GetPlayerArray()
{
return playerArray;
}
public int GetRoundNumber()
{
return roundNumber;
}
private String SetRoundWinnerName()
{
// sort the array from high to low - if the first two total are equal then its a tie
Player[] tempArray = playerArray;
Arrays.sort(tempArray);
if (tempArray[0].GetOverallTotal() == tempArray[1].GetOverallTotal())
return "Tie";
if (tempArray[0].GetOverallTotal() > tempArray[1].GetOverallTotal())
return tempArray[0].GetPlayerName();
return "Unknown Winner???";
}
private double SetAveragePoints()
{
double totalPoints = GetTotalPointsForRound();
double average = totalPoints/playerArray.length;
return Math.round(average*100.0)/100.0;
}
private int SetAllPointsForRound()
{
int allPoints = 0;
for (int i = 0; i < playerArray.length; i++)
{
allPoints = allPoints + playerArray[i].GetOverallTotal();
}
return allPoints;
}
}
Then since you want to keep totals for all the players, you may want to make a small PlayerTotals class. This class will simply consist of a player name, total wins for all rounds and total points for all rounds. Keep in mind these are totals for ALL rounds not for a single round as each Player object in the Round's playerArray will contain totals for that particular round.
A PlayerTotals class example is below
public class PlayerTotals implements Comparable<PlayerTotals>
{
String playerName;
int totalWins = 0;
int totalPoints = 0;
public PlayerTotals(String inPlayerName)
{
playerName = inPlayerName;
}
public int GetTotalPoints()
{
return totalPoints;
}
public void SetTotalPoints(int inPoints)
{
totalPoints = inPoints;
}
public int GetTotalWins()
{
return totalWins;
}
public void SetTotalWins(int inWins)
{
totalWins = inWins;
}
public int compareTo(PlayerTotals otherPlayerTotals)
{
int thisTotalPoints = this.GetTotalPoints();
int otherTotalPoints = otherPlayerTotals.GetTotalPoints();
return otherTotalPoints - thisTotalPoints;
}
}
Then two more classes which you could actually combine into one class. One is a static GameUtils class that helps do some global things like: GetPlayerArray, this method gets an array of Player objects. Each Player object will contain an array of the 3 dice each player rolled. This dice array will be sorted from low to high. This is the method that gets your initial random rolls for each player for each round. Also here we can GetPlayerOverallWins where we can loop through all rounds and total up how many wins each player had. A method called GetTotalTies to get the total number of ties from all the rounds. And a method GetPlayerOverallPoints to get a total of all players points from all rounds. Also here I placed your prompts for the user to enter the number of players and number of rounds with a check to make sure the user input is valid.
A GameUtils example is below:
public final class GameUtils
{
public static Player[] GetPlayerArray(int numOfPlayers, int numOfDice)
{
Player[] playerArray = new Player[numOfPlayers];
for (int i = 0; i < numOfPlayers; i++)
{
Die[] diceArray = new Die[numOfDice];
for (int j = 0; j < numOfDice; j++)
{
diceArray[j] = new Die();
}
Arrays.sort(diceArray);
playerArray[i] = new Player("Player " + (i + 1), diceArray);
}
return playerArray;
}
public static int GetNumberOfPlayers(Scanner input)
{
return GetValidInteger("Please input number of players (greater than 0) --> ", input);
}
public static int GetNumberOfRounds(Scanner input)
{
return GetValidInteger("Please input number of rounds (greater than 0) --> ", input);
}
private static int GetValidInteger(String prompt, Scanner input)
{
boolean done = false;
int validInt = -1;
String userInput = "";
while (!done)
{
System.out.print(prompt);
userInput = input.nextLine();
try
{
validInt = Integer.parseInt(userInput);
done = true;
}
catch (NumberFormatException e)
{
System.out.println("Invalid Input: " + userInput + " Try again!");
}
}
return validInt;
}
public static int GetPlayerOverallWins(String playerName, Round[] allRounds)
{
int totalWins = 0;
for (int i = 0; i < allRounds.length; i++)
{
Round curRound = allRounds[i];
String roundWinner = curRound.GetRoundWinnerName();
if (playerName.equals(roundWinner))
{
totalWins++;
}
}
return totalWins;
}
public static int GetTotalTies(Round[] allRounds)
{
int totalTies = 0;
for (int i = 0; i < allRounds.length; i++)
{
Round curRound = allRounds[i];
String roundWinner = curRound.GetRoundWinnerName();
if (roundWinner.equals("Tie"))
{
totalTies++;
}
}
return totalTies;
}
public static int GetPlayerOverallPoints(String player, Round[] allRounds)
{
int totalPoints = 0;
for (int i = 0; i < allRounds.length; i++)
{
Round curRound = allRounds[i];
for (int j = 0; j < curRound.GetPlayerArray().length; j++)
{
Player curPlayer = curRound.GetPlayerArray()[j];
if (player.equals(curPlayer.GetPlayerName()))
{
totalPoints = totalPoints + curPlayer.GetOverallTotal();
break;
}
}
}
return totalPoints;
}
}
Lastly a DiceGame class with a main entry to put it all together. A dice game class will consist of global variables numberOfPlayers. numberOfRounds, numberOfDice, and a playerArray to use for each round, then an array of Rounds to hold all the rounds for totaling after all the rounds have been run. The example below starts by setting a loop for the number of rounds, in this loop we create all the players and dice values for them then save the round information into a new Round object then place each new Round object into an array. Then the results from the current round is output to the user. Once the loop on the number of rounds finishes, we should then have an array of Round objects. Here is where the PlayerTotals class helps as we can create another array of PlayerTotals objects for all rounds. This uses some methods from GameUtils and these methods could just a well be placed into this main class. After all player totals for all rounds have been added up, the results are output to the user.
Main DiceGame class example:
public class DiceGame
{
public static Scanner input = new Scanner(System.in);
static int numberOfPlayers;
static int numberOfRounds;
static int numberOfDice = 3;
static Player[] playerArray;
static Round[] allRounds;
public static void main(String[] args)
{
numberOfPlayers = GameUtils.GetNumberOfPlayers(input);
numberOfRounds = GameUtils.GetNumberOfRounds(input);
System.out.println("");
allRounds = new Round[numberOfRounds];
// for each round - we want to create players with the proper number of random dice
for (int i = 0; i < numberOfRounds; i++)
{
// get an array of players with random dice
playerArray = GameUtils.GetPlayerArray(numberOfPlayers, numberOfDice);
Round currentRound = new Round(i, playerArray);
allRounds[i] = currentRound;
// print the results of this round
System.out.println("Round " + (i + 1) + " Results - Winner is: " + currentRound.GetRoundWinnerName()
+ " -- Average score for this round: " + currentRound.GetAveragePointsForRound());
for (int j = 0; j < playerArray.length; j++)
{
System.out.println(playerArray[j].toString());
}
System.out.println("---------------------------------------");
}
// now get totals for all rounds
// first create an array of PlayerTotals
PlayerTotals[] allPlayersTotals = new PlayerTotals[numberOfPlayers];
for (int i = 0; i < numberOfPlayers; i++)
{
PlayerTotals curPlayer = new PlayerTotals(playerArray[i].GetPlayerName());
curPlayer.SetTotalPoints(GameUtils.GetPlayerOverallPoints(curPlayer.playerName, allRounds));
curPlayer.SetTotalWins(GameUtils.GetPlayerOverallWins(curPlayer.playerName, allRounds));
allPlayersTotals[i] = curPlayer;
}
// print the overall results
System.out.println("");
System.out.println(" -- Overall Results --");
System.out.println("Ties: " + GameUtils.GetTotalTies(allRounds));
Arrays.sort(allPlayersTotals);
PlayerTotals curPlayer;
for (int i = 0; i < allPlayersTotals.length; i++)
{
curPlayer = allPlayersTotals[i];
System.out.println(curPlayer.playerName + " Won " + curPlayer.totalWins + " times - Total Points: " + curPlayer.totalPoints);
}
}
}
Hope these make things easier. Good Luck!

Troubles outputting array counter

I'm new to Java and I have a program players guess the price of an item (exact price is inputted first). I have an array called winnerCount which keeps track of the rounds won by each player. I want to output this using "JOptionPane.showMessageDialog" and part of the code involves giving each player a prize based on the rounds won. So for my pseudocode I have IF roundsWon = 1 THEN prize won: $15,125. When I try the same idea in Java it gives me the error "incomparable types" since its comparing int and int[]. Since Java can't compare different data types, what way(s) can I output the desired result ("winnerCount" and prizes won by each player)?
Here's what I'm working with
import javax.swing.JOptionPane;
import java.lang.Math;
import java.util.*;
public class priceIsRight {
public static void main(String[] args) {
double [] numPlayers = new double [4];
double exactPrice = getExactPrices();
double [] guessPrice = getGuessPrices(exactPrice);
int roundsWon = getRoundsWon(guessPrice, exactPrice);
int numRounds = 0;
int [] winnersCount = new int [4];
int roundWinner = getRoundsWon(guessPrice, exactPrice);
int prizesWon = calculatePrizesWon(winnersCount, roundWinner);
}
public static int getRoundsWon(double[] guessPrice, double exactPrice) {
int roundWinner = getRoundsWon(guessPrice, exactPrice);
int [] winnersCount = new int [4];
int numRounds = 0;
do {
double minValue = Math.abs(exactPrice-guessPrice[0]);
roundWinner = 0;
for (int i=1;i < guessPrice.length; i++) {
double diff = Math.abs(exactPrice-guessPrice[i]);
if (diff<minValue) {
minValue=diff;
roundWinner=i;
}
winnersCount[roundWinner]++;
}
}
while (numRounds <=3);
return roundWinner;
}
//Outputs result
public static int calculatePrizesWon(int [] winnersCount, int roundWinner) {
int prizesWon = 0;
if (winnersCount = 0) {
JOptionPane.ShowMessageDialog(null, "Prize won: $106 consolidation prize!");
}
else if (winnersCount = 1) {
JOptionPane.ShowMessageDialog(null, "Prize won: $15,125!");
}
else if (winnersCount = 2) {
JOptionPane.ShowMessageDialog(null, "Prize won: $30,110!");
}
else if (winnersCount = 3) {
JOptionPane.ShowMessageDialog(null, "Prize won: $15,120,000!");
}
}
}
You need to specify which location in the array you want to compare. Try this:
public static int calculatePrizesWon(int[] winnersCount, int roundWinner) {
int prizesWon = 0;
if (winnersCount[roundWinner] == 0) {
JOptionPane.showMessageDialog(null, "Prize won: $106 consolidation prize!");
} else if (winnersCount[roundWinner] == 1) {
JOptionPane.showMessageDialog(null, "Prize won: $15,125!");
} else if (winnersCount[roundWinner] == 2) {
JOptionPane.showMessageDialog(null, "Prize won: $30,110!");
} else if (winnersCount[roundWinner] == 3) {
JOptionPane.showMessageDialog(null, "Prize won: $15,120,000!");
}
return prizesWon; // Replace this with the real prize won number.
}
You'll probably do better using a switch statement instead. If you want to see or receive comments on other things you can do better post a comment.
There are some things that don't make sense about this code. For example, why did you make numPlayers a double[]? Wouldn't it make more sense for it to be
int numPlayers = 4;
And for your winnersCount, is that storing how many rounds each player won? If so then I assume your calculatePrizesWon method should be iterating through each player, and outputting their prize.
Something like
public static int calculatePrizesWon(int [] winnersCount, int roundWinner)
{
int prizesWon = 0;
for (int i = 0; i < winnersCount.length; i++)
{
if (winnersCount[i] == 0)
{
JOptionPane.ShowMessageDialog(null, "Player "+i+" - Prize won: $106 consolidation prize!");
}
else if (winnersCount[i] == 1)
{
JOptionPane.ShowMessageDialog(null, "Player "+i+" - Prize won: $15,125!");
}
else if (winnersCount[i] == 2)
{
JOptionPane.ShowMessageDialog(null, "Player "+i+" - Prize won: $30,110!");
}
else if (winnersCount[i] == 3)
{
JOptionPane.ShowMessageDialog(null, "Player "+i+" - Prize won: $15,120,000!");
}
}
}
Also, what is the "round winner" parameter you're passing into calculatePrizesWon for?
And what is the "prizesWon" variable for? If, for example, a player won three rounds, then wouldn't they also have won three prizes? So what distinction is there between the winnersCount and the prizesWon?
I'll try to help but you'll need to explain what you're doing a little more clearly.

Having trouble with this java code - supposed to print and count number of heads and tails in a random coin toss

So as the title says, I have to use a class file and also a main method java file that calls the class file and prints out the starting coin face, as well as 40 more coin face flips. I also need to have 2 counters that count the number of heads and number of tails. Here is my code for my class file and main method file. The problem I'm having is that whenever I run it, it always prints out that heads has 0 count and tails as 40 counts.
Class File:
import java.util.Random;
public class CoinToss
{
private String sideUp;
public CoinToss()
{
Random randomNum = new Random();
int number = randomNum.nextInt();
if(number%2 == 0)
sideUp = "heads";
else
sideUp = "tails";
System.out.println(sideUp);
}
public void toss()
{
Random randomNum = new Random();
int number = randomNum.nextInt();
if(number%2 != 0)
{
sideUp = "heads";
}
else
{
sideUp = "tails";
}
System.out.println(sideUp);
}
public String getSideUp()
{
return sideUp;
}
}
Main Method File
public class CoinTossDemo
{
public static void main(String[] args)
{
int headsCount = 0;
int tailsCount = 0;
System.out.print("The Starting side of the coin is: ");
CoinToss coin = new CoinToss();
System.out.println();
for(int x = 0; x < 40; x++)
{
System.out.print("The next side of the coin is: ");
coin.toss();
System.out.println();
if(coin.equals("heads"))
{
headsCount++;
}
else
{
tailsCount++;
}
}
System.out.println("The amount of heads that showed up is: " + headsCount);
System.out.println();
System.out.println("The amount of tails that showed up is: " + tailsCount);
}
}
Please help, thanks in advance.
Currently you're comparing the CoinToss coin object with the String value heads and that's why its always going to the else part.
I can see that you are setting the result of the current coin toss to sideUp(which is a String). Thus you need to compare that with the heads in the if.
if(coin.getSideUp().equals("heads")) { // getSideUp() returns the sideUp value
headsCount++;
} else {
tailsCount++;
}
You are assigning your answer to side up property so get that value coin.getSideUp()
for (int x = 0; x < 40; x++)
{
System.out.print("The next side of the coin is: ");
coin.toss();
System.out.println();
if (coin.getSideUp().equals("heads")) // use the side up property
{
headsCount++;
}
else
{
tailsCount++;
}
}

Categories