Object Oriented Approach for a simple game - java

I am working on building a simplified version of this game. The problem states that you can have a computer that is smart or stupid but i have decided that to exclude that feature for now and decided to only go with a computer that picks a random amount of objects. I posted a question earlier and worked on it. (https://softwareengineering.stackexchange.com/questions/244680/object-oriented-design-of-a-small-java-game/244683#244683)
So initially i only had designed one class. But now i have designed 3 classes as stated by the problem. I have a pile class , a player class and a game class (also my main class).
I have so far coded the Pile and Player class. I started coding the Game class aswell however i am stuck now as i dont know how to make the game class interact with the Player and Pile class. I basically determine who's turn it is first and then rotate turns till the pile of objects is complete and declare a winner...I don't know how to make the different classes interact with each other . SO i would highly appreciate if someone can guide me further and help me finish this simple game.
I sincerely apologize if i have asked a bad question. This is my first such program i am doing in java dealing with multiple classes so it is a little confusing. I do not want anyone write code but even mentioning or telling me i should make so and so methods etc will be great !
HERE IS THE CODE I HAVE SO FAR.
PILE CLASS
package Nim;
import java.util.Random;
public class Pile {
private int initialSize;
public Pile() {
}
Random rand = new Random();
public void setPile() {
initialSize = (rand.nextInt(100 - 10) + 10);
}
public void reducePile(int x) {
initialSize = initialSize - x;
}
public int getPile() {
return initialSize;
}
public boolean hasStick() {
if (initialSize > 0) {
return true;
}
else {
return false;
}
}
}
PLAYER CLASS
package Nim;
import java.util.Scanner;
import java.util.Random;
public class Player {
public static final int HUMAN = 0;
public static final int COMPUTER = 1;
private int type;
public Player(int theType) {
type = theType;
}
Scanner in = new Scanner(System.in);
// n is number of marbles left in the pile
public int makeMove(int n) {
int max = n / 2;
int grab;
if (type == HUMAN) {
System.out.println("There are " + n
+ " marbles in total. However you can only"
+ "grab no more than " + max + " marbles");
System.out.println("Please Enter the number of marbles to grab: ");
grab = in.nextInt();
while (grab > max || grab < 0) {
System.out.println("You have entered a illelgal value. Please enter a legal value: ");
grab = in.nextInt();
}
return grab;
}
else {
Random rand = new Random();
grab = (rand.nextInt(n / 2 - 1) + 1);
System.out.println("Computer has grabbed: " + grab + " marbles");
return grab;
}
}
public void updateTurn(int n) {
type = n;
}
}
GAME CLASS (in progress)
package Nim;
import java.util.Scanner;
import java.util.Random;
public class Game {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
Random rand = new Random();
System.out.println(welcome());
Pile marbles = new Pile();
Player human = new Player(Player.HUMAN);
Player computer = new Player(Player.COMPUTER);
marbles.setPile();
System.out.println("There are total: " + marbles.getPile()
+ " marbles in the Pile.");
System.out.println("Time for a toin coss to see who goes first!");
System.out.println("Please Select heads(0) or Tails(1): ");
int choice = in.nextInt();
int tossResult = rand.nextInt(2);
boolean playerTurn = false;
boolean computerTurn = false;
if (choice == tossResult) {
System.out.println("You have won the Coin Toss! You will go first!");
human.updateTurn(0);
playerTurn = true;
}
else {
System.out.println("Computer has won the coin toss! Computer will go first");
computer.updateTurn(1);
computerTurn = true;
}
while (marbles.getPile() > 0 && marbles.hasStick()) {
while (playerTurn) {
int removeMarbles = human.makeMove(marbles.getPile());
marbles.reducePile(removeMarbles);
computerTurn = true;
playerTurn = false;
}
while (computerTurn) {
int removeMarbles = computer.makeMove(marbles.getPile());
marbles.reducePile(removeMarbles);
playerTurn = true;
computerTurn = false;
}
}
}
private static String welcome() {
return "Welcome to the Game of Nim";
}
}

