My first class called Match creates an individual soccer/football game. It makes you choose 2 teams and the final score. The second class called "team" is a bit more advanced. When the play (match match) method is called, the number of games played increments by 1. This part works fine. My else if statements for (goalsForThisMatch) also works fine. However, when I inspect the Team class object, it should display the same goals for and goals against that I inputted in the Match class. What actually happens is when I inspect the Team class after pressing the play(Match match) method, most of the methods are set to 0, except the "played" method (which increments by 1 like it's supposed to) and whatever the final score is. So if I inputted the score in the match class so that the home team has scored more goals and has won the match, then the Won method in the object inspector for the Team class will go up by 1. I need two of the other methods in the team class to link with the match class. These methods are: Goals For and Goals Against. If I input the GoalsFor in the match class to be "4" then when I inspect the Team class the goalsFor should be set to 4 also.
I know this all probably sounds VERY confusing, please forgive me, I'm so TIRED I'm about to head off to sleep. Hopefully in the morning, someone would have sorted this issue for me.
public class Match
// instance variables - replace the example below with your own
private String HomeTeam;
private String AwayTeam;
private int HomeGoals;
private int AwayGoals;
/**
* Constructor for objects of class Match
*/
public Match(String ShortHomeTeamName, String ShortAwayTeamName, int NewHomeGoals, int NewAwayGoals)
{
// initialise instance variables
HomeTeam = ShortHomeTeamName;
AwayTeam = ShortAwayTeamName;
HomeGoals = NewHomeGoals;
AwayGoals = NewAwayGoals;
}
public String getHomeTeamName(){
return HomeTeam;
}
public String getAwayTeamName(){
return AwayTeam;
}
public int getHomeGoals(){
return HomeGoals;
}
public int getAwayGoals(){
return AwayGoals;
}
}
public class Team
private String TeamName;
private String ShortName;
private int Played;
private int GoalsFor;
private int GoalsAgainst;
private int GoalDifference;
private int Won;
private int Drawn;
private int Lost;
private int Points;
/**
* Constructor for objects of class Team
*/
public Team(String FullTeamName, String ShortTeamName)
{
// initialise instance variables
TeamName = FullTeamName;
ShortName = ShortTeamName;
Played = 0;
GoalsFor = 0;
GoalsAgainst = 0;
GoalDifference = 0;
Won = 0;
Drawn = 0;
Lost = 0;
Points = 0;
}
public String getTeamName(){
return TeamName;
}
public String getShortName(){
return ShortName;
}
public int getPlayed(){
return Played;
}
public void getGoalsFor(int InsertGoalsFor){
GoalsFor = InsertGoalsFor;
}
public void getGoalsAgainst(int InsertGoalsAgainst){
GoalsAgainst = InsertGoalsAgainst;
}
public int getGoalDifference(){
return (GoalsFor - GoalsAgainst);
}
public int getWon(){
return Won;
}
public int getDrawn(){
return Drawn;
}
public int getLost(){
return Lost;
}
public int getPoints(){
return Points;
}
public void play(Match match){
Played++;
int GoalsFor = match.getHomeGoals();
int goalsForThisMatch = match.getHomeGoals();
int goalsAgainstThisMatch = match.getAwayGoals();
String homeTeam = match.getHomeTeamName();
String ShortName = match.getHomeTeamName();
if (ShortName.equals(TeamName)){
ShortName = homeTeam;
} else {
ShortName = match.getAwayTeamName();
}
if (goalsForThisMatch > goalsAgainstThisMatch){
Won++;
}
else if (goalsForThisMatch == goalsAgainstThisMatch){
Drawn++;
}
else {
Lost++;
}
}
}
I believe the problem you're having is that the fields of your Team class are not being updated when you invoke the play method.
The reason you see this behavior is that you're defining local variables inside the play method that hide your class member variables:
public void play(Match match){
...
int GoalsFor = match.getHomeGoals();
int goalsForThisMatch = match.getHomeGoals();
int goalsAgainstThisMatch = match.getAwayGoals();
String homeTeam = match.getHomeTeamName();
String ShortName = match.getHomeTeamName();
...
Your GoalsFor and ShortName local variables defined inside this method are hiding the class member variables you defined at the top of the class:
public class Team
private String TeamName;
private String ShortName;
private int Played;
private int GoalsFor;
...
Related
As the code showed below, I'm trying to make user input the speed (1,2,3) into the enum and return the input back into toString method.
private enum speed
{
SMALL(1),
MEDIUM(2),
FAST(3);
private int speedValue;
private speed (int speedValue)
{
this.speedValue = speedValue;
}
public int getSpeed()
{
return speedValue;
}
public static Optional<speed> get(int speedValue)
{
return Arrays.stream(speed.values())
.filter(spe -> spe.speedValue == speedValue)
.findFirst();
}
}
private boolean on;
The problem is when I put this.speed = speed or any other stuff, the speed class will be missing with error "speed cannot be resolved or is not a field"
This happened the same in the toString class.
public Fan(speed seed, boolean on)
{
speed.get() = seed; //what shall i put here
this.on = on;
}
public boolean getOn()
{
return this.on;
}
public String toString()
{
return speed; //what shall i put here
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("Please enter speed");
int sp = sc.nextInt();
System.out.println("On/Off");
boolean on = sc.nextBoolean();
Optional<speed>spe = speed.get(sp); //getting enum integer values
System.out.println(spe.get());
Fan fan = new Fan(sp, on)
Is there any solution that I would be able to return the integer value of enum into the public class and toString class?
With private enum speed {...} you declare the enum type speed, but you never declare a field of this type.
If you want to have a field named speed of this enum type you must declare it with private speed speed;.
This looks confusing and therefore I suggest that you follow the Java naming conventions where names of classes start with an uppercase letter (and enum types are classes).
That means your enum type should be written as
public enum Speed {
SMALL(1),
MEDIUM(2),
FAST(3);
private int speedValue;
private Speed (int speedValue) {
this.speedValue = speedValue;
}
public int getSpeed() {
return speedValue;
}
public static Optional<Speed> get(int speedValue) {
return Arrays.stream(Speed.values())
.filter(spe -> spe.speedValue == speedValue)
.findFirst();
}
}
Your Fan class needs these fields:
private boolean on;
private Speed speed;
The constructor is
public Fan(Speed seed, boolean on) {
speed = seed;
this.on = on;
}
or, assuming that the parameter name seed is a spelling mistake and it should be speed instead:
public Fan(Speed speed, boolean on) {
this.speed = speed;
this.on = on;
}
The other methods:
public boolean getOn() {
return this.on;
}
public String toString() {
return speed.toString();
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("Please enter speed");
int sp = sc.nextInt();
System.out.println("On/Off");
boolean on = sc.nextBoolean();
Optional<Speed> spe = Speed.get(sp); //getting enum integer values
System.out.println(spe.get());
Fan fan = new Fan(spe.get(), on);
// note that the above line produces not output. Why should it?
// if you want to see the result of f.toString() you need to print it out:
System.out.println(fan.toString());
// or shorter (since println() calls toString() automatically):
System.out.println(fan);
}
Note 1: I also changed the placement of the opening braces ({) to follow general Java conventions - for seasoned Java programmers this looks less surprising.
Note 2: as Mark Rotteveel correctly remarks: the Fan class has a public constructor and therefore the Speed enum should also be declared public. Otherwise no one outside of the Fan class will be able to construct a new Fan object.
I have been creating a java text game but I am stuck trying to figure out on how to implement the last 2 methods. I want it to print out the items in the room and the name of the npc thats in the room (A sort of a Look function). I am not sure on how to go on about it. Any help would be appriciated.
Room[] place = new Room[]{station, UC, Ollies, lounge, palace, AT301};
Sword sword = new Sword();
Thing heal = new HealthPotion();
Thing armour = new Armour();
Thing trap = new Trap();
and for the NPC (Mike, Jake, Evil, Carl)
public abstract class Player{
//abstract attributes
private String name;
private int currentHealth;
private int maxHealth;
private int damage;
private Room currentRoom;
private int stack;
private int effect;
//Constructor for player
public Player(String name, int currentHealth, int maxHealth, int damage, int effect, int stack){
this.name = name;
this.currentHealth = currentHealth;
this.maxHealth = maxHealth;
this.damage = damage;
this.effect = effect;
this.stack = stack;
}
//getters
public String getName(){ return name;}
public int getCurrentHealth(){ return currentHealth;}
public int getMaxHealth(){ return maxHealth;}
public int getDamage(){ return damage;}
public Room getCurrentRoom(){ return currentRoom;}
public int getEffect(){ return effect;}
public int getStack(){ return stack;}
//setters
public void setCurrentHealth(int currentHealth){this.currentHealth = currentHealth;}
public void setMaxHealth(int maxHealth){this.maxHealth = maxHealth;}
public void setDamage(int damage){ this.damage = damage;}
public void setCurrentRoom(Room room){this.currentRoom = room;}
public void setEffect(int effect){ this.effect = effect;}
public void setStack(int stack){ this.stack = stack;}
public void enter(Room room){ this.currentRoom = room;}
//abstract method because each player has a different attack;
public void takeDamage(int damage){ setCurrentHealth(this.currentHealth-damage);}
public boolean isDead(){
if(this.currentHealth<=0){ return true;}
return false;
}
}
I was able to make everything functional except the Look function for the player. I can't figure out how to go on about it.
Room is a vector of items right ? If so you can do a function on the player class that when it is called it goes to the vector of the room you're in and simply print out the items that are in the vector, something like this:
String lookAround(){
ArrayList temp = (ArrayList)getCurrentRoom(); //returns the array containing the items in the current room
for(Thing i : temp){
i.getDescription(); //Method present in all classes that come from Thing that prints out the name of the item and/or its caracheteristics
}
}
In the array of the room you should try to include the name of all players in the room including yourself so that you can print out everyone present in the room
Hope this helps
I would recommend you first of all creating a class Npc with attribute name and add it to the room.
I don't get what's going on here, but the final method
s.castable()
that overrides the motherclass's namesake abstract method doesn't get called.
Here is where I try to call s.castable():
public void cast(String[] request) {
System.out.println("cast called");
if (this.session.getPlayer()==this.game.getTurnPlayer()) {
System.out.println("first condition passed");
Spell s = this.session.getPlayer().getCharacter().getSpells().get(Integer.valueOf(request[1]));
ArrayList<String> usernames = new ArrayList();
System.out.println("Now printing spell: "+s);
for (int i = 6; i < request.length; i++) {
usernames.add(request[i]);
}
System.out.println("username create.d");
if (s.castable()) { //HERE
System.out.println("Second condition passed");
s.cast(Integer.valueOf(request[1]), Integer.valueOf(request[2]),request[3].charAt(0), request[4].charAt(0), usernames);
String str = "";
for (String st : usernames) {
str += st;
}
this.session.send("YOUSPELL "+request[1]+" "+request[2]+" "+request[3]+" "+request[4]+" "+str);
System.out.println("Done");
}
}
}
Here is the "Spell" MotherClass:
public abstract class Spell {
private int manaCost;
private int coolDown;
private int range;
private Player player;
public abstract void cast(int x, int y, char mode1, char mode2,ArrayList<String> usernames);
public abstract Boolean castable();
//Then all getters and setters.
}
And here is the final class "Velocity":
public final class Velocity extends Spell {
private final int manaCost;
private final Player player;
private final int coolDown;
private final int coolDownTime;
private final int additionalMovement;
private final int spellRef;
private final ArrayList<String> usernames = new ArrayList();
public Velocity(Player p) {
this.spellRef = 0;
this.additionalMovement = 5;
this.player = p;
this.manaCost = 5;
this.coolDownTime = 3;
this.coolDown = 0;
super.setCoolDown(coolDown);
super.setManaCost(manaCost);
super.setPlayer(p);
}
#Override
public final void cast(int x, int y, char mode1, char mode2,ArrayList<String> usernames) {
System.out.println("Velocity casted.");
player.setMovement(player.getMovement() + additionalMovement);
setCoolDown(coolDownTime);
}
#Override
public final Boolean castable() {
System.out.println(player.getMana());
System.out.println(manaCost);
System.out.println(getCoolDown());
if (player.getMana() >= manaCost && getCoolDown() >= 0) {
return true;
}
return false;
}
}
Finally, the console output:
cast called
first condition passed
Now printing spell: model.haraka.be.Velocity#739bb60f
username create.d.
As you can see the spell object is known.
Can you help me ?
Thank you
The only possible problem here can be that Abstract class Spell's variable s doesn't contain the reference to Velocity object.
hence the castable method of velocity class never gets called.
If the castable method is returning false as mentioned by many
people System.out.println() statements must be printed which is not
the case I think.
But to be sure this is the problem, Please explain:
Spell s = this.session.getPlayer().getCharacter().getSpells().get(Integer.valueOf(request[1]));
What are below methods return type ?
getPlayer()
getSpells()
get(Integer.valueOf(request[1])
This is too much to ask/comment in comment section hence posting as an answer.
I'm not sure how eloquently I can really explain what I don't understand/need help with, I'm still Very new to Object Oriented Programming. This is regarding my coursework and I don't expect anyone to do it for me, I just need help understanding how to move on, and if I'm even on the right track.
Ok, so on to my question. Basically, I am attempting to create an arraylist which will hold a few objects which themselves has a bunch of information(obviously), my spec said to create an abstract class, which will be extended by my constructor class, which I did. The abstract class has a few variables (decided by spec) But I dont know how to move them over to my extended class.
I'll post my code below, and I hope it makes sense. I'd be very thankful for any help you all could provide. I'm very confused right now.
Basically, I would love to know, A) How do I create an object in my arraylist which will be able to contain everything in SportsClub and FootballClub, and preferably all the variables user inputted.
And B) I don't know how to print The object, When I print right now I get coursework.FootballClub#49233bdc, Which I'm sure there's a reason for but I need the information in the objects to display, E.g. name. And if possible to sort the results by alphabetical order with respect to name? I hope this is all written ok. Sorry and Thank you in advance.
package coursework;
import java.util.*;
/**
*
* #author w1469384
*/
public class PremierLeagueManager implements LeagueManager{
public static void main(String[] args) {
Scanner c1 = new Scanner(System.in);
Scanner c2 = new Scanner(System.in);
ArrayList<FootballClub> PL = new ArrayList<FootballClub>();
int choice;
System.out.println("Enter 1; To create a club, 2; To Delete a Club, 3; To display all clubs and 99 to close the program");
choice = c1.nextInt();
//Creates and adds a new FootballClub Object
while (choice != 99){
if (choice == 1){
System.out.println("Please Enter The games played for the club");
int played = c1.nextInt();
System.out.println("Please enter the number of wins");
int wins = c1.nextInt();
System.out.println("please enter the number of losses");
int losses = c1.nextInt();
System.out.println("please enter the number of draws");
int draws = c1.nextInt();
System.out.println("please enter the number of goals for");
int goalsFor = c1.nextInt();
System.out.println("please enter the number of goals against");
int goalsAgainst = c1.nextInt();
FootballClub club = new FootballClub(played, wins, losses, draws, goalsFor, goalsAgainst);
PL.add(club);
System.out.println("check");
}
//Deletes a FootballClub Object
if (choice == 2){
}
//Displays all Football Clubs in the PremierLeague array
if (choice == 3){
System.out.println(PL);
}
//Closes the Program 1
choice = c1.nextInt();
}
}
}
public abstract class SportsClub {
public String name;
public String location;
public int capacity;
public void setName(String Name){
name = Name;
}
public void setLocation(String Location){
location = Location;
}
public void setCapacity(int Capacity){
capacity = Capacity;
}
public String getName(){
return name;
}
public String getLocation(){
return location;
}
public int getCapacity(){
return capacity;
}
}
public class FootballClub extends SportsClub {
//Statistics for the club.
int played;
int wins;
int losses;
int draws;
int goalsFor;
int goalsAgainst;
public FootballClub(int gPlayed, int gWins, int gLosses, int gDraws, int gFor, int gAgainst){
played = gPlayed;
wins = gWins;
losses = gLosses;
draws = gDraws;
goalsFor = gFor;
goalsAgainst = gAgainst;
}
public void setPlayed(int newPlayed){
played = newPlayed;
}
public void setWins(int newWins){
wins = newWins;
}
public void setLosses(int newLosses){
losses = newLosses;
}
public void setDraws(int newDraws){
draws = newDraws;
}
public void setGoalsFor(int newGoalsFor){
goalsFor = newGoalsFor;
}
public void setGoalsAgainst(int newGoalsAgainst){
goalsAgainst = newGoalsAgainst;
}
public int getPlayed(){
return played;
}
public int getWins(){
return wins;
}
public int getLosses(){
return losses;
}
public int getDraws(){
return draws;
}
public int getGoalsFor(){
return goalsFor;
}
public int getGoalsAgainst(){
return goalsAgainst;
}
}
FootballClub inherits the variables declared in SportsClub so you can set them as you please.
public FootballClub(
int gPlayed, int gWins, int gLosses, int gDraws, int gFor, int gAgainst,
String inName, String inLocation, int inCapacity
) {
played = gPlayed;
wins = gWins;
losses = gLosses;
draws = gDraws;
goalsFor = gFor;
goalsAgainst = gAgainst;
// set the variables from the superclass
name = inName;
location = inLocation;
capacity = inCapacity;
}
FootballClub also inherits the methods declared in SportsClub so you can use the setters and getters too.
Normally you would create a constructor for SportsClub that sets these and then call that constructor from the FootballClub constructor.
// in SportsClub
protected SportsClub(
String inName, String inLocation, int inCapacity
) {
name = inName;
location = inLocation;
capacity = inCapacity;
}
// in FootballClub
public FootballClub(
int gPlayed, int gWins, int gLosses, int gDraws, int gFor, int gAgainst,
String inName, String inLocation, int inCapacity
) {
super(inName, inLocation, inCapacity);
played = gPlayed;
wins = gWins;
losses = gLosses;
draws = gDraws;
goalsFor = gFor;
goalsAgainst = gAgainst;
}
You should also make your member variables protected or private if you are using setters and getters.
I don't know how to print The object
You need to override toString. There is a short tutorial here.
Also unrelated side note: all Java variable identifiers should start with a lowercase letter.
When you have a method like this:
public void setName(String Name) { name = Name; }
It should be:
public void setName(String inName) { name = inName; }
Or:
public void setName(String name){ this.name = name; }
It's a little bit difficult but i'll try to explain my problem. I've created a program with a superclass (RichIndustrialist) two subclasses (PredecessorRichIndustrialist and another one I didn't add) and 4 subclasses to these subclasses (CrazyRichIndustrialist and another 3). Now, the program is too difficult to explain but the problem is actually simple. My constructor is in the superclass and every subclass use it to initilize. Every time I create a new subclass object like CrazyRichIndustrialist, it resets all the already existed subclasses (from any subclass) to the value of the new object. I don't know how to fix this. Thank you in advance...
RichIndustrialist:
package Mortal;
import java.util.Random;
public class RichIndustrialist implements Mortal {
private static String Name;
private static double holdings;
private static int Alive;
public RichIndustrialist(String Rich_Name, double Rich_holdings) {
this.Name = Rich_Name;
this.holdings = Rich_holdings;
this.Alive = 1;
}
public int isAlive() {
return (this.Alive);
}
public void setHoldings(double new_holdings) {
this.holdings = new_holdings;
}
public double getHoldings() {
return (this.holdings);
}
public String getName() {
return (this.Name);
}
public void die() {
this.Alive = 0;
}
public void getHeritage(double heritage) {
this.holdings = this.holdings + heritage;
}
}
PredecessorRichIndustrialist:
package Mortal;
import java.util.Arrays;
public class PredecessorRichIndustrialist extends RichIndustrialist {
private static String Name;
private static double holdings;
private RichIndustrialist[] successors = {};
private static int Alive;
public PredecessorRichIndustrialist(String Rich_Name, double Rich_holdings) {
super(Rich_Name,Rich_holdings);
}
public void die() {
super.die();
}
public void Inheritance(double holdings, RichIndustrialist[] successors) {
int i = 0;
while (i < successors.length) {
int Alive = successors[i].isAlive();
System.out.println(Alive);
if (Alive == 0) {
removeSuccessor(successors[i]);
i++;
} else {
i++;
}
}
}
public void addSuccessor(RichIndustrialist new_successor) {
RichIndustrialist[] new_successors = new RichIndustrialist[successors.length + 1];
if (successors.length == 0) {
new_successors[0] = new_successor;
successors = new_successors;
} else {
for (int i = 0; i < successors.length; i++) {
new_successors[i] = successors[i];
}
new_successors[new_successors.length - 1] = new_successor;
}
this.successors = new_successors;
}
public void removeSuccessor(RichIndustrialist removed_successor) {
RichIndustrialist[] new_successors = new RichIndustrialist[this.successors.length - 1];
int j = 0;
for (int i = 0; i < this.successors.length; i++) {
if (!this.successors[i].equals(removed_successor)) {
new_successors[j] = this.successors[i];
} else {
j--;
}
j++;
}
}
public RichIndustrialist[] getSuccessors() {
return successors;
}
}
CrazyRichIndustrialist:
package Mortal;
import java.util.Random;
public class CrazyRichIndustrialist extends PredecessorRichIndustrialist {
private RichIndustrialist[] successors = {};
private static String Name;
private static double holdings;
private static int Alive;
public CrazyRichIndustrialist(String Rich_Name, double Rich_holdings) {
super(Rich_Name,Rich_holdings);
}
public void die() {
super.die();
Inheritance(getHoldings(),getSuccessors());
}
public void addSuccessor(RichIndustrialist new_successor) {
super.addSuccessor(new_successor);
}
public void removeSuccessor(RichIndustrialist removed_successor) {
super.removeSuccessor(removed_successor);
}
public void Inheritance (double holdings , RichIndustrialist[] successors) {
super.Inheritance(holdings, successors);
for (int i=0; i<successors.length-1; i++)
{
double random = new Random().nextDouble();
double amount = this.holdings * random;
successors[i].getHeritage(amount);
holdings = this.holdings - amount;
}
successors[successors.length-1].getHeritage(this.holdings);
this.holdings = 0;
}
public String getName(){
return super.getName();
}
public double getHoldings(){
return super.getHoldings();
}
public RichIndustrialist[] getSuccessors(){
return super.getSuccessors();
}
public void setHoldings(double new_holdings){
super.setHoldings(new_holdings);
}
public int isAlive() {
return super.isAlive();
}
public void getHeritage(double heritage) {
super.getHeritage(heritage);
}
}
Most of your fields are static. What that means is that all the instances of your classes share the same value. When you call the constructor, the static fields are modified, which affects all the existing instances.
For example:
this.Name = Rich_Name;
should actually have been written:
RichIndustrialist.Name = Rich_Name;
You can read about the difference between instance and class (or static) members in this tutorial.
The following fields should be declared as non-static. When these fields are declared as static each RichIndustrialist instance will share these fields and their assigned values. Declaring them as non-static allows each RichIndustrialist instance to have its own copy of these fields, which is autonomous from the other instances of RichIndustrialist.
private String Name;
private double holdings;
private int Alive;
Here is a good description of static from the Java Tutorial
Sometimes, you want to have variables that are common to all objects.
This is accomplished with the static modifier. Fields that have the
static modifier in their declaration are called static fields or class
variables. They are associated with the class, rather than with any
object. Every instance of the class shares a class variable, which is
in one fixed location in memory. Any object can change the value of a
class variable, but class variables can also be manipulated without
creating an instance of the class.
Your properties/variables are static. and we know static variable are shared between all the objects.
That is the reason the last object will replace the existing value of your variables
Suggestion:
change your static modifier to instance modifier
From
private static String Name;
private static double holdings;
private static int Alive;
To
private String Name;
private double holdings;
private int Alive;
I am sure your problem will resolve.
You are declaring the Name member field in all of your classes, you should only declare it in the super-class and let the other sub-classes (re)use it.
Furthermore, you declared the field as static, all instances of your class will use the same field, which is probably not what you intended, so remove the static part.
Same goes for all of your other member fields.
Note: do not start the member fields with a capital: Name should be defined and used as name. Class names on the other hand should start with a capital! This is a generically accepted Java convention and keeps things more clear/separated.