Java 2 player trivia game - java

I am having some trouble with this, and I would greatly appreciate some help. I am still a "noobie" when it comes to java so please understand that I probably will have stupid mistakes. Anyways, I am trying to make a two player java game and I keep getting errors that I do not understand. I have three separate classes. This is my main class
import java.io.File;
import java.io.IOException;
import java.util.Scanner;
public class Assignment3
{
public static void main(String args[]) throws IOException
{
// Constants
final int NUM_QUESTIONS = 10;
final int NUM_PLAYERS = 2;
// Variables
int playerTurn = 1; // The current player
int questionNum; // The current question number
int playerAnswer; // The player's chosen answer
int player1points = 0; // Player 1's points
int player2points = 0; // Player 2's points
// Create an array of Player objects for player #1 and player #2.
player[] players = new player[NUM_PLAYERS];
for (int i = 0; i < NUM_PLAYERS; i++)
{
players[i] = new player(i+1);
}
// Create an array to hold Question objects.
questions[] questions = new questions [NUM_QUESTIONS];
// Initialize the array with data.
intQuestion(questions);
// Play the game.
for (int i = 0; i < NUM_QUESTIONS; i++)
{
// Display the question.
Assignment3.displayQuestion(qArray[i], playerTurn);
// Get the player's answer.
players[playerTurn - 1].chooseAnswer();
// See if the correct answer was chosen.
if (qArray[i].getCorrectAnswerNumber() == players[playerTurn - 1].getCurrentAnswer())
{
players[playerTurn -1].incrementPoints();
}
// See if the the player chose the wrong answer.
// do nothing
// Switch players for the next iteration.
if (playerTurn == 1)
playerTurn = 2;
else
playerTurn = 1;
}
// Show the game results.
showGameResults(players);
}
/**
* The initQuestions method uses the contents of the trivia.txt file to
* populate the qArray parameter with Question objects.
*/
public static void initQuestions(questions qArray[]) throws IOException
{
// Open the trivia.txt file.
File file = new File("trivia.txt");
Scanner inputFile = new Scanner(file);
// Populate the qArray with data from the file.
for (int i = 0; i < qArray.length; i++)
{
// Create a Question object in the array.
qArray[i] = new questions();
// Get the question text from the file.
qArray[i].setQuestion(inputFile.nextLine());
// Get the possible answers.
for (int j = 1; j <= 4; j++)
{
qArray[i].setPossibleAnswer(inputFile.nextLine(), j);
}
// Get the correct answer.
qArray[i].setCorrectAnswerNumber(Integer.parseInt(inputFile.nextLine()));
}
}
public static void displayQuestion(questions q, int playerNum)
{
// Display the player number.
System.out.println("Question for player #" + playerNum);
System.out.println("------------------------");
// Display the question.
System.out.println(q.getQuestionText());
for (int i = 1; i <= 4; i++)
{
System.out.println(i + ". " + q.getPossibleAnswer(i));
}
}
public static void showGameResults(player[] players)
{
// Display the stats.
System.out.println("Game Over!");
System.out.println("---------------------");
System.out.println("Player 1's points: " + players[0].getPoints());
System.out.println("Player 2's points: " + players[1].getPoints());
// Declare the winner.
if (players[0].getPoints() > players[1].getPoints())
System.out.println("Player 1 wins!");
else if (players[1].getPoints() > players[0].getPoints())
System.out.println("Player 2 wins!");
else
System.out.println("It's a TIE!");
}
}
This is my player class
import java.util.Scanner;
public class player
{
private int playerNumber; // The player number
private int points; // Player's points
private int currentAnswer; // Current chosen answer
//Constructor
public player(int playerNum)
{
playerNumber = playerNum;
points = 0;
}
public void chooseAnswer()
{
// Create a Scanner object for keyboard input.
// Get the user's chosen answer.
Scanner keyboard = new Scanner(System.in);
System.out.print("Please enter your Answer"); //Asks user for a number
this.currentAnswer = keyboard.nextInt();
}
public int getCurrentAnswer()
{
return this.currentAnswer; //Returns Current Answer
}
public void incrementPoints()
{
this.points++; //Increments the points
}
public int getPoints()
{
return this.points; //Returns the points
}
}
This is my questions class
public class questions
{
// Constant for the number of answers
public final int NUM_ANSWERS = 10;
// The trivia question
private String questionText;
// An array to hold possible answers.
private String possibleAnswers[] = new String[NUM_ANSWERS];
// The number (1, 2, 3, or 4) of the correct answer.
private int correctAnswer;
//Constructor
public questions()
{
// Initialize all fields to "" or 0;
questionText = "";
correctAnswer = 0;
for (int i = 1; i < NUM_ANSWERS; i++)
setPossibleAnswer("", i);
}
public void setQuestion(String question)
{
//Sets the question
this.questionText = question;
}
public void setPossibleAnswer(String text, int num)
{
//Sets possible Answer
this.possibleAnswers[num] = text;
}
public void setCorrectAnswerNumber(int num)
{
//Sets correct Answer
this.correctAnswer = num;
}
public String getQuestionText()
{
//Returns Question Text
return this.questionText;
}
public String getPossibleAnswer(int num)
{
//Returns Possible Amswer
return this.possibleAnswers[num];
}
public int getCorrectAnswerNumber()
{
//Returns Correct Answer
return this.correctAnswer;
}
public String getCorrectAnswer()
{
//Returns Possible Answer
return this.possibleAnswers[this.correctAnswer];
}
}
If there is any help you guys can offer, I would greatly appreciate. I just can't seem to figure out why I keep getting these errors that are stopping it from running. Please and thank you.
these are the errors I get, I don't know if this is what you mean, I found out what I had earlier was from something else
Exception in thread "main" java.lang.Error: Unresolved compilation problems:
The method intQuestion(questions[]) is undefined for the type Assignment3
qArray cannot be resolved to a variable
qArray cannot be resolved to a variable
at Assignment3.main(Assignment3.java:42)

