I'm new to Java and I am having trouble wrapping my mind around one of the concepts.
The assignment I am currently working on is the card game War. The current instructions is for me to remove a random card from a a deck of cards.
I have created an array, but it is an array of class Card. The class creates the card by basically adding an int and a String together. I then created the array from that class. In my mind, I neither have an int or a String in my array, is that correct?
Now I need to remove one of the random cards from the deck and give it to a player. This is where I am getting lost. I would think I can just use Random to remove a random card, but I always seem to get an error.
I'm not asking for you to do the assignment for me, but if you would please point me in the right direction and possibly correct me if I am confused.
Current Class I am working on:
import java.util.Random;
import java.util.*;
public class War3
{
Random ran = new Random();
public FullDeck randomCard()
{
ArrayList <FullDeck> randCard = new ArrayList <FullDeck> (52);
int index = ran.nextInt(randCard.size());
FullDeck x = randCard.remove(index);
return x;
}
public void display()
{
System.out.println("Your card is" + randomCard());
}
}
Entire project for clarification Java - War Game - Gist
Many thanks in advance.
ArrayList <FullDeck> randCard = new ArrayList <FullDeck> (52);
This creates an ArrayList. You do not need to specify the number 52, since ArrayLists grow dynamically, as opposed to Arrays. The call is similar to
ArrayList <FullDeck> randCard = new ArrayList <FullDeck> ();, the difference being that the constructor you used sets the initial capacity of the ArrayList to 52. That in no way restricts the size of the ArrayList though.
Anyway, you are creating a new, empty ArrayList. Then you want the size, but since you didn't put anything into the list, it is still empty, to the size is zero. You then try to call ran.nextInt(0)... nextInt(int n) expects a number greater than zero. From the javadoc:
public int nextInt(int n) {
if (n <= 0)
throw new IllegalArgumentException("n must be positive");
Two issues that I see:
You're creating an ArrayList that can hold a reference to 52 instances of the FullDeck class, but you're not adding anything to it. You need to do something like randCard.add(new FullDeck()) 52 times/in a loop**. Then likely you'll want to "shuffle" the deck, see this question for how to do that.
You're naming is a little weird...the FullDeck class in actuality seems like it should be renamed to just Card, and the randCard variable should be renamed to something like fullDeck...after you've added 52 Cards.
**EDIT: actually, the generation of a deck of cards will be more complicated to make sure you don't have any duplicate cards.
Related
Ok so, I have a fillhand method that is supposed to get cards from a shuffled deck and add the cards one by one through the top method while also sorting them by suits. The top method saves the card at shuffledDeck at index 0 to a variable, removes the index at 0, and then returns the card. So i added the first card, then its suppose to check if the next card that top returns is of a different suit, if it is then add it to the array list, if it is of the same suit then add it to the arraylist but, in order of ranks within that suit. As of now, where it is supposed to check if the handArray contains the upcoming card's suit == false is not working.
public ArrayList fillHand(ArrayList Array, int handSize)
{
ArrayList<Card> shuffledDeck = Array;
handArray.add(deck.top(shuffledDeck));
for (int i = 0; i < handSize + 1; i++)
{
if (handArray.contains(shuffledDeck.get(i).getSuit()) == false)
{
handArray.add(deck.top(shuffledDeck));
}
}
return handArray;
}
Since you didn't post any code, I'll assume that Deck is a class with two attributes(rank and suit).
You'll want to create a method for this class that makes it print itself(i.e. "Ace of Spades" or "Jack of Hearts")
You'll also need a method that returns the suit.
From there you iterate over your arraylist and call that method on each node that satisfies the required suit
Edit, since code was posted:
The logic itself seems flawed, you're iterating over the handSize, checking if the suit number is in the handArray. This is a major issue, as handArray is an array of Card, not an array of int.
There are multiple ways to fix this, the simpler ones are:
Simplest: iterate over the handArray manually, checking if the suit matches with any of the card's
Faster: creating an array of size 4, with all values initialized as false, representing whether or not a suit is in the handArray.
Now that the if statement is dealt with, we must fix it's code. As of now, you're checking if the i suit is in the Array, and adding the top card to it.
The best course of action here would be ditching the for loop, replacing it with something like this:
while(ArrayList.size()){
/* code */
}
This will loop the array due to the way that top works, since it removes the top card
I'm trying to deal a card (the object) from my deck (the arraylist) and I'm having trouble trying to get the first object in the arraylist.
I've used a shuffle method (which is working and prints out the total number of cards in the newly shuffled pack) but I have no idea how to get the first object from the array (ie dealing a card from the top).
Can anyone point me in the right direction please?
Thanks.
Take a look at the ArrayList.get(int index) method. It'll return the object at the given position (index).
In your case, it'd be the yourList.get(0).
List#remove() will help:
List<String> cards = new ArrayList<>();
for (char suit : "♥♦♠♣".toCharArray())
for (char rank : "23456789TJQKA".toCharArray())
cards.add(String.valueOf(rank) + String.valueOf(suit));
Collections.shuffle(cards);
System.out.println(cards.remove(0)); // Q♥ //
I received the task of simulating a lottery draw in java. The program skeleton yields the method generateOneDraw, which creates 6 random numbers between 1 and 49
static int[] generateOneDraw() {
int numbers[] = new int[NUMBER_OF_ELEMENT_PER_DRAW];
for(int i=0; i<numbers.length; ++i) {
int nextNumber;
do {
nextNumber = generateNextRandomNumber();
} while(numberIsInArray(nextNumber, numbers));
numbers[i] = nextNumber;
}
return numbers;
}
We are then required to implement a function that simulates the lottery draw over 5 weeks and stores them in the variable draws. I believe this should be done over a two-dimensional array. Am I right in this way of thinking? Any pointers on implementing it would be greatly appreciated.
static void generateAllDraws()
Thanks in advance.
EDIT: Nevermind, I did it with a simple two dimensional array and it worked.
Since this seems like home work, I will not go into much detail but you can either:
Create a 2 dimensional list, as per your initial reasoning;
Create a Draw class which represents a lotto draw, and create multiple instances of this class. Each Draw class could have a Date which would denote when did the draw take place.
Both approaches should work, the second approach is a little more object oriented.
I am creating a old school game where the user has to collect the falling objects. Currently I have an image that is printed to the GraphicsContext several times accross the pane and is added and removed from an arrayList() when it disappears off of the screen. I can create a random number and I can print this to the same position as the falling image. However the random number is always the same and I want the number to be different on each of the objects. My code in my start method is as follows:
int i;
for(i=0;i<800; i+=90)
arrayList.add(new Object(ImageView, noOnImage, i,-10));
I then also have an update method where the objects are continously redrawn:
int newObject = 0;
Iterator<Object> objectIterator = object.iterator();
while(objectIterator.hasNext())
{
Object ob = objectIterator.next();
if(ob.move())
{
objectIterator.remove();
newObject++;
}
gc.drawImage(ob.objectImage,ob.r.getX(), ob.r.getY(), ob.r.getWidth(),
ob.r.getHeight());
gc.fillText(String.valueOf(noOnImage), ob.r.getX()+8, ob.r.getY()+22);
}
noOneImage is just a randomly generated number that I declared at the top. I would like each object to contain a different random value, currently they are all the same though, even though it is random.
When you create the object, pass in the random number within your loop.
Random rand = new Random()
arrayList.add(new Object(ImageView, noOnImage, i,-10, rand.nextInt(0, 10)));
That rand will give you a number between 0 and 10. You can put whatever int you want in there.
And make sure the object you create has the field and you are able to retrieve this number (e.g. for a score tally, etc.).
I am a complete beginner with Java and am having trouble understanding how to pass objects around between classes and methods. I have made some progress, however my app now fails when I try to create playing cards inside a for loop. It works fine if I remove the loop. Here is the first part of the class that contains the error:
public class Testing
{
public static void main(String[] args)
{
int Deal = 1;
for(int Hand = 0; Hand < Deal; ++Hand)
{
//instantiate and derive values for Player
Card card1 = new Card();
card1.setSuit(); //assign card 1's suit
card1.setValue(); //asign card 1's value
//instantiate and derive values for Computer
Card card2 = new Card();
card2.setSuit(); //assign card 2's suit
card2.setValue(); //assign card 2's suit
//compare the two cards and make sure they are different
cardCompare(card1,card2);
}
//output the two cards to the screen
output(card1,card2);
}
This is the error I get:
Testing.java:26: error: cannot find symbol
output(card1,card2);
^
symbol: variable card1
location: class Testing
Testing.java:26: error: cannot find symbol
output(card1,card2);
^
symbol: variable card2
location: class Testing
2 errors
Since the code works if I remove the for loop, I'm assuming that somehow the names card1 and card2 are not visible outside the loop? If I wanted to create ten or twenty cards, I'd want to do that in a loop, so I must be missing something about instantiating new objects and using them elsewhere in the program.
Thanks for your help.
**Update: thanks for the initial feedback. I see now that if I move my instantiate statements outside the for loop, I could theoretically assign new values for those objects over and over again using a loop, which is all I need to complete this particular task.
I'm still curious though, is it not possible to instantiate new objects inside a loop, but still use them outside the loop? It seems like this must be possible somehow.
public class Testing
{
public static void main(String[] args)
{
int Deal = 1;
//instantiate and derive values for Player
Card card1 = new Card();
//instantiate and derive values for Computer
Card card2 = new Card();
for(int Hand = 0; Hand < Deal; ++Hand)
{
card1.setSuit(); //assign card 1's suit
card1.setValue(); //asign card 1's value
card2.setSuit(); //assign card 2's suit
card2.setValue(); //assign card 2's value
//compare the two cards and make sure they are different
cardCompare(card1,card2);
}
//output the two cards to the screen
output(card1,card2);
}
The card1 and card variables are declared inside the for loop and is thus only visible inside of the loop. To use it outside of the loop, you must declare it before the loop. Please read up on Java scoping rules.
Both card1 and card2 are in scope of the for loop, not the rest of main(). Move your initialization to before the for.
Well, as it stands, its going to keep trying to overwrite card1 and card2 since you'll both declare and initialize them "deal" times. Additionally, and more importantly, they'll be out of scope. Instead, declare it beforehand and only initialize them inside the loop.
What you probably want here is:
public class Testing
{
public static void main(String[] args)
{
int Deal = 1;
ArrayList<Card> playerCards = new ArrayList<Card>();
ArrayList<Card> computerCards = new ArrayList<Card>();
//instantiate and derive values for Player
Card card1;
//instantiate and derive values for Computer
Card card2;
for(int Hand = 0; Hand < Deal; ++Hand)
{
card1 = new Card();
card1.setSuit(); //assign card 1's suit
card1.setValue(); //asign card 1's value
card2 = new Card();
card2.setSuit(); //assign card 2's suit
card2.setValue(); //assign card 2's value
//compare the two cards and make sure they are different
cardCompare(card1,card2);
playerCards.Add(card1);
computerCards.Add(card2);
}
//output the two cards to the screen
output(card1,card2);
}
Haven't tested it, but it should work.
You also need to rethink your use of your Output method, too. Since you're going to have ~20 cards per person, when do you think you need to show them to the user? Currently, you have it outside of the for loop, so it's only going to display the LAST value assigned to each one. If you want to show them each card they're getting, put the output call inside the for loop, and maybe use Thread.Sleep() to pause the program for a half second or so so that they can see each card they get. That, or write an overload of output that accepts an ArrayList of cards, and prints all of them at the same time. Once again, if you need help with that, ask me.
By the way, im not sure what cardcompare() is really doing behind the scenes, but you probably want to make it return a bool representing whether or not they were different. something like:
bool areCardsDistinct = cardcompare(card1,card2);
That way, you can use the result to decide whether or not to get random new cards again