I am new on Java, but my problem can be language independent.
I have a Player class and in my game logic, i have a map stores created players.
I write a method -getNext()- that returns the next player to me and it works like a charm. But in the game, players that eliminated must not get in line. So I write a new method -getNextAlive()- should return next alive (!isLoser) player. If there isn't any loser player, getNextAlive() is working but if there is, program gets in while loop and looping infinitely. In while loop I switch to next player and sure that next is alive, but I think while(p.checkLose()) not affected in while changes and give this output forever:
player: allyozturk
I can't get why this happens in this way, what should I do for skipping all isLoser players and get the next alive one? (BTW, I use libgdx ArrayMap and my map is ordered because of order of next player is importont for my game)
in-game I use:
currPlayer = currPlayer.getNextAlive();
and here my Player.java is:
public class Player{
private static int counter;
public static int alives;
private int uniqueId;
private String name;
private boolean isLoser;
.
.
.
private Player getNext(){
int index = MyGdxGame.players.indexOfKey(uniqueId);
if(++index < MyGdxGame.players.size)
return MyGdxGame.players.getValueAt(index);
else
return MyGdxGame.players.getValueAt(0);
}
public Player getNextAlive(){
Player p = getNext();
while(p.checkLose()){
p = getNext();
MyGdxGame.logger.error("player: " + p.getName()); // just for testing purpose
}
return p;
}
}
And an addition question coming from some curiosity and some for doing the best: Is it totally appropriate that using a method returns Player in the Player class?
Replace p = getNext(); with p = p.getNext();
Related
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 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
I have a Sudoku puzzle solver that requires us to use recursion.. The problem is my boolean to check for available space is supposed to update the current position by reference and it is not. What would cause this?
public boolean solve()
{
Coordinate current = new Coordinate();
if (findEmptyGridSlot(current)) { // THE ERROR IS HERE ********** THIS IS SHOWING (0,0) STILL ******************
for (int number = 1; number <= 9; number++)
if (canPlaceNumber(current, number)) {
grid[current.getRow()][current.getColumn()] = number;
if (solve())
return true;
grid[current.getRow()][current.getColumn()] = 0;
} return false;
}else
return true;
}
private boolean findEmptyGridSlot(Coordinate coordinate)
{
boolean found = false;
try{
while (!found)
{
if (grid[coordinate.getRow()][coordinate.getColumn()] == 0)
found = true;
else
coordinate = coordinate.next(); // *****This is supposed to update the current coordinate ******
}
}catch (Exception e){
//CREATE No Empty Cells Exception
}
return found;
}
public Coordinate next()
{
Coordinate result = new Coordinate(row, column);
result.column++;
if (result.column > MAX_COORDINATE)
{
result.column = MIN_COORDINATE;
result.row++;
if (result.row > MAX_COORDINATE) result = null;
}
return result;
}
Java passes by value. This means you are getting a copy of the reference to coordinate. If you point that copy to a new object (i.e. coordinate = coordinate.next) you are only changing the local copy. Now, on the other hand, if you changed an attribute of the object your variable refers to (e.g. coordinate.x = foo or coordinate.setX(foo)) that change will be visible to the caller of your method.
jpm is correct, but I misread the first time so i'm going to try to clarity
private boolean findEmptyGridSlot(Coordinate coordinate)
A reference is passed by value. Think in these terms "coordinate" is a box that holds a piece of paper, on the piece of paper an address is written. coordinate is a box that belongs to only this method and it has its own piece of paper (many pieces of paper may have the same address written on them)
We can look in this box and 'post' things to the address written on the piece of paper, however when we say
coordinate=something
this means write on a new piece of paper the address of 'something'. Throw away the old piece of paper.
This action in no way affects the original 'house' that the first piece of paper had the address on. When my friend Jon updates his address book it doesn't matter what he writes, I still live in my house.
So, if coordinate has some easy substructure (eg x and y) you can 'post' an instruction to change x and y to be equal to the "next" one.
Or as a hack you can enclose a Coordinate inside annother object so you can post an instruction to it to change what the hack class points to
Test Code refered to in comments:
public class Test {
public static void main(String args[]){
String bareMinObject="start";
changeString(bareMinObject);
System.out.println(bareMinObject); //Prints start, change string has no effect
}
public static void changeString(String input){
String temp="end";
input=temp;
}
}
I'm working on a text-based adventure game and I'm trying to externalise as much of the setup as possible so that I can work with a friend who wants to write the storyline. I have three classes so far. A room class with a title, description, and an array of Exits. Also an Exit class with the following constructor.
public Exit(int direction, Room connection);
Exits also have public int variables referring to the different directions:
public static final int NORTH = 0;
This is all so I can set up an exit on a room by saying:
Room r = new Room("Title","Description");
Room r2 = new Room("Title", "Description");
r.addExit(new Exit(Exit.NORTH, r2);
This would make an exit on the room r that is on the north side and leads to the room r2. Now for the externalisation I'm trying to make a .txt file where I can simply put the current room number, the exit direction (string), and the room number it leads to.
I can do this just fine as far as reading the file goes but where I'm struggling is when I'm setting up the direction, I can't say
Exit. /*String read from file*/
So how can I access those public integers from the Exit class using a string from the txt file?
Try using an enum instead.
public enum ExitDirection { NORTH = 0, … };
ExitDirection foo = ExitDirection.valueOf (stringFromFile);
…else, you'll just have to bite the bullet with something like
if (stringFromFile.equals("NORTH")) { foo = NORTH; }
else if (stringFromFile ... (ad nauseum)
The quick and dirty fix is to implement a method to do string comparison and return the appropriate constant. But you should also consider using an enum as suggested by BRPocock, it's a much cleaner way to do it.
int directionFromStr(String str) {
// Putting the string constant on the left side of the expression guards against null input
if ("NORTH".equalsIgnoreCase(str)) return Exit.NORTH;
if ("SOUTH".equalsIgnoreCase(str)) return Exit.SOUTH;
if ("EAST".equalsIgnoreCase(str)) return Exit.EAST;
if ("WEST".equalsIgnoreCase(str)) return Exit.WEST;
// You could also return -1 or something like that
throw new IllegalArgumentException("bad direction");
}
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.