Your method is named initQuestion, but you are calling intQuestion.
Oh, and you are using qArray outside of initQuestion, the only place where it seems to be defined.

Related

Java array values gets overwritten

I am new to Java and this is a very basic question.
However I struggle to find a solution, so hopefully someone could give me some pointers.
I am trying to fill values into an array "addedPlayer".
However, every time I run the AddPlayer() method it is initialiezed to zero again.
How can I structure this in a better way?
public class DemoApplication implements CommandLineRunner {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
public void AddPlayer() {
int[] addedPlayer;
addedPlayer = new int[500];
System.out.println(" *** Add new player *** ");
System.out.println("Name:");
String name = System.console().readLine();
System.out.println("Age:");
int age = Integer.parseInt(System.console().readLine());
System.out.println("JNUM:");
int jnum = Integer.parseInt(System.console().readLine());
player p = new player();
p.SetAge(age);
p.SetName(name);
p.SetJnum(jnum);
System.out.println(addedPlayer[0]);
for (int j = 0; j < addedPlayer.length; j++) {
if (addedPlayer[j] != 0) {
} else {
addedPlayer[j] = p.GetAge();
System.out.println(addedPlayer[j]);
System.out.println(j);
break;
}
}
}
public void EditPlayer() {
//empty
}
public void ListPlayer() {
//empty
}
#Override
public void run(String... args) throws Exception {
while (true) {
System.out.println(" *** MENY *** ");
System.out.println(" 1. Add player ");
System.out.println(" 2. Edit player ");//ÖKurs
System.out.println(" 3. List player ");
System.out.println(" 100. Exit ");
System.out.println("Ange val");
int sel = Integer.parseInt(System.console().readLine());
if (sel == 100) break;
if (sel == 1) AddPlayer();
if (sel == 2) EditPlayer();
if (sel == 3) AddPlayer();
}
}
}
Each time you run AddPlayer(), it creates a new player from scratch. If you want to keep your modifications to a bare minimum, you must put it outside of the method and make it a property for your class like List<int[]> addedPlayers = new ArrayList<int[]>(); and you can add this line AddPlayer to add it in a list addedPlayers.add(addedPlayer). Otherwise, if you want a more cleaner code, you should add more classes than only one main class. To improve your code, you can see #g.momo's answer.
int[] addedPlayer; addedPlayer = new int[500];
It gets overridden because you are creating an new local var addedPlayer, and then setting all values to 0 (addedPlayer = new int[500];) I'm assuming you would want addedPlayer to be global, so don't define it locally and set it to 0.
Also, should addedPlayer be a player[] or just a player rather than an int[]? Plus, you didn't close the function in the code you gave us, so is there more missing or did you just not close it?
Your code and your expectations are completely differents.
Read this and tell us if you understand. It is the way I would have written if I were you . But it is NOT TESTED:
public class AddPlayer { // you create a class
player[] addedPlayer; // array of players
int index;
public AddPlayer() { // constructor of the class
addedPlayer = new player[500]; // max 500 players
index = 0;
}
public void addPlayer(player p) {
if(index < 500) {
addedPlayer[index] = p; // add at index,
index = index + 1; // then increment index for the next added player
}
}
public static void main(String... args) {
AddPlayer addPlayers = new AddPlayer();
int i = 0;
while(i < 5) { // will run 5 times, so only 5 players will be added. Change to stop when you will need
// here your read console inputs
System.out.println(" *** Add new player *** "+ (i+1));
System.out.println("Name:");
String name = System.console().readLine();
System.out.println("Age:");
int age = Integer.parseInt(System.console().readLine());
System.out.println("JNUM:");
int jnum = Integer.parseInt(System.console().readLine());
// initialize the player
player p = new player();
p.SetAge(age);
p.SetName(name);
p.SetJnum(jnum);
addPlayers.addPlayer(p); // add in the array
i++;
}
}
}

