Java object scope, referencing from a method - java

I'm having some trouble getting scope right in my head. I understand why the code below won't work, but I don't understand conceptually how I should be doing it.
public class Game {
private String playerName = "";
private int numberOfPegs = 0;
private boolean gameRunning = "True";
public static void main(String[] args) {
Game game = new Game();
game.setupGame();
game.playGame();
}
public void setupGame() {
Display display = new Display();
Code code = new Code();
display.showGreeting();
playerName = display.getUserInput("Enter your name: ");
numberOfPegs = Integer.parseInt(display.getUserInput("How many pegs would you like?"));
code.generateNewCode(numberOfPegs);
}
public void playGame() {
String result = display.getGuess();
}
}
I know why I can't call display.getGuess() from playGame(), it's because display is out of scope. I don't understand how to do this correctly. Do I create a new instance Display() for that method, that just doesn't feel like it's correct. I feel like I'm missing a Object Oriented concept when it comes to working with multiple objects.

Set the display as an instance field, and then initialize it in the setupGame() method.
private String playerName = "";
private int numberOfPegs = 0;
private boolean gameRunning = "True";
private Display display;
public static void main(String[] args) {
Game game = new Game();
game.setupGame();
game.playGame();
}
public void setupGame() {
display = new Display();
Code code = new Code();
display.showGreeting();
playerName = display.getUserInput("Enter your name: ");
numberOfPegs = Integer.parseInt(display.getUserInput("How many pegs would you like?"));
code.generateNewCode(numberOfPegs);
}
public void playGame() {
String result = display.getGuess();
}
There's no need to instantiate a member when you declare it. When you declare a member without instantiating, it takes its default value; 0 for numeric types, false for boolean and null for Object types. So in this case,
private int numberOfPegs = 0;
Would be the same as:
private int numberOfPegs;

Related

Setters And Getters to different Class

My problem is that, simply I don't know what code to use to get my value from my getX method to my other classses main method.
package hangman;
public class Hangman {
private int triesLimit;
private String word;
public void setTriesLimit(int triesLimit) {
this.triesLimit = triesLimit;
}
public void setWord(String word) {
this.word = word;
}
public int getTriesLimit() {
return this.triesLimit;
}
public String getWord() {
return this.word;
}
#Override
public String toString() {
return ("Enter Secret Word " + this.getWord()
+ ".\nEnter max # of tries (Must be under 7) "
+ this.getTriesLimit());
}
}
Thats from the sub-class and I am trying to store the value of the triesLimit into the main of this classes main method
package hangman;
public class PlayHangman {
public static void main(String[] args) {
Hangman hangman = new Hangman();
Scanner scn = new Scanner(System.in);
int triesCount = 0;
int correctCount = 0;
hangman.toString();
int triesLimit = hangman.getTriesLimit();
String secretWord = hangman.getWord();
StringBuilder b = new StringBuilder(secretWord.length());
for (int i = 0; i < secretWord.length(); i++) {
b.append("*");
}
char[] secrectStrCharArr = secretWord.toCharArray();
int charCnt = secretWord.length();
for (int x = 0; triesCount < triesLimit; triesCount++) {
while (charCnt >= 0) {
System.out.println("Secrect Word :" + b.toString());
System.out.println("Guess a letter :");
char guessChar = scn.next().toCharArray()[0];
for (int i = 0; i < secrectStrCharArr.length; i++) {
if (guessChar == secrectStrCharArr[i]) {
b.setCharAt(i, guessChar);
correctCount++;
} else if (guessChar != secrectStrCharArr[i]) {
triesCount++;
System.out.println("Incorrect: " + triesCount);hangmanImage(triesCount,correctCount);
}
}
}
}
}
I tried looking it up on here but couldn't find setters and getters used in a sub/superclass
You need to create an instance of the class in the main method to access the variables and method available in that class like so
public class PlayHangman {
public static void main(String[] args) {
Hangman hangman = new Hangman();
hangman.setTriesLimit(2)
int value = hangman.getTriesLimit();
}
You can look into static keyword to access the value directly but that requires a bit more understanding of OOP's and JAVA.
This should work fine.
Hope it helps :)
EDITED
ToString method is just to convert everything in your model class to String which you have done correctly,but you have implemented incorrectly.... Change your ToString content so
#Override
public String toString() {
return ("The Secret Word you entered: " + this.getWord()
+ ".\n The max # of tries (Must be under 7): "
+ this.getTriesLimit());
}
You have initialized Scanner which does what you want, to ask the user to enter the values but again you haven't implemented it so add this to your main method
Scanner scn = new Scanner(System.in);
hangman.setTriesLimit(scn.nextInt());
hangman.setWord(scn.next());
hangman.toString()//Will work now
Trial and error is your best friend now :)
and Google some of the issues rather than waiting for an answer :)
Like rohit said, this is as simple as understand the basics of OOP, specific the encapsulation.
If you want to get a little deeper into OOP patterns, you could use the Observer pattern. This allows you to change the status of any class instance, even if they're not related by inheritance, aggregation, etc.
You can scale the solution by making List of Observer
Your observable interface
public interface IObservable {
// Set the observer
public void setObserver(IObserver iObserver);
// Notify the observer the current status
public void notifyObserver();
}
Your observer interface
public interface IObserver {
public void update(boolean status);
}
Your observer implementation
public class PlayHangman implements IObserver {
private boolean status = false;
public void printStatus() {
System.out.println("Status: " + (this.status ? "Win" : "Lose"));
}
#Override
public void update(boolean status) {
// The instance status is updated
this.status = status;
// Print the current status
this.printStatus();
}
}
Your observable implementation
public class Hangman implements IObservable{
private String goalWord = "";
private String currentWord = "";
private int triesLimit = 0;
private int tries = 0;
private IObserver iObserver;
public Hangman(String goalWord, int triesLimit) {
this.goalWord = goalWord;
this.triesLimit = triesLimit;
}
public void setCurrentWord(String currentWord) {
this.currentWord = currentWord;
this.notifyObserver();
}
public void addTry() {
this.tries++;
this.notifyObserver();
}
#Override
public void setObserver(IObserver iObserver) {
this.iObserver = iObserver;
}
#Override
public void notifyObserver() {
// True = win
this.iObserver.update(this.tries < this.triesLimit &&
this.goalWord.equals(this.currentWord));
}
}
Your Main class
public class Main{
public static void main(String[] args) {
// PlayHangman (game status)
PlayHangman playHangman = new PlayHangman();
// Hangman initializes with a goalWord and the triesLimit
Hangman hangman = new Hangman("HangmanJava", 5);
// Set the observer
hangman.setObserver(playHangman);
// During the game you just can set the current word and add a try
// You're not setting the status directly, that's the magic of the Observer pattern
hangman.setCurrentWord("Hang");
hangman.addTry();
hangman.setCurrentWord("HangmanJava");
}
}
Hope this helps and enjoy Java