So I'm going to take a step back and look at your class diagram.
You have three classes: Pile, Player, and Game. Pile can represent the pile at the center. Game can be the class with the main method that manages everything. And Player? Well, since you're having one Player class for all three (or two) possible states (Human, Dumb, and Smart) it should be pretty easy to implement.
Let's start with Game. It need to contain two instances of Player (human and computer), and an instance of Pile. It also needs to have a loop that goes until the game is over. So let's start to come up with a basic implementation:
Starting with Pile:
private int size;
public Pile(int newSize) {
size = newSize;
}
public boolean takeMarbles(int amount) {
size -= amount;
if (size < 1)
return false;
return true;
}
The constructor is pretty self explanatory. The takeMarbles method is returning false if the player lost, and true if they're still in the game.
Now on to Player:
public static final int HUMAN = 0;
public static final int COMPUTER = 1;
private int type;
public Player(int type) {
this.type = type;
}
Those two static fields may seem a little out of place, but it will come together in a second. On to the Game class:
Pile pile = new Pile(size);
Player human = new Player(Player.HUMAN);
Player computer = new Player(Player.COMPUTER);
Now we have a pile with a certain size, and two players that differ by type. This is how we're using the classes.
Now we need to get the main game loop working. Basically, just add an update() method to Player that depends on it's type (ie prompts for input if player, randomly decides if computer). The update method should return the amount of marbles to take. Then create a loop in the main method in Game. The loop will call update of the player and the computer repeatedly until someone loses (takeMarbles returns false). Then it will break out of the loop and print the output.
This is the basic idea, good luck and feel free to ask more questions!

Related

How to fix a variable from a class not being subtracted in a method?