Any advice on how to fix this Stack Overflow error? Java

While developing a simple auto generating game of war in my free time, I ran into a "StackOverFlow" error.
Here is my Deck class where the error occurs:
It occurs in my compare() method. Any insight as to what I can do to avoid this error is accepted as I am struggling to understand what can be done to fix this and have little knowledge as to what this error even means besides my class doesn't have recursion done well. Thanks!
import java.util.*;
import java.math.*;
public class Deck
{
private int num = 0;
private int cardnum2 = 0;
private int cardnum = 0;
private int decrease = 0;
private int rnd = 0;
private int winner = 0;
private String suit = " ";
private int suitNum = 0;
private int val = 1;
private String name = "";
private ArrayList<Card> Deck = new ArrayList<Card>();
private Card[] cardCheck = new Card[51];
private ArrayList<Card> play1 = new ArrayList<Card>();
private ArrayList<Card> play2 = new ArrayList<Card>();
public Deck()
{
createDeck();
}
public void createDeck()
{
for(int i = 0; i < 4; i++)
{
val = 1;
suit = " ";
name = " ";
suitNum++;
System.out.println();
System.out.println();
for(int z = 0; z < 13; z++)
{
if(suitNum == 1)
{
suit = "Hearts";
}
if(suitNum == 2)
{
suit = "Diamonds";
}
if(suitNum == 3)
{
suit = "Spades";
}
if(suitNum == 4)
{
suit = "Clubs";
}
if(val == 1)
{
name = "Ace";
}
else if(val == 11)
{
name = "Jack";
}
else if(val == 12)
{
name = "Queen";
}
else if(val == 13)
{
name = "King";
}
else {
name = "";
}
Card myCards = new Card(val, suit, name);
Deck.add(myCards);
System.out.print(myCards + " ");
val++;
}
}
}
public void Deal()
{
int size = 52 / 2;
for(int i = 0; i < size; i++)
{
Random();
for(int z = 0; z < cardCheck.length; z++)
{
if(cardCheck[i] == null)
{
cardCheck[i] = Deck.get(rnd);
play1.add(cardCheck[i]);
System.out.println(play1);
}
else
{
Random();
}
}
}
System.out.println();
System.out.println();
for(int i = 0; i < size; i++){
Deck.remove(play1.get(i));
}
for(int i = 0; i < size; i++){
play2.add(Deck.get(i));
}
for(int i = 0; i < size; i++)
{
System.out.println(play2.get(i));
}
}
public void Random()
{
rnd = (int)(Math.random() * 52) - decrease;
}
public void flip()
{
if(play1.indexOf(cardnum) >= play1.size() || play2.indexOf(cardnum2) >= play2.size())
{
cardnum = (int)(Math.random() * play1.size());
System.out.println(play1.get(cardnum));
cardnum2 = (int)(Math.random() * play2.size());
System.out.println(play2.get(cardnum2));
}
}
public void compare()
{
System.out.println("War!!!\n");
if(play1.get(cardnum).getNum() > play2.get(cardnum2).getNum())
{
System.out.println();
winner = 1;
System.out.println(play1.get(cardnum) + " vs " + play2.get(cardnum2));
play1.add(play2.get(cardnum2));
play2.remove(cardnum2);
System.out.println("Player 1 took the cards!");
System.out.println();
printDecks();
}
if(play1.get(cardnum).getNum() < play2.get(cardnum2).getNum())
{
System.out.println();
winner = 2;
System.out.println(play1.get(cardnum) + " vs " + play2.get(cardnum2));
play2.add(play1.get(cardnum));
play1.remove(cardnum);
System.out.println("Player 2 took the cards!");
System.out.println();
printDecks();
}
if(play1.get(cardnum).getNum() == play2.get(cardnum2).getNum())
{
System.out.println();
System.out.println(play1.get(cardnum) + " vs " + play2.get(cardnum2));
System.out.println("War!!");
winner = 0;
flip();
flip();
flip();
compare();
System.out.println();
printDecks();
}
}
public void playW()
{
while(play1.size() > 0 || play2.size() > 0)
{
flip();
compare();
}
}
public void printDecks()
{
for(int i = 0; i < play1.size(); i++)
{
System.out.print(play1.get(i) + " ");
}
System.out.println();
for(int i = 0; i < play2.size(); i++)
{
System.out.print(play2.get(i) + " ");
}
System.out.println();
System.out.println("Player 1 has: " + play1.size() + " cards");
System.out.println("Player 2 has: " + play2.size() + " cards");
}
}
This is more a comment but it became too long.
There is a lot to say about this code. Use switch case instead of series of if. Or at least use if else. What is the point of a for loop if you use cases inside? What is the 'i' variable for if you then increment yourself a suitNum variable? Don't use capital letter for methods. Only classes. Why does Random edits a variable and returns void? It would be more logical that random() returns the result you want and this way you get free of the useless variable 'rnd'
There is a lot more to say but it is a good start. About your error, in short, a stack overflow means that your program is using too much memory. This is especially common in code that contains an infinite recursive loop. Here, the infinite recursion is due to the compare method called inside the compare method...
and have little knowledge as to what this error even means besides my class doesn't have recursion done well.
Yes, your code has recursion, and it's easy to find. You know that the problem is coming from within the compare method, and so all you have to do is look within that method for compare() and find out where you're having the method call itself.
The solution is not to call the method within itself, and why should it be doing this anyway?
You're having the issue partly because your class structure is broken. The Deck class is class that should represent the structure and behavior of a deck of cards, nothing more and nothing less, It should have methods like public void shuffle(), like public Card Deal(), and such. It should not have any code that directly interacts with the user, and this code should go elsewhere, perhaps in your driver or Game class, or even as separate class(es) entirely.
I'm guessing that you'll also want to have a Hand class, one that holds a player's hand, and perhaps inside of this class, have a compare method that compares the current Hand with another Hand, passed in as a parameter.
You'll also want a Game class should have a game-loop that controls play, that ends when there is a winner or a draw, that holds the Deck, that holds 1 or more Player objects...
e.g.,
public enum Suit {
CLUBS, DIAMONDS, HEARTS, SPADES
}
public enum Value {
//....
}
public class Card {
private Suit suit;
private Value value;
// TODO: constructor, methods including equals, hashCode
}
public class Deck {
private List<Card> cards = new ArrayList<>();
public Card deal() {
return cards.remove(0);
}
public void shuffle() {
Collection.shuffle(cards);
}
//....
}
class Player {
// either use a List in each Player or create a class called hand
private List<Card> hand;
private int cash;
private String name;
private Game game;
// TODO: constructor
// TODO: methods including receiveCard(Card c), List<Card> showHand(),...
}
public class Game {
private Player p1;
private Player p2;
private Deck deck;
private int moneyPot;

How to read through file and compute win/loss chart from records given in file?

My assignment is I have to manage a soccer league.There is a soccer league (text file) that I have to import into the program.Each line of the imported file displays the outcome of a single game:the name of two teams together with the scores like
Peter 4 Tiger 3
Sky 2 Peter 0
Tiger 1 Sky 2
I have to write the program to read this text file and displays the output of team records like
Team Wins Losses
Peter 1 1
Tiger 0 2
Sky 2 0
I don't understand how to read through the lines and calculate the wins and losses associated with each team/String.
import java.util.*;
import java.io.*;
public class SoccerLeagueStandings
{
public static void main(String[] args) throws IOException
{
File inFile = new File("LeagueScore.txt");
if(! inFile.exists())
{
System.out.println("Error could not open the file");
return;
}
String Panthers="Panthers";
String Tigers = "Tigers";
String Sky = "Sky";
Scanner input = new Scanner (inFile);
int PW=0;
int PL=0;
int TW =0;
int TL = 0;
int SW=0;
int SL=0;
while (input.hasNextLine())
{
String firstTeam=input.next();
input.nextInt();
int firstScore=input.nextInt();
String secondTeam=input.next();
input.nextInt();
int secondScore = input.nextInt();
if (firstScore>secondScore)
{
if (firstTeam.equals(Panthers))
{
PW+=1;
}
if (firstTeam.equals(Tigers))
{
TW+=1;
}
if (firstTeam.equals(Sky))
{
SW+=1;
}
}
}
}
}
The main challenge in this problem is to keep track of the wins and losses of each team.
So i suggest to create a class called Team which holds: name, winsCount, lossCount. This class represents a single team along with its wins and loss count.
Create an arrayList of Team and fill it using the file content.
So your algorithm would be as the following:
Parse the file line by line using Scanner.
Split each line by space in order to get the teams and their scores.
Compare the scores of the teams.
Add the winner team to the ArrayList OR increment its winsCount if already exist.
Do the same for the loser team.
Below is a non-tested sample code:
Following is the Team class:
public class Team {
private String name;
private int winsCount;
private int lossCount;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getWinsCount() {
return winsCount;
}
public void setWinsCount(int winsCount) {
this.winsCount = winsCount;
}
public int getLossCount() {
return lossCount;
}
public void setLossCount(int lossCount) {
this.lossCount = lossCount;
}
}
Below is how to fill the arraylist from the input file:
private void generateWinsLossesFromInput(String filePath)
{
Scanner input = new Scanner(filePath);
List<Team> teams = new ArrayList<Team>();
while(input.hasNext())
{
String match = input.next();
// Split the line and get teams and their scores.
String[] splittedMatch = match.split("\\s+");
String firstTeam = splittedMatch[0];
int firstTeamScore = Integer.parseInt(splittedMatch[1]);
String secondTeam = splittedMatch[2];
int secondTeamScore = Integer.parseInt(splittedMatch[3]);
if(firstTeamScore > secondTeamScore)
{
addWinner(firstTeam, teams);
addLoser(secondTeam, teams);
}
else
{
if(secondTeamScore > firstTeamScore)
{
addWinner(secondTeam,teams);
addLoser(firstTeam, teams);
}
}
}
}
private void addWinner(String team, List<Team> teams)
{
int index = 0;
for(index = 0; index<teams.size(); index++)
{
Team t = teams.get(index);
if(t.getName().equalsIgnoreCase(team))
{
// Team already exists, so just increment its winsCount
t.setWinsCount(t.getWinsCount() + 1);
break;
}
}
if(index == teams.size())
{
// team not found, So add it as new team to the list.
Team t = new Team();
t.setName(team);
t.setWinsCount(1);
t.setLossCount(0);
teams.add(t);
}
}
private void addLoser(String team, List<Team> teams)
{
int index = 0;
for(index = 0; index<teams.size(); index++)
{
Team t = teams.get(index);
if(t.getName().equalsIgnoreCase(team))
{
// Team already exists, so just increment its loss count.
t.setLossCount(t.getLossCount() + 1);
break;
}
}
if(index == teams.size())
{
// team not found , then add new team to the list
Team t = new Team();
t.setName(team);
t.setWinsCount(0);
t.setLossCount(1);
teams.add(t);
}
}
At the end, you would be able to iterate over the array list and print out each team along with its Wins and loss counts.

Java - Creating Object Arrays [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 7 years ago.
Improve this question
I can't seem to work out these object arrays, I'm attempting to create a list of player names with values stored, each with an integer and some multiple strings for each.
This is what i'm working on so far, were object arrays the correct storage package for this? The error was in line 237 when I try to add a player in the class addPlayer: player[userCount].setName(name);
The error is:- Exception in thread "main" index out of bounds.
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Scanner;
public class PlayerKarma {
static Scanner input = new Scanner(System.in);
static private String[] username = {"name1","name2","test","moretesting","fervor","stackoverflow","imported","quaternion","jetstream"};
static private int[] karma = {1000,800,800,5,15,-4,-403,54,11,210};
static private boolean exit = false;
static private int maxKarmaChange = 10; //How much a players karma can change per day.
static Player[] userArray = new Player[10000];
//ArrayList<Player> userArray = new ArrayList<Player>();
static private int userCount = 0;
public static void main(String[] args)
{
while (!exit)
{
System.out.println("");
System.out.println("Select an option");
System.out.println("1: Display a player's karma");
System.out.println("3: Display all player names and karma");
System.out.println("5: Add player");
String command = input.nextLine();
switch(command)
{
//Display player's karma.
case "1": {
System.out.println("Enter a player's name: ");
String inputString = input.nextLine();
int playerindex = findPlayer(inputString);
if (playerindex == -1)
{
System.out.println("Player doesn't exist");
}
else //If the player exists.
{
System.out.println(userArray[playerindex].getName() + " has a karma of " + karma[userArray[playerindex].getKarma()]);
break;
}
break;}
//Display all player names and karma.
case "3": {getAllPlayerKarma(); sleep(1500); break;}
//Add player.
case "5": {
System.out.println("Enter a player's name:");
String inputString = input.nextLine();
if (userCount > 0) //If there is at least one user in the database.
{
int playerindex = findPlayer(inputString);
if (playerindex == -1)
{
addPlayer(inputString,0);
}
else //If the player exists.
{
break;
}
}
else //If there's no users.
{
addPlayer(inputString,0);
}
break;}
}
}
}
//Class creation for players.
public class Player
{
public String name;
public int karma;
//public String[] notes = new String[5];
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getKarma() {
return karma;
}
public void setKarma(int karma) {
this.karma = karma;
}
}
private static void getAllPlayerKarma() {
System.out.println("");
for (int k = 0; k < userCount; k++)
{
System.out.println(userArray[k].getName() + " has a karma of " + userArray[k].getKarma());
}
}
private static void setAllPlayerKarma(String karmaValue) {
System.out.println("");
for (int k = 0; k < username.length; k++)
{
int parseKarma = Integer.parseInt(karmaValue);
karma[k] = parseKarma;
}
System.out.println("All karma has been set to " + karmaValue);
}
private static void addPlayer(String name, int karma) {
//Adds a new user
Player[] player = new Player[userCount];
//Player[userCount] = new Player(userCount);
player[userCount].setName(name);
player[userCount].setKarma(karma);
//userArray[userCount].setName(name);
//userArray[userCount].setKarma(karma);
userCount++;
}
//Returns the index of the player in the database.
private static int findPlayer(String playerName) {
int playerIndex = -1;
for (int j = 0; j < userCount; j++)
{
System.out.println("Testing name: " + playerName + " against " + userArray[j].getName());
if (playerName.equals(userArray[j].getName())) {
playerIndex = j;
System.out.println("Match");
break;
}
else
{
//System.out.println("No match");
}
}
return playerIndex;
}
private static void sleep(int sleep) {
try {Thread.sleep(sleep);}
catch(InterruptedException ex) {
Thread.currentThread().interrupt();}
}
}
There are three problems with this code:
Player[] player = new Player[userCount];
player[userCount].setName(name);
Firstly, you're creating a new array each time - I suspect you want to populate userArray instead.
Secondly, you're creating an array of size userCount and then trying to use the element with index userCount - that's never going to work. Array indexes are 0-based, so an element with length 3 has valid indexes 0, 1 and 2 for example.
Thirdly, you're not creating a new Player object - so every element in the array is null. Even if you fixed the index, player[x].setKarma(karma) would throw a NullPointerException.
I suspect you want the method to look like this:
private static void addPlayer(String name, int karma) {
Player player = new Player();
player.setKarma(karma);
player.setName(name);
userArray[userCount] = player;
userCount++;
}
That's now fine, until the user count exceeds the length of your array. At that point, you should start looking at List<E> (and ArrayList<E> in particular).
You initialize usercount with the value of 0 and therefore create an array with the size of 0 Player[] player = new Player[userCount];, this leads to your error.

Why am I getting a null pointer exception and should I use reflection?

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.
The setRange() method depends on game not being null. Because setRange() is called in the Player's constructor, it will always throw a NullPointerException because the game instance variable has not been initialized.
One way to fix this is to make Player's constructor accept a HiLo parameter, and set game to that value before calling setRange():
public Player(int playerType, HiLo game) {
this.game = game;
// ...
}
Now you need to update the player = new Player(playerType); statement to use the correct parameters. Because that statement is in an instance method of HiLo, we can simply pass this as the second parameter:
player = new Player(playerType, this);
Here is the setRange code:
public int setRange() {
int r = game.getUpperLimit() - game.getLowerLimit();
return r;
}
There is only one possible explanation for that method throwing an NPE. That is - game is null.
Work with that ... figure out why game is null ... and fix it.
Hint: there are two distinct game fields in your code. You are initializing one of them ... but not the other one.
... and should I use reflection?
Reflection is not a solution to NPE's.

Categories