Warning

 

Close

Confirm Action

Are you sure you wish to do this?

Confirm Cancel
BCM
User Panel

Site Notices
Posted: 2/19/2017 11:41:28 PM EDT
trying to reacquaint myself, went through java 2x as CS1 and CS2 back in undergrad n like 2002, pretty much forgot everything.  Have pretty much gone through a complete udemy course in java its like 119 lessons its a great refresher.

so now im trying to do a self-directed mini project, creating a deck of cards.  2 classes, a Card class and a Deck class.  and a 3rd file for the main() which is extremely simple that just creates the deck and then displays it.  I can create the deck which has a constructor and also 1 public method: displayDeck().  Deck's constructor calls Cards constructor and also Card's setCard() method.  But for some reason I get null pointer exception inside Deck's displayDeck method, on statement "System.out.println(Cards[ctr].toString());".  That Cards[52] object is created by the Deck constructor and also accessed and edited by Deck's constructor, but for some reason that Cards[52] object gives that null pointer exception.  I cant see any reason why it thinks its null.  any help?


public class Card {

private int name;
private int suite;

public Card() {
name = 0;
suite = 0;
}

public void setCard(int n, int s) {
if (n > -1 && n < 13 && s > -1 && s < 4) {
name = n;
suite = s;
}
name = 0;
suite = 0;
}

public String toString() {
if (name == 0 || suite == 0) {
return "NOT INIT";
}
else {
String output = new String();
if (name == 0) output = "Two of ";
else if (name == 1) output = "Three of ";
else if (name == 2) output = "Four of ";
else if (name == 3) output = "Five of ";
else if (name == 4) output = "Six of ";
else if (name == 5) output = "Seven of ";
else if (name == 6) output = "Eight of ";
else if (name == 7) output = "Nine of ";
else if (name == 8) output = "Ten of ";
else if (name == 9) output = "Jack of ";
else if (name == 10) output = "Queen of ";
else if (name == 11) output = "King of ";
else if (name == 12) output = "Ace of ";

if (suite == 0) output += "Hearts ";
else if (suite == 1) output += "Diamonds ";
else if (suite == 2) output += "Clubs ";
else if (suite == 3) output += "Spades";
return output;
}
}
}


import java.util.Random;

public class Deck {

public Card[] Cards;

public Deck() {

Card[] Cards = new Card[52];
boolean [][] cardPos = new boolean[13][4];
for (int i = 0; i < 13; ++i) {
int ctr = 0;
for(int j = 0; j < 4; ++j) {
cardPos[i][j] = false;
Cards[ctr] = new Card();
Cards[ctr].setCard(0, 0);
ctr++;
}
}
Random rnd = new Random(System.currentTimeMillis());

boolean stopShuffle = false;

System.out.println("Shuffling: ");
int randPicks = 0;
do {
int ctr = 0;
int rnd1 = rnd.nextInt(13);
int rnd2 = rnd.nextInt(4);
System.out.print("*");
if (++randPicks % 10 == 0)
System.out.println();
if (cardPos[rnd1][rnd2] == false) {
cardPos[rnd1][rnd2] = true;
stopShuffle = true;
Cards[++ctr].setCard(rnd1, rnd2);

for (int i = 0; i < 13; ++i)
for(int j = 0; j < 4; ++j)
if (cardPos[i][j] == false)
stopShuffle = false;
}
} while (!stopShuffle);
System.out.println("\n" + randPicks);
}

public void displayDeck() {
for (int ctr = 0; ctr < 52; ++ctr) {
System.out.println(ctr);
System.out.println(Cards[ctr].toString());
}
}
}



