I'm new in Java programming, Just made simple Guess a number game and now i need to make GUI. I Just start with some simple showMessage and other stuff but i have a problem. How can i define my Human player result, that it will accept it and game will keep playing. Game is between Human and Robot. Problem starts when i input my number answer and game just stops. I Know now the code is broken, but can you give me some advice or tips what to do ? Thanks
**public class Human extends Player {**
private Player guesser;
private final PrintStream printer;
private final Scanner scanner;
private final String name;
Human(String name, PrintStream printer, Scanner scanner) {
this.name = name;
this.printer = printer;
this.scanner = scanner;
}
#Override
public String getName() {
return name;
}
#Override
public int guess(int n) {
JOptionPane.showInputDialog(String.format ("What do you think about %d?"));
char result = scanner.nextLine().trim().charAt(0);
return result == '=' ? 0 : result == '<' ? -1 : 1;
}
#Override
public int play() {
JOptionPane.showMessageDialog(null, String.format("%s wants your guess:", guesser.getName()), null, JOptionPane.PLAIN_MESSAGE);
int n = Integer.parseInt(scanner.nextLine().trim());
return guesser.guess(n);
}
#Override
public void setGuesser(Player player) {
this.guesser = player;
}
}
**public class Robot extends Player {**
private static final Random RANDOM = new Random();
private final String name;
private Player guesser;
private final PrintStream printer;
private int min = 0;
private int max = Integer.MAX_VALUE;
private int last = 1 + RANDOM.nextInt(1);
private final int guessedNumber;
public Robot(String name, PrintStream printer, int min, int max) {
this.name = name;
this.printer = printer;
this.guessedNumber = min + RANDOM.nextInt(max - min);
}
#Override
public String getName() {
return name;
}
#Override
public int guess(int n) {
int result = Integer.compare(guessedNumber, n);
printer.printf("%s says that %d is %s.%n", getName(), n,
result < 0 ? "too much" : result > 0 ? "not enough" : "just fine"
);
return result;
}
#Override
public int play() {
JOptionPane.showMessageDialog(null,"Robot thinks that Human guessed " + last,"aaa", JOptionPane.PLAIN_MESSAGE);
int guessResult = guesser.guess(last);
if (guessResult != 0) {
if (max - min <= 0) {
throw new IllegalStateException("YOU BLOODY CHEATER! SCREW YOU.");
}
if (guessResult == -1) {
max = last - 1;
} else {
min = last + 1;
}
}
last = min + (max - min) / 2;
return guessResult;
}
#Override
public void setGuesser(Player player) {
this.guesser = player;
}
}
Change your
PrintStream.print method
to JOptionPane.showMessageDialog, or even better put a GUI element like a textbox or label and change the text.
Related
I followed some discussion on the website and implemented some suggestions but I was not able to complete the task.
I have this assignment to build Tic Tac Toe game in Java.
There's a lot of tutorials on the web I know, but I wanted to build it using threads for each player so that only one player at a time could enter X/O to the board and I was not able to figure out the implementation for the wait/ notify.
To be honest, I find it a bit confusing! I guess the logic is 90% done, and I am wondering how to finish it.
Basically, I have these classes:
abstract public class Player extends Thread
public class HumanPlayer extends Player
public class MachinePlayer extends Player
public class Board
public class Game
public class Main
I'll paste first the players classes. Notice the run method I tried to Synchronize on top of the gameOver variable:
Player.java
abstract public class Player extends Thread {
abstract int getMyTurn() ;
abstract String getPlayerName() ;
abstract void setPlayerName(String n ) ;
abstract void setSign(int n ) ;
abstract int getSign() ;
}
MachinePlayer.java
import java.util.Random;
public class MachinePlayer extends Player {
private String name ;
private int sign ;
Board board ;
public MachinePlayer(Board board) {
this.board = board;
}
#Override
public void run() {
System.out.println("Player "+name+" turn:" );
while (!board.isGameOver())
{
board.setCurrentPlayerTurn(this.getSign()); // i think it keeps track of which player is holding the lock ?
Move move = generateRandomMove();
board.makeMove(this, move.getX(), move.getY() );
}
}
#Override
int getMyTurn() {
return 0;
}
#Override
public String getPlayerName() {
return name;
}
#Override
public void setPlayerName(String name) {
this.name = name;
}
#Override
void setSign(int sign) {
this.sign = sign ;
}
#Override
int getSign() {
return sign;
}
private Move generateRandomMove(){
while (true)
{
int x = getRandomNumber(0,board.getBoardSize()) ;
int y = getRandomNumber(0,board.getBoardSize()) ;
if (board.isPositionAvalabile(x, y ))
{
return new Move(x,y);
}
}
// todo implement the best move !
}
public int getRandomNumber(int min, int max) {
return (int) ((Math.random() * (max - min)) + min);
}
}
HumanPlayer.java
public class HumanPlayer extends Player {
private String name ;
private int sign ;
private Board board ;
public HumanPlayer(Board board) {
this.board = board;
}
#Override
public void run() {
while (!board.isGameOver())
{
board.setCurrentPlayerTurn(this.getSign()); // I think it keeps track of which player is holding the lock ?
Move move = requestMoveFormHuman(); // request move for human player // will be changed in the GUI?
board.makeMove(this, move.getX() , move.getY()); // check for move logic here >
}
}
#Override
int getSign() {
return sign;
}
#Override
int getMyTurn() {
return 0;
}
#Override
public String getPlayerName() {
return name;
}
#Override
public void setPlayerName(String name) {
this.name = name;
}
#Override
void setSign(int n) {
this.sign = n ;
}
// logic
private Move requestMoveFormHuman(){
int i=0 ;
while (true)
{
System.out.println(i);
Move move = requestMove() ;
int x = move.getX();
int y = move.getY();
if (board.isPositionAvalabile(x,y))
{
return new Move(x,y);
}
}
}
private Move requestMove() {
System.out.println("Player "+name+" turn:" );
System.out.println("Enter Row number: ");
int x = ScanInt();
System.out.println("Enter Coulmn number ");
int y = ScanInt();
return new Move(x ,y ) ;
}
private int ScanInt(){
Scanner scan = new Scanner(System.in);
// This method reads the number provided using keyboard
int num = scan.nextInt();
// Closing Scanner after the use
return num;
}
}
Main.java
public class Main {
public static void main(String[] args) {
Game game = new Game() ;
game.start();
}
}
Board.java
import java.util.HashMap;
import java.util.Scanner;
public class Board {
private int currentPlayerTurn = 0 ;
public int getBoardSize() {
return boardSize;
}
private int boardSize ;
private int[][] board_values ;
private boolean gameOver ;
private HashMap<String , String> result_history;
public Board(int boardSize) {
this.boardSize = boardSize;
board_values = new int[boardSize][boardSize];
for (int i = 0; i < boardSize; i++) {
for (int j = 0 ; j < boardSize; j++)
board_values[i][j] = 0 ;
}
System.out.println("");
}
private String getSign(int n) {
if (n==1)
return "X" ;
if (n==2)
return "0" ;
return " " ; // empty cell
}
public void printBoard(){
// todo change to ui components
for (int i = 0 ; i < boardSize ; i++)
{
for (int j = 0 ; j < boardSize ; j++)
{
System.out.print("|");
System.out.print(" " + getSign(board_values[i][j])+ " ");
System.out.print("|");
}
System.out.println("");
System.out.println("----------------------------------" );
}
}
/** is this the Synchronized one ? */
public boolean makeMove(Player player , int x , int y ) {
/*Update Board Value
insert 1 in the 2d board at x,y for player 1
insert 2 in the 2d board at x,y for player 2
*/
int sign = player.getSign();
updateBoard(x,y , sign ) ;
/*print Board*/
printBoard();
/* check for winner */
doWeHaveAwinner(x,y , sign);
return true ;
}
/*check the whole row (x) for if all signs are equals
, checks the whole column (x) for if all signs are equals
check diagonal if x=y */
private boolean doWeHaveAwinner(int x, int y, int sign) {
// TODO: 16/01/2022
return false ;
}
private void updateBoard(int x, int y , int sign ) {
board_values[x][y] = sign ;
}
public boolean isPositionAvalabile(int x , int y ){
return !(x>this.boardSize || x < 0 || y>this.boardSize || y < 0) ;
}
private void checkMove() {
// todo > ?
}
private void resetBoard(){
// todo set al values to 0
}
private void updateResultHistory(){
// TODO: 16/01/2022 update <Winner Name , Ps+1 >
}
private int ScanInt(){
Scanner scan = new Scanner(System.in);
System.out.print("Enter any number: ");
// This method reads the number provided using keyboard
int num = scan.nextInt();
// Closing Scanner after the use
return num;
}
/*Get Set*/
public synchronized boolean isGameOver() {
return gameOver;
}
public void setGameOver(boolean gameOver) {
this.gameOver = gameOver;
}
public int getCurrentPlayerTurn() {
return currentPlayerTurn;
}
public void setCurrentPlayerTurn(int currentPlayerTurn) {
this.currentPlayerTurn = currentPlayerTurn;
}
}
And here is Game.java, it basically inits 2 players.
Notice that in each player init I passed the board instance as a parameter.
It might a look little bit messy but I think passing the board instance for the players is the important thing here. Also I called the player1().start and player2.start()
Game.java
public class Game {
private Player player1 ;
private Player player2 ;
private Board board ;
private void initBoard(){
/* request board size */
int board_size = requestBoardSize();
board = new Board(board_size); // Synchronized class fields ?
}
private void initGameMode(){
/*
init the players objects as follows
1 - for human-machine game
2 - for machine-human game, and
3 - for human-human game
*/
System.out.println(Utils.str_gameType);
Scanner scanner = new Scanner( System.in);
int game_mode = scanner.nextInt( );
switch (game_mode) {
case 1:
/* init game type1 human-machine Game*/
player1 = new HumanPlayer(board);
player2 = new MachinePlayer(board);
break;
case 2:
player1 = new MachinePlayer(board);
player2 = new HumanPlayer(board);
break;
case 3:
player1 = new HumanPlayer(board);
player2 = new HumanPlayer(board);
break;
default:
throw new IllegalStateException("Unexpected value: " + game_mode);
}
player1.setSign(1);
player2.setSign(2);
System.out.println("");
}
private void initPlayersName(){
/*request name player 1 */
System.out.println(Utils.str_player1Name); /*Scan first name*/
Scanner scan1 = new Scanner(System.in);
String name1 = scan1.next();
player1.setPlayerName(name1);
/*request name player 2 */
System.out.println(Utils.str_player2Name); /*Scan first name*/
Scanner scan2 = new Scanner(System.in);
String name2 = scan2.next();
player2.setPlayerName(name2);
}
public Game() {
System.out.println(Utils.str_start_game);
initBoard();
initGameMode();
initPlayersName();
}
public void start() {
// todo change who starts first
player1.start();
new Thread(new Runnable() {
#Override
public void run() {
try {
Thread.sleep(300);
player2.start();
}catch (Exception e)
{
}
}
}).start();
}
private int requestBoardSize() {
System.out.println(Utils.str_request_board_size);
Scanner scanner = new Scanner(System.in) ;
int i = scanner.nextInt() ;
return i ;
}
}///End of Class
I am trying to check the selected enemy's weapons and armor to see if they are better than the main character's. So, I want to check each one by one, and if the enemy's are better I want to set the main character's weapon equal to the enemy's to basically take it and it to the main character's bag. Everything I have tried so far has been checking to see if one weapon is better and replacing all weapon regardless if the others are better or not. Is there a way I can check each individually?
I have four classes. Main. Character. Weapon. Armor. This is the part of the main class where I am trying to switch:
import java.util.Scanner;
import Character.Character;
import java.util.Random;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("> Welcome to The Game Project <");
System.out.println("\n >> Input Main Character Name: ");
String main_name = scanner.nextLine();
System.out.println(">> Input Main Character Power: ");
int main_power=scanner.nextInt();
System.out.println(">> Input Main Character Hp: ");
int main_hp=scanner.nextInt();
System.out.println("----------------------------------------------------");
Character main_ch=new Character (main_hp,main_power,main_name);
show_status(main_ch);
check_bag(main_ch);
Character enemies[]=new Character [10];
enemies[0]= new Character("Werewolf");
enemies[1]= new Character("Vampire");
enemies[2]= new Character("Alien");
enemies[3]= new Character("Witch");
enemies[4]= new Character("Ghost");
enemies[5]= new Character("Skeleton");
enemies[6]= new Character("Zombie");
enemies[7]= new Character("Demon");
enemies[8]= new Character("Mummy");
enemies[9]= new Character("Dragon");
boolean check = false;
int dead_count=0;
while(true) {
Random rnd=new Random();
int selected = rnd.nextInt(enemies.length); //random enemy selected
System.out.println();
System.out.println(">>>>> An enemy has appeared! <<<<<");
while(enemies[selected].getHp()>0) {
System.out.println();
System.out.println(">>>>> "+enemies[selected].getName()+" wants to fight!");
show_status(enemies[selected]);
check_bag(enemies[selected]);
System.out.println();
System.out.println(">> What do you want to do?");
System.out.println("\t1. Fight!");
System.out.println("\t2. Use skill.");
System.out.println("\t3. Check your stats.");
int input = scanner.nextInt();
if(input==1) {
// originally using int damageToEnemy = rnd.nextInt(main_ch.hit_point());
// originally using int damageTaken = rnd.nextInt(enemies[selected].hit_point());
int damageToEnemy = main_ch.hit_point();
int damageTaken = enemies[selected].hit_point();
enemies[selected].hp -= damageToEnemy;
main_ch.hp -= damageTaken;
if(enemies[selected].hp <= 0) {
enemies[selected].hp=0;
dead_count=dead_count+1;
main_ch.level=main_ch.level+1; //gain one level after enemy defeated
System.out.println(">> You defeated the enemy and gained a level!");
main_ch.getBag().setMoney(main_ch.getBag().getMoney() + enemies[selected].getBag().getMoney());//take defeated enemy's money
System.out.println();
System.out.println("\t>> You found "+enemies[selected].getBag().getMoney()+" dollars. You now have "+main_ch.getBag().getMoney()+" dollars in your bag.");
if(enemies[selected].getWeapon().getPower() > main_ch.getWeapon().getPower()) { //check to see if enemy's weapons have higher power
for(int i = 0; i<4; i++) {
main_ch.getBag().setWeaponArray(i, enemies[selected].getBag().getWeaponArray()[i]); //replace weapons if they are better
}
System.out.println("\t>> You found better weapons! They have been added to your bag.");
}
if(enemies[selected].getArmor().getDefense() > main_ch.getArmor().getDefense()) { //check to see if enemy's armor is better
for(int i = 0; i<4; i++) {
main_ch.getBag().setArmorArray(i, enemies[selected].getBag().getArmorArray()[i]); //replace armor if it is better
}
System.out.println("\t>> You found better armor! They have been added to your bag.");
}
break;
}
System.out.println("\n>> You caused "+ damageToEnemy +" damage to the enemy! Their hp is now "+ enemies[selected].hp+".");
System.out.println(">> You received "+ damageTaken +" damage from the enemy! Your hp is now "+main_ch.hp+".");
if(main_ch.hp <=0) {
System.out.println();
System.out.println(">> Oh no! You died! Better luck next time. Thanks for playing!");
System.out.println();
break;
}
}
else if(input==2) {
if(main_ch.getSkill()>0 && main_ch.getMp()>0) {
main_ch.useSkill();
System.out.println("\t>> You used a skill. Your hit point increased to "+main_ch.hit_point()+". Your MP decreased to "+main_ch.getMp()+".");
}
else {
if(main_ch.getSkill()<=0) {
System.out.println("You have no skill points left.");
}
else{
System.out.println("\t>> Your MP is too low to use skill.");
}
}
}
else if(input==3) {
System.out.println();
show_status(main_ch);
check_bag(main_ch);
}
else {
System.out.println(">> You have entered an invalid key.");
}
}
if(dead_count==enemies.length) {
check=true;
}
if(check) {
System.out.println();
System.out.println(">>>>>>>>>> You won! Congratulations, you defeated all of your enemies! <<<<<<<<<");
break;
}
if(main_ch.hp <=0) {
System.out.println();
System.out.println(">> Oh no! You died! Better luck next time. Thanks for playing!");
System.out.println();
break;
}
}
}
public static void show_status(Character character) {
System.out.println("----------------- Character Status -----------------");
System.out.println("\tCharacter Name:\t\t"+character.getName());
System.out.println("\tCharacter HP:\t\t"+character.getHp());
System.out.println("\tCharacter Power:\t"+character.getPower());
System.out.println("\tCharacter Defense:\t"+character.getDefense());
System.out.println("\tCharacter MP:\t\t"+character.getMp());
System.out.println("\tCharacter Level:\t"+character.getLevel());
System.out.println("\tCharacter Hit Point:\t"+character.hit_point());
System.out.println("\tCharacter Skill:\t"+character.getSkill());
System.out.println("\tWeapon Name:\t\t"+character.getWeapon().getName());
System.out.println("\tWeapon Power:\t\t"+character.getWeapon().getPower());
System.out.println("\tArmor Name:\t\t"+character.getArmor().getName());
System.out.println("\tArmor Defense:\t\t"+character.getArmor().getDefense());
System.out.println("----------------------------------------------------");
}
public static void check_bag(Character character) {
System.out.println("-------------------- Bag Status --------------------");
System.out.println("\tMoney:\t\t\t$"+ character.getBag().getMoney());
for(int i = 0; i<4; i++) {
System.out.println("\tWeapon Name/Power:\t"+ character.getBag().getWeaponArray()[i].getName()+" // "+character.getBag().getWeaponArray()[i].getPower());
}
for(int i = 0; i<4; i++) {
System.out.println("\tArmor Name/Defense:\t"+ character.getBag().getArmorArray()[i].getName()+" // "+character.getBag().getArmorArray()[i].getDefense());
}
System.out.println("----------------------------------------------------");
}
}
This is the Character class:
import java.util.Random;
import Equipment.*;
public class Character {
private Armor armor = new Armor();
private Weapon weapon = new Weapon();
private Bag bag = new Bag();
public static String server_name = "CS172";
public int hp, power, defense, mp, level, skill;
private String name;
Random rnd=new Random();
public Character(String name) {
this.name=name;
Random rnd=new Random();
this.hp=rnd.nextInt(500)+1;
this.power=rnd.nextInt(100)+1;
this.defense=rnd.nextInt(100)+1;
this.mp=rnd.nextInt(50)+1;
this.level=1;
this.skill=5;
}
public Character(int hp, int power, String name) {
this.hp=hp;
this.power=power;
this.name=name;
this.defense=rnd.nextInt(100)+1;
this.mp=rnd.nextInt(50)+1;
this.level=1;
this.skill=5;
}
public int getHp() {
return hp;
}
public void setHp(int hp) {
this.hp = hp;
}
public int getPower() {
return power;
}
public void setPower(int power) {
this.power = power;
}
public int getDefense() {
return defense;
}
public void setDefense(int defense) {
this.defense = defense;
}
public int getMp() {
return mp;
}
public void setMp(int mp) {
this.mp = mp;
}
public int getLevel() {
return level;
}
public void setLevel(int level) {
this.level = level;
}
public String getName() {
return name;
}
public int damage(int enemy_power) {
int damage = enemy_power - this.defense;
if(damage<0){ //avoid healing by damage
damage=0;
}
this.hp=this.hp - damage;
if(this.hp<0) { //avoid negative hp
this.hp = 0;
}
return damage;
}
public Armor getArmor() {
return armor;
}
public void setArmor(Armor armor) {
this.armor = armor;
}
public Weapon getWeapon() {
return weapon;
}
public void setWeapon(Weapon weapon) {
this.weapon = weapon;
}
public int hit_point() {
int total_power = this.power + this.weapon.getPower();
return total_power;
}
public int useSkill() {
this.mp=this.mp-1;
this.skill--;
this.power =this.power + 30;
return hit_point();
}
public int getSkill() {
return skill;
}
public Bag getBag() {
return bag;
}
public void setBag(Bag bag) {
this.bag = bag;
}
public class Bag{
Weapon weaponArray[] = new Weapon[4];
Armor armorArray[] = new Armor[4];
int money = 150;
public Bag(){
for(int i=0; i<weaponArray.length; i++) {
weaponArray[i] = new Weapon();
armorArray[i] = new Armor();
}
}
public Weapon[] getWeaponArray() {
return weaponArray;
}
public void setWeaponArray(int yourWeaponIndex, Weapon enemyWeapon) {
this.weaponArray[yourWeaponIndex] = enemyWeapon;
}
public Armor[] getArmorArray() {
return armorArray;
}
public void setArmorArray(int yourArmorIndex, Armor enemyArmor) {
this.armorArray[yourArmorIndex] = enemyArmor;
}
// public void setArmorArray(Armor[] armorArray) {
// this.armorArray = armorArray;
// }
public int getMoney() {
return money;
}
public void setMoney(int money) {
this.money = money;
}
}
}
I am doing this for a class, and we wrote part of the code in class with the professor. I have a feeling I am supposed to use this somehow, but I don't even really understand what it is doing:
public void setWeaponArray(int yourWeaponIndex, Weapon enemyWeapon) {
this.weaponArray[yourWeaponIndex] = enemyWeapon;
}
Can someone explain this to me please?
Weapons class:
package Equipment;
import java.util.Random;
public class Weapon {
private String name;
private int power;
Random rnd = new Random();
public Weapon() {
this.name="Weapon #" + rnd.nextInt(20);
this.power=rnd.nextInt(50)+1;
}
public Weapon(String name) {
this.name=name;
this.power=rnd.nextInt(50)+1;
}
public int getPower() {
return power;
}
public void setPower(int power) {
this.power = power;
}
public String getName() {
return name;
}
}
Armor class:
import java.util.Random;
public class Armor {
private String name;
private int defense;
Random rnd = new Random();
public Armor() {
this.name="Armor #"+rnd.nextInt(10);
this.defense=rnd.nextInt(10)+1;
}
public Armor(String name) {
this.name=name;
this.defense=rnd.nextInt(10)+1;
}
public int getDefense() {
return defense;
}
public void setDefense(int defense) {
this.defense = defense;
}
public String getName() {
return name;
}
}
Based on the code you are providing
public void setWeaponArray(int yourWeaponIndex, Weapon enemyWeapon) {
this.weaponArray[yourWeaponIndex] = enemyWeapon;
}
This method sets the current weapon of the bag (Your object here is the bag) to another enemyWeapon using the index of the element in the array weaponArray[] . But, since your array length is 4, I believe you have to call it 4 times to make the 4 weapons in the bag.
main_ch.getBag().setWeaponArray(enemies[selected].getBag().getWeaponArray());
In this line, you are not specifying the index (You normally have 2 parameters for the method setWeapon(int yourWeaponIndex, Weapon enemyWeapon)
It should be something like this :
main_ch.getBag().setWeaponArray(i ,enemies[selected].getBag().getWeaponArray());
i is the index of the weapon to change.
Example
main_ch.getBag().setWeaponArray(0 ,enemies[selected].getBag().getWeaponArray() );
This line only changes the first weapon if the enemy's weapon is better.
Instead of replacing the whole bag array just replace the weapon at the specific index in the loop.
You are almost there... That method that you wanted to use is exactly used for what you want. It is a method that requires two things. The position of your weapon to be replaced (yourWeaponIndex) and the item to replace it with (enemyWeapon). The weapons loop you are replacing the whole bag instead of the weapon in question.
for(int i = 0; i<4; i++) { //loop through your items one by one
for(int j = 0; j<4; j++) { //loop through enemy items one by one
//compare item 1 to all 4 enemies items (order 16 comparison - 4 x 4 comparisons)
if(enemies[selected].getBag().getWeaponArray()[j].getPower() > main_ch.getBag().getWeaponArray()[i].getPower()) { //check to see if enemy's weapons have higher power
//put stronger enemy weapon (j) in your bag
main_ch.getBag().setWeaponArray(i, enemies[selected].getBag().getWeaponArray()[j]);
//put your weaker weapon (i) in enemy bag
enemies[selected].getBag().setWeaponArray(j, main_ch.getBag().getWeaponArray()[i]);
//alert that items have changed
System.out.println("\t>> You found better weapons! They have been added to your bag.");
}
}
}
For the purpose of interest and learning
for(int k = 0; k<4; k++) { //loop through your items one by one
for(int l = 0; l<4; l++) { //loop through enemy items one by one
//compare item 1 to all 4 enemies items (order 16 comparison - 4 x 4 comparisons)
if(enemies[selected].getBag().getArmorArray()[l].getDefense() > main_ch.getBag().getArmorArray()[k].getDefense()) { //check to see if enemy's armor has higher power
//put stronger enemy armor in your bag
main_ch.getBag().setArmorArray(k, enemies[selected].getBag().getArmorArray()[l]);
//put your weaker armor in enemy bag
enemies[selected].getBag().setArmorArray(l, main_ch.getBag().getArmorArray()[k]);
//alert that items have changed
System.out.println("\t>> You found better weapons! They have been added to your bag.");
}
}
}
See the working code:
https://onlinegdb.com/rkg3n7ICH
This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 5 years ago.
I keep getting this error in my code. Can someone fix it and how is the code written? Can it be improved by maybe using setters and getters only?
Exception in thread "main" java.lang.NullPointerException
at Player.attack(Player.java:72)
at Main.main(Main.java:15)
My code:
Player.java
public class Player {
String name;
String race;
int hp;
int power;
int armour;
Weapon weapon;
public Player (String n, String r, int h, int p, int a) {
name = n;
race =r;
hp = h;
power = p;
armour = a;
}
public void setName (String n) {
name = n;
}
public String getName() {
return name;
}
public void setRace (String r) {
race = r;
}
public String getRace() {
return race;
}
public void setHP (int h) {
hp = h;
}
public int getHP() {
return hp;
}
public void setPower (int p) {
power = p;
}
public int getPower() {
return power;
}
public void setArmour (int a) {
armour = a;
}
public int getArmour() {
return armour;
}
public boolean dead() {
return hp <= 0;
}
public boolean equip(Weapon weapon) {
this.weapon = weapon;
return true;
}
public boolean receiveDamage(int i) {
if ((hp - i) > 0) {
hp = hp - i;
return true;
}
hp = 0;
return false;
}
public boolean attack(Player player) {
return player.receiveDamage(weapon.useWeapon());
}
}
Main.java
public class Main {
public static void main(String args[]) {
Player Mensch = new Player("Mensch", "Mensch", 85, 12, 10);
Player Ork = new Player("Shrek", "Ork", 50, 14, 6);
Weapon MenschW = new Weapon("mächtiges Schwert", 15, 100);
Weapon OrkW = new Weapon("große Axt", 7, 100);
Mensch.equip(Mensch.weapon);
Ork.equip(Ork.weapon);
while (!Mensch.dead() && !Ork.dead() ) { //Alternativ: for (player hp >=0)
System.out.println("Mensch gegen Ork " + Mensch.attack(Ork));
if (Mensch.dead() || Ork.dead()) {
break;
}
System.out.println("Mensch gegen Ork " + Ork.attack(Mensch));
}
System.out.println("Ork ist tot: " + Ork.dead());
System.out.println("Mensch ist tot: " + Mensch.dead());
}
}
Weapon.java
import java.util.concurrent.ThreadLocalRandom;
public class Weapon {
String name;
int damage;
int hp;
public Weapon(String string, int d, int hp) {
// TODO Auto-generated constructor stub
}
public void setName (String n) {
name = n;
}
public String getName() {
return name;
}
public void setDamage (int d) {
damage = d;
}
public int getDamage() {
return damage;
}
public void setWHP (int h) {
hp = h;
}
public int getWHP() {
return hp;
}
public int useWeapon() {
if
(broken())
return 0;
hp = hp - 5;
return (damage / 2) + random();
}
private int random() {
return ThreadLocalRandom.current().nextInt(1, damage + 1);
}
private boolean broken() {
return hp <= 0;
}
}
I know its a lot of code but I keep getting the same error, also I'm quite new to java so I would appreciate some tips or suggestions to make my code better or more failsave. The code doesn't do much yet but it will (hopefully) be a simple game soon in which two characters fight eachother with some calculations on damageoutput of each player. In this case a Human and Ork. Feel free to try it out
Change
Mensch.equip(Mensch.weapon); // Mensch.weapon is not initialized in constructor so it is null.
Ork.equip(Ork.weapon); // Ork.weapon is not initialized in constructor so it is null as well.
To
// Use your newly created weapons in the main instead.
Mensch.equip(MenschW );
Ork.equip(OrkW);
So I rewrote it with your suggestion (Todd Hopp) and updated the post in the (*) section in the BlackJack class so you can see how I have it now but I'm still getting the same errors and it is not printing the computePlayerValue for some reason....
ERROR:
Exception in thread "main" java.lang.NumberFormatException: For input string: "King" at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
at java.lang.Integer.parseInt(Integer.java:580)
at java.lang.Integer.parseInt(Integer.java:615)
at BlackJack.dealCards(BlackJack.java:25)
at PlayCardGame.main(PlayCardGame.java:9)
P.S. I'm was trying to look this up in the book but couldn't find the answer...The BlackJack class is partially source code from an earlier chapter in the book and I couldn't figure out if it was necessary to have super(); in the constructor there? I thought it only had to do if the parent class constructor had an argument? Any help on if it has to be there and if so what it's doing.
BlackJack Class
public class BlackJack extends CardGameFP{
int computePlayerValue;
int computeDealerValue;
int cardValue;
public BlackJack() {
**super();**
player1 = 2;
player2 = 2;
}
public void display() {
System.out.println("BlackJack");
}
//*************************************************************
public int getCardValue(Card card) {
final String rank = card.getRank();
switch (rank) {
case "Ace":
return 1;
case "King":
case "Queen":
case "Jack":
return 10;
default:
return Integer.parseInt(rank);
}
}
public void dealCards() {
//Player 1
System.out.println("Player 1:");
for(int x = 0; x < playerHand; x++) {
shuffle();
System.out.println(fullDeck[x].getRank() + " of " + fullDeck[x].getSuit());
}
cardValue1 = getCardValue(fullDeck[0]);
cardValue2 = getCardValue(fullDeck[1]);
computePlayerValue = cardValue1 + cardValue2;
System.out.println(computePlayerValue);
}
//*************************************************************
//Dealer hand
System.out.println("\nPlayer 2:");
for(int x = 0; x < player2; x++) {
System.out.println(fullDeck[x].getRank() + " of " + fullDeck[x].getSuit() );
shuffle();
}
}
}
public class Card {
protected String suit;
protected int value;
protected String rank;
protected final int LOW_VALUE = 1;
protected final int HIGH_VALUE = 13;
public String getRank() {
return rank;
}
public int getValue() {
return value;
}
public String getSuit() {
return suit;
}
public void setSuit(String st) {
suit = st;
}
public void setValue(int val) {
if(val >= LOW_VALUE && val <= HIGH_VALUE) {
value = val;
}
else {
value = LOW_VALUE;
}
if(val == 1) {
rank = "Ace";
}
else if(val == 11) {
rank = "Jack";
}
else if(val == 12) {
rank = "Queen";
}
else if(val == 13) {
rank = "King";
}
else {
rank = Integer.toString(value);
}
}
}
CardGame Class
abstract public class CardGameFP {
int suitNum = 1;
int val = 1;
int player1;
int player2;
protected final int DECK_OF_CARDS = 52;
Card fullDeck[] = new Card[DECK_OF_CARDS];
protected final int LOW_VALUE = 1;
protected final int HIGH_VALUE = 13;
protected final int HIGH_SUIT = 4;
protected final int CARDS_IN_SUIT = 13;
public abstract void display();
public abstract void dealCards();
public CardGameFP() {
for(int i = 0; i < fullDeck.length; i++) {
fullDeck[i] = new Card();
if(suitNum == 1) {
fullDeck[i].setSuit("Spades");
}
else if(suitNum == 2) {
fullDeck[i].setSuit("Hearts");
}
else if(suitNum == 3) {
fullDeck[i].setSuit("Diamonds");
}
else {
fullDeck[i].setSuit("Clubs");
}
fullDeck[i].setValue(val);
val++;
if(val > HIGH_VALUE) {
suitNum++;
val = 1;
}
}//end for
}
public void shuffle() {
for(int firstCard = 0; firstCard < DECK_OF_CARDS; firstCard++ ) {
firstCard = ((int)(Math.random() * 500) % DECK_OF_CARDS);
int secondCard = ((int)(Math.random() * 500) % DECK_OF_CARDS);
Card temp = fullDeck[firstCard];
fullDeck[firstCard] = fullDeck[secondCard];
fullDeck[secondCard] = temp;
}
}
}
PlayCardGame Class
PlayerCardGame
public class PlayCardGame {
public static void main(String[] args) {
Card CG = new Card();
BlackJack BJ = new BlackJack();
BJ.display();
BJ.dealCards();
}
}
Instead of this line:
cardValue = Integer.parseInt(fullDeck[0].getRank());
I suggest that you create a getCardValue(Card) method:
public int getCardValue(Card card) {
final String rank = card.getRank();
switch (rank) {
case "Ace":
return 1;
case "King":
case "Queen":
case "Jack":
return 10;
default:
return Integer.parseInt(rank);
}
}
and then use:
cardValue = getCardValue(fullDeck[0]);
EDIT: Following the suggestion by #WorldSEnder, you can define a Rank enum:
public enum Rank {
ACE("Ace", 1),
TWO("2", 2),
...
QUEEN("Queen", 10),
KING("King", 10);
private final String displayName;
private final int value;
protected Rank(String displayName, int value) {
this.displayName = displayName;
this.value = value;
}
public String displayName() {
return displayName;
}
public int value() {
return value;
}
}
Then you can modify Card to use a Rank instead of a String for the rank and use:
cardValue = fullDeck[0].getRank().value();
When you call :
cardValue = Integer.parseInt(fullDeck[0].getRank());
the method Interger.parseInt() is attempting to read an int from a string. The problem is that some cards have ranks which themselves are not strings like, King. So when you return the rank of that card, parseInt() doesn't know how to handle King. You should instead be getting the cards actual value using fullDeck[0].getVaule() and parsing that instead. It will be a string between 1 and 13.
So I'm fairly certain that this code should work, but when I run it it spits out that.
Problem occurs at:
return planetArray[arr[0].viewPosition()].testCost();
My code is posted below. I've scoured over this but cannot see how it's null?
The purpose is to take the currentPosition of the Player[x] and use it to check the cost of the planet Player[x] is on and return the cost.
Sorry if I posted too much / not enough code, wasn't sure where the error was.
public class Launcher
{
private static Planet returnCost;
private static Planet myTest;
private static PlanetInfo myPlanetInfo;
private static PlanetInfo[] planetArray;
private static Player[] arr; //NEED THIS FOR arr = myArray.getPlayerArray(); to work..
public static void main(String[] args)
{
Planet myPlanetArray = new Planet();
PlayerArray myArray = new PlayerArray();
myPlanetArray.getPlanetArray();
myArray.getPlayerArray();
planetArray = myPlanetArray.getPlanetArray();
arr = myArray.getPlayerArray(); //holy moses this worked...
System.out.println("player 1's ID: " + arr[0].viewID());
System.out.println("player 1's balance: " + arr[0].viewBalance());
arr[0].playerGo();
System.out.println("You've landed on: " /* + myPlanetArray.returnName()*/ + " it costs: " + myPlanetArray.returnCost());/*arr[0].viewPosition());*/
//^^^this line causes the error
}
}
and...
public class PlanetInfo
{
Scanner scan = new Scanner(System.in);
private static PlanetInfo[] planetArray;
private static Player[] arr;
private String name; //same with this
private int cost; // doesnt need setter or getter methods, it's permanent.
private int position; // same with this
private int group; // same with this
private int owner;
private int rent; // done
private int town;
private int city;
private int sellValue; // same with this
public void setRent()
{
System.out.println("How many towns would you like to add?");
town = scan.nextInt();
if(position != 39 && town == 1) {rent *= 5;}
else if(position == 39 && town == 1){rent = 200;}
if(town == 2) {rent *= 3;}
if(position <= 13 && town == 3) {rent *= 3;}
else if(position > 13 && town == 3) {rent *= 2.5;}
if(position < 20 && town == 4) {rent *= 1.45;}
else if((position > 20 && position < 40) && town == 4) {rent *= 1.3;}
}
public int getRent(){return rent;}
//public void setOwner(){owner = arr[0].viewID();}
//public int getOwner(){return owner;}
//^^^^Will do this in Player class.
public PlanetInfo(String planetName, int planetCost, int boardPosition, int groupColor, int currentOwner, int startRent, int numTown, int numcity)
{
cost = planetCost;
name = planetName;
position = boardPosition;
group = groupColor;
owner = currentOwner;
rent = startRent;
town = numTown;
city = numcity;
sellValue = cost/2;
}
}
finally..
import java.util.Scanner;
import java.util.Random;
public class Planet
{
private static Player[] arr;
private static PlanetInfo[] planetArray;
private String name;
private int cost;
private int playerPosition;
public void Planet()
{
//cost,boardposition,color,currentowner,startingRent,#towns,#city
Planet testPlanet = new Planet();
PlayerArray myArray = new PlayerArray();
PlanetInfo[] planetArray;
myArray.getPlayerArray();
arr = myArray.getPlayerArray();
planetArray = new PlanetInfo[40];
planetArray[1] = new PlanetInfo("Tatooine Mos Eisley",60,1,1,-1,2,0,0);
planetArray[3] = new PlanetInfo("Tatooine Mos Espa",60,3,1,0,-1,0,0);
planetArray[6] = new PlanetInfo("Dagobah",100,6,2,-1,6,0,0);
//MORE OF THIS NOT IMPORTANT SO REMOVED
planetArray[34] = new PlanetInfo("Alderaan",320,34,7,-1,28,0,0);
planetArray[37] = new PlanetInfo("Coruscant Jedi Temple",350,37,8,-1,35,0,0);
planetArray[39] = new PlanetInfo("Coruscant Senate",400,39,8,-1,50,0,0);
public int testCost()
{
return cost;
}
}
public PlanetInfo[] getPlanetArray()
{
return planetArray;
}
public String testName()
{
return name;
}
public int testCost()
{
return cost;
}
public int returnCost() //returns int of cost
{
return planetArray[arr[0].viewPosition()].testCost();
}
}
You never show what the PlanetArray class looks like. Most likely you are not instantiating the Player[] array that gets returned in the getPlanetArray() method.