Reputation:
I'm a beginner with Java:
for (int i = 0; i <= 4; i++) {
taken = false;
spun = wheel.spinWheel();
for (PrizeCard a : playerOne) {
if (spun.getID() == a.getID()) {
taken = true;
}
}
if (!taken) {
playerOne.add(spun);
} else {
i--;
}
}
For this code I am trying to pick out objects from another arraylist randomly and add it to the arraylist known as playerOne. However, the arraylist playerOne cannot hold the same object again (each object different by thier ID number, that is what the method .getID() returns).
So what I have believe should work, spinWheel() is the method that randomly returns an object, then it goes through each object and checks it's ID with previous one, if it is the same, it will not add the object and spin one more because I subtracted one from the variable i.
Any help would be greatly appreciated, thanks!
Clarification if needed:
If I have an arraylist named holder:
["Hello", "Dinosaur", "Chicken"]
And another arraylist named list2:
[]
How would I make it so I randomly get values from holder, add it to list2, but make sure that I only add it if it is not already added.
For instance, if I add "Chicken", it will never add "Chicken" into list 2 again.
Here is the other methods:
import java.util.*;
import java.lang.*;
public class GameWheel {
private ArrayList<PrizeCard> prizeCards;
private int currentPos;
public GameWheel() {
prizeCards = new ArrayList<PrizeCard>();
currentPos = 0;
prizeCards = initGameWheel();
prizeCards = scramble();
}
public ArrayList<PrizeCard> initGameWheel() {
ArrayList<PrizeCard> init = new ArrayList<PrizeCard>();
for (int i=1; i <= 40; i++) {
if (i%2 == 1)
init.add(new PrizeCard(i, "red", i*10));
else if (i%10 == 0)
init.add(new PrizeCard(i, "black", i*200));
else
init.add(new PrizeCard(i, "blue", i*100));
}
return init;
}
public ArrayList<PrizeCard> getPrizeCards() {
return prizeCards;
}
public PrizeCard spinWheel() {
int power = (int)(Math.random()*100 + 1);
int newPos = (currentPos + power) % prizeCards.size();
currentPos = newPos;
return prizeCards.get(currentPos);
}
}
public class PrizeCard {
private int id;
private String color;
private int prizeAmount;
public PrizeCard() {
id = 0;
color = "red";
prizeAmount = 0;
}
public PrizeCard(int nID, String nColor, int nPrizeAmount) {
id = nID;
color = nColor;
prizeAmount = nPrizeAmount;
}
public int getID() {
return id;
}
public int getPrizeAmount() {
return prizeAmount;
}
public String toString() {
return "ID: " + id +
", Color: " + color +
", Prize Amount: $" + prizeAmount;
}
}
Upvotes: 0
Views: 113
Reputation: 1168
Use a Set
, which allows only unique values.
Don't forget to override equals()
and hashCode()
.
You can check if the object is in the Set
by calling someSet.contains(element)
.
Upvotes: 1
Reputation: 380
Okay, so I'm not quite sure exactly what you're asking for. If you're looking for a more efficient way of testing to see if the player already has the prize, a HashSet
is by far your best bet. You no longer have to iterate through all of the PrizeCard
objects in playerOne
, you can just check to see if the spun
object is in the set.
HashSet<PrizeCard> prizes = new HashSet<PrizeCard>();
for (int i=0; i<=4; i++) {
do{
spun=wheel.spinWheel();
}while(prizes.contains(spun));
prizes.add(spun);
}
However, this still begs the question of how spinWheel()
works. Because if it's accessing an ArrayList
at random indices that's some pretty bad efficiency, because you're having to loop through over and over until you happen upon an index you haven't accessed. Not too terrible with only five slots, but what if you have five hundred? What if you have a list of prizes that contains duplicates? An infinite loop risk is what happens! I would "shuffle" the prizes on method creation, put them in a Stack
, and then pop the stack every time. Doing so you can get rid of that nested do{ ... } while(...);
public class Wheel{
Stack<PrizeCard> prizes;
public Wheel(){
prizes = new Stack<PrizeCard>();
//populate prizes here
}
public PrizeCard spinWheel(){
return prizes.isEmpty() ? null : prizes.pop();
}
}
Granted, a Stack
might not be exactly what you're going for, especially if you're planning on reusing it. In that case I would store them in a PrizeCard
array. You could also do a shuffle algorithm and put it in a reset()
method.
PrizeCard[] prizeCards; //populated in constructor
public void reset(){
for(int i = 0; i < prizeCards.length; i++){
swap(i, rand.nextInt(prizeCards.length)); //There are better shuffle algorithms for the record
}
}
private void swap(int i, int j){
PrizeCard temp = prizeCards[i];
PrizeCard[i] = PrizeCard[j];
PrizeCard[j] = temp;
}
Just don't call reset()
unless you're okay with duplicates potentially surfacing (which you could just re-implement that do{ ... }while( ... );
to fix).
Last, fun fact, you can take if(notTaken==true)
and chop off the ==true
bit, the if statement is just evaluating a boolean, checking if a boolean is true is redundant, as it just returns true or false. Something that took me about a half a year to pick up on, so I'll save you some time :)
Upvotes: 1