public class Play {

public static void main(String[] args) {
Deck myDeck = new Deck();
myDeck.displayDeck();
}
}
Link Posted: 2/20/2017 12:02:42 AM EDT
[#1]
Should be:

for (int ctr = 0; ctr < 52; ctr++) {

In all of the for loops.  That's not the problem, but it's convention.z
Link Posted: 2/20/2017 12:07:07 AM EDT
[#2]
you know right after I posted OP, i realized all my preincs should be postincs.  not just in the for loops but also elswhere i had tone preincs,  so I went and adjusted everything accordingly, and modified code that needed it after changing to postincs.  still same problem.

for some reason, maybe, Cards[] object that is declared as public in the Deck class and in the constructor in that Deck class and that is created in the constructor, just doesnt seems to exist in the displayDeck method I wrote as part of that Deck class.

in fact i took out all the postincs and have incrementors as completely isolated lines, same issue.

I think Eclipse is giving me a HUGE clue here, im just not smart enough to understand what it means: in the constructor method, any reference to "Cards" is in regular colored font.  in my apparently fubarred method displayDeck, its in color blue.  I just dont dont know what that means, but im sure thats the hint.  Just up at the top of the class itself, my "public Card[] Cards;" statement has "Cards" in that same blue color.  that doesnt seem to be a problem tho since the constructor is making my 52 cards.

import java.util.Random;

public class Deck {

public Card[] Cards;

public Deck() {

Card[] Cards = new Card[52];
boolean [][] cardPos = new boolean[13][4];
for (int i = 0; i < 13; i++) {
int ctr = 0;
for(int j = 0; j < 4; j++) {
cardPos[i][j] = false;
Cards[ctr] = new Card();
Cards[ctr].setCard(0, 0);
ctr++;
}
}
Random rnd = new Random(System.currentTimeMillis());

boolean stopShuffle = false;

System.out.println("Shuffling: ");
int randPicks = 0;
do {
int ctr = 0;
randPicks++;
int rnd1 = rnd.nextInt(13);
int rnd2 = rnd.nextInt(4);
System.out.print("*");
if (randPicks % 10 == 0) {
System.out.println();
}

if (cardPos[rnd1][rnd2] == false) {
cardPos[rnd1][rnd2] = true;
stopShuffle = true;
Cards[ctr].setCard(rnd1, rnd2);
ctr++;

for (int i = 0; i < 13; i++) {
for(int j = 0; j < 4; j++) {
if (cardPos[i][j] == false) {
stopShuffle = false;
}
}
}
}
} while (!stopShuffle);
System.out.println("\n" + randPicks);
}

public void displayDeck() {
for (int ctr = 0; ctr < 52; ctr++) {
System.out.println(ctr);
System.out.println(Cards[ctr].toString());
}
}
}
Link Posted: 2/20/2017 12:45:04 AM EDT
[#3]
I'm not a Java dev, (C# here).

Your problem is that you're not initializing Deck's 'Cards' field. Instead you're creating a local variable of the same name in the Deck constructor.
In C# we have different variable casing/convention for member variables vs local variables--this would have helped you catch this problem more easily.
Link Posted: 2/20/2017 12:45:21 AM EDT
[#4]
Copied it into Visual Studio to compile as C# (with a few slight modifications).

It looks like your first definition of ctr is not defined in the correct spot given how your code is laid out. Where it is now, you will not fill all 52 cards.
You'll reset it to zero every 13 cards.

One suggestion which I think helps and goes a long ways: break your code out into more functions. This give you what I call clean code (well its from this guy Uncle Bob)-- and makes it near impossible for issues and bugs to hide.
On the plus side its even easier to read and maintain and reuse.
Link Posted: 2/20/2017 11:20:21 AM EDT
[#5]
Discussion ForumsJump to Quoted PostQuote History
Quoted:
I'm not a Java dev, (C# here).

Your problem is that you're not initializing Deck's 'Cards' field. Instead you're creating a local variable of the same name in the Deck constructor.
In C# we have different variable casing/convention for member variables vs local variables--this would have helped you catch this problem more easily.
View Quote


looks like this has got me a bit closer here - in java the constructor does not have any modifier such as private/public/protected - the constructor just has a name.  in my case i had the method i intended to use as constructor as "public".  I removed that "public" but still have same issue.  fro my understanding of java, and as demonstrates in my udemy lectures' exercises , whatever types you define as parts of the class are allocated and instantiated in the constructor, then all member methods of that class should have direct access to it (or this is how I understand it). so not sure what else is wrong here.

ok now my constructor is public, and i removed the 'new' statement from the class statement and only use "new" in the constructor.  this resolved eclipse from showing "Cards" in different colors, but still have the same issue.

I even have this failing:

import java.util.Random;

public class Deck {

public Card[] Cards;

public Deck() {

Cards = new Card[52];
for (int i = 0; i < 52; i++) {
Cards[i].setCard(0, 0);
}
}
}


that last statement throws a null exception.  i guess i just dont grasp how to declare and implement arrays in objects/constructors/classes
Link Posted: 2/20/2017 5:16:10 PM EDT
[#6]
That last bit of code will not work because you are not initializing any of the 52 cards. You are just attempting to call the setCard method on each Cards[i] (which are all null).


Heres my C# code that I was using (for reference)


public class Deck
   {

       public Card[] Cards;

       public Deck()
       {

           Cards = new Card[52];
           bool[,] cardPos = new bool[13,4];
           int ctr = 0;
           for (int i = 0; i < 13; ++i)
           {
               for (int j = 0; j < 4; ++j)
               {
                   cardPos[i,j] = false;
                   Cards[ctr] = new Card();
                   Cards[ctr].setCard(i, j);
                   ctr++;
               }
           }
           Random rnd = new Random(DateTime.Now.Millisecond);

           bool stopShuffle = false;

           Console.WriteLine("Shuffling: ");
           int randPicks = 0;
           do
           {
               ctr = 0;
               int rnd1 = rnd.Next(13);
               int rnd2 = rnd.Next(4);
               Console.WriteLine("*");
               if (++randPicks % 10 == 0)
                   Console.WriteLine();
               if (cardPos[rnd1,rnd2] == false)
               {
                   cardPos[rnd1,rnd2] = true;
                   stopShuffle = true;
                   Cards[++ctr].setCard(rnd1, rnd2);

                   for (int i = 0; i < 13; ++i)
                       for (int j = 0; j < 4; ++j)
                           if (cardPos[i,j] == false)
                               stopShuffle = false;
               }
           } while (!stopShuffle);
           Console.WriteLine("\n" + randPicks);
       }

       public void displayDeck()
       {
           for (int ctr = 0; ctr < 52; ++ctr)
           {
               Console.WriteLine(ctr);
               Console.WriteLine(Cards[ctr].toString());
           }
       }
   }




Are you using the debugger at all to set breakpoints? This will aid in your exploratory understanding.

In your setCard function, you always end up setting the two integers to zero. Also you can't use zero as a valid value and an uninitialized value (otherwise you'll never get any "Two of" or any "Hearts"), you could use -1 like below.
You might consider Enumerations instead of integers for your enumeration of kinds of cards (name and suit), then you get named things as well as not having an uninitialized Card.


public class Card
   {

       private int name = -1;
       private int suite = -1;
       
       public void setCard(int n, int s)
       {
           if (n > -1 && n < 13 && s > -1 && s < 4)
           {
               name = n;
               suite = s;
           }
       }

       public String toString()
       {
           if (name == -1 || suite == -1)
           {
               return "NOT INIT";
           }
           else {
               String output = "";
               if (name == 0) output = "Two of ";
               else if (name == 1) output = "Three of ";
               else if (name == 2) output = "Four of ";
               else if (name == 3) output = "Five of ";
               else if (name == 4) output = "Six of ";
               else if (name == 5) output = "Seven of ";
               else if (name == 6) output = "Eight of ";
               else if (name == 7) output = "Nine of ";
               else if (name == 8) output = "Ten of ";
               else if (name == 9) output = "Jack of ";
               else if (name == 10) output = "Queen of ";
               else if (name == 11) output = "King of ";
               else if (name == 12) output = "Ace of ";

               if (suite == 0) output += "Hearts ";
               else if (suite == 1) output += "Diamonds ";
               else if (suite == 2) output += "Clubs ";
               else if (suite == 3) output += "Spades";
               return output;
           }
       }
   }
Link Posted: 2/20/2017 5:18:04 PM EDT
[#7]
If you're on a Windows box, may I ask if you have considered C#?
They have a Community edition Visual Studio which is a great IDE to work with. The built in libraries are also really nice.

(But-- I'm bias )
Link Posted: 2/20/2017 5:37:35 PM EDT
[#8]
well im having to brush up on my java due to a MSCS class I have coming up that is all java stuff.

but in other news I figured it out.  you have to "touch" the variable 3x:  once in the class to define it is part of an object, and 2x in the constructor:  once to alloc it and then once again for each object in the array to actually construct it.  Thanks for your hint earlier on regarding me simply just reusing the name, that helped a lot in me figuring this out.

public class Deck {

Card[] Cards;

public Deck() {

Cards = new Card[52];
for (int i = 0; i < 52; i++)
Cards[i] = new Card();
View Quote


i still have that other issue you said though, about writing to zero.  im looking at that now.  thanks again
Link Posted: 2/20/2017 11:03:09 PM EDT
[#9]
No problem. Happy coding.
Link Posted: 2/21/2017 11:56:23 PM EDT
[#10]
well i finished my goal.  wrote an OO java program that creates a desk of cards, randomizes it, then deals it in to 2 player decks.  then the 2 players play war. had to make a recursive method to do it for cases if multiple chained battles.  it works well but i think there is some bug in it as very occasionally it just goes forever.  but this is as far as i go

public class Card {

String level;
String suit;

public Card () {
level = "";
suit = "";
}

public Card (String l, String s) {
level = l;
suit = s;
}

public String getLevel() {
return level;
}

public String showCard () {
return level.substring(1) + " of " + suit;
}
}


import java.util.ArrayList;
import java.util.Random;

public class Deck {
ArrayList<Card> cards;

public Deck() {
cards = new ArrayList<Card>();
}

public void load52() { // adds 52 standard cards into the deck, in order
String[] levels = new String[] {"ATwo", "BThree", "CFour", "DFive", "ESix", "FSeven", "GEight", "HNine", "ITen", "JJack", "KQueen", "LKing", "MAce"};
String[] suits = new String[] {"Hearts", "Diamonds", "Clubs", "Spades" };
for (String level :  levels)
for(String suit: suits)
cards.add(new Card(level, suit));
}

public void shuffle() { // randomize order of the cards
Random rnd = new Random(System.currentTimeMillis());
for (int i = cards.size(); i > 0; i--)
cards.add(cards.remove(rnd.nextInt(i)));
}

public void showDeck() { // print out all the cards
for (int i = 0; i < cards.size(); i++)
System.out.println(cards.get(i).showCard());
}
public Card showCard(int l) {
return cards.get(l);
}

public int cardsIn() { // get number of cards left in deck
return cards.size();
}

public Card takeCard() {
return cards.remove(0);
}

public void putCard(Card c) {
cards.add(c);
}
}


public class Game {

public static void main(String[] args) {

// create game deck and load it and shuffle
Deck myDeck = new Deck();
myDeck.load52();
myDeck.shuffle();

// create 2 player decks and divide cards
Deck p1 = new Deck();
Deck p2 = new Deck();
while (myDeck.cardsIn() != 0) {
p1.putCard(myDeck.takeCard());
p2.putCard(myDeck.takeCard());
}

// start playing war
int[] ctr = new int[2];
ctr[0] = 0; // this is number of battles that were played
ctr[1] = 0; // 1 = p1 our of cards, 2 = p2 out of cards
while (p1.cardsIn() != 0 && p2.cardsIn() != 0)
battle(p1, p2, 1, ctr);
ctr[0]--;
System.out.println(ctr[0] + " battles");
}

static void battle(Deck d1, Deck d2, int b, int[] c) {
//print scores for 2 players
System.out.println("p1: "  + d1.cardsIn());
System.out.println("p2: "  + d2.cardsIn() + "\n");

//check if players have enough cards
if (d1.cardsIn() < b || d2.cardsIn() < b) { // someone or both, out of cards
if (d1.cardsIn() < b) { //then take all d1 cards they lose
for (int ctr = 0; ctr < d1.cardsIn(); ctr++)
d1.takeCard();
} else {  //then take all d2 cards they lose
for (int ctr = 0; ctr < d2.cardsIn(); ctr++)
d2.takeCard();
}
} else { // ok they have enough cards, now compare cards and decide
c[0]++;
if (d1.showCard(b-1).getLevel().compareTo(d2.showCard(b-1).getLevel()) > 0) {
for(int ctr = 0; ctr < b; ctr++) {
d1.putCard(d1.takeCard());
d1.putCard(d2.takeCard());
}
} else if (d1.showCard(b-1).getLevel().compareTo(d2.showCard(b-1).getLevel()) < 0) {
for(int ctr = 0; ctr < b; ctr++) {
d2.putCard(d1.takeCard());
d2.putCard(d2.takeCard());
}
}
else { // if equal, then recurse to battle again
battle(d1, d2, b+4, c);
}
}
}
}
Link Posted: 3/8/2017 6:06:34 AM EDT
[#11]
I would not use recursion, just test and loop until you get a final outcome.  That should resolve your issue with the never ending program -- recursion is not often the best solution for something like this.
Link Posted: 3/8/2017 5:13:22 PM EDT
[#12]
hmm.  ok how about this?  are you saying its mathematically impossible for an overall game or war to last forever (tie)?  the rules i have set up here in main() dictate that suits mean nothing, and a tie is resolved by each player betting 3 additional cards where the higher of a 4th additional card takes all 10.  the recursion sets up possibility of strung battles, and a requirement of recursion is setting up the path for it to be able to stop, which I believe ive done, and *think* ive done correctly.  at least, most games (usually that do have single and multiple battles in them) *do* end.  and if the math says that for any entire game, that ties shouldnt happen, or shouldnt happen that often, then more than likely i have in fact done something wrong here.  but im not sure of the math there.

what you are describing of doing it w/o recursion removes the possibility of having to battle multiple multiple times per play, or at least past the number of times youd have to statically program into main(), which is a nightmare, and why i tried it with recursion.
Link Posted: 3/8/2017 9:52:07 PM EDT
[#13]
Discussion ForumsJump to Quoted PostQuote History
Quoted:
hmm.  ok how about this?  are you saying its mathematically impossible for an overall game or war to last forever (tie)?  the rules i have set up here in main() dictate that suits mean nothing, and a tie is resolved by each player betting 3 additional cards where the higher of a 4th additional card takes all 10.  the recursion sets up possibility of strung battles, and a requirement of recursion is setting up the path for it to be able to stop, which I believe ive done, and *think* ive done correctly.  at least, most games (usually that do have single and multiple battles in them) *do* end.  and if the math says that for any entire game, that ties shouldnt happen, or shouldnt happen that often, then more than likely i have in fact done something wrong here.  but im not sure of the math there.

what you are describing of doing it w/o recursion removes the possibility of having to battle multiple multiple times per play, or at least past the number of times youd have to statically program into main(), which is a nightmare, and why i tried it with recursion.
View Quote


You don't have to statically program it.  There is literally no algorithm anywhere that is recursively implemented that cannot be iteratively implemented -- and you remove many issues by doing it iteratively.  Recursion can make the code more concise, but I wouldn't use it for this algorithm.  

Give me some time to dump this into netbeans and I'll show you how I would do it.  You may not have done the recursion incorrectly -- but you can still run into problems with it at times.  Java sucks.  Maybe when I try to do it I'll figure out that recursion is better, but in my experience it's often better to iterate.
Link Posted: 3/10/2017 8:12:39 AM EDT
[#14]
I just finally got a few minutes to load this up into my IDE and build and run it -- the second time ran forever (until I stopped it) -- the problem with recursion is that you need very clear and well defined stop cases.  I'll be evaluating those cases closely as I get a little time, but from what I can tell you don't have your exit cases defined well enough or thoroughly enough.  Give me a little time and I'm going to rewrite it iteratively first, and then I'll go back and show the correct recursive cases once I figure out how the game is supposed to be played...
Link Posted: 3/10/2017 10:39:30 AM EDT
[#15]
Discussion ForumsJump to Quoted PostQuote History
Quoted:
I just finally got a few minutes to load this up into my IDE and build and run it -- the second time ran forever (until I stopped it) -- the problem with recursion is that you need very clear and well defined stop cases.  I'll be evaluating those cases closely as I get a little time, but from what I can tell you don't have your exit cases defined well enough or thoroughly enough.  Give me a little time and I'm going to rewrite it iteratively first, and then I'll go back and show the correct recursive cases once I figure out how the game is supposed to be played...
View Quote
you mean to tell me you never played that card game war as a kid????  you must be a lot younger than i thought.  though there are many different sets of rules that people can choose to use for the game.

i did do a bit of searching - apparently infinite games happen, and theres nothing that doing it with recursion or not doing it with recursion can help with that, also read that infinite games happen more frequently if you do not shuffle each deck after you run out of cards (which my program currently doesnt do.  in fact, the way I wrote it, it would be more complex than you'd think to shuffle your deck at the appropriate time, since im just sticking winnings at bottom of your deck instead of a new deck that you can shuffle and grab later).  im still not completely sure my algo for the game play is 100% correct though - i suck at proofs, got a C in discrete math and at that point promptly changed my major from CS to IT.  what i am doing now is never re-shuffling, just sticking any winnings at the bottom of deck, always in the same order.  in IRL games ive played there was never any shuffling after running out, but there was always a good bit of hysteresis injected by randomness of collecting the winnings such that the order you stack them at bottom of deck was a bit mixed up, and like i said, the program currently is never shuffling except at beginning of games, and for winnings just sticking them at bottom always in same order.
Link Posted: 3/10/2017 2:26:35 PM EDT
[#16]
Discussion ForumsJump to Quoted PostQuote History
Quoted:
you mean to tell me you never played that card game war as a kid????  you must be a lot younger than i thought.  though there are many different sets of rules that people can choose to use for the game.

i did do a bit of searching - apparently infinite games happen, and theres nothing that doing it with recursion or not doing it with recursion can help with that, also read that infinite games happen more frequently if you do not shuffle each deck after you run out of cards (which my program currently doesnt do.  in fact, the way I wrote it, it would be more complex than you'd think to shuffle your deck at the appropriate time, since im just sticking winnings at bottom of your deck instead of a new deck that you can shuffle and grab later).  im still not completely sure my algo for the game play is 100% correct though - i suck at proofs, got a C in discrete math and at that point promptly changed my major from CS to IT.  what i am doing now is never re-shuffling, just sticking any winnings at the bottom of deck, always in the same order.  in IRL games ive played there was never any shuffling after running out, but there was always a good bit of hysteresis injected by randomness of collecting the winnings such that the order you stack them at bottom of deck was a bit mixed up, and like i said, the program currently is never shuffling except at beginning of games, and for winnings just sticking them at bottom always in same order.
View Quote View All Quotes
View All Quotes
Discussion ForumsJump to Quoted PostQuote History
Quoted:
Quoted:
I just finally got a few minutes to load this up into my IDE and build and run it -- the second time ran forever (until I stopped it) -- the problem with recursion is that you need very clear and well defined stop cases.  I'll be evaluating those cases closely as I get a little time, but from what I can tell you don't have your exit cases defined well enough or thoroughly enough.  Give me a little time and I'm going to rewrite it iteratively first, and then I'll go back and show the correct recursive cases once I figure out how the game is supposed to be played...
you mean to tell me you never played that card game war as a kid????  you must be a lot younger than i thought.  though there are many different sets of rules that people can choose to use for the game.

i did do a bit of searching - apparently infinite games happen, and theres nothing that doing it with recursion or not doing it with recursion can help with that, also read that infinite games happen more frequently if you do not shuffle each deck after you run out of cards (which my program currently doesnt do.  in fact, the way I wrote it, it would be more complex than you'd think to shuffle your deck at the appropriate time, since im just sticking winnings at bottom of your deck instead of a new deck that you can shuffle and grab later).  im still not completely sure my algo for the game play is 100% correct though - i suck at proofs, got a C in discrete math and at that point promptly changed my major from CS to IT.  what i am doing now is never re-shuffling, just sticking any winnings at the bottom of deck, always in the same order.  in IRL games ive played there was never any shuffling after running out, but there was always a good bit of hysteresis injected by randomness of collecting the winnings such that the order you stack them at bottom of deck was a bit mixed up, and like i said, the program currently is never shuffling except at beginning of games, and for winnings just sticking them at bottom always in same order.


Never.  I'm older than you think, but I was in college at 12 and working full time by 14.  I can't remember a time that I was a child.  

You can prove a piece of code.  It gets very hard very quickly and when you toss recursion into the mix that difficulty rapidly goes towards infinity.

I found your error, I'll go over that later.  I'm going to post my solution in the next post.

BTW, I'll have to research the infinite game thing -- the rules I found seem that once you run out of cards (assuming you're just continuing down the line -- the game can't continue.  I guess it could go back and forth forever in some cases, I only ran about 20 or 30 test runs, I got to 900 rounds on one but they all ended eventually.
Link Posted: 3/10/2017 2:38:41 PM EDT
[#17]
Card.java

package cards;


public class Card {

   String level;
   String suit;

   public Card() {
       level = "";
       suit = "";
   }

   public Card(String l, String s) {
       level = l;
       suit = s;
   }

   public String getLevel() {
       return level;
   }

   public String showCard() {
       return level.substring(1) + " of " + suit;
   }
}



Cards.java (yeah, sue me.  I hate Java).


package cards;


/**
*
* @author josh
*/
public class Cards {


   static Game g;
   
   public static void main(String[] args) {
       
       
      g = new Game();

   }

}


player.java

/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package cards;

import cards.Deck;
import static java.lang.Boolean.FALSE;


/**
*
* @author josh
*/
public class Player {
   Deck d;
   Boolean win;
   
   public Player(){
       d = new Deck();
       win = FALSE;
   }
   
   public Deck returnDeck(){
       return (d);
   }//this is a hack, this method should never exist, I just don't feel like coding all the accessors for all the deck variables and methods right now
   
   
   public int returnScore(){
       return(d.cardsIn());
   }
 
   public Boolean returnWin(){
       return (win);
   }
   
   public void setWin(Boolean w){
       win = w;
   }
   
}


Deck.Java

package cards;

import java.util.ArrayList;
import java.util.Random;

public class Deck {

   ArrayList<Card> cards;

   public Deck() {
       cards = new ArrayList<Card>();
   }

   public void load52() { // adds 52 standard cards into the deck, in order
       String[] levels = new String[]{"ATwo", "BThree", "CFour", "DFive", "ESix",
           "FSeven", "GEight", "HNine", "ITen", "JJack", "KQueen", "LKing", "MAce"};
       String[] suits = new String[]{"Hearts", "Diamonds", "Clubs", "Spades"};
       for (String level : levels) {
           for (String suit : suits) {
               cards.add(new Card(level, suit));
           }
       }
   }

   public void shuffle() { // randomize order of the cards
       Random rnd = new Random(System.currentTimeMillis());
       for (int i = cards.size(); i > 0; i--) {
           cards.add(cards.remove(rnd.nextInt(i)));
       }
   }

   public void showDeck() { // print out all the cards
       for (int i = 0; i < cards.size(); i++) {
           System.out.println(cards.get(i).showCard());
       }
   }

   public Card showCard(int l) {
       return cards.get(l);

   }

   public int cardsIn() { // get number of cards left in deck
       return cards.size();
   }

   public Card takeCard() {
       return cards.remove(0);
   }

   public void putCard(Card c) {
       cards.add(c);
   }
   
   public ArrayList returnDeck(){
       return (cards);
   }
}



Game.java

package cards;

import static java.lang.Boolean.FALSE;
import static java.lang.Boolean.TRUE;

public class Game {

   Player player1;
   Player player2;
   int numberOfGames = 0;

   public Game() {
       player1 = new Player();
       player2 = new Player();
       // create game deck and load it and shuffle
       Deck myDeck = new Deck();
       myDeck.load52();
       myDeck.shuffle();

// create 2 player decks and divide cards
//player class instantiates a deck already, just need to fill it up with cards from the game deck
       while (myDeck.cardsIn() > 0) {
           player1.returnDeck().putCard(myDeck.takeCard());
           player2.returnDeck().putCard(myDeck.takeCard());
       }

       battle();

       System.out.println(numberOfGames + " battles");

   }

   public void battle() {
       Boolean gameOver = FALSE;
       int it = 0;

       while (!player1.win && !player2.win && !gameOver) {

           if (player1.returnDeck().cardsIn() > it && player2.returnDeck().cardsIn() > it) {


//What we're testing here is 1 -- do we have any cards, and 2 -- do we have enough cards to play the game anymore?
               if (player1.returnDeck().showCard(it).getLevel().compareTo(player2.returnDeck().showCard(it).getLevel()) > 0) {
                   System.out.println("Player 1: " + player1.returnDeck().showCard(it).showCard() + "  Player 2: " + player2.returnDeck().showCard(it).showCard());
                   for (int i = 0; i <= it; i++) {//do this as many times as we are iterations deep
                       System.out.println("Moving " + (it+1) + " cards from player 2 to player 1");
                       player1.returnDeck().putCard(player1.returnDeck().takeCard()); //move top card to bottom
                       player1.returnDeck().putCard(player2.returnDeck().takeCard()); //take player2's card

                   }
                   it = 0;

                   System.out.println("Player 1 Wins this round");
               } else if (player1.returnDeck().showCard(it).getLevel().compareTo(player2.returnDeck().showCard(it).getLevel()) < 0) {
                   System.out.println("Player 1: " + player1.returnDeck().showCard(it).showCard() + "  Player 2: " + player2.returnDeck().showCard(it).showCard());
                   for (int i = 0; i <= it; i++) {//do this as many times as we are iterations deep
                       System.out.println("Moving " + (it+1) + " cards from player 1 to player 2");
                       player2.returnDeck().putCard(player2.returnDeck().takeCard()); //move top card to bottom
                       player2.returnDeck().putCard(player1.returnDeck().takeCard()); //take player1's card
                   }
                   it = 0;
                   System.out.println("Player 2 Wins this round");
               } else {
                   System.out.println("Player 1: " + player1.returnDeck().showCard(it).showCard() + "  Player 2: " + player2.returnDeck().showCard(it).showCard());

                   //need to keep going because we've got to play some more, increment our round counter that tells us how many cards we are deep
                   it++;
                   System.out.println();
                   System.out.println("Nobody wins this round " + it + " number of rounds");
               }
               numberOfGames++;
           } else if (player1.returnDeck().cardsIn() <= it) {//player 1 cannot continue, player2 wins
               player2.setWin(TRUE);
               System.out.println("Player 2 Wins");
           } else if (player2.returnDeck().cardsIn() <= it) {  //player 2 cannot continue, player 1 wins
               player1.setWin(TRUE);
               System.out.println("Player 1 Wins");
           } else {
               //neither player has enough cards to continue -- what's the rule on this case?
               gameOver = TRUE;//using this as a default case -- it's not correct really.  Fix later
           }

       }
   }
}


Note that I made some different design decisions based on how I interpret OOP best practices over the years...  Keep in mind I am *not* a Java developer, most of what I've done is C++ / Fortran / Objective C / etc.  OO was something I learned at 35 after I'd been writing code for like 25 years in functional languages.  

It took me more time trying to dig up that one OO class I took where we used Java out of my brain to remember the little quirks here than doing the algorithm.  I used some of your code, but rewrote quite a bit also.  No recursion -- one of the things about proving correctness, recursion is pretty much *never* allowed.  You look at rts code or critical subsystem type code and you simply aren't allowed to do it, which is part of why I will almost always use an iterative solution.  The compiler is ultimately going to turn it into the same assembly, most likely, but you can prove an iterative solution where you may not be able to prove a recursive one.  And if the compiler doesn't turn it into the same thing you're screwed and you may get to spend many hours trying to debug something that ought to work perfectly but doesn't.

I hate recursion, in case you didn't notice.
Link Posted: 3/10/2017 7:57:02 PM EDT
[#18]
 aawesomesauce.  Give me some time to go over this.  I dont even know what package is

What do you hate more, java or recursion.  Youd really hate the recursion i did to score ncaa football team results.  1 pt for a win.  Half point for each beaten opponent win.  Quarter point for next level and so on. Routinely get 65 levels deep
Link Posted: 3/10/2017 8:21:52 PM EDT
[#19]
packages make it easier to work with in netbeans.  That's the default when you create a project, you don't have to import everything that's in the package -- just refer to it and it's automatically available.  

You can delete all the package stuff and just manually import to make it work if you do it in another IDE.

That code was written late last night as I was dealing with multiple stupid-Sailor-tricks so I won't vouch for it's perfection, I didn't even write tests for it so there may be an edge case where it breaks but I didn't get it to the few times I ran it (maybe 30 -- I got to 900+ rounds in one game).  The more I think about it, the odds of a perfect infinite game are so vanishingly small as to be probably up there like hitting the lottery multiple times in a row.  I think most humans might think they hit an infinite game, but probably just because they wouldn't have the patience to run 900 rounds of it.

It's not such a huge deal now, but going that deep in recursion takes a fuckton of memory.
Link Posted: 3/10/2017 9:37:31 PM EDT
[#20]
Packages are kinda important in Java.
Link Posted: 3/10/2017 9:39:33 PM EDT
[#21]
Discussion ForumsJump to Quoted PostQuote History
Quoted:
Packages are kinda important in Java.
View Quote


I don't really do Java.  I fucking hate Java.  It was a tool to learn OO back in the early 2000s, then I used it in Android development for a few projects, but I'd rather code in C++.

But they're not a big deal for what he's doing.
Link Posted: 3/11/2017 12:28:12 AM EDT
[#22]
I do 12B trans a year with Java. There's nothing wrong with Java if it's done right. It's been years since I touched C/C++ but I can say I don't have a single positive thing to say about the .NET apps I'm forced to interact with.

I agree. Just pointing it out in case he goes further. 
Link Posted: 3/11/2017 2:12:11 PM EDT
[#23]
Discussion ForumsJump to Quoted PostQuote History
Quoted:
I do 12B trans a year with Java. There's nothing wrong with Java if it's done right. It's been years since I touched C/C++ but I can say I don't have a single positive thing to say about the .NET apps I'm forced to interact with.

I agree. Just pointing it out in case he goes further. 
View Quote


Close Join Our Mail List to Stay Up To Date! Win a FREE Membership!

Sign up for the ARFCOM weekly newsletter and be entered to win a free ARFCOM membership. One new winner* is announced every week!

You will receive an email every Friday morning featuring the latest chatter from the hottest topics, breaking news surrounding legislation, as well as exclusive deals only available to ARFCOM email subscribers.


By signing up you agree to our User Agreement. *Must have a registered ARFCOM account to win.
Top Top