I have implemented a cardgame and need to test the shuffle method. I am using netbeans 7.2 and am now having a problem because the deckBeforeShuffle is empty after i call the instance.shuffleDeck method so I cant compare it with my deckAfterShuffle array to see if it is shuffled! Its the first time I am using JUnit and have tried different ways to fix this but it has all been in vain.
#Test
public void testShuffleDeck() {
System.out.println("shuffleDeck");
CardDeck instance = new CardDeck(1);
ArrayList<Card> deckBeforeShuffle = instance.getDeck();
instance.shuffleDeck();
ArrayList<Card> deckAfterShuffle = instance.getDeck();
boolean isShuffled = false;
int position = 0;
System.out.println(deckBeforeShuffle.size());
while(position<deckBeforeShuffle.size() && !isShuffled){
if(deckBeforeShuffle.get(position).getSuitValue() != deckAfterShuffle.get(position).getSuitValue() && deckBeforeShuffle.get(position).getvalue() != deckAfterShuffle.get(position).getvalue()){
isShuffled = true;
}
position++;
}
assertEquals(true, isShuffled);
}
My shuffle method!
public void shuffleDeck(){
ArrayList<Card> temp = new ArrayList();
Random rand = new Random();
int position;
while(deck.size() > 0){
position = rand.nextInt(deck.size());
temp.add(deck.remove(position));
}
deck = temp;
}
I appreciate any help!
actually it would suffice to to check for non-equality. the List's equals() method will take care of the rest.
assertFalse(deckBeforeShuffle.equals(deckAfterShuffle)); // not equal
assertEquals(deckBeforeShuffle.size(), deckAfterShuffle.size()); // but same size
assertEquals( // and same number of elements
new HashSet<Card>(deckBeforeShuffle), new HashSet<Card>(deckAfterShuffle);
And for the shuffling, you can use the existing Collections.shuffle() method. Beware, however that you have to make a copy of the list before shuffling it.
As described in this answer (and in many other sources around the Internet), there's assertArrayEquals(), which does exactly that.
Related
In c++ permutations of an array can be generated using the function next_permutation. Is there a java equivalent of such a function to generate permutations of a size N array?
I am trying to come up with an equivalent recursive implementation but am struggling to solidify my logic.
There isn't a built-in function like this in java. You'll have to create your own, which is not that complicated. I'll provide an edit to this answer momentarily with a solution (not necessarily the best solution)
public static void printperms(int[] perm, boolean[] used, int k)
{
if (k == perm.length) print(perm);
for (int i=0; i<perm.length; i++) {
if (!used[i]) {
used[i] = true;
perm[k] = i;
printperms(perm, used, k+1);
used[i] = false;
}
}
}
you can then create a new method, like so, to call it:
public void perms(int n){
printperms(new int[n], new boolean[n], 0);
}
Lastly, where I have the print method, you can have the Array added to a list instead so that you can collect them all in a list, or you can just print it out. Your choice. Do with it as you please.
The idea is if i am at a certain stair i can either go one step down or two so if am at stair 3 i can go down 1 1 1 or 2 1 for example. My code should print all the possibilities. The error I get is that I can't convert the add function to an array (since the add method is a boolean). What is wrong with this algorithm?
public class Stairs {
public static void staircase (int height ){
ArrayList<Integer> Array = null;
explore (height,Array);
}
public static void explore(int objheight,ArrayList<Integer>Array){
int intialheight = 0;
if (intialheight == objheight){
Array.toString();
}
else{ if (objheight > intialheight ){
explore(objheight-2,Array.add(2));
explore(objheight-1,Array.add(1));
}
}
after your feedback I am getting an empty output
import java.lang.reflect.Array;
import java.util.ArrayList;
public class Stairs {
public static void staircase (int height ){
ArrayList<Integer> Array = new ArrayList<Integer>();
explore (height,Array);
}
public static void explore(int objheight,ArrayList<Integer>Array){
int intialheight = 0;
if (intialheight == objheight){
Array.toString();
}
else{ if (objheight > intialheight ){
Array.add(2);
explore(objheight-2,Array);
Array.add(1);
explore(objheight-1,Array);
}
}}
public static void main (String args[]){
staircase(3);
}
}
The method add(E e) in ArrayList returns true upon appending the element e passed as a parameter to the end of the ArrayList.
Your method, explore(int objHeight, ArrayList<Integer> Array) does not accept a boolean for its second parameter. Yet, in that same method, explore, you are recursively calling explore and passing in a boolean to the method.
The following code should be modified to first invoke the add method of Array and then pass Array to the explore method.
Before:
explore(objheight-2,Array.add(2)); This code is passing parameters int and boolean to the explore method, which is not the parameters it accepts. You should instead attempt the following.
After:
Array.add(2);
explore(objheight-2,Array); This code first adds 2 to the Array and then passes the Array to the explore method without invoking any further methods on the Array object.
You will also need to do this for the next line of code, where you have explore(objheight-1,Array.add(1));.
Edit: Upon further examination of the code, I discovered another (sooner) error that occurs. A NullPointerException will occur each time the program runs:
ArrayList<Integer> Array = null;
explore (height,Array);
Then inside the explore method, different methods on Array are invoked, despite Array always being null:
Array.toString();, Array.add(2) and Array.add(1).
The Array object must be initialized inside of either the staircase or explore methods.
ArrayList<Integer> Array = new ArrayList<Integer>(); or ArrayList<Integer> Array = null;
Array = new ArrayList<Integer>();
So I have been creating this simple poker game in java. I have Created a deck of cards (The cards are objects that consist of a string and integer) and array lists to represent your hand and the dealers hand. Once I have cards in the yourHand array, how can I create a way to check for different suits? I want to keep it simple like having it only check for pairs and 3 of a kind. How can I approach this? The way I think it may be done, is to create a loop that will check each element in the array, and see if any of those elements are equal to another. But that seems easier said then done as I really don't understand how I would do that. And then the idea comes up, would it be an issue to do it that way since the card objects are of type String AND integer? I'm new to programming and will appreciate any help. Thanks! (also, let me know if you guys would like to see my code that sets up the card objects, which I have in a different class)
public class pokerMain implements StackInterFace {
public static void main (String [] args){
ArrayList<String> suits = new ArrayList<String>();//array list for the card suits
ArrayList<Integer> val = new ArrayList<Integer>();//array list for card values
ArrayList<CARDS> newCards = new ArrayList<CARDS>();//array list for cards with assigned val/suits
ArrayList<CARDS> yourHand = new ArrayList<CARDS>();//array list for your hand
ArrayList<CARDS> dealerHand = new ArrayList<CARDS>();//array list for the dealer's hand
Stack<CARDS> deck = new Stack();//Stack to represent deck
suits.add("Clubs");//These are the suits, added to the suits ArrayList
suits.add("Hearts");
suits.add("Diamonds");
suits.add("Spades");
System.out.println("suits contains: " + suits );//Testing for suit
for(int i = 1; i <= 13; i ++){//loop that adds all 13 values to to the val ArrayList
val.add(i);
}
System.out.println("val contains " + val);//Testing for val
for(Integer i : val) {//second attempt of adding objects to newCards
for(String s : suits) {
newCards.add(new CARDS(s, i));
}
}
System.out.println("the full deck contains: ");
System.out.println(newCards.toString());//prints newCards arrayList
Collections.shuffle(newCards);//shuffles array newCards
System.out.println("When shuffled this is what is in the deck");
System.out.println(newCards.toString());//prints shuffled array
deck.addAll(newCards);//adds newCards into the decks stack
System.out.println("Test print stack");
System.out.println(deck.toString());//prints stack as test
System.out.println("You pulled a " + deck.pop());//test pulling card from deck
for(int i = 0; i < 5; i ++){//loop to draw cards and put into hand
yourHand.add(deck.pop());
}
for(int i = 0; i < 5; i ++){//loop to draw cards and put into hand
dealerHand.add(deck.pop());
}
System.out.println("Please draw your cards");
System.out.println("Your hand contains:");
System.out.println(yourHand.toString());
for(int i = 0; i < yourHand.size(); i ++){//loop to check for pairs
}
}
#Override
public Object pop() {
// TODO Auto-generated method stub
return null;
}
#Override
public Object peek() {
// TODO Auto-generated method stub
return null;
}
#Override
public boolean isEmpty() {
// TODO Auto-generated method stub
return false;
}
#Override
public void clear() {
// TODO Auto-generated method stub
}
#Override
public void push(ArrayList newCards) {
// TODO Auto-generated method stub
}
#Override
public void addAll(ArrayList newCards) {
// TODO Auto-generated method stub
}
}
One simple way is to sort the cards by face value. That makes it easy to find N of the same values in a row.
I don't write java, so this is probably full of syntax errorrs, but do something like:
class CardFaceComparartor implements Comparator<CARD>
public int compare(CARD a, CARD b) {
return a.getFaceval() - b.getFaceaval;
}
}
...
Collections.sort(yourHand, CardFaceComparator);
int numSame=1;
int sets[4] = {0,0,0,0} //counts singles, pairs, ...
bool maybeFlush=True;
for (i=0; i<yourHand.size()-; i++) {
if (yourHand[i].getFaceval()== yourHand[i-1].getFaceval())
numSame+=1;
else {
sets[numSame]+=1;
numSame = 1;
}
maybeFlush = maybeFlush & (yourHand[i].getSuit() == yourHand[i-1.getSuit());
}
// now you have all the info to find best hand.
Consider this example of using a Comparator and the Collections utils:
public static final Comparator comparator = new Comparator<Card>() {
#Override
public int compare(Card cardOne, Card cardTwo) {
return cardOne.getFaceVal().compareTo(cardTwo.getFaceVal());
}
};
/* Later on we can then use the comparator object to sort! */
Collections.sort(cards, comparator);
Make the fields of your Card object have type String for Suit, and of type Integer for value. Then the above code can be applied to sort a particular ArrayList that contains Card objects such as your hand, or the dealers hand, etc.. What you gain from this is checking for straights, pairs, etc can be optimized and easier since everything is in ascending order.
Here is an example of a hand before sort:
5, 4, Q, 5, 2
Without the sort, you can see checking for a straight is very hard to while then also needing to find pairs... The algorithm would be to see you have a 5, and check for a straight like [5,6,7,8,9] by looking through the rest of the cards, and that is difficult to also keep track of pairs. The logic would get very messy in code, and hard to test or have someone else read. By sorting it we would get
2, 3, 4, 5, 5
We can, in one scan, see there is no straight as well as finding pairs. We know to expect the subsequent card to be just one value greater than the last card, and if it's not no straight can exist. If it's the same value it's a pair! More logic is involved at well for finding a three of a kind, 4 of a kind, etc.. but I'll leave that exercise up to you!
There will be edge cases for an Ace though, as it in some games can be used in sequence with 2, 3, 4, 5 to be a straight.. You didn't say what poke game you were making. Also ensure to consider J-A to be 11-14 respectively.
In my Java program's constructor I have the following:
thirdRow.add(button);
button.setActionCommand("Sumbit");
button.addActionListener(this);
And here is the corresponding actionPerformed method that's supposed to take 3 values from some textfields and store them into arrays:
public void actionPerformed(ActionEvent e)
{
String arg = e.getActionCommand();
if (arg == "Submit")
{
//enlarge arrays
qtyStr = enlargeArray(qtyStr);
typeStr = enlargeArray(typeStr);
colorStr = enlargeArray(colorStr);
//add from textfields into current
qtyStr[qtyStr.length-1] = qty.getText();
typeStr[typeStr.length-1] = type.getText();
colorStr[colorStr.length-1] = color.getText();
}
}
//method to enlarge an array by 1
public String[] enlargeArray(String[] currentArray)
{
String[] newArray = new String[currentArray.length + 1];
for (int i = 0; i<currentArray.length; i++)
newArray[i] = currentArray[i];
return newArray;
}
When I run the application, populate the textfields, and click the submit button nothing happens. How can I verify that my string arrays are being appended like they're supposed to?
You've a problem here: if (arg == "Submit")
Don't compare Strings using ==. Use the equals(...) or the equalsIgnoreCase(...) method instead. Understand that == checks if the two objects are the same which is not what you're interested in. The methods on the other hand check if the two Strings have the same characters in the same order, and that's what matters here. So instead of
if (fu == "bar") {
// do something
}
do,
if ("bar".equals(fu)) {
// do something
}
or,
if ("bar".equalsIgnoreCase(fu)) {
// do something
}
Also, for safety's sake, I try to use String constants wherever possible so as not to be tripped up by misspellings.
If you want to do your code this way, I would probably do two things:
1) maintain index fields for each array for the next free index, and
2) I wouldn't recommend resizing your array by 1 each time, as our current code is running through the array 2 n times (n = array length), 1st to initialize the array, and 2nd to create a new array.
Two options to optimize thisL one would be be to look into the Arrays class. it contains methods such as Array.copyOf() that can perhaps be useful here. You could also check if the array is full, and if it is then resize it by a number greater than one to reduce extra work.
For instance:
import java.util.Arrays;
class Test{
private String[] a;
private int next;
public Test(int size){
a = new String[size];
next = 0;
}
public void add(String s){
if(next == a.length){
Arrays.copyOf(a, a.length+1);
}
a[next] = s;
next++;
}
}
The easiest way would be to use an ArrayList (or any class that implements the java.util.List interface), as previously mentioned by Jon Skeet - it will do all the work for you.
Ok, here is the code and then the discussion follows:
public class FlatArrayList {
private static ArrayList<TestWrapperObject> probModel = new ArrayList<TestWrapperObject>();
/**
* #param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
int [] currentRow = new int[10];
int counter = 0;
while (true) {
for (int i = 0; i < 10; i++) {
currentRow[i] = probModel.size();
}
TestWrapperObject currentWO = new TestWrapperObject(currentRow);
probModel.add(counter, currentWO);
TestWrapperObject testWO = probModel.get(counter);
// System.out.println(testWO);
counter++;
if (probModel.size() == 10) break;
}
// Output the whole ArrayList
for (TestWrapperObject wo:probModel) {
int [] currentTestRow = wo.getCurrentRow();
}
}
}
public class TestWrapperObject {
private int [] currentRow;
public void setCurrentRow(int [] currentRow) {
this.currentRow = currentRow;
}
public int [] getCurrentRow() {
return this.currentRow;
}
public TestWrapperObject(int [] currentRow) {
this.currentRow = currentRow;
}
}
What is the above code supposed to do? What I am trying to do is load an array as a member of some wrapper object (TestWrapperObject in our case). When I get out of the loop,
the probModel ArrayList has the number of elements it is supposed to have but all have the same value of the last element (an array of size 10 with each item equal to 9). This is not the case inside the loop. If you perform the same "experiment" with a primitive int value everything works fine. Am I missing something myself regarding arrays as object members? Or did I just encounter a Java bug? I am using Java 6.
You are only creating one instance of the currentRow array. Move that inside the row loop and it should behave more like you expect.
Specifically, the assignment in setCurrentRow does not create a copy of the object, but only assigns the reference. So each copy of your wrapper object will hold a reference to the same int[] array. Changing the values in that array will make the values appear to change for all other wrapper objects that hold a reference to the same instance of the array.
i don' t want to sound condescending, but always try to remember tip #26 from the excellent pragmatic programmer book
select isn't broken
it is very rare to find a java bug. keeping this in mind often helps me to look over my code again, turn it around, and shake out the loose bits until i finally discover where i was wrong. of course asking for help early enough is very encouraged, too :)