java coding problem: hangs on a arraylist add - java

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.

Related

NullPointerException, can't find reason even after research

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.

Setting up my Hangman methods and calling them in my main method

Having difficulty calling the methods in my Game class to my main method for my hangman game.
We're supposed to spin a wheel to get a jackpot amount for 100,250 or 500 bucks then play the game as you'd expect... But methods are a necessity. Im nowhere near done I just want to be able to call my methods at this point to see how its working.
Here's my code:
import java.util.Scanner;
import java.util.Random;
public class GameDemo {
public static void main(String[] args) {
String[] songs = {"asdnj", "satisfaction", "mr jones",
"uptown funk"}; //note this is a very short list as an example
Random rand = new Random();
int i = rand.nextInt(songs.length);
String secretword = songs[i];
System.out.print("Welcome to The Guessing Game. The topic is song titles. \nYou have 6 guesses. Your puzzle has the following letters: ");
System.out.print("After spinning the wheel, you got " + spinWheel());
//continue the code here.
}
}
class Game {
Random rand = new Random();
String[] songs = {"asdnj", "satisfaction", "mr jones",
"uptown funk"};
int i = rand.nextInt(songs.length);
private String secretword = songs[i];
private char [] charSongs = secretword.toCharArray();
private char [] guessed = new char [charSongs.length];
private int guesses;
private int misses;
private char letter;
private char [] jackpotAmount = {100,250,500};
public Game (){}
public int spinWheel(int[] jackpotAmount){
int rand = new Random().nextInt(jackpotAmount.length);
return jackpotAmount[rand];
}
public char guessLetter(char charSongs [], char letter){
int timesFound = 0;
for (int i = 0; i < charSongs.length; i++){
if (charSongs[i] == letter){
timesFound++;
guessed[i] = letter;
}
}
return letter;
}
}
And the return error is
GameDemo.java:11: error: cannot find symbol System.out.print("After
spinning the wheel, you got " + spinWheel()); ^
To call methods from another class you need to make the method public. Once that is done, make them static if you will call the same method many times and you want it do the same function each time (the parameters can still be different).
To call the method do the following (this is a general form for most classes and methods, you should be able to use this to call all your methods):
yourClassWithMethod.methodName();
There are several issues in your spinWheelmethod call:
You haven't instantiated any any Game object to call this method. Either you have to make it static or just instantiate a Game and call it from that objet. I personally prefer the second (non-static) option because, especially because a static method cannot access directly non-static method or variables (... you need an instance or to make them static).
In main, you can do this (non-static solution):
Game game = new Game();
System.out.print("After spinning the wheel, you got " + game.spinWheel());
spinWheel requires an argument of type int[]. It seems that it is not useful since there is an instance variable jackpotAmount that seems to have been created on that purpose. jackpotAmount (see also second point) should be static in you example.
spinWheel becomes :
//you can have "public static int spinWheel(){"
//if you chose the static solution
//Note that jackpotAmount should also be static in that case
public int spinWheel(){
int rand = new Random().nextInt(jackpotAmount.length);
return jackpotAmount[rand];
}
Note that jackpotAmount should better be an int[]than a char[]

Multiple game instance

I have a method createGame on Server which create an instance of a game. What i want is to create another instance of the game for differents clients, but when i create another instance of the game, the first game created does not work anymore.
Here is the code:
private void createGame(){
gameThread.add(new GameThread(playerList, controllers.get(controllerNumber), controllers.get(controllerNumber)));
gameThread.get(gameNumber).start();
//just to shift the array of game
gameNumber++;
//shift the array of controller
controllerNumber++;
clientCounter = 0;
playerList.clear();
controllers.add(new ControllerServerSide());
}
Why I can't play two games at the same time, if each one is on a different thread?
EDIT:
GameThread
public class GameThread extends Thread{
private Settings settings;
private Game game;
private static int gamesActive = 0;
public GameThread(ArrayList<Player> playerList, Observer observer, ObservableInput controllerServer){
ArrayList<Player> newPlayerList = new ArrayList<>();
int size = playerList.size();
for(int i = 0; i < size; i++){
newPlayerList.add(playerList.remove(0));
}
settings = new Settings("src/main/java/it/polimi/ingsw/ps05/gamelogic/mappa.xml", newPlayerList);
game = new Game(settings, gamesActive++, observer, controllerServer);
game.init();
}
public void run(){
game.play();
}
}
From your code it isn't clear what are the members or what they do.. it's really hard to understand what your code does..
But I'll give it a shot:
Try and see if one of the new threads change the same objects as the old game thread.
Or - and I think that might be the problem - you clear the array/list of players and controllers - which both games use.. so the first game works fine but the second clean those list/arrays and destrying what's in there - so your first game stop working.. check it out.
private void createGame(){
gameThread.add(new GameThread(playerList, controllers.get(controllerNumber), controllers.get(controllerNumber)));
gameThread.get(gameNumber).start();
//just to shift the array of game
gameNumber++;
//shift the array of controller
controllerNumber++;
clientCounter = 0;
playerList.clear();
controllers.add(new ControllerServerSide());

Adding a string to an arraylist through another arraylist's object's method

I am in the process of updating my game to Java, but the only minor bug I have left is this:
Every time a dead player's name is "added" to the dead player name list, it adds the Player object's hashcode instead.
EDIT: Here is a link to a zip folder with the source code:
https://dl.dropboxusercontent.com/u/98444970/KarmaSource.zip
The code in question is the two places where the line gets the player object and gets the object's name. When it is used in println, it works fine and prints the player's name. However, in the second part where it does the same thing, but it prints the hashcode of the player object instead of calling its get_name method and returning the String. I'm not sure if it has to do with the third part, where it adds the "name" to dead player list pdead.
If you'd like a link to the compiled version, let me know. It's compiled under JDK 7 Update 51 64-bit.
EDIT: I got it working, I was originally referencing the players list instead of the pdead list. Thanks to all who contributed to helping. If you still want the game, let me know and I'll put a download link :D
Answering your question:
This code is wrong:
if (karma.pdead.isEmpty())
{System.out.println("None");}
else
for (int index = 0;index < karma.pdead.size();index++)
System.out.println(pdead.get(index));
What is karma? Whatever that is, looks like you're referring to 2 different things there.
Try this:
if (pdead.isEmpty()) {
System.out.println("None");
} else {
for (String deadPlayer : pdead) {
System.out.println(deadPlayer);
}
}
Pretty sure this will work :)
Some further, constructive advice:
Your code is breaking pretty much all conventions/good-practices I know in Java. But I am here to help, not to criticize, so let's try to improve this code.
Never keep state in static fields. This is a recipe for causing memory leaks.
your main function won't even compile. Should look like this:
public static void main(String[] args)
Always wrap the body of for loops with braces.
Be consistent: if you open braces in a new line, then do it every time. NEVER write code on the same line as the opening bracket.
GOOD:
public void doSomething()
{
// body
}
GOOD:
public void doSomething() {
// body
}
BAD:
public void doSomething() {
// body
}
public void somethingOther()
{
// inconsistent!
}
public void terribleCode()
{ System.out.println("Never do this"); }
Do not use underscores to separate words. In Java, the favoured convention is to use camelCase. getName(), not get_name().
class names ALWAYS start with a capital letter, whereas variable names generally start with a lower-case letter.
if you're iterating over all items of a list, just use the forEach construct (shown above) not index navigation.
I wanted to check to see if there was some subtle syntax error, so I cut/paste your code into an editor and tried to massage it to get it running. After my massaging, I ran it and it ran fine. Here is the code I ran and the results I got:
Code:
import java.util.ArrayList;
public class Game {
private static ArrayList<Player> players = new ArrayList<Player>();
private static ArrayList<String> pdead = new ArrayList<String>();
public static void main(String[] args) {
// Some Test Data
Player p1 = new Player("George");
p1.setHp(10);
players.add(p1);
Player p2 = new Player("Bob");
p2.setHp(10);
players.add(p2);
// Print Current State of data
System.out.println("Current Players");
for(Player p: players) {
System.out.println(p.getName() + ": " + p.getHp());
}
System.out.println("Dead Players");
if (pdead.isEmpty()) {
System.out.println("None");
} else {
for (int index=0; index < pdead.size(); index++) {
System.out.println(pdead.get(index));
}
}
// Kill Bob
p2.setHp(0);
// Do work to add names to dead players data structure
for (int index2=0; index2 < players.size(); index2++) {
if ((players.get(index2).getHp() <= 0) && !(pdead.contains(players.get(index2).getName()))) {
pdead.add(players.get(index2).getName());
}
}
// Print Current State of data
System.out.println("Current Players");
for(Player p: players) {
System.out.println(p.getName() + ": " + p.getHp());
}
System.out.println("Dead Players");
if (pdead.isEmpty()) {
System.out.println("None");
} else {
for (int index=0; index < pdead.size(); index++) {
System.out.println(pdead.get(index));
}
}
}
}
class Player {
private String name = "";
private int hp = 0;
public Player(String n) {
name = n;
}
public String getName() {
return name;
}
public int getHp() {
return hp;
}
public void setHp(int h) {
hp = h;
}
}
Here are the results that code gives me:
javac Game.java
java Game
Current Players
George: 10
Bob: 10
Dead Players
None
Current Players
George: 10
Bob: 0
Dead Players
Bob

Why does Java method return null?

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();.

Categories