The gist of this assignment is that there are two players who take a stick out of a pile. I made a class that has the number of sticks available. There is a method that is called to remove sticks. However when I try to remove sticks the number of sticks doesn't change. Therefore the game not being able to end because there are still sticks "left".
I've tried using int sticks to be subtracted. The total amount of sticks changes but only in the method in which they are subtracted. The number of sticks don't change in the main method.
I decided to make use classes as I saw on this site that that is how this issue can be fixed. I've had no success with it.
So I made a class that has the amount of sticks so now the number of sticks is the same for each method. The same issue persists. One that changes the number of sticks in the getSticksRemove() method but not main() or getSticksLeft().
//Main Class
public class Main {
//Method to remove sticks which considers different scenarios.
public static int getSticksRemove(int sticks) {
sticks = StickPile.getValue(StickPile.value);
Scanner input = new Scanner(System.in);
print ("How many sticks to remove?(1-3)");
int x = input.nextInt();
if( x>=1 && x<=3) {
sticks -= x;
}else if(sticks < 3 && x ==2 ) {
print("Not enough sticks left.");
getSticksRemove(sticks);
}else if (x>3) {
sticks -=3;
}else { `enter code here`
sticks-=1;
}
print(sticks);
return sticks;
}
//Main method
public static void main(String [] args) {
StickPile stickPile = new StickPile();
int turnP1 = 0;
int turnP2 = 0;
int sticks = 0;
print("How many sticks are there initially? (1-100)");
StickPile.setValue();
sticks = StickPile.getValue(StickPile.value);
//This is the loop that determines when to stop the game
while(sticks != 0) {
System.out.print("Player 1: ");
getSticksRemove(sticks);
getSticksLeft(sticks);
turnP1++;
System.out.print("Player 2: ");
getSticksRemove(sticks);
getSticksLeft(sticks);
turnP2++;
}
if(turnP1 % 2 == 0 && turnP2 % 2 == 1) {
System.out.println("P2 Loses");
}else {
System.out.println("P1 Loses");
}
}
}
// This StickPile class is the one I made to store the number of sticks.
public class StickPile {
static Scanner input = new Scanner(System.in);
public static int value;
public static void setValue() {
value = input.nextInt();
}
public static int getValue(int x) {
x = value;
System.out.println(x);
return x;
}
I expect to enter a number of sticks to remove from the pile. Ex. PileAmount: 20--> Remove: 12--> PileAmount: 8.
However, I get Ex. PileAmoun: 20 --> Remove: 5--> PileAmount: 20,
You're ignoring the return of getSticksRemove. You can't reassign the parameter to effect the number outside of the function.
Just use the return value:
sticks = getSticksRemove(sticks)
Make that change in both places.

How to get the value of a method in the run area that was changed inside of method?

I apologize if the title is confusing. I'm very new to Java coding and have just completed a coding course provided through my High School.
I am trying to create a small text-adventure game using Java through a program called codehs. In the game there is a player, with a class for their stats. There are also monsters in the game, which have a separate class based on their individual stats. Each monster is created at random per encounter and is spawned from a pool of monsters that scale with player level.
My problem arises when I initiate a fight between the player and the monster. I currently initiate the fight through a method called monster fight, where the method inputs the players level and their health in a variable called HP (kept separate from the stats class). The problem is, after the fight, my player has obviously lost some HP with the fight, but since the HP variable is changed inside of the method, it reverts back to the default full HP after the fight when I try to display the current HP. Is there a way I can display the HP of the player after the fight in the run area?
I apologize for the long wording and probably terrible understanding of Java, but I would appreciate any help trying to make this work.
Edit: Here is some code
What I call in the run area:
monsterFight(player.getLevel(), player.getHP());
Method for monster Fight:
public void monsterFight(int level, int HP)
{
int whatMonster = Randomizer.nextInt(1,3);
Monster monster = null;
if(whatMonster == 1)
{
monster = new Monster("Gremlin", level, 1500);
}
if(whatMonster == 2)
{
monster = new Monster("Troll", level, 3000);
}
if(whatMonster == 3)
{
monster = new Monster("Brute", level, 4000);
}
Monster.getHP();
System.out.println(monster);
int enemHP = Monster.getHP();
while (HP > 0 && enemHP > 0)
{
System.out.println("");
String fbfAttack = readLine("How will you attack? Choose lightning or fireball: ");
if (fbfAttack.equals("lightning"))
{
System.out.println("Your lightning blasts the ");
int damage = Randomizer.nextInt(400,500);
enemHP = enemHP - damage;
}
if (fbfAttack.equals("fireball"))
{
System.out.println("Your fire burns the " + monster.getName());
int damage = Randomizer.nextInt(700,1000);
enemHP = enemHP - damage;
}
if (enemHP <= 0)
{
break;
}
System.out.println("The " + monster.getName() + " is at: " + enemHP + "HP");
int enemAttack = Randomizer.nextInt(200,300);
HP = HP - enemAttack;
System.out.println("The " + monster.getName() + " attacks! Your HP: " + (HP));
}
if (HP < 0)
{
System.out.println("Game over, you died");
System.exit(0);
}
System.out.println("HP in fight method " + HP);
newHP(HP);
}
public int newHP(int HP)
{
return HP;
}
}
You're very close. First of all, let me just say there are plenty of ways to solve this. Here's one:
you could pass in a player object to the monsterFight(Player player)
public class Player {
private int health;
private int lvl;
public Player(int health, int lvl) {
this.health = health;
this.lvl = lvl;
}
...
// getters & setters
}
and then in the monsterFight(Player player) you could call player.setHealth(health) whenever the player loses health!
It seems to me, that you should have an object which is initialised in the main or which has its state saved somewhere global and after each fight you change the HP of the player to the new value on that object. To show the HP you just query the objects state.
Player p;
object Player {
int level;
int health;
}
public int getLevel(){
return this.level
}
public int setLevel(int level){
this.level = level
}
public int getHealth(){
return this.health
}
public int setHealth(int health){
this.health = health
}

Starting out with OOP -Dice game question

