Multiple game instance - java

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

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.

Java text based adventure game, what to put under my main method

I'm making a text based adventure game with java, im a first year computer science student.
I made a room, exit, creature, item and world class and put in the API that was given to me in the class. It was just basic methods and some constructors.
We're suppose to create a textAdventure class were we bring together all the other classes and create the game.
The player and game class was given to me and my professor did all the necessary code in order to make the game run in that class.
My problem is I don't know how to start in my TextAdventure Class, also thats where my main method is.
So I'm confused on how to make a starting room and how to put an exit in that room leading to another room.
Here's some code
public class MyTextAdventure {
private Room room1;
private Room room2;
private Room room3;
private Room room4;
private Room room5;
private Room room6;
private Room room7;
private Room room9;
private Room room10;
public static void main(String [] args){
}
If I wanted to make a player start in room1, can I just do this.
public static void main(String [] args){
public Room startingRoom;
}
I have already declared startingRoom in the room class.
I'm sorry if my skills are bad, I just have no idea what I'm doing and where to start.
Use an array to keep track of your rooms. This allows you to avoid having to keep track of 10 different variable names. It also allows you to do math on the array index. For example, if you wanted to set the current room from 3 to 4, you wouldn't have to check which room was set to current. You could just do currentRoom++
Try something like this.
public class MyTextAdventure {
private Room[] rooms; //array for all rooms
int currentRoom = 0;
boolean over;
//class constructor
public MyTextAdventure() {
rooms = new Room[10]; //Initialize new room array of size 10
over = false; //game is not over yet
for(int i = 0; i < rooms.length; i++) {
//Initialize all rooms
rooms[i] = new Room();
}
}
public void start() {
//do your game loop in here
while(!over) {
}
}
}
public static void main(String [] args){
MyTextAdventure adventure = new MyTextAdventure();
adventure.start();
}
The main function should just start your game. Functions and classes should be designed to accomplish a singular task that is clear. Name classes, functions and variables so that you know exactly what they are doing.
Using the current room as an integer allows you to make use of it as an array index. For example if you want to get the current room you can do this for a function.
public Room getCurrentRoom() {
return rooms[currentRoom];
}

Copying Array from ArrayList Element

I'm building a Java based game in Swing, which is essentially a grid of Jbuttons
I have an Object called Cell, which is a custom JButton with additional parameters for storing objects. The game grid is represented by Cell[][]
I have an arraylist of type Cell[][] to allow me to store the state of the gamegrid after each move. If I want to undo the move, I need to copy the last element of the ArrayList to the game grid to allow it to be displayed on the UI.
My gamegrid is panelHolder and my arraylist is moveHolder.
So far I've tried Collections.copy(panelHolder, moveHolder.get(moveHolder.size())); which will not compile due to the "arguments not being applicable for the type Cell[][]"
I've also tried System.arraycopy(moveHolder.get(moveHolder.size()-1), 0, panelHolder, 0, panelHolder.length);, which throws and out of bounds exception. Initially I thought this was due to the moveHolder.size()-1, but even just as moveHolder.size() it has the same problem.
I've found numerous questions on StackOverflow and others that both show these two ways of doing it, but I can't seem to get it to work. Is there something more obvious I'm missing? Full class method below:
public class UndoClass implements MoveCommand{
public ArrayList<Cell[][]> moveHolder = new ArrayList<Cell[][]>();
public Cell[][] execute(Cell[][] panelHolder) {
if (moveHolder.size() > 0){
Collections.copy(panelHolder, moveHolder.get(moveHolder.size()));
if (moveHolder.size() > 0){
moveHolder.remove(moveHolder.size());
}
}
System.out.println("Move Undone. Undos available:" + moveHolder.size());
return panelHolder;
}
public void addMove(Cell[][] panelHolder){
moveHolder.add(panelHolder);
}
public ArrayList<Cell[][]> getMoves(){
return moveHolder;
}
}
Cell Class
public class Cell extends JButton {
int co_x = 0;
int co_y = 0;
ArrayList<Players> current = new ArrayList <Players>();
}
Just wanted to point our your execute(...) method accepts the Cell[][] both as a parameter and the return argument. That approach is going to force all of your commands to keep copying your input param arrays to the return statement array. Notice if you don't need to keep the two in sync and you just use the return arg, you don't have to worry about copying at all:
Cell[][] lastState = moveHolder.get(moveHolder.size()-1);
moveHolder.remove(moveHolder.size()-1);
return lastState; // Not updating the panelHolder array, just returning
But of course now the input parm and return are out of sync. Instead you might want to encapsulate that state into a single object to make your life easier. Something like this (note that the execute now returns a void):
public ArrayList<GameState> previousStates = new ArrayList<GameState>();
public void execute(GameState currentState) {
if (previousStates .size() > 0) {
GameState lastState = previousStates.get(previousStates.size()-1);
currentState.restoreFrom(lastState);
previousStates .remove(moveHolder.size()-1);
}
}
Good luck on the game!
if (moveHolder.size() > 0) {
for (int i = 0; i < panelHolder.length; i++) {
panelHolder[i] = moveHolder.get(moveHolder.size()-1)[i].clone();
}
moveHolder.remove(moveHolder.size()-1);
}
Try this. You need to make copies of each internal array when copying 2D arrays.
Try a Linked List
LinkedList<Cell[][]> ll = new LinkedList();
ll.removeLast();
panelHolder = ll.clone();

Count amount of members in a class

I'm making a small game in java for school purposes.
Now I want to count the number of players, code I have:
Player player1;
player1 = new Player();
player1.name = "Name1";
player1.score = 0;
player1.lives = 100.0;
Player player2;
player2 = new Player();
player2.name = "Name2";
player2.score = 0;
player2.lives = 50.0;
In the players use a static variable count that increments in the player constructor.
private static int playerCount = 0;
//constructor
Player(){
playerCount++;
}
Put all the players in a list:
List<Player> allPlayers = new ArrayList<Player>();
Player player;
player = new Player();
player.name = "Name1";
player.score = 0;
player.lives = 100.0;
allPlayers.add(player);
player = new Player();
player.name = "Name2";
player.score = 0;
player.lives = 50.0;
allPlayers.add(player);
allPlayers.size(); //Number of players
player = allPlayers.get(0); //Player 1
player = allPlayers.get(1); //Player 2
The best way to go about it is to use a container class, something that's a descendent of java.util.Collections.
When a player is added, he is added to the collection. When the player drops out of the game, he is removed from the collection. As a result, to determine the number of players at any moment in time, one only need to count the members of the collection (which is already implemented if you use a java.util pre-implemented Collection).
Even then, there are two techniques. One of these are flawed, and I'll demonstrate the flawed technique first (which is not much better than the static counter example others have provided).
private static HashSet<Player> players = new HashSet<Player>();
public Player() {
players.add(this);
}
public static int getPlayerCount() {
return players.size();
}
This leads to an interesting problem. The Player count will never go down, as even if Player classes are dereferenced, the counting collection holds a reference preventing garbage collection. This leads to the java version of a "garbage leak", but don't confuse it with the C/C++ "garbage leak" which is more nefarious.
The second technique arises from fixing the problems in the first. Basically, it doesn't rely upon construction to register, as destruction is an unsafe means of deregistering. Within a snippet of code you would have
HashSet<Player> players = new HashSet<Player>();
Player player = new Player("bob");
players.add(player);
... later on ...
players.remove(player);
or something equivalent. Basically the main idea is to have your current player list at the same level as the player creation. There are a million variants, depending on where the originating call comes from; however, the main idea is the same: explicit deregistering of the player, not directly tied to object life cycle.

java coding problem: hangs on a arraylist add

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.

Categories