Subclass final method not being called

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.

Changing data in an Object Array

I have been trying to make a game for a friend, but I'm having a problem with getting my line player[i].setName(getName(pn)); in class Players to work. I want to be able to set the names of the players, or change them, in the list. but I keep getting errors at this line. This happened after i changed the public variables in class Player from static.
"Exception in thread "main" java.lang.NullPointerException
at worldhomicide.drinkinggame.PlayerInfo.Players.setPlayers(Players.java:16)
at worldhomicide.drinkinggame.main.Game.main(Game.java:25)"
Any help would be greatly appreciated! I posted all needed code below.
Game Class
public class Game{
public static void main(String[] args) {
MessageHandler.gameRules(); // Display Game Information
Players.getAmount();Players.setPlayers(); // Get player data
System.out.println("What player would you like to look up?");
int choice = Integer.parseInt(EventHandler.keyboard.next()); choice -= 1;
System.out.println(Players.player[choice].name);
}
}
Players Class
public class Players extends EventHandler {
public static int playerAmount;
public static Player[] player;
public static void setPlayers(){
player = new Player[playerAmount];
for(int i = 0; i < player.length; i++){
int pn = i+1;
player[i].setName(getName(pn));
}
}
public static void getAmount(){
MessageHandler.playerAmount();
playerAmount = Integer.parseInt(keyboard.next());
}
}
Class EventHandler
public class EventHandler {
public static Scanner keyboard = new Scanner(System.in);
public static String getName(int playerNumber){
System.out.println("What is player " + playerNumber + "'s name?");
String name = keyboard.next();
return name;
}
}
Player Class
public class Player {
public String name;
public int score;
public void setName(String name){
this.name = name;
}
}
Note that in your setPlayers() method, inside the loop, you didn't create Player object before accessing the player[i].setName() method.
for(int i = 0; i < player.length; i++){
int pn = i+1;
player[i] = new Player(); //you need to create Player object
player[i].setName(getName(pn));
}