Hi I am trying to grasp object oriented programming (OOP).
I am making a die game, but I am a little stuck -
package ch6CLASSES;
import java.util.Scanner;
public class getDie {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
System.out.println("A simple dice game.");
int COUNT =10;
for (int i=0;i<COUNT;i++) {
Die userDie = new Die();
System.out.println("user: "+userDie.getValue());
Die computerDie = new Die();
System.out.println("computer: "+computerDie.getValue());
System.out.println();
}
}
}
So I have another class where I calculated everything - but now my question is... within the for loop I had I would like to make a running count of how many times the computer or user wins after each round, any help?
First off you need to have some way to determine whether the computer or user wins. (Since you are practicing OOP a method would probably be most appropriate) Looking at your code it looks like each Die will only have one value, so you have to keep recreating objects. I would recommend having a roll() method that would return a random number between 1 and 6. That way you wouldn't have to create new objects on each iteration of the loop.
Second you'll need a method to determine is the user won. One easy way to do this would be to have the method accept an int parameter and then compare it to the value of the current Die object. Here are some code to get you started in the right direction:
public int roll() {
//generate random number
}
public boolean wonRoll(int value) {
if(this.getValue() > value) {
return true;
} else {
return false;
}
}
And then in your loop:
int computerWins = 0;
int userWins = 0;
Die userDie = new Die();
Die computerDie = new Die();
for (int i=0;i<COUNT;i++) {
System.out.println("user: "+userDie.getValue());
System.out.println("computer: "+computerDie.getValue());
if(userDie.wonRoll(computerDie.getValue()) {
userWins++;
} else {
computerWins++;
}
}
System.out.println("Computer won " + computerWins + " many times");
System.out.println("User won " + userWins + " many times");

Random generator always amounting to 0 (Java)

I am working through Head First Java, and my Random generator is amounting to 0. Here are my classes:
This is my class with the main method.
public class GameLauncher {
public static void main(String[] args) {
GuessGame game = new GuessGame();
game.startGame();
}
}
This is my player object class:
import java.util.Random;
public class Player {
int number = 0; //Where the guess goes
public void guess() {
//random1 is in GuessGame
Random random2 = new Random();
int number = random2.nextInt(10);
System.out.println("I'm guessing " + number);
}
}
Finally, this is the class where most of the code is happening.
import java.util.Random;
public class GuessGame {
//Guessgame has three instance variables for the three Player objects
Player p1;
Player p2;
Player p3;
public void startGame() {
//Create three Player objects and assign them to the three Player instance variables
p1 = new Player();
p2 = new Player();
p3 = new Player();
//Declare three variables to hold the three guesses the players make
int guessp1 = 0;
int guessp2 = 0;
int guessp3 = 0;
//Declare three variables to hold a true or false based on the player's answer
boolean p1isRight = false;
boolean p2isRight = false;
boolean p3isRight = false;
//Make a "target" number that the players have to guess
Random random = new Random();
//Generate a number between 0 and 9
int targetNumber = random.nextInt(10);
System.out.println("I'm thinking of a number between 0 and 9...");
while (true) {
System.out.println("Number to guess is " + targetNumber);
//Call each player's guess() method
p1.guess();
p2.guess();
p3.guess();
/*
Get each player's guess (the result of their guess() method
running) by accessing the number variable of each player
*/
guessp1 = p1.number;
guessp2 = p2.number;
guessp3 = p3.number;
System.out.println("Player one guessed " + guessp1);
System.out.println("Player two guessed " + guessp2);
System.out.println("Player three guessed " + guessp3);
/*
Check each player's guess to see if it matches the target number. If a player is right, then set that player's variable to be true (remember, we set it false by default)
*/
if (guessp1 == targetNumber) {
p1isRight = true;
}
if (guessp2 == targetNumber) {
p2isRight = true;
}
if (guessp3 == targetNumber) {
p3isRight = true;
}
//If player one OR player two OR player three is right... (the || operator means OR)
if (p1isRight || p2isRight || p3isRight) {
System.out.println("We have a winner!");
System.out.println("Player one got it right? " + p1isRight);
System.out.println("Player two got it right? " + p2isRight);
System.out.println("Player three got it right? " + p3isRight);
System.out.println("Game is over.");
break; //Game over, so break out of the loop
}
else {
//We must keep going because nobody got it right!
System.out.println("Players will have to try again.");
} //end if/else
} //end loop
} //end method
} //end class
I am new to these forums, so if I did something wrong please let me know :)
Does anyone know why this isn't working?
Thanks,
Lyfe
You are storing random number in local variable and you think you set it in instance variable
at line
int number = random2.nextInt(10);
change it to
this.number = random2.nextInt(10);
that atleast solves stated problem.
Also See
Java Variables

