I'm in an intro CS class and I'm writing a program that plays a game. I have the framework classes down but this error occurs when I try to run. It says there is a null point at line 51 in the game method but I can't find where the null point is occurring. Here's the code for the four classes.
public class Pog //THIS IS DONE
{
public static void main (String [] Agrs)
{
PogPlayer human = new PogPlayer( "Human" );
PogPlayer computer = new PogPlayer( "Computer" );
PogGame game = new PogGame ( human, computer );
game.play();
} // method main
} // class Pog
public class PogDice
{
private int die1; // Stores the value (1-6) of die1.
private int die2; // Stores the value (1-6) of die2.
private Random rand;
public PogDice()
{
rand = new Random();
} // default constructor
public int roll()
{
int total = 0;
int turnTotal = 0;
String choice;
Scanner scan;
scan = new Scanner(System.in);
do { die1 = rand.nextInt( 5 )+1;
die2 = rand.nextInt( 5 )+1;
total = die1+die2;
System.out.println("Current score is: " + total + "\nRoll again?");
choice = scan.nextLine();
} while (choice == "yes" && hasDoubleOne() == false);
turnTotal = turnTotal + total;
return turnTotal;
} // method rollDice
public boolean hasDoubleOne()
{
boolean doubleOne = false;
if(die1 == 1 && die2 == 1)
doubleOne = true;
else
doubleOne = false;
return doubleOne;
} // method hasDoubleOne
public String toString()
{
return (die1 + ", " + die2);
} // method toString
} // class PogDice
public class PogGame
{
private PogPlayer human;
private PogPlayer computer;
/**
* PogGame (constructor)
*
* #param PogPlayer (human)
* #param PogPlayer (computer)
*/
public PogGame ( PogPlayer humanArg, PogPlayer computerArg )
{
PogPlayer human = humanArg;
PogPlayer comptuer = computerArg;
} // method PogGame (constructor)
public void play()
{
System.out.println("Hello, Welcome to Pog.\n\n This game takes the user "+
"and puts them agaisnt the computer\n in a dice-based "+
"game. Each player takes turns rolling two dice,\n "+
"with their sum being the total points the "+
"player gets.\n If you roll two 1s you lose all "+
"points that turn.\n You have the option to turn "+
"over the dice at any point\n during your turn to "+
"keep all of your points.\n First one to 21 wins!.\n");
human.getCurrent();
} // method play
} // class pogGame
public class PogPlayer
{
private int current; // Value of the current roll
private int score; // Player's point score.
private PogDice dice; // Player's dice
private String name; // Player's name.
public final int WINNER = 21; // number of points required to win
public PogPlayer ( String nameArg )
{
PogDice dice = new PogDice();
score = 0;
} // method PogPlayer (constructor)
public int getCurrent()
{
int current;
current = dice.roll();
return current;
} // method getCurrent
public PogDice getDice()
{
new PogDice();
return new PogDice();
} // method getDice
public int getScore()
{
score = current + score;
return score;
} // method getScore
public boolean hasWon()
{
boolean win;
if(score == WINNER)
{
win = true;
}
else
win = false;
return win;
} // method hasWon
public boolean rollDice()
{
return false;
} // method rollDice
} // class PogPlayer
I'm pretty sure the error is occurring at the human.getCurrent(); line.
public static void main (String [] Agrs)
{
PogPlayer human = new PogPlayer( "Human" );
PogPlayer computer = new PogPlayer( "Computer" );
PogGame game = new PogGame ( human, computer );
game.play();
} // method main
"human" is a local variable. When you call human.getCurrent() in play, it's a different human. In particular, a null one that hasn't been initialized yet.
The problem is that you don't actually setting the human and computer variables correctly in PogGame class, because in the constructor you're creating a new variable, but the instance variable remains null.
private PogPlayer human;
private PogPlayer computer;
/**
* PogGame (constructor)
*
* #param PogPlayer (human)
* #param PogPlayer (computer)
*/
public PogGame ( PogPlayer humanArg, PogPlayer computerArg )
{
PogPlayer human = humanArg; // human is a new variable rather than the human instance variable
PogPlayer comptuer = computerArg;
}
So when you call human.getCurrent(); here will throw an NPE since human didn't initialized.
so change the code to something like:
public PogGame ( PogPlayer humanArg, PogPlayer computerArg )
{
human = humanArg;
comptuer = computerArg;
}
Same thing goes with dice in PogPlayer constructor, change it to:
public PogPlayer(String nameArg) {
dice = new PogDice();// instead of PogDice dice = new PogDice();
score = 0;
}
Related
So I am having an issue where I would like to create a record in one procedure, then alter the attributes of that record using other procedures and functions.
import java.util.Scanner; // Imports scanner utility
import java.util.Random;
import java.lang.Math;
class alienPet
{
public void main (String[] param)
{
// We want to call all of the functions
// and procedures to make an interactive
// alien program for the user.
welcomeMessage();
alienCreation();
System.exit(0);
} // END main
/* ***************************************
* Define a method to obtain the users input
* and start the correct method.
*/
public static String userInput (String message)
{
Scanner scan = new Scanner(System.in);
String inp;
print(message);
inp = scan.nextLine();
return inp;
} // END userInput
/* ***************************************
* Define a method to print messages.
*/
public static void print (String message)
{
System.out.println(message);
return;
} // END print
/* ***************************************
* Define a method to
*/
public static void welcomeMessage ()
{
print("Thank you for playing the pet alien game");
print("In this game, you will have to look after your own alien.");
print("There is multiple aspects to looking after your alien, such as:");
print("Hunger, Behaviour and Thirst.");
print("");
print("When prompted, you can use the following commands:");
print("feed -> Replenishes alien to max hunger level");
print("drink -> Replenished thirst level to max");
print("");
return;
} // END
/* ***************************************
* Define a method to
*/
public void alienCreation ()
{
Alien ufo = new Alien();
ufo.name = userInput("What would you like to name your new alien?");
ufo.hungerRate = ranNum(1, 6);
print("On a scale of 1-6, your alien, " + ufo.name + ", has a hunger rate of " + ufo.hungerRate);
alienBehaviour(ufo.hungerRate);
return;
} // END alienCreation
public void alienBehaviour (int hunger) {
if (hunger <= 2){
print(ufo.name + " is very hungry, and is dangerously angry!!");
String action = userInput("You should feed it as soon as possible. (by typing 'feed')");
if (action.equals("feed")){
feedAlien();
}else if (action.equals("drink")) {
alienDrink();
}else{
print("That is a dangerous decision.");
}
}else if (hunger <= 4) {
print(ufo.name + " is mildly hungry, but is in a calm state.");
String action = userInput("Would you like to take any actions?");
if (action.equals("feed")){
feedAlien();
}else if (action.equals("drink")) {
alienDrink();
}else{
print("Okay.");
}
}else if (hunger <= 6) {
print(ufo.name + " is not hungry and is in a happy state.");
String action = userInput("Would you like to take any actions?");
if (action.equals("feed")){
feedAlien();
}else if (action.equals("drink")) {
alienDrink();
}else{
print("Okay.");
}
}
}
public void feedAlien() {
ufo.hungerRate = 6;
print(ufo.name + "'s hunger level replenished to max level 6.");
print(ufo.name + " is now at a happy level.");
}
public void alienDrink() {
ufo.thirst = 6;
print(ufo.name + "'s thirst level replenished to max level 6.");
}
public static int ranNum(int min, int max){ // A function that generates a random integer wihin a given range.
Random random = new Random();
return random.ints(min,(max+1)).findFirst().getAsInt();
} // END ranNum
} // END class alienPet
class Alien {
String name;
int age = 0;
int hungerRate;
int thirst = 6;
}
Obviously, some of the annotations are incomplete as of this time, but the issue I am having is in the alienBehaviour(), feedAlien() and alienDrink() procedures, I cannot seem to access the record created in the alienCreation() procedure.
The errors are all the same and is as follows:
alienPet.java:84: error: cannot find symbol
print(ufo.name + " is very hungry, and is dangerously angry!!");
^
symbol: variable ufo
location: class alienPet
Now I am new to java, so I'm not sure whether I have to make the record global or something, so any help would be greatly appreciated.
Variables declared inside of a method are called local variables and are likely disposed of when the method finishes executing.
Variables declared outside any function are called instance variables and they can be accessed (used) on any function in the program.
You are looking for an instance Alien ufo variable.
class alienPet{ // It is recommended you use the java naming convention.
Alien myAlien = new Alien();
// alienPet a = new alienPet();
// a.myAlien; // you could potentially do this to get an alien from an alienPet class
void someVoid(){
Alien otherAlien;
}
void errorVoid(){
otherAlien.toString();
// causes an error, the otherAlien variable is never visible to errorVoid as it is a local variable
myAlien.toString(); // OK
}
}
https://www.oracle.com/technetwork/java/codeconventions-135099.html
You're having problems with the scope of your variable. Variables are only valid within the curly braces which they were declared in.
WRONG
public void alienCreation ()
{
Alien ufo = new Alien();
ufo.name = userInput("What would you like to name your new alien?");
ufo.hungerRate = ranNum(1, 6);
print("On a scale of 1-6, your alien, " + ufo.name + ", has a hunger rate of " + ufo.hungerRate);
alienBehaviour(ufo.hungerRate);
return;
} // END alienCreation and of the scope of your variable ufo
RIGHT
class alienPet
{
Alien ufo;
[...]
public void alienCreation ()
{
ufo = new Alien();
ufo.name = userInput("What would you like to name your new alien?");
ufo.hungerRate = ranNum(1, 6);
print("On a scale of 1-6, your alien, " + ufo.name + ", has a hunger rate of " + ufo.hungerRate);
alienBehaviour(ufo.hungerRate);
return;
} // END alienCreation and your variable ufo will be initialized afterwards
}
I am using the template method. I have a driver that was supplied to me that creates a Game and passes through one of two switching classes, AlwaysSwitch or NeverSwitch. The driver then creates a trial for Always Switch and a separate trial of NeverSwitch. Each trial runs 100 times and tallies how many times each case wins the game.
Both of these classes extend Game. Game has an abstract method called switching(). Both switching classes inherit this method. I put a simple print statement in both classes. AlwaysSwitch has "I would like to switch", while NeverSwitch has "I will stay."
My problem is even in the Always switch trial which creates a new Game g = new AlwaysSwitch();, the output is always "I will stay." and in the new Game g = new NeverSwitch();, the output again is "I will stay.".
I have tried commenting out the NeverSwitch trial in the driver and only then will the AlwaysSwitch trial work.
I don't understand why the neverSwitch class is overriding the alwaysSwitch class?
public class Host {
private Door prizeDoor;
/**
* Choose a random prize door and keep it secret.
*/
public void choosePrizeDoor() {
prizeDoor = Door.randomDoor();
}
/**
* Reveal a door that does not contain the prize and does not
* match the one the contestant chose.
*/
public Door revealADoor(Door contestantChoice) {
Door result = contestantChoice;
// Randomly pick a door. Might iterate few times.
while (result == contestantChoice || result == prizeDoor) {
result = Door.randomDoor();
}
return result;
}
/**
* Determine if the contestant's door wins or loses.
*/
public boolean isAWinner(Door contestantChoice) {
return prizeDoor == contestantChoice;
}
}
/**
* An enum representing a door. Left = 1, center = 2, right = 3.
* Can also choose random doors here.
*
* #author Todd Whittaker
* #version 20180110
*/
public enum Door {
LEFT(1),
CENTER(2),
RIGHT(3);
private int value;
private static final Random r = new Random();
Door(int value) {
this.value = value;
}
/**
* Find the door that matches the number.
*/
public static Door valueOf(int num) {
switch (num) {
case 1: return LEFT;
case 2: return CENTER;
default: return RIGHT;
}
}
/**
* return the number matching this door.
*/
public int valueOf() {
return value;
}
/**
* Pick a random door (LEFT, CENTER, RIGHT).
*/
public static Door randomDoor() {
return Door.valueOf(r.nextInt(3)+1);
}
}
public abstract class Game {
private Host host;
public Door contestantChoice;
public Door revealedDoor;
/**
* Creates the game and its host.
*/
public Game () {
this.host = new Host();
}
/**
* Implements the algorithm for the game:
* 1. The host chooses which door has a prize at random.
* 2. The contestant picks a door (left, center, or right) at random.
* 3. The host reveals one of the two other doors that does not contain
the prize.
* 4. The contestant can then switch to the other door or keep their
current door.
* 5. The prize is revealed and the contestant wins or loses.
*/
final boolean runGame() {
host.choosePrizeDoor(); //1
System.out.println("Let's Play");
contestantChoice = contestantChoice.randomDoor();//2
System.out.println("Contestant chooses " + contestantChoice);
revealedDoor = host.revealADoor(contestantChoice); //3
System.out.println("reveal door " + revealedDoor);
System.out.println("would you like to switch?");
switching();
if(host.isAWinner(contestantChoice) == true)
{
System.out.println("Winner!! \n");
return true;
}
System.out.println("Sorry you lose \n");
return false;
}
abstract void switching();
}
public class AlwaysSwitch extends Game {
void switching()
{
System.out.println("I would like to switch" );
}
}
public class NeverSwitch extends Game {
void switching()
{
System.out.println("I will stay." );
}
}
public class Driver {
private static final int TRIALS = 100;
public static void main(String [] args) {
int switchWins = 0;
int stayWins = 0;
for (int i = 0; i < TRIALS; ++i) {
Game g = new AlwaysSwitch();
if (g.runGame()) {
++switchWins;
}
}
for (int i = 0; i < TRIALS; ++i) {
Game g = new NeverSwitch();
if (g.runGame()) {
++stayWins;
}
}
System.out.println("Out of " + TRIALS + " trials:");
System.out.println(" Switch won " + switchWins + " times.");
System.out.println(" Stay won " + stayWins + " times.");
}
}
All results say "I will stay."
To complete the code, you could change the signature of switching() to:
abstract Door switching(Door contestantsChoice, Door revealedDoor);
Then you would call it in Game.runGame() like this:
contestantsChoice = switching(contestantsChoice, revealedDoor);
Your AlwaysSwitch implementation would be:
Door switching(Door contestantChoice, Door revealedDoor)
{
System.out.println("I would like to switch" );
return selectRemainingDoor(contestantChoice, revealedDoor);
}
private Door selectRemainingDoor(Door contestantChoice, Door revealedDoor) {
List<Door> doors = new ArrayList<>(asList(LEFT, CENTER, RIGHT));
doors.remove(contestantChoice);
doors.remove(revealedDoor);
return doors.get(0);
}
And your NeverSwitch implementation would like like this:
Door switching(Door contestantChoice, Door revealedDoor)
{
System.out.println("I will stay." );
return contestantChoice;
}
I am programming a very basic bot for planet wars in java and I cant seem to find the errors in my code. I am receiving a few different error messages but the main issue for me is the error: class, interface, or enum expected. Ive checked my brackets about a thousand times. Any help would be appreciated. Here's my bot code:
import java.util.List;
import java.util.Random;
import shared.Planet;
import shared.PlanetWars;
public class MyNewBot {
public static void doTurn(PlanetWars pw) {
// (1) If we currently have a fleet in flight, then do nothing until
// it arrives.
if (pw.myFleets().size() >= 10) {
return;
}
// (2) Pick one of my planets based on the number of ships
Planet source = null;
int largestForce = 0;
for (Planet p : pw.myPlanets()){
int force = pw.numShips();
if( force > largestForce){
largestForce = force;
source = p;
}
}
// (3) Pick a target planet at random.
Planet dest = null;
int highestGrowthRate = 0;
int shortestDistance = 9999;
for (Planet p = pw.notMyPlanets()){
int growthRate = pw.growthRate();
if( growthRate > highestGrowthRate){
highestGrowthRate = growthRate;
dest = p;
}else if (growthRate == highestGrowthRate){
int distance = pw.distance(source,p);
if (distance < shortestDistance){
shortestDistance = distance;
dest = p;
}
}
}
// (4) Send half the ships from source to destination.
if (source != null && dest != null) {
int numShips = source.numShips() / 2;
pw.issueOrder(source, dest, numShips);
}
}
// Ignore the main method unless you know what you're doing.
// Refer to the doTurn function to code your bot.
public static void main(String[] args) {
String line = "";
String message = "";
int c;
try {
while ((c = System.in.read()) >= 0) {
switch (c) {
case '\n':
if (line.equals("go")) {
PlanetWars pw = new PlanetWars(message);
doTurn(pw);
pw.finishTurn();
message = "";
} else {
message += line + "\n";
}
line = "";
break;
default:
line += (char) c;
break;
}
}
} catch (Exception e) {
// Owned.
}
}
}
and the supporting class files:
package shared;
public class Planet implements Cloneable {
private int planetID;
private int owner;
private int numShips;
private int growthRate;
private double x, y;
public Planet(int planetID, int owner, int numShips, int growthRate,
double x, double y) {
this.planetID = planetID;
this.owner = owner;
this.numShips = numShips;
this.growthRate = growthRate;
this.x = x;
this.y = y;
}
public int planetID() {
return planetID;
}
public int owner() {
return owner;
}
public int numShips() {
return numShips;
}
public int growthRate() {
return growthRate;
}
public double x() {
return x;
}
public double y() {
return y;
}
public void owner(int newOwner) {
this.owner = newOwner;
}
public void numShips(int newNumShips) {
this.numShips = newNumShips;
}
public void addShips(int amount) {
numShips += amount;
}
public void removeShips(int amount) {
numShips -= amount;
}
private Planet(Planet _p) {
planetID = _p.planetID;
owner = _p.owner;
numShips = _p.numShips;
growthRate = _p.growthRate;
x = _p.x;
y = _p.y;
}
public Object clone() {
return new Planet(this);
}
}
package shared;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;
public class PlanetWars {
// Constructs a PlanetWars object instance, given a string containing a
// description of a game state.
public PlanetWars(String gameStateString) {
planets = new ArrayList<Planet>();
fleets = new ArrayList<Fleet>();
parseGameState(gameStateString);
}
// Returns the number of planets. Planets are numbered starting with 0.
public int numPlanets() {
return planets.size();
}
// Returns the planet with the given planet_id. There are NumPlanets()
// planets. They are numbered starting at 0.
public Planet getPlanet(int planetID) {
return planets.get(planetID);
}
// Returns the number of fleets.
public int numFleets() {
return fleets.size();
}
// Returns the fleet with the given fleet_id. Fleets are numbered starting
// with 0. There are NumFleets() fleets. fleet_id's are not consistent from
// one turn to the next.
public Fleet getFleet(int fleetID) {
return fleets.get(fleetID);
}
// Returns a list of all the planets.
public List<Planet> planets() {
return planets;
}
// Return a list of all the planets owned by the current player. By
// convention, the current player is always player number 1.
public List<Planet> myPlanets() {
List<Planet> r = new ArrayList<Planet>();
for (Planet p : planets) {
if (p.owner() == 1) {
r.add(p);
}
}
return r;
}
// Return a list of all neutral planets.
public List<Planet> neutralPlanets() {
List<Planet> r = new ArrayList<Planet>();
for (Planet p : planets) {
if (p.owner() == 0) {
r.add(p);
}
}
return r;
}
// Return a list of all the planets owned by rival players. This excludes
// planets owned by the current player, as well as neutral planets.
public List<Planet> enemyPlanets() {
List<Planet> r = new ArrayList<Planet>();
for (Planet p : planets) {
if (p.owner() >= 2) {
r.add(p);
}
}
return r;
}
// Return a list of all the planets that are not owned by the current
// player. This includes all enemy planets and neutral planets.
public List<Planet> notMyPlanets() {
List<Planet> r = new ArrayList<Planet>();
for (Planet p : planets) {
if (p.owner() != 1) {
r.add(p);
}
}
return r;
}
// Return a list of all the fleets.
public List<Fleet> fleets() {
List<Fleet> r = new ArrayList<Fleet>();
for (Fleet f : fleets) {
r.add(f);
}
return r;
}
// Return a list of all the fleets owned by the current player.
public List<Fleet> myFleets() {
List<Fleet> r = new ArrayList<Fleet>();
for (Fleet f : fleets) {
if (f.owner() == 1) {
r.add(f);
}
}
return r;
}
// Return a list of all the fleets owned by enemy players.
public List<Fleet> enemyFleets() {
List<Fleet> r = new ArrayList<Fleet>();
for (Fleet f : fleets) {
if (f.owner() != 1) {
r.add(f);
}
}
return r;
}
// Returns the distance between two planets, rounded up to the next highest
// integer. This is the number of discrete time steps it takes to get
// between the two planets.
public int distance(int sourcePlanet, int destinationPlanet) {
Planet source = planets.get(sourcePlanet);
Planet destination = planets.get(destinationPlanet);
double dx = source.x() - destination.x();
double dy = source.y() - destination.y();
return (int) Math.ceil(Math.sqrt(dx * dx + dy * dy));
}
// Returns the distance between two planets, rounded up to the next highest
// integer. This is the number of discrete time steps it takes to get
// between the two planets.
public int distance(Planet source, Planet destination) {
double dx = source.x() - destination.x();
double dy = source.y() - destination.y();
return (int) Math.ceil(Math.sqrt(dx * dx + dy * dy));
}
// Sends an order to the game engine. An order is composed of a source
// planet number, a destination planet number, and a number of ships. A
// few things to keep in mind:
// * you can issue many orders per turn if you like.
// * the planets are numbered starting at zero, not one.
// * you must own the source planet. If you break this rule, the game
// engine kicks your bot out of the game instantly.
// * you can't move more ships than are currently on the source planet.
// * the ships will take a few turns to reach their destination. Travel
// is not instant. See the Distance() function for more info.
public void issueOrder(int sourcePlanet, int destinationPlanet, int
numShips) {
System.out.println("" + sourcePlanet + " " + destinationPlanet + " "
+ numShips);
System.out.flush();
}
// Sends an order to the game engine. An order is composed of a source
// planet number, a destination planet number, and a number of ships. A
// few things to keep in mind:
// * you can issue many orders per turn if you like.
// * the planets are numbered starting at zero, not one.
// * you must own the source planet. If you break this rule, the game
// engine kicks your bot out of the game instantly.
// * you can't move more ships than are currently on the source planet.
// * the ships will take a few turns to reach their destination. Travel
// is not instant. See the Distance() function for more info.
public void issueOrder(Planet source, Planet dest, int numShips) {
System.out.println("" + source.planetID() + " " + dest.planetID() + " "
+ numShips);
System.out.flush();
}
// Sends the game engine a message to let it know that we're done sending
// orders. This signifies the end of our turn.
public void finishTurn() {
System.out.println("go");
System.out.flush();
}
// Returns true if the named player owns at least one planet or fleet.
// Otherwise, the player is deemed to be dead and false is returned.
public boolean isAlive(int playerID) {
for (Planet p : planets) {
if (p.owner() == playerID) {
return true;
}
}
for (Fleet f : fleets) {
if (f.owner() == playerID) {
return true;
}
}
return false;
}
// If the game is not yet over (ie: at least two players have planets or
// fleets remaining), returns -1. If the game is over (ie: only one player
// is left) then that player's number is returned. If there are no
// remaining players, then the game is a draw and 0 is returned.
public int winner() {
Set<Integer> remainingPlayers = new TreeSet<Integer>();
for (Planet p : planets) {
remainingPlayers.add(p.owner());
}
for (Fleet f : fleets) {
remainingPlayers.add(f.owner());
}
switch (remainingPlayers.size()) {
case 0:
return 0;
case 1:
return ((Integer) remainingPlayers.toArray()[0]).intValue();
default:
return -1;
}
}
// Returns the number of ships that the current player has, either located
// on planets or in flight.
public int numShips(int playerID) {
int numShips = 0;
for (Planet p : planets) {
if (p.owner() == playerID) {
numShips += p.numShips();
}
}
for (Fleet f : fleets) {
if (f.owner() == playerID) {
numShips += f.numShips();
}
}
return numShips;
}
// Returns the production of the given player.
public int production(int playerID) {
int prod = 0;
for (Planet p : planets) {
if (p.owner() == playerID) {
prod += p.growthRate();
}
}
return prod;
}
// Parses a game state from a string. On success, returns 1. On failure,
// returns 0.
private int parseGameState(String s) {
planets.clear();
fleets.clear();
int planetID = 0;
String[] lines = s.split("\n");
for (int i = 0; i < lines.length; ++i) {
String line = lines[i];
int commentBegin = line.indexOf('#');
if (commentBegin >= 0) {
line = line.substring(0, commentBegin);
}
if (line.trim().length() == 0) {
continue;
}
String[] tokens = line.split(" ");
if (tokens.length == 0) {
continue;
}
if (tokens[0].equals("P")) {
if (tokens.length != 6) {
return 0;
}
double x = Double.parseDouble(tokens[1]);
double y = Double.parseDouble(tokens[2]);
int owner = Integer.parseInt(tokens[3]);
int numShips = Integer.parseInt(tokens[4]);
int growthRate = Integer.parseInt(tokens[5]);
Planet p = new Planet(planetID++, owner, numShips, growthRate,
x, y);
planets.add(p);
} else if (tokens[0].equals("F")) {
if (tokens.length != 7) {
return 0;
}
int owner = Integer.parseInt(tokens[1]);
int numShips = Integer.parseInt(tokens[2]);
int source = Integer.parseInt(tokens[3]);
int destination = Integer.parseInt(tokens[4]);
int totalTripLength = Integer.parseInt(tokens[5]);
int turnsRemaining = Integer.parseInt(tokens[6]);
Fleet f = new Fleet(owner, numShips, source, destination,
totalTripLength, turnsRemaining);
fleets.add(f);
} else {
return 0;
}
}
return 1;
}
// Store all the planets and fleets. OMG we wouldn't wanna lose all the
// planets and fleets, would we!?
private ArrayList<Planet> planets;
private ArrayList<Fleet> fleets;
}
package shared;
public class Fleet implements Comparable<Fleet>, Cloneable {
private int owner;
private int numShips;
private int sourcePlanet;
private int destinationPlanet;
private int totalTripLength;
private int turnsRemaining;
public Fleet(int owner, int numShips, int sourcePlanet,
int destinationPlanet, int totalTripLength, int turnsRemaining) {
this.owner = owner;
this.numShips = numShips;
this.sourcePlanet = sourcePlanet;
this.destinationPlanet = destinationPlanet;
this.totalTripLength = totalTripLength;
this.turnsRemaining = turnsRemaining;
}
public Fleet(int owner, int numShips) {
this.owner = owner;
this.numShips = numShips;
this.sourcePlanet = -1;
this.destinationPlanet = -1;
this.totalTripLength = -1;
this.turnsRemaining = -1;
}
public int owner() {
return owner;
}
public int numShips() {
return numShips;
}
public int sourcePlanet() {
return sourcePlanet;
}
public int destinationPlanet() {
return destinationPlanet;
}
public int totalTripLength() {
return totalTripLength;
}
public int turnsRemaining() {
return turnsRemaining;
}
public void removeShips(int amount) {
numShips -= amount;
}
// Subtracts one turn remaining. Call this function to make the fleet get
// one turn closer to its destination.
public void TimeStep() {
if (turnsRemaining > 0) {
--turnsRemaining;
} else {
turnsRemaining = 0;
}
}
#Override
public int compareTo(Fleet f) {
return this.numShips - f.numShips;
}
private Fleet(Fleet _f) {
owner = _f.owner;
numShips = _f.numShips;
sourcePlanet = _f.sourcePlanet;
destinationPlanet = _f.destinationPlanet;
totalTripLength = _f.totalTripLength;
turnsRemaining = _f.turnsRemaining;
}
public Object clone() {
return new Fleet(this);
}
}
for (Planet p = pw.notMyPlanets()){ should be for (Planet p : pw.notMyPlanets()){.
You've not posted the Fleet class, so as it is the code won't compile for me. However, the above is the only other error I could see.
I get the following error when compiling my java implementation of a Sokoban game:
<<< Process finished. (Exit code 1) javac Sokobantest.java Process
started >>> .\Level.java:44: error: expected myPlayer =
new Player(this.room);
^ .\Level.java:44: error: cannot find symbol myPlayer = new Player(this.room); ^ symbol: class myPlayer location: class
Level Sokobantest.java:43: error: cannot find symbol Level myLevel =
new Level(this.room);
Here is my code so far:
Sokobantest.java
import java.io.BufferedReader;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Scanner;
/**
* This class is the second part for the Sokoban game
*
* #author Jane Doe 1234567 Group 42h
* #author John Doe 1234567 Group 42h
*/
class Sokobantest {
private final static int X = 0;
private final static int Y = 1;
private final static char WALL = '#';
private final static char PLAYER = '#';
private final static char BOX = '$';
private final static char GOAL = '.';
private final static char PLAYER_ON_GOAL = '+';
private final static char BOX_ON_GOAL = '*';
private final static char FREE = ' ';
private final static int[] UP = {0, -1};
private final static int[] DOWN = {0, 1};
private final static int[] LEFT = {-1, 0};
private final static int[] RIGHT = {1, 0};
//private static char[][] room;
private static int freeBox;
private static int emptyGoal;
private static int[] size = {-1, 0};
private static int[] player;
Level myLevel = new Level();
myLevel = new Level(this.room);
/**
* Function for vector addition
*
* #param first first vector
* #param second second vector
* #return new vector = first + second
*/
private static int[] add(int[] first, int[] second) {
return new int[]{first[X] + second[X], first[Y] + second[Y]};
}
/**
* The Main method for the Sokoban game with contains all of the game logic
*
* #param args args[0] the path to the level
*/
public static void main(String[] args) {
String file = "sokoban.txt";
if (args.length > 0) {
file = args[0];
}
if (!myLevel.isValidLevel(file)) {
System.err.println("Level has an invalid format");
return;
}
if (myLevel.isCompleted()) {
System.out.println("Yeah you have solved the level :)");
} else {
System.out.println("You have not solved the level :(");
}
System.out.println(myLevel.toString());
System.out.println("Goodbye");
}
}
Player.java
class Player{
//Standardkontruktor
public Player()
{
}
//Parametrisierter Konstruktor
public Player(char[][] room)
{
this.room = room;
}
//Attribut Raum
private static char[][] room;
//Attribut Spilerposition
//move Methode
/**
* Makes a move
*
* #param direction as a vector
* #return true iff it was successful, otherwise false
*/
private static boolean move(int[] direction) {
int[] next = add(player, direction);
switch (room[next[Y]][next[X]]) {
case BOX_ON_GOAL:
case BOX:
int[] behind = add(next, direction);
if (!(room[behind[Y]][behind[X]] == FREE || room[behind[Y]] [behind[X]] == GOAL)) {
return false;
}
if (room[next[Y]][next[X]] == BOX_ON_GOAL) {
emptyGoal++;
freeBox++;
}
if (room[behind[Y]][behind[X]] == GOAL) {
room[behind[Y]][behind[X]] = BOX_ON_GOAL;
emptyGoal--;
freeBox--;
} else {
room[behind[Y]][behind[X]] = BOX;
}
if (room[next[Y]][next[X]] == BOX_ON_GOAL) {
room[next[Y]][next[X]] = GOAL;
} else {
room[next[Y]][next[X]] = FREE;
}
case GOAL:
case FREE:
if (room[player[Y]][player[X]] == PLAYER_ON_GOAL) {
room[player[Y]][player[X]] = GOAL;
} else {
room[player[Y]][player[X]] = FREE;
}
player = next;
if (room[player[Y]][player[X]] == FREE) {
room[player[Y]][player[X]] = PLAYER;
} else {
room[player[Y]][player[X]] = PLAYER_ON_GOAL;
}
return true;
default:
return false;
}
}
}
Level.java
class Level{
//Standardkontruktor
public Level()
{
}
//Parametrisierter Konstruktor
public Level(char[][] room)
{
this.room = room;
}
//Objekt Namens myPlayer vom Typ Player als Attribut eines Levels
Player myPlayer = new Player();
myPlayer = new Player(this.room);
//Attribut Raum
private static char[][] room;
private boolean isValidLevel(String file){
return this.loadLevel(file);
}
//Methode LoadLevel
/**
* Loads the level from the "file" and validate it
*
* #param file path to the file
* #return false iff an error occurs or the level is invalid, true otherwise
*/
private static boolean loadLevel(String file) {
BufferedReader bufferedReader;
try {
bufferedReader = Files.newBufferedReader(Paths.get(file));
bufferedReader.mark(100 * 100);
String line;
while ((line = bufferedReader.readLine()) != null) {
size[Y]++;
if (size[X] > -1 && size[X] != line.length()) {
return false;
} else {
size[X] = line.length();
}
}
bufferedReader.reset();
room = new char[size[Y]][];
int i = 0;
while ((line = bufferedReader.readLine()) != null) {
room[i] = new char[line.length()];
for (int j = 0; j < line.length(); j++) {
room[i][j] = line.charAt(j);
}
i++;
// oder room[i++] = line.toCharArray();
}
bufferedReader.close();
} catch (IOException e) {
return false;
}
for (int i = 0; i < room.length; i++) {
for (int j = 0; j < room[i].length; j++) {
switch (room[i][j]) {
case FREE:
case BOX_ON_GOAL:
case WALL:
break;
case PLAYER_ON_GOAL:
emptyGoal++;
case PLAYER:
if (player != null) {
return false;
} else {
player = new int[]{j, i};
}
break;
case BOX:
freeBox++;
break;
case GOAL:
emptyGoal++;
break;
default:
return false;
}
}
}
return !(player == null || emptyGoal != freeBox);
}
//Methode toString für die Ausgabe des Spielfeldes
/**
* Prints the level to the output stream
*/
public String toString() {
String safwensTempString= "";
for (char[] row : room) {
safwensTempString=safwensTempString+row;
}
}
/**
* Game logic for Sokoban
*
* #return true if the level was solved, otherwise false
*/
private static boolean isCompleted() {
// create new Scanner that reads from console
Scanner input = new Scanner(System.in);
// flag if we quit the program
boolean run = true;
int[] direction;
do {
System.out.println(myLevel.toString());
System.out.println("Do you want to go up, down, left, right or exit the program?");
// check which command was chosen and execute it
switch (input.next()) {
case "w":
case "up":
direction = UP;
break;
case "s":
case "down":
direction = DOWN;
break;
case "a":
case "left":
direction = LEFT;
break;
case "d":
case "right":
direction = RIGHT;
break;
case "exit":
run = false;
continue;
default: // if the user input is not one of our commands print help
System.out.println("Command unknown! Please type up, down, left or right to move or exit to quit this program");
continue;
}
if (!myPlayer.move(direction)) {
System.out.println("You can not go there!");
}
} while (run && emptyGoal != 0 && freeBox != 0);
return run;
}
}
Thanks in advance for any hints or help!
EDIT
I compile in Notepad++ like this:
Statements have to be placed inside methods (or an initialiser block which is added to the constructor). You can only declare and initialise a field outside a method.
Instead of
Level myLevel = new Level();
myLevel = new Level(this.room);
you can write
Level myLevel = new Level(this.room);
Let me give an example of a hello world program with two classes
$ vi A.java
class A {
static B b = new B();
public static void main(String...a) {
System.out.println(b.message);
}
}
$ vi B.java
class B {
String message = "Hello World";
}
$ javac A.java
$ java A
prints
Hello World
All of the program's templates. This was a past assignment but at this point, I'm just trying to understand what's going on.
Under the Apartment class, I'm confused on how to correctly return an array of window orders for one unit, all units, and then the #Override method under ThreeBedroom.
Just for reference of what I've done so far (probably not all correct):
public class Window {
private final int width, height;
public Window(int width, int height) {
this.width = width;
this.height = height;
}
// print text like: 4 X 6 window
public String toString() {
String s = "";
s = width + " x " + height + " window";
return s;
}
// compare window objects by their dimensions
public boolean equals(Object that) {
if (that instanceof Window) {
Window w = (Window) that;
return this.width == w.width && this.height == w.height;
}
else { return false; }
}
}
class WindowOrder {
final Window window; // window description (its width and height)
int num; // number of windows for this order
WindowOrder(Window window, int num) {
this.window = window;
this.num = num;
}
// add the num field of the parameter to the num field of this object
//
// BUT
//
// do the merging only of two windows have the same size
// do nothing if the size does not match
//
// return the current object
WindowOrder add(WindowOrder order) {
if (order.equals(window)) {
this.num -= num;
return order;
}
else {
return order;
}
}
// update the num field of this object by multiplying it with the parameter
// and then return the current object
WindowOrder times(int number) {
WindowOrder window = new WindowOrder(this.window, this.num);
this.num *= number;
return window;
}
// print text like: 20 4 X 6 window
#Override
public String toString() {
String s = "";
s = num + " " + window.toString();
return s;
}
// Two orders are equal if they contain the same number of windows of the same size.
#Override
public boolean equals(Object that) {
if (that instanceof WindowOrder) {
WindowOrder order = (WindowOrder) that;
return this.num == order.num && this.window == order.window;
}
else { return false; }
}
}
public class Room {
Window window;
int numOfWindows;
Room(Window window, int numOfWindows) {
this.window = window;
this.numOfWindows = numOfWindows;
}
WindowOrder order() {
return new WindowOrder(window, numOfWindows);
}
// Print text like: 5 (6 X 8 window)
#Override
public String toString() {
String s = "";
s = numOfWindows + " (" + window.toString() + ")";
return s;
}
// Two rooms are equal if they contain the same number of windows of the same size
#Override
public boolean equals(Object that) {
if (that instanceof Room) {
Room room = (Room) that;
return this.window == room.window && this.numOfWindows == room.numOfWindows;
}
else { return false; }
}
}
class MasterBedroom extends Room {
MasterBedroom() {
super(new Window(4, 6), 3);
}
// Call parent's toString method
//
// return text like: Master bedroom: 3 (4 X 6 window)
#Override
public String toString() {
String s = "";
s = "Master bedroom: " + numOfWindows + " " + window.toString();
return s;
}
}
class GuestRoom extends Room {
GuestRoom() {
super(new Window(5, 6), 2);
}
// Call parent's toString method
//
// return text like: Guest room: 2 (5 X 6 window)
#Override
public String toString() {
String s = "";
s = "Guest room: " + numOfWindows + " " + window.toString();
return s;
}
}
class LivingRoom extends Room {
LivingRoom() {
super(new Window(6, 8), 5);
}
// Call parent's toString method
//
// return text like: Living room: 5 (6 X 8 window)
#Override
public String toString() {
String s = "";
s = "Living room: " + numOfWindows + " " + window.toString();
return s;
}
}
For Apartment's orderForOneUnit() method, I wrote this, but it seems to simplistic and I feel like I should be using a for loop..
WindowOrder[] orderForOneUnit() {
WindowOrder[] order = new WindowOrder[rooms.length];
return order;
}
Am I even close to correctly understanding this? What should be under the Apartment methods?
Didn't looks at the templates but from what you've provided, you're close. All you've done so far is create a WindowOrder[] array of length rooms. You need to add new WindowOrder(desc, num) to these arrays before return order;
/**
* All apartment rooms have the same number of windows, with the
* same size window for each of those.
*/
public class Apartment
{
private int numRooms_;
private int windowsPerRoom_;
private Window window_;
/**
* Constructor
*/
public Apartment(numRooms, windowsPerRoom, desiredWindowHeight, desiredWindowLength)
{
numRooms_ = numRooms;
windowsPerRoom_ = windowsPerRoom;
window_ = new Window(desiredWindowHeight, desiredWindowLenght);
}
/**
* Orders for one room in apartment
*/
public WindowOrder orderForOneUnit()
{
WindowOrder order = new WindowOrder(window_, 1);
return order;
}
/**
* Orders for all rooms in apartment
*/
public List<WindowOrder> orderForAllUnits()
{
List<WindowOrder> orders = new ArrayList<WindowOrder>();
WindowOrder order;
for(i=0; i<numRooms_; i++)
{
orders.add(new WindowOrder(window_, windowsPerRoom_);
}
return orders;
}
}
Now when you're in your code and you're ready for a new Apartment(x, x, x, x) you can do the following (I'll assume you're just in main())
public class ApartmentComplex
{
public static void main(String[] args)
{
int numWindowsPerRoom = 3;
int desiredWindowHeight = 10;
int desiredWindowWidth = 10;
int numRooms = 5;
Apartment aptWithFiveRooms = new Apartment(numRooms, numWindowsPerRoom, desiredWindowHeight, desiredWindowWidth);
WindowOrder singleSingleOrder = apt.orderForOneUnit();
List<WindowOrder> allRoomsOrder = apt.orderForAllUnits();
numRooms = 3;
Apartment aptWithThreeRooms = new Apartment(numRooms, numWindowsPerRoom, desiredWindowHeight, desiredWindowWidth);
List<WindowOrder> threeRoomsOrder = apt.orderForAllUnits();
}
}
You do need a for loop. At the moment you are returning an Array where each entry in the array is null.
Here is an example of filling an array:
for (int i = 0; i < array.length; i++) { // iterate over an array
array[i] = getValueFor(i); // put value in the array
}