I'm trying to write a game in Java with a Player class that has 2 subclasses: HumanPlayer and ComputerPlayer. I want to allow the user to choose which player to play against, and once chosen - to create the relevant object and play.
Since the object is created within an if statement, the compiler doesn't let me perform any operations outside the if scope. In other cases I would create the object within the class' scope but in this case I cant know in advance which object to create (human/computer)
Here is some code for illustration:
public class Player {
private String name;
public String getName(){
return name;
}
}
public class HumanPlayer extends Player {
public void play(){
System.out.println("Human playing");
}
}
public class ComputerPlayer extends Player {
public void play(){
System.out.println("Computer playing");
}
}
import java.util.Scanner;
public class PlayerDriver {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
System.out.println("Please type 1 for human, 2 for computer");
int selection = in.nextInt();
if (selection==1){
HumanPlayer player = new HumanPlayer();
} else if (selection==2){
ComputerPlayer player = new ComputerPlayer();
} else {
throw new IllegalArgumentException("invalid answer");
}
Player.play(); //can't do that
}
}
Harness the power of polymorphism
Player player = null; // player should never be null as you would have thrown an exception, but for the sake of completeness
if (selection == 1){
player = new HumanPlayer();
} else if (selection == 2){
player = new ComputerPlayer();
} else {
throw new IllegalArgumentException("invalid answer");
}
player.play();
assuming the Player class has a play() method. I see it doesn't. Change your class Player to have an override-able play() method which you override in the sub types.
Related
I have 7 classes(shown in pick below) with main method class for testing is Animalstuff class. When I'm running the code its getting hung and not moving any where. Need your help to solve this.At the end I want to run using Junit.
classes all
running Animalstuff class, see below it hang and not moving forward.
hung
here is the code for complete Animalstuff class.
/**
*
*/
import java.util.ArrayList;
import java.util.Scanner;
public class AnimalStuff {
// main function
public static void main(String[] args) {
// for taking inputs
Scanner in = new Scanner(System.in);
// arrayList to store all the animals
ArrayList<Animal> myList = new ArrayList<Animal>();
int ch;
// Loop until user chooses to quit
do {
// print menu
System.out.println("Menu");
System.out.println("1. Add animal");
System.out.println("2. Print");
System.out.println("3. Exit");
System.out.print("Enter your choice: ");
ch = in.nextInt();
// if user chooses to add animal to list
if(ch==1) {
// input the kind/name of animal
in.nextLine();
String word;
System.out.print("Enter name of animal: ");
word = in.nextLine();
// create object of that kind
Animal obj = Animal.newInstance(word);
// if user entered invalid animal, print message
if(obj==null) {
System.out.println("Animal doesn't exist.");
}
// else add to the list
else {
myList.add(obj);
}
}
// if user chooses to see information of all the
// animals in the list
else if(ch == 2) {
for(int i=0;i<myList.size();i++) {
myList.get(i).print(true);
}
}
// if user chooses to quit
else {
System.out.println("See you soon!");
}
}while(ch != 3);
}
}
Below is the code for Animal class
import java.util.ArrayList;
import java.util.Scanner;
public class Animal {
// variables
public String kind;
public String integument;
public boolean fast;
// private constructor to avoid plain animals
private Animal() {
}
// public argument constructor for Mammal and Bird class to
// call
public Animal(String kind, boolean fast) {
this.kind = kind;
this.fast = fast;
}
// movement method
public String movement() {
if(fast) {
return "I run on four legs.";
}
else {
return "I walk on four legs.";
}
}
// sound method
public String sound() {
return "";
}
// method to print all the information about the animal
public void print(boolean fast) {
String move = "";
if(fast)
move = "fast";
else
move = "slowly";
System.out.println("I am a "+kind);
System.out.println(" I have "+integument);
System.out.println(" When I go "+move+", "+movement());
System.out.println(" The sound I make is "+sound());
}
// method to return the animal object of type kind
public static Animal newInstance(String kind) {
Animal obj;
boolean correct = false;
if(kind.toLowerCase().equals("cow")) {
obj = new Cow();
Cow cow = new Cow();
if(obj.equals(cow)) {
correct = true;
}
}
else if(kind.toLowerCase().equals("duck")) {
obj = new Duck();
Duck duck = new Duck();
if(obj.equals(duck)) {
correct = true;
}
}
else if(kind.toLowerCase().equals("parrot")) {
obj = new Parrot();
Parrot parrot = new Parrot();
if(obj.equals(parrot)) {
correct = true;
}
}
else if(kind.toLowerCase().equals("whale")) {
obj = new Whale();
Whale whale = new Whale();
if(obj.equals(whale)) {
correct = true;
}
}
else {
return null;
}
if(correct) {
System.out.println("Correct object is formed.");
}
else {
System.out.println("Wrong object is formed.");
}
return obj;
}
// Function to check if two methods are same, i.e., this function
// checks whether the object formed is correct or not
public boolean equals(Animal obj) {
if(this.kind.equals(obj.kind)) {
if(this.integument.equals(obj.integument)) {
if(this.movement().equals(obj.movement())) {
if(this.sound().equals(obj.sound())) {
return true;
}
}
}
}
return false;
}
}
Please let me know whats worng in this and how I can fix. The other classes are very small if need I can give code for those as well.
Thanks
Enter your choice:
If you are getting this line in the console then it's asking for the input ch. Enter your input and you'll proceed further.
I am making a PVP RPG game and the display box comes out with "null" instead of the variable I have already declared.
I have declared the variable as the user's next input and stored that information in the variable. Then when I try to display the variable, it only shows "null",
System.out.println("Welcome, Player One and Player Two!");
delay(1500);
System.out.println("What is your name, Player One?");
playerOne.name = userInput.nextLine();
I already declared playerOne as a new character(different class)
System.out.println("Your turn, " + playerOne.name+".");
if (p1Swordgo == 1) {
This is the problem I'm coming up with. It is in the same main method and the variables are declared in the main method, and yes I imported scanner and declared the variable userInput
I expected it to be what the user typed in, but it came up with null. As I've said previous, it's in the same main method and nothing should go wrong, but it comes up with "null"
import java.util.Random;
import java.util.Scanner;
public class Arena {
Random generator = new Random();
public static void main(String[] args) {
Character playerOne = new Character(10,10,0);
Character playerTwo = new Character(10,10,0);
boolean P1hasClass = false;
boolean P2hasClass = false;
int p1Swordgo = 0;
int p2Alchgo = 0;
int p2Archgo = 0;
Scanner userInput = new Scanner(System.in);
System.out.println("Welcome, Player One and Player Two!");
delay(1500);
System.out.println("What is your name, Player One?");
playerOne.name = userInput.nextLine();
delay(1000);
System.out.println("Hello, " +playerOne.name +".");
delay(1000);
System.out.println("What is your name, Player Two?");
playerTwo.name = userInput.nextLine();
delay(1000);
System.out.println("Hello, " +playerTwo.name +".");
delay(1500);
countdown();
System.out.println("Your turn, " + playerOne.name+".");
if (p1Swordgo == 1) {
if (p2Archgo == 1 || p2Alchgo == 1) {
if (playerOne.move == 1){
System.out.println("What do you want to do?" +'\n' +"1 = Move into range of " +playerTwo.name +'\n' +"2 = Heal" +'\n' +"3 = Forfeit");
int P1Choice = userInput.nextInt();
if (P1Choice == 1) {
playerOne.move --;
System.out.println(playerOne.move);
}
}
}
}
}
public static void delay ( int time){
try {
Thread.sleep(time);
} catch (InterruptedException ex) {
Thread.currentThread().interrupt();
}
}
public static void countdown() {
delay(500);
System.out.println("Get ready to fight in 5,");
delay(1000);
System.out.println("4");
delay(1000);
System.out.println("3");
delay(1000);
System.out.println("2");
delay(1000);
System.out.println("1");
delay(1000);
System.out.println("Fight!");
delay(750);
}
}
And then in a class called Character
public class Character {
public int strength;
public double health;
public int move;
public String name;
public Character(double health, int strength, int move) {
this.health = health;
this.strength = strength;
this.name = name;
this.move = move;
}
}
And in a class called SwordFighter
public class SwordFighter extends Character {
public SwordFighter() {
super(60,15, 1);
}
}
And in a class called Archer
public class Archer extends Character{
public Archer() {
super(45,20, 0);
}
}
And finally, in a class called Alchemist
public class Alchemist extends Character {
public Alchemist() {
super(50,15, 0);
}
}
Thank you for your patience, by the way
Once the two players have chosen their name and you have set it using playerOne.name = userInput.nextLine();, you assign a different object, with a null name, to playerOne:
playerOne = new SwordFighter();
So, after this line has been executed, playerOne.name is null.
I've made 4 classes (Mage,Rouge,Warrior&fool) that extend a class 'Character'. Each of these have their own specific battle methods inside their respective classes. However since only one of these objects are being constructed inside an if/else statement java doesn't recognize them as existing. The problem is I need to call the class specific method outside of the if/else statement. I tried initializing the 4 objects as null first then constructing/overwriting them but when I call the method it still refers to them as null. Formatting is a little screwed up but here:
EDIT: Thanks for the feedback!
public class Rpg {
public static Warrior wplayer = null;
public static Rouge rplayer = null;
public static Mage mplayer = null;
public static Fool fplayer = null;
public static void main(String[] args){
a2 = scan.nextInt();
if (a2 == 1){
Warrior wplayer = new Warrior();
} else if (a2 == 2) {
Rouge rplayer = new Rouge();
} else if (a2 == 3) {
Mage mplayer = new Mage();
} else {
Fool fplayer = new Fool();
while (!notdone){
System.out.println("1: Arena");
System.out.println("2: Blacksmith");
System.out.println("3: Shop");
System.out.println("4: Leave town");
System.out.println("5: Save and Quit");
int choice = scan.nextInt();
if (choice == 1 && wplayer != null){
wplayer.fightEnemy();
} else if (choice == 1 && rplayer != null){
rplayer.fightEnemy();
} else if (choice == 1 && mplayer != null){
mplayer.fightEnemy();
} else {
fplayer.fightEnemy();
}
}
}
}
}
The scope of those variables is limited to inside the if/else blocks. If you want to access it outside, you should do the following:
Character player = null;
if (a2==1){
player = new Warrior();
} else if (a2==2){
player = new Rouge();
} else if (a2==3){
player = new Mage();
} else{
player = new Fool();
}
// by now, player was instantiated by some concrete class and you can use it
If each Character implements their own fightEnemy() method, then you can leverage polymorphism here to automatically choose the correct concrete method:
...
if (choice==1){
// java will figure out which "Character" this really is
// then it will call the fightEnemy method for that specific "Character" type
player.fightEnemy();
}
...
Change
if (a2==1){
Warrior wplayer = new Warrior();
}
to
if (a2==1){
wplayer = new Warrior();
}
You have several mistakes in this code.
Non-static variable visibility is limited to {}. So you can see, that whe you write if(a2 == 1) { Warrior wplayer = new Warrior(); } then wplayer variable is visible only within {} and cannot be accessed after if...else. To fix it, you should define Warrior wplayer outside if...else and initialize inside if...else:
Warrior wplayer = null;
if(a2 == 1) {
Warrior wplayer = new Warrior();
}
// wplayer is visible here
Additionnaly, you should look at structure of your code. You have several types of Player. All players have specific fightEnemy() implementation and to choose correct instance you use if...else. Imagine, if later you add some more type of Player, then you have to modify all these if...else. This is not good. Let me give you example how it could be done.
Example
interface Player {
void fightEnemy();
}
class Warrior implements Player {
public void fightEnemy() { }
}
class Rouge implements Player {
public void fightEnemy() { }
}
class Mage implements Player {
public void fightEnemy() { }
}
class Fool implements Player {
public void fightEnemy() { }
}
Scanner scan = new Scanner(System.in);
int a2 = scan.nextInt();
Player player;
if (a2 == 1) {
player = new Warrior();
} else if (a2 == 2) {
player = new Rouge();
{ else if (a2 == 3) {
player = new Mage();
} else {
player = new Fool();
}
System.out.println("1: Arena");
System.out.println("2: Blacksmith");
System.out.println("3: Shop");
System.out.println("4: Leave town");
System.out.println("5: Save and Quit");
int choice = scan.nextInt();
if (choice == 1) {
player.fightEnemy();
}
So I want to create a menu where a user can choose to play two different games. I want to create a main method and be able to make a for loop or switch statements for the different game options or for the user to quit but I am not sure how I would call the classes so that the game runs when they choose it.
Can someone explain to me how I would go about this. Thanks!
import java.util.Scanner;
import java.util.Random;
public class RpsGame {
/* Valid user input: rock, paper, scissors */
public static void main(String[] args) {
System.out.print("Please Make Your Choice (Rock, Paper or Scissors): ");
try {
Scanner sc =
new Scanner(System.in);
String userInput =
sc.next();
if (isValid( userInput )) {
game( userInput );
} else {
print("Invalid user input!\nWrite rock, paper or scissors!");
}
} catch (Exception e) {
e.printStackTrace();
}
}
public static void print(String text) {
System.out.println( text );
}
public static boolean isValid(String input) {
if (input.equalsIgnoreCase("rock")) {
return true;
}
if (input.equalsIgnoreCase("paper")) {
return true;
}
if (input.equalsIgnoreCase("scissors")) {
return true;
}
return false;
}
public static void game(String user) {
String computer = computerResults();
//System.out.print("Please Make Your Choice: ");
print( user + " vs " + computer + "\n");
if (user.equalsIgnoreCase(computer)) {
print("Oh, Snap! Tied - No winners.");
} else {
if (checkWin(user, computer)) {
print("You won against the computer!");
} else {
print("You lost against the computer!");
}
}
}
public static String computerResults() {
String types[] =
{"rock", "paper", "scissors"};
Random rand = new Random();
int computerChoice = rand.nextInt(3);;
return types[computerChoice];
}
public static boolean checkWin(String user, String opponent) {
if ( (!isValid( user )) && (!isValid( opponent )) ) {
return false;
}
String rock = "rock", paper = "paper", scissors = "scissors";
if ( (user.equalsIgnoreCase( rock )) && (opponent.equalsIgnoreCase( scissors )) ) {
return true;
}
if ( (user.equalsIgnoreCase( scissors)) && (opponent.equalsIgnoreCase( paper )) ) {
return true;
}
if ( (user.equalsIgnoreCase( paper )) && (opponent.equalsIgnoreCase( rock )) ) {
return true;
}
return false;
//If no possible win, assume loss.
}
}
The easiest method that I am familiar with is using something called a Driver Class. A Driver Class is a class that is designed to run code from other classes - perfect for running two different games. Check this post if you need more info: What is a driver class? (Java)
Try something like this:
public class MyGameApp {
public static final String OPTION_1 = "1";
public static final String OPTION_2 = "2";
public static final String OPTION_EXIT = "3";
public static void main(String... args) {
Scanner sc = new Scanner(System.in);
String userChoice = null;
do {
System.out.println("Choose an option: \n 1. Game 1\n2. Game 2\n3. Exit");
userChoice = sc.nextLine();
switch(userChoice) {
case OPTION_1:
/*
Calls a static method of a class, so there is no need of instantiate the class first.
*/
GameOne.start();
break;
case OPTION_2:
/*
In this case, create a new instance of the class GameTwo, and then call the method start().
*/
GameTwo game = new GameTwo();
game.start();
break;
default:
System.out.println("Wrong option, try again.");
}
while(!OPTION_EXIT.equals(userChoice));
}
}
class GameOne {
public static void start() { ... }
}
class GameTwo {
public void start() { ... }
}
I am working on a game of tic-tac-toe for class and in one class I create a Board object which contains a String array and then pass it to a player class. However I cannot figure out how to allow me to use this information in the new class. Can anybody here give me some pointers?
public static void main(String[] args)
{
//new tic-tac-toe board
Board board = new Board();
//two new players (computer and human)
Player computer = new Player(board, "X"); //Give computer player access to board and assign as X.
Player human = new Player(board, "O"); //Give human player access to board and assign as O.
and the class I'm trying to use it in
package outlab5;
import java.util.Scanner;
public class Player {
private String[][] currentBoard;
private String move;
Scanner input = new Scanner(System.in);
public Player(Board inBoard, String inMove){
move = inMove;
}
public void computerMove(){
boolean valid = false;
while(!valid){
int moveCols = (int)(Math.random()*4);
int moveRows = (int)(Math.random()*4);
System.out.print(currentBoard[0][0]);
}
}
I think your Board class has a field representing the String[][] array, which you are looking for.
In your player class, store the borad object properly.
public class Player {
private String[][] currentBoard;
private String move;
private Board board; //define a variable
Scanner input = new Scanner(System.in);
public Player(Board inBoard, String inMove){
board = inBoard;
move = inMove;
}
You dont show the code of Board class, so i have to guess how you may access the string[][],probably the Board class provides some get-Methods, to get access to the string array.
String[][] currentBoard = board.get....(); //this call must be placed in a method
Here is an example, of how you can do your application.
Board Class
public class Board {
// TODO : Stuff and Stuff ( Where your 3x3 Matrix may be )
}
Player Abstract Class
abstract class Player {
private final Board board;
private final String move;
public Player(Board _board, String _move) {
this.board = _board;
this.move = _move;
}
public void playerMove() {
// TODO : Default Movement Actions
}
public void playerWin() {
// TODO : Default Event on Player Win
}
}
Computer Class
public class Computer extends Player {
public Computer(Board _board, String _move) {
super(_board, _move);
}
#Override
public void playerMove() {
// TODO : Computer Related Movements ( Like AI )
super.playerMove();
}
#Override
public void playerWin() {
// TODO : Computer Related Events for Computer ( Like Increase Dif )
super.playerWin();
}
}
Human Class
public class Human extends Player {
public Human(Board _board, String _move) {
super(_board, _move);
}
#Override
public void playerMove() {
// TODO : Human Related Movements ( Like I/O )
super.playerMove();
}
#Override
public void playerWin() {
// TODO : Human Related Events on Win ( Like Score )
super.playerWin();
}
}