I cannot pass a (String-)value to another class's setter method [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
I know that i have not written a catch block yet.(reason?, but i think it's actually not the problem; the attributes of the "Game" class are perfectly changeable)
I always get an IOException when i try to call the setName method in Player (even if I set "name" in Player to public and change it directly).
public class game{
protected static int amountPlayers;
protected static Player[] playerList = new Player[amountPlayers];
public static void main (String[] args) throws IOException{
//Scanner reader = new Scanner(System.in);
InputStreamReader isr = new InputStreamReader(System.in);
BufferedReader br = new BufferedReader(isr);
String input;
System.out.println("new round? (1 for yes; enter for no):");
int boo = Integer.parseInt(br.readLine());
if (boo == 1) {
Rounds.setNew(true);
} // end of if
if (Rounds.getNew() == true) {
//SavingManagement.createFile();
System.out.println("# of players:");
int amount = Integer.parseInt(br.readLine());
setAmountPlayers(amount);
} // end of if
for (int i = 0; i < amountPlayers; i++) {
System.out.println("Name player No. " + (i + 1) + ":");
input = br.readLine();
playerList[i].setName(input);
} // end of for
}
public class Player {
protected static int score;
protected static String name = "";
public static void setName(String input) {
name = input;
}
}
Assuming that you are providing the valid size in amountPlayers, by writing the following statement you are just creating the Player array and not initializing it.
protected static int amountPlayers = 100;
/* This will just create the array */
protected static Player[] playerList = new Player[amountPlayers];
Before you can use setName(), you'll have to initialize the array as follows:
for(int x = 0; x < amountPlayers; x++) {
playerList[x] = new Player();
}
OR you can do something like this:
/* Create a new object of class Player */
Player myPlayer = new Player();
/* Set Name */
myPlayer.setName(input);
/* Assign it to your array */
playerList[i] = myPlayer;
Do you need the Player class as a public inner class?
Do you need to protoct the score and the Name?
Otherwise this should work:
public class game {
protected static int amountPlayers;
protected static Player[] playerList = new Player[amountPlayers];
public static void main(String[] args) throws IOException {
for (int i = 0; i < amountPlayers; i++) {
playerList[i].setName("test");
}
}
}
class Player {
private int score;
private String name = "";
public void setName(String input) {
name = input;
}
}
The PlayerList contains Player objects, so when you are calling the setName method like this: playerList[i].setName(input) it is through an instance of class Player, but the method is actually static and should be called in this way:
Player.setName()
Although, the best thing you could do is add a constructor in class Player, add new Player objects in the array playerList and make the method setName() and the other variables in class Player non-static.

Is there a way to send variables from main class to subclass using user input JAVA

So I'm working on a (supposedly) simple java application that uses console inputs from a user, to change private variables in another class. Now I can change the value of the private variables in the EmpCls class directly from the main class by manually inputting a variable into the object, e.g.
EmpCls empObject1 = new EmpCls("josh"); but how do I get something like this
EmpCls empObject1 = new EmpCls(ctName); to work? where ctName is the variable that the user inputs. here's the relevant code from the main class:
import java.util.*;
public class NewWan {
static Scanner console = new Scanner(System.in);
public static void main(String[] args) {
EmpCls empObject1 = new EmpCls(ctName);
String ctName = empObject1.getName();
System.out.println("enter name: ");
ctName = console.next();
}
}
And the subclass in question:
public class EmpCls {
private String name;
private String ext;
private int yearStarted = 0;
public EmpCls()
{
}
public EmpCls(String inName)
{
this.name = inName;
}
public void setEmpDetails(String inName) //, String inExt, int inYearStarted)
{
this.name = inName;
// this.ext = inExt;
// this.yearStarted = inYearStarted;
}
public String getName()
{
return this.name;
}
public int getYearStarted()
{
return this.yearStarted;
}
public String getExt()
{
return this.ext;
}
public void displayDetails()
{
System.out.println("Name: " + name);
System.out.println("Ext: " + ext);
System.out.println("Year Started" + yearStarted);
}
}
some parts of the code are commented just to enable easier trouble shooting, other parts are part of a different problem im working on.
You just need to reorder the statements a bit and remove the one that doesn't make sense:
public static void main(String[] args) {
System.out.println("enter name: ");
String ctName = console.next();
EmpCls empObject1 = new EmpCls(ctName);
}
Hum... just to organize your code in the good way ? You use variable before getting value, and before declare it... Strange way ^^
public static void main(String[] args) {
System.out.println("enter name: ");
String ctName = console.next();
EmpCls empObject1 = new EmpCls(ctName);
System.out.println("You just enter " + empObject1.getName());
}

Categories

Resources