I'm writing a program that should play the game HiLo. HiLo is a game, where a random number is generated and the player has to guess it. If they guess wrong, they are told if the answer is higher or lower than their guess, then they are allowed to guess again. My program should have the ability to limit the number of guesses if needed, set the range of values the answer can be chosen from (and therefore the range of guesses too). I also need to have the option of selecting whether a human will play the game, or if I will let the computer play, and if so, at what skill level (bad, medium, good).
I've written 3 classes: GameManager, HiLo and Player.
The GameManager class allows multiple games to be played and keeps track of the number of wins.
public class GameManager {
private HiLo game;
private int wins;
private int totalRounds;
private int player;
/**
* Constructor for objects of class GameManager
*/
public GameManager()
{
player = 2;
}
public void playGames(int rounds)
{
int i = 0;
while(i < rounds) {
game = new HiLo(player);
game.play();
wins += game.getHasWon();
i++;
}
totalRounds += rounds;
}
public void changePlayer(int playerType)
{
player = playerType;
}
} //This should be indented better, but it won't format properly, apologies
The HiLo class basically sets up and plays an individual game of HiLo.
public class HiLo {
private int guessLimit;
private int lowerLimit;
private int upperLimit;
private int guesses;
private int answer;
private boolean hasWon;
private Player player;
private String result;
/**
* Constructor for objects of class HiLo
*/
public HiLo(int playerType) //Set default values
{
guessLimit = 10;
lowerLimit = 0;
upperLimit = 50;
hasWon = false;
player = new Player(playerType);
}
public HiLo(int guessLimit, int lowerLimit, int upperLimit, int playerType) //Overload
{
this.guessLimit = guessLimit;
this.lowerLimit = lowerLimit;
this.upperLimit = upperLimit;
hasWon = false;
player = new Player(playerType);
}
//Returns lower limit
public int getLowerLimit()
{
return lowerLimit;
}
//Returns upper limit
public int getUpperLimit()
{
return upperLimit;
}
//Returns 1 if hasWon is true and 0 if hasWon is false
public int getHasWon()
{
if(hasWon) {
return 1;
} else {
return 0;
}
}
//Returns the number of guesses so far
public int getGuesses()
{
return guesses;
}
//Play a game of HiLo
public void play()
{
answer = randInt(lowerLimit, upperLimit);
guesses = 0;
while(guesses < guessLimit) {
int guess = player.guess(); //This gets a guess from the player
result = isCorrect(guess); //Was the guess correct?
if(result.equals("Win")) {
break; //If the player has won, break from the while loop
}
guesses++;
}
}
//Checks if the guess was correct
public String isCorrect(int guess)
{
if(guess == answer) {
hasWon = true;
return "Win";
} else if(guess < answer) {
lowerLimit = guess;
return "Higher";
} else {
upperLimit = guess;
return "Lower";
}
}
public int randInt(int min, int max)
{
Random rand = new Random();
int randomNum = rand.nextInt((max - min) + 1) + min;
return randomNum;
}
}
The Player Class determines which player is playing (0 = human, 1 = badComp, 2 = medComp, 3 = goodComp) and the strategy they are going to use to guess.
import java.util.Random;
import java.util.Scanner;
public class Player {
private int playerType;
private HiLo game;
private int range;
private int lowestLimit; //This is the starting value of lowerLimit
/**
* Constructor for objects of class Player
*/
public Player(int playerType)
{
if(playerType < 0 || playerType > 3) {
System.out.println("ERROR. Please pick a valid playerType");
}
this.playerType = playerType;
range = 0;
range = setRange();
lowestLimit = game.getLowerLimit();
}
public int guess()
{
if(playerType == 0) {
return humanPlayer();
} else if(playerType == 1) {
return badComputerPlayer();
} else if(playerType == 2) {
return mediumComputerPlayer();
} else {
return goodComputerPlayer();
}
}
//Guess from a good computer player
public int goodComputerPlayer()
{
return (game.getUpperLimit() - game.getLowerLimit())/2;
}
//Guess from a medium computer player
public int mediumComputerPlayer()
{
return randInt(game.getLowerLimit(), game.getUpperLimit());
}
//Guess from a bad computer player
public int badComputerPlayer()
{
return randInt(lowestLimit, range);
}
public int humanPlayer()
{
Scanner keyboard = new Scanner(System.in);
System.out.println("enter an integer");
int myint = keyboard.nextInt();
return myint;
}
//Generates a random number in the range maz-min
public int randInt(int min, int max)
{
Random rand = new Random();
int randomNum = rand.nextInt((max - min) + 1) + min;
return randomNum;
}
//Set the range of values to guess from for bad player
public int setRange()
{
int r = game.getUpperLimit() - game.getLowerLimit();
return r;
}
}
When I create an object from the HiLo class and input all the arguments, I get a NullPointException:
java.lang.NullPointerException
at Player.setRange(Player.java:75)
at Player.<init>(Player.java:26)
at HiLo.<init>(HiLo.java:35)
I'm new to both programming and Java, and this is my first NullPointException error. I've read some of the other posts on them, but I can't figure it out.
I also don't think the player class is doing exactly what I want it too. Each new instance of the Player class is conceptually tied to the instance of the HiLo game that creates that instance, because a HiLo game can only have one player at a time. I want the new instance of the Player class to reference the instance of the HiLo class that created it:
lowestLimit = game.getLowerLimit();
I'm trying to set lowestLimit = to the lower limit of the instance of the HiLo game that created this Player instance, however I think that's I'm just referencing the object game created from the HiLo class, rather than the instance that created this Player instance. Sorry if this is confusing, I'm trying my best to explain :)
I do this in quite a few other methods inside the Player class too. I've read something about using reflection to potentially solve this, but I'm really not sure I understand it yet.
Any help and/or thoughts would be greatly appreciated,
Thanks.
EDIT: Just thought I'd let you know that I'm using the BlueJ environment.