Getting New Random Numbers For Guessing Game In Java

I am building a game for Java and I've gotten down to one of the last parts. There are still other things to fix which are easy fixes. Although there is one problem I can't figure out, which is that after every time I run the game I can't get new random numbers to show up.
For instance, if nobody guesses the number that is made at random by the computer from numbers (1-20) than the game repeats itself. You are playing 2 computers during this and their numbers are also made up at random (again 1-20 values).
Here is some of the code for the Player class I made
import java.util.Scanner;
import java.util.Random;
public class Player {
private double currentGuess = 0;
private String firstName;
private boolean isCorrect;
Scanner myScanner = new Scanner(System.in);
public Player() {
}
public double autoGuess() {
Random randomNumber = new Random();
double number = randomNumber.nextInt(20) + 1;
return number;
}
Here is my GuessGame class, which is where the action actually happens. I cannot figure out why when I call for the autoGuess method (from the player class) I cannot get new random numbers to show up after each game which resulted in nobody guessing the right number. Same goes for randomly generating the number to be guessed (WINNING_NUMBER), it still stays the same after every new game. Here is some of the code of my GuessGame class.
import java.util.Random;
public class GuessGame {
Player player1 = new Player();
Player player2 = new Player();
Player player3 = new Player();
double player2Guess = player2.autoGuess();
double player3Guess = player3.autoGuess();
int numberOfTries = 0;
public double generateWinningNumber() {
Random randomGenerate = new Random();
double randomNumber = randomGenerate.nextInt(20) + 1;
return randomNumber;
}
private final double WINNING_NUMBER = generateWinningNumber();
public void startGame() {
System.out.println("VM: Welcome we are going to play a number guessing game. I'm (the JVM)\n"
+ "going to randomly pick a number between 0 and 20. You and the 2 other\n"
+ "computer-generated players are going to try to guess that number. The game\n"
+ "will end when at least one of the players correctly guesses the number.\n");
System.out.println(WINNING_NUMBER);
System.out.print("What is your name? ");
String player1Name = player1.readName();
while (player1.isCorrect() == false)
{
System.out.print(player1Name + ", enter your guess: ");
player1.readGuess();
player2.autoGuess();
player3.autoGuess();
numberOfTries++;
if (player1.getCurrentGuess() == WINNING_NUMBER || player2Guess == WINNING_NUMBER || player3Guess == WINNING_NUMBER)
{
player1.setCorrect(true);
displayGuesses();
determineWinner();
}
else
{
displayGuesses();
displayHints();
System.out.println("No one guessed the number.\nPlayers will need to guess again.\n");
System.out.println("The winning number was: " + WINNING_NUMBER);
generateWinningNumber();
}
}
}
public void displayGuesses() {
System.out.print("Player 2's guess is: " + player2Guess + "\n");
System.out.print("Player 3's guess is: " + player3Guess + "\n\n");
}
There is more to this and obviously more to fix, but I'm trying to just get this issue out of the way. I have my driver class starting this game and also know I need to round my numbers to Ints so there isn't a decimal place. Also, all the hint method is referring to is just if statements that tell you if you are hot, warm, or cold. That runs perfectly fine. Just needing some help with figuring out how to get a new random number after every new unsuccessful game from my while statement.
Your generateWinningNumber() method returns a double, it does not actually change any values itself. Also, because WINNING_NUMBER is a constant, even if you did want to change it, you wouldn't be able to. You should definitely not make WINNING_NUMBER final, and either modify generateWinningNumber() so that it modifies your global variable itself, or leave it as-is and use its return value to assign to your non-constant winningNumber global.

Categories

Resources