I am trying to debug why my Java method returns null. Here are the details.
We are making a simple card "game" and Im having trouble with external method call and creating a new object.. It is a deck of cards ..So 1 class for the cards, 1 class for deck and 1 for the Game
This is my class the code goes into
public class Game
{
private InputReader reader;
private Deck deck;
private ArrayList<Card> listCard;
/**
* Constructor for objects of class Game
*/
public Game()
{
deck = new Deck();
reader = new InputReader()
listCard = new ArrayList<Card>();
}
/**
*
*/
public void dealCard()
{
listCard.add(deck.takeCard());
}
}// End of Game class
and this is the deck class which I will grabbing methods from
import java.util.ArrayList;
/**
* Write a description of class Deck here.
*
* #author
* #version 2012.05.31
*/
public class Deck
{
private ArrayList<Card> redblue;
/**
* Main constructor for objects of class Deck
*/
public Deck()
{
redblue = new ArrayList<Card>();
}
public Card takeCard()
{
**return redblue.remove(0);** /// this is the Index.pointer.exception
}
}
}// End of class
So my problem is im trying to pull the first card off the deck and add it to my "hand" ..So im trying to call dealCard() which calls takeCard()..The takeCard() works fine but when I try and call if through dealCard() it returns null and errors out because i cant add null to arrayList..
I think my problem might be external method calling not step up with the right variables, I dunno
Thanks in advance
***Edited. Removed irrelevant methods and Class..
Look at your constructor for Deck:
public Deck()
{
redblue = new ArrayList<Card>();
}
After that constructor has run, how many cards are there in the redBlue ArrayList?
What do you think might happen if you try to remove a card from that ArrayList?
I think you need to post some more code from your main(game class) showing us the usage of your deck and card classes. Only thing that took my attention now is this:
public Card takeCard()
{
**return redblue.remove(0);** /// this is the Index.pointer.exception
}
According to this an exception can be thrown if:
IndexOutOfBoundsException - if index out of range (index < 0 || index >= size()).
Are you sure your deck is filled with cards? You could add a check to your method. If your list of cards is empty, 0 = it's size.
public void dealCard()
{
Card card = deal.takeCard();
if (card != null)
listCard.add(deck.takeCard());
}
public Card takeCard()
{
if ( !this.redblue.isEmpty() )
return redblue.remove(0);
return null;
}
Somehow the first element of your
redblue
is null. Nulls are allowed in an ArrayList.
My guess is that there is more code where you fill in the Deck of cards and the first time around you are adding null to the ArrayList
Check the ArrayList specification here.
It seems to me like redblue doesn't actually have anything in it! when you intialise it like so:
redblue = new ArrayList<Card>();
You're just creating an empty container for Cards, not actually putting cards in it.
What you may want to do is create a function to generate the cards for redblue.. something like..
public ArrayList<Card> createInitialDeck(){
//Create an empty ArrayList
//Do some code here to create new cards..
//you might want to consider nested for loops if you're creating 13 cards of 4 different suits for example
//while inside those for loop add each new card object to your array list
//return arrayList;
}
then instead of redblue = new ArrayList<Card>(); you'd do redblue = createInitialDeck();.
Related
This is regarding a Java homework assignment:
I want to create a method that takes the list of cards as a parameter and prints all the cards to the screen. Each card should print all stored information so that I can use the newly created method to print all the cards. And it is required for me to use the Array list of Card objects as a parameter.
I have three class in this program, namely - Main.java, HandDrawn.Java, and Card.java. Basically the program tracks the Christmas card information with the sender's name and if they are hand written or not. I'm stuck at this point as I don't know how to use ArrayLists properly and pass them through a method in order to print them.
public class Main {
public ArrayList<Card> cardsList = new ArrayList<>();
public static void main (String [] args){
Main myApp = new Main();
}
public void printAll (ArrayList<Card> cardArrayList){
System.out.println(cardArrayList);
HandDrawn sender1 = new HandDrawn("Anna", true);
HandDrawn sender2 = new HandDrawn("Kalle", false);
cardsList.add(0, sender1);
cardsList.add(1, sender2);
}
public void printing(ArrayList<Card> cardsList) {
System.out.println(cardsList);
}
}
Please see this examples:
how to print ArrayList in java
System.out.println("Print Arraylist using for each loop");
for( String strDay : aListDays ){
System.out.println(strDay);
}
Your logic does print the List before ot has anything in it. Try adding something to the List before printing the content.
public void printAll (ArrayList<Card> cardArrayList){
System.out.println("List content: " + cardArrayList.toString()); // <- Empty List at this point
HandDrawn sender1 = new HandDrawn("Anna", true);
HandDrawn sender2 = new HandDrawn("Kalle", false);
cardsList.add(0, sender1);
cardsList.add(1, sender2);
}
The output is then:
List content: []
I'm coding a cards game, I have an ArrayList holding cards (Object) where
each one of them has its id.
Since I want to make this game to support multiplayer mode,
I must in some way send/receive game progress between the 2 players.
Now, if I shuffled the cards on a side, I must do the same thing in the other but it will be a big packet to be sent since every card has an image.
What I thought is to send an integer array of the shuffled list, so it will be received on the other side and re-ordered following the integer array.
How can I send the shuffled order and apply it on the other side?
The Random class can be used for this.
If two instances of Random are created with the same seed, and the
same sequence of method calls is made for each, they will generate and
return identical sequences of numbers. In order to guarantee this
property, particular algorithms are specified for the class Random.
Java implementations must use all the algorithms shown here for the
class Random, for the sake of absolute portability of Java code.
This means that you can transmit only the seed value to the client, instantiate a new Random instance using it and expect to receive the same sequence of random numbers as on the other player's machine.
Collections.shuffle can be invoked with a Random source.
Although it is possible to initialize two java.util.Random instance with the same seed, and use these instances with Collections.shuffle() as mentioned by Henrik. The only problem is that Collections.shuffle() calls with these instances have to be called in the same sequence (i.e. synchronized). It may not be possible to guarantee this, for example if one player requests card shuffle more than one in very quick succession, and the other player falls out of sync (due to network issues).
One alternative is to do the sorting manually on both ends. An illustration is given below.
public class Card {
private final int id;
private final String imageURL;
public Card(int id, String imageURL) {
this.id = id;
this.imageURL = imageURL;
}
public int getId() {
return id;
}
public String getImageURL() {
return imageURL;
}
/**
* Getters and setters below
*/
}
public class Example {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
final int NUMBER_OF_CARDS = 6;
//
final List<Card> originalList = new ArrayList<>();
//
for (int i = 1; i <= NUMBER_OF_CARDS; i++) {
originalList.add(new Card(i, "image_url"));
}
//Create player card list
final List<Card> firstPlayerCardsList = new ArrayList<>(originalList);
final List<Card> secondPlayerCardsList = new ArrayList<>(originalList);
//
//1. Shuffle list on one side
Collections.shuffle(firstPlayerCardsList);
//
//2. Iterate over the list and add indices to array
final int[] indices = new int[NUMBER_OF_CARDS];
//note indices are zero based to allign with arrays
for (int i = 0; i < NUMBER_OF_CARDS; i++) {
indices[i] = firstPlayerCardsList.get(i).getId();
}
//
// 3. Send the shuffle indices array across to second player
// ********* omitted ******
//
// 4. Recreate the shuffle order at the second players end, based on the shuffle indices array
final List<Card> tempCardsList = new ArrayList<>(secondPlayerCardsList);
secondPlayerCardsList.clear();
IntStream.range(0, NUMBER_OF_CARDS).forEach((int index) -> {
final int id = indices[index];
for (final Card c : tempCardsList) {
if (c.getId() == id) {
secondPlayerCardsList.add(c);
}
}
// can also use in place of the above
//tempCardsList.stream().filter((c) -> (c.getId() == id)).forEachOrdered((c) -> {
// secondPlayerCardsList.add(c);
//});
});
// Show the results for this illustration
System.out.println(" Original" + " First" + " Second");
IntStream.range(0, NUMBER_OF_CARDS).forEach((int index) -> {
System.out.println("\t" + originalList.get(index).getId() +"\t" + firstPlayerCardsList.get(index).getId() + "\t" + secondPlayerCardsList.get(index).getId());
});
}
}
Yes, just initialise and store the cards in an read-only array of 52 Card objects at the start of both sides:
final Card[] allCards = new Card[52] {...};
Use this array exclusively in the whole application on both sides to refer to each card using just an int index instead of a Card instance.
Then you'll have a deck object which is an int[52]. Initially, it will contain all the numbers from 0 to 51. Then you shuffle the array. Then you send the array of ints to the other side, and the other side then has the same shuffled deck.
EDIT2: Sorry all... I believe it is due to the lack of understanding of question that cause this misconception. After reading through, I think what they want is for the return value of getWinningPoint() be the biggest number among the players and yet still <=21. so that in the game output, can loop each player to get their card point again and compare it to this winningpoint. I thank all of your input and help. Moderator or Admin can close this thread. Thanks again.
I would like to find out how to access the particular object in the arraylist so that i can cast the method on it. In a overall view, I am able to make method that apply to all items in the arraylist of players (distributeCardsToPlayer). But my 2nd method of getWinningPoints() is a int that sum up all the cards the particular player in arraylist players have. The winningPoint is a individual result which will ultimately be used in printWinners() method. I'm only familiar with accessing a obj with "Player player = players.get(0);" but in this case the "player" itself will be calling getWinningPoints() to check their own result.
P.S - I am not sure how to put it properly,and hopefully someone can point me to the right direction.
import java.util.*;
public class ModifiedBlackJack
{
protected ArrayList<Card> gameDeck;
protected ArrayList<Player> players;
public ModifiedBlackJack(ArrayList<Player> players)
{
this.players=players;
}
public void distributeCardsToPlayers()
{
Scanner console = new Scanner(System.in);
for (Player player : players)
{
player.drawACard(getACardFromDeck());
player.drawACard(getACardFromDeck());
System.out.println(player.getName()+": " + player.toString());
System.out.print("Draw another card? (y/n): ");
char input = console.nextLine().toLowerCase().charAt(0);
if(input == 'y')
{
player.drawACard(getACardFromDeck());
}
}
EDIT2: After reading through, I think what they want is for the return value of getWinningPoint() be the biggest number among the players and yet still <=21. so that in the game output, can loop each player to get their card point again and compare it to this winningpoint.
public int getWinningPoints()
{
int wp=0;;
int point=0;
for (Player player:players)
{
point = player.getCardsPoints();
if (point>=21 && point>wp)
{
wp=point;
}
}
return wp;
}
In the Player class, there is a function for summing up all the cards point
public int getCardsPoints()
{
int point=0;
for (Card c: cards)
{
point=point+c.getPoints();
}
return point;
}
I am new to java and any help or guidance is very much appreciated.
Thank You
You may be overthinking this, and the method getWinningPoints isn't entirely required.
Because you already have getCardsPoints declared in Player, and you already have an instance of Player to work with in your loop, the only thing you realistically need to do is...invoke it.
System.out.println(player.getName() + "Chips: " + player.getChips() + "[]" + player.getCardsPoints());
Whatever conditions you need to satisfy the min parameter should be done inside of this loop; that is, conditionally print the values that are larger than min.
If you want to invoke a Player class method you need to have a player object to call a method that it "owns".
Pass the player object to the method and accept the player object in getWinningPoints().
Call
getWinningPoints(player)
Declaration
public int getWinningPoints(Player localPlayer)
{
return localPlayer.getCardsPoints();
}
I'm having bad times with creating typical card/deck class in java. I've read some similar questions & answers but either they're not relatable/helpful or I can't simply comprehend it yet.
Here's the code
public class Cards {
boolean isAvailable;
int card_id;
static final int AC = 32;
public Cards [] deck = new Cards[AC];
public void set () {
int a = 0;
for (int i = 0; i < AC; i++) {
if(a == 4) a = 0;
deck[i].isAvailable = true; // <---------
deck[i].card_id = i + (a * 101); // <---------
a++;
}
}
public void read () {
for (int i = 0; i < AC; i++)
System.out.println(deck[i].isAvailable + " " + deck[i].card_id);
}
public static void main (String[] args) {
Cards c = new Cards();
c.set();
c.read();
}
}
Exception in thread "main" java.lang.NullPointerException
at Cards.set(Cards.java:13)
at Cards.main(Cards.java:24)
1.
I've read about similar issues and found that problem can be in initialization of an array and I've tried to do the same with my prog but it went bad anyway.
I marked 13th and 14th lines because they are being pointed (when i comment 13th line just for check, pointer sets to the next line).
2.
Next part of help I would like to get from you is:
Even though there is main (for training purposes), I see other class using this class (which just creates deck) so I guess I won't be needing main... Is everything well set besides probs in first point?
Very simple:
public Cards [] deck = new Cards[AC];
creates an empty array with AC number of slots for Cards objects.
Now you have to put a non-null Cards object into each slot!
But thing is: actually your abstraction is broken.
You wrote code that seems to take one card to be the same as a card set - by adding that array of Cards into your Cards class! And that makes it actually hard to fix your current code. As the "normal" way to fix this would be to add a constructor like
public Cards() {
deck = new Cards[AC];
for (int i=0; i<deck.length;i++) {
deck[i] = new Cards();
}
If you try that ... you immediately run into an endless recursion (creating one new Cards would result in creating AC new Cards (to fill the array); causing a stackoverflow very soon.
Thus the real answer goes somewhere along these lines:
public class Card {
... a class that represents a SINGLE card in your game
and then
public card GameOfCards {
... a class that (for example!) uses an array to hold n objects of class Card!
Finally, as Peter is indicating in his comment: you should learn to use debugging means to work on such problems yourself. One good way: before using any data structure, iterate it and print out its content. Or even better, learn how to use a debugger, and walk through your code step by step! As you should please understand: this is very basic stuff; that you normally should not bring forward here.
i used before arraylist as structure but in this piece of code it doesnt works.
Can someone help me since i cant find the error ? (i am sure it s my mistake but the IDE says nothing)
the flow:
first the class Game. i call the runGame adn it flows ok untill the point Hand hand = new Hand(this.deck); ( ther is a comment on the right to signale the problem
public class Game {
private ArrayList<Player> playerArray;
private int maxPlayers;
private Deck deck;
//constructor
public Game(ArrayList playerArray, int maxPlayers)
{
this.playerArray = playerArray;
this.maxPlayers = maxPlayers;
}
// game method for the match
public void runGame()
{
//shuffle of players
Collections.shuffle(this.playerArray);
//creation of the deck
this.deck = new Deck();
System.out.println(new java.util.Date().toString() +" "+"deck created");
//shuffle the deck
this.deck.shuffleDeck();
System.out.println(new java.util.Date().toString() +" "+"deck shuffled");
// distribuiting the hands to all players
//and preventing them to send something
for (int i = 0; i < this.maxPlayers; i++)
{
Player currentPlayer = this.playerArray.get(i);
Socket socket = currentPlayer.getConnection();
Hand hand = new Hand(this.deck);// the problem starts here comes form the constructor of the hand
System.out.println(" after hand ");
sendingBlockString(socket, currentPlayer); //send the block string
sendingHand(socket, currentPlayer, hand );//send the hand
}
The problem is clearly in the hand constructor in the class Hand where it hangs in the cycle for, exaclty trying to add the popped car of the deck ( the deck.popCard() function is tested and works perfectly so it s not that blocking the add() function ) i never reach the second system.out.println here the code:
public class Hand implements Serializable
{
private ArrayList<Card> theHand;
private Player player;
private int handValue ; // from 1 to 10
public Hand(Deck deck)
{
for (int i=0; i<4; i++)
{
System.out.println("before popping deck");
this.theHand.add(i, deck.popCard());// adding the card taken from the deck (5 times) //// this is the problem it hangs!
System.out.println("after add to hand");
}
}
Are you sure it hangs ? It should throw a NullPointerException since your ArrayList is not initialized.
I would suspect that dec.popCard() blocks if there are no more cards. the add method itself can't hang.