I'm creating a Monopoly program in Java and I run into a problem: When a player lands on a Property always get's to buy it, even if it's already owned.
Here are the two pieces of code that come in question:
Property class:
class Property{
public int ownerID = -1;
public Player owner;
public boolean isOwned;
public int price, rent; // defined in Constructor
public void onLanded(Player p){
if(OwnerID < 0){
p.offerProperty(this);
} else if(ownerID != p.getID(){
p.transfer(-rent);
owner.transfer(rent);
System.ou.println("bla bla");
} else {
System.out.println("bla bla");
}
}
public void buy(Player p){
p.transfer(-price);
setOwner(p);
p.assets.add(this);
}
public void setOwner(Player p){
owner = p;
ownerID = p.getID();
isOwner = true;
}
}
class Player:
class Player{
int id, money; // defined in Constructor
ArrayList<Property> assets = new ArrayList<Property>();
public void offerProperty(Property p){
if(money >= p.getPrice()){
System.out.println("wanna bu?");
String inputAnswer = scanner.next();
if(agreed(inpuAnswer))
p.buy(this);
}
}
public boolean agreed(String s){
if(s.equals("yes") return true;
return false;
}
public int getID(){
return id;
}
public void transfer(int amount){
money += amount;
}
}
Now, as I said, every time I run the game I get that if a player lands on a already owned property, he get the possibility to buy it instead of having to pay the rent to the owner. I have been looking for solutions for days and I also tried some other approach to the problem but always unsuccessful. Does anybody have an idea how to solve this issue?
In class Property, change this method:
public void buy(Player p) {
if (owner == null) {
p.transfer(-price);
setOwner(p);
p.assets.add(this);
}
}
I found my bug, and it wasn't actually in the piece of code I wrote in the question. :)
The bug was that every time a player moves, he creates a new board and moves on it, so the property is always not owned.
Related
I have three classes in my program. Ship.java, Cabin.java and Passenger.java. According to the program a single cabin can hold upto a maximum of 3 passengers. I'm trying to set passenger details but i keep getting this error
Cannot invoke "classes.Passenger.setFirstName(String)" because
"classes.Main.myShip[0].passenger[0]" is null at
classes.Main.main(Main.java:22)
Ship.java
public class Ship
{
public static Scanner scanner = new Scanner(System.in);
public static Cabin[] myShip = new Cabin[12];
public static void main(String[] args)
{
for (int count = 0; count < 12; count++)
{
myShip[count] = new Cabin();
}
myShip[0].passenger[0].setFirstName("a");
}
}
Cabin.java
public class Cabin
{
int cabinNumber;
Passenger[] passenger = new Passenger[3];
public Cabin()
{
}
public Cabin(int cabinNumber, Passenger[] passenger)
{
this.cabinNumber = cabinNumber;
this.passenger = passenger;
}
public void setCabinNumber(int cNumber)
{
cabinNumber = cNumber;
}
public int getCabinNumber()
{
return cabinNumber;
}
}
Passenger.java
public class Passenger
{
String firstName;
String lastName;
int expenses;
public Passenger()
{
}
//Constructors
public Passenger(String cabinFirstName, String cabinLastName, int pExpenses)
{
firstName = cabinFirstName;
lastName = cabinLastName;
expenses = pExpenses;
}
public void setFirstName(String cabinFirstName)
{
firstName = cabinFirstName;
}
public String getFirstName()
{
return firstName;
}
public void setLastName(String cabinLastName)
{
lastName = cabinLastName;
}
public String getLastName()
{
return lastName;
}
public void setExpenses(int pExpenses)
{
expenses = pExpenses;
}
public int getExpenses()
{
return expenses;
}
}
Please be kind enough to help me out.
Your model is wrong. A ship can (and does) have cabins with no occupants. You have provided no way to have unoccupied cabins. Your cabins need to be fully booked before the ship can be built!
I would consider redefining your Cabin class to be constructed empty -- which means it would have a constructor with a signature like Cabin(), and then provide a way to assign Passengers to Cabins. Maybe this would be a method in the Cabin class, like
boolean assignPassenger(Passenger p) {
... check occupancy...
... return false if full up ...
... otherwise add 'p' to the passenger array ...
... and return true ...
}
You're halfway there in that you're attempting to set the Cabins in the Ship by using a Cabin() constructor -- which is essentially an empty Cabin -- but you have not actually implemented a constructor with that signature.
What I'm getting at here is that, rather than just tweaking some Java, I think you should rethink it a bit. You'd want, I think, to be able to have unoccupied cabins and to be able to determine which cabins are occupied.
I'm making a program, in school, that plays monopoly and I set up all the own-able properties as objects in the property class and I want to be able to search for the properties by their position value. so if the player's position is 3 (which is Baltic Ave. in my code) I want to be able to search all own-able properties for one with a position of 3 then have the player buy/pay rent for the property. Is this possible or should I go at the problem from a different angle?
public class property
{
String owner;
int position;
int price;
int rent;
public property(int startPrice, int startPosition, int startRent)
{
price = startPrice;
position = startPosition;
owner = "none";
rent = startRent;
}
public void setOwn(String newOwn)
{
owner = newOwn;
}
public void changePrice(int newprice)
{
price = newprice;
}
public void changeRent(int newRent)
{
rent = newRent;
}
public int getprice()
{
return price;
}
public int getpos()
{
return position;
}
public String getown()
{
return owner;
}
public int getrent()
{
return rent;
}
}
To start, I'd have some sort of data structure to keep track of properties that can be bought. A HashSet is best since order doesn't matter and you can add and remove elements quickly. Set it up so that it contains properties that can be bought. Then I'd make this method: (don't put it in your Property class)
private static Property getPropertyAtPos(Player player, HashSet buyableProperties) {
for(Property p : buyableProperties) {
if(p.position == player.position) {
return p;
}
}
return null;
}
Call this method to get the property that can be bought by that player. Hope this helps.
I am currently programming a simple Android app that asks the user a series of questions and then tells them how many they got correct. I have one class that has a global variable (called "score") that is private and I have getter and setter methods for it. When the user gets the answer correct, the score is incremented (locally) and updates from 0 to 1 in that class. However, when I try to use the getScore() method I have created, to access the value of score in another class, it says scores value is 0, and not 1.
E.g.
public ClassA {
private int score = 0;
public void setScore(int s) {
this.score = s;
}
public int getScore() {
return score;
}
}
public ClassB {
private ClassA eg = new ClassA();
private int score = eg.getScore();
}
I've been stuck on this for a while and really don't know why this isn't working.
Help is much appreciated.
Thanks.
Set the Score, before getting the Score.
public ClassB {
private ClassA eg = new ClassA();
eg.setScore(5);
private int score = eg.getScore();
System.out.println(score);
}
Hope this helps.
Make sure to actually increment the score in ClassB. Also make score a static variable.
Edit your code like this :
public ClassA {
private static int score = 0;
public void setScore(int s) {
this.score = s;
}
public int getScore() {
return score;
}
}
public ClassB {
private ClassA eg = new ClassA();
int score = 0;
if(answerCorrect())
{
score++;
eg.setScore(score);
}
private int realScore = eg.getScore();
System.out.print("Final Score : "+realScore);
}
And, create a method answerCorrect() to check whether answer is correct or not, this method will return boolean.
I really don't understand the principle of Object Oriented Design??
So I have classes
Map class holds rooms and connects all of rooms , places all of hazards randomly into rooms, return the particulate room, and return the random rooms.
and
Player class that play turns, move player from room to another, shoot into rooms and play games.
also
Room class as follow.
import java.util.ArrayList;
public class Room
{
private int myRoomID;
private ArrayList<Room> myNeighbours;
private boolean myHasBats;
private boolean myHasPit;
private boolean myHasWumpus;
public Room(int id) {
myRoomID = id;
myNeighbours = new ArrayList<Room>();
}
public int getRoomID() {
return myRoomID;
}
public ArrayList<Room> getNeighbours() {
return myNeighbours;
}
public void connectTo(Room room) {
myNeighbours.add(room);
}
public boolean hasBats() {
return myHasBats;
}
public void setHasBats(boolean flag) {
myHasBats = flag;
}
public boolean hasPit() {
return myHasPit;
}
public void setHasPit(boolean flag) {
myHasPit = flag;
}
public boolean hasWumpus() {
return myHasWumpus;
}
public void setHasWumpus(boolean flag) {
myHasWumpus = flag;
}
public void checkBats() {
boolean bats = false;
for (Room r : myNeighbours) {
if (r.hasBats()) {
bats = true;
}
}
if (bats) {
System.out.println("I hear squeaking!");
}
}
public void checkPit() {
boolean pit = false;
for (Room r : myNeighbours) {
if (r.hasPit()) {
pit = true;
}
}
if (pit) {
System.out.println("I feel a draft!");
}
}
public void checkWumpus() {
boolean wumpus = false;
for (Room r : myNeighbours) {
if (r.hasWumpus()) {
wumpus = true;
}
}
if (wumpus) {
System.out.println("I smell a wumpus!");
}
}
public boolean enter(Player player) {
System.out.println("You are in Room " + myRoomID);
System.out.print("Exits lead to rooms");
for (Room r : myNeighbours) {
System.out.print(" " + r.getRoomID());
}
System.out.println();
checkBats();
checkPit();
checkWumpus();
if (myHasBats) {
System.out.println("A flock of bats picks you up and carries you off to another room!");
return player.moveRandom();
}
else if (myHasPit) {
System.out.println("You fall into a bottomless pit!");
return true;
}
else if (myHasWumpus) {
System.out.println("You have been eaten by a wumpus!");
return true;
}
return false;
}
public boolean shoot()
if (myHasWumpus) {
System.out.println("You killed the Wumpus!");
return true;
}
else {
System.out.println("Your arrow falls with a clatter to the floor!");
return false;
}
}
And I want to change this so that the wumpus needs to be shot more than once (you choose how many times) to be killed. Each time it is shot it runs to a random neighbouring room (not the one the player is in).
I am assuming that I need to change public boolean shoot() method into loop and call public Room getRandomRoom() as below.
But I really don't understand how to do this, especially because the use of boolean method is very confusing to me.
Does anyone know where I can find a information to learn the basic's of Object Oriented Design?
public Room getRandomRoom() {
Random rng = new Random();
int i = rng.nextInt(Map.NUM_ROOMS);
return myRooms.get(i);
}
Later on we are going to use implements in the class to separate all of hazards into classes. but for not they are all in Map and Room class.
Well without a wumpus class that's going to be messy and limited and even more inefficient. Your problem isn't that you don't get OO, it's that you are being restricted from using it.
Without out the class.
You are goingto have to add a myWumpusShotCount to room
Then in your shoot function, add 1 to it, test to see if it's 3 and if so kill it else random choose a room and set hasWumpus and WumpusShotCount in it
If you had a wumpus class it would have a property room , and another for how many bullets it had shipped and a behaviour when shot, ie the state of the wumpus and the behaviours of wumpus would be implemented by wumpus, not room. That's OO.
With the help of Tony Hopkinson, I have come up with this code but it doesn't compile yet. It says can not find symbol - method getRandomRoom() To call the methodgetRandomRoom();` from Map class.
To send wumpus to the room another room randomly
public boolean shoot() {
if (myHasWumpus) {
myWumpusShotCount = 3;
for(int i = 0; i< myWumpusShotCount; i++){
if(myWumpusShotCount<=i){
System.out.println("You killed the Wumpus!");
return true;
}
else {
Room wRoom = getRandomRoom();
System.out.println("You killed the Wumpus!");
return false;
myWumpusShotCount++;
}
System.out.println("Your arrow falls with a clatter to the floor!");
return false;
}
System.out.println("You killed the Wumpus!");
return true;
}
}
System.out.println("Your arrow falls with a clatter to the floor!");
return false;
}
I am trying to test my player class properly, I have almost done it but I am having issues with my p1.setPlayerHand method. This is the following code I have used for my player class:
Player Class:
package model;
public class Player
{
private String PlayerName;
private Hand PlayerHand;
private boolean Dealer;
public Player(String name)
{
PlayerName = name;
PlayerHand = new Hand();
Dealer = false;
}
public void setName (String name)
{
this.PlayerName = name;
}
public String getName()
{
return PlayerName;
}
public void setDealer (Boolean dealer)
{
this.Dealer = dealer;
}
public boolean getDealer()
{
return Dealer;
}
public void setPlayerHand (Hand hand)
{
this.PlayerHand = hand;
}
public void getHand()
{
PlayerHand.displayCardsinHand();
}
public static void main (String [] args)
{
Player p1 = new Player("player1");
Hand h = new Hand();
//System.out.println(p1);
p1.setName("BARRY");
System.out.println(p1.getName());
p1.setDealer(false);
System.out.println(p1.getDealer());
//this is the error that is preventing my program to run
p1.setPlayerHand(h.addCard(new Card(Suit.CLUBS, CardRank.ACE)));
p1.getHand();
}
}
The following error I receive (after testing the Player Class) is this:
Exception in thread "main" java.lang.Error: Unresolved compilation problem: The method setPlayerHand(Hand) in the type Player is not applicable for the arguments (void)
at model.Player.main(Player.java:57)
This is the Hand Class underneath (that is linked to the Player Class):
Hand Class:
package model;
import java.util.Vector;
import java.util.Random;
public class Hand
{
private Vector<Card> hand;
public Hand()
{
hand = new Vector<Card>();
}
public void addCard(Card c)
{
hand.add(c);
}
public void displayCardsinHand()
{
for (int card = 0; card < hand.size(); card++)
{
System.out.println(hand.elementAt(card));
}
}
public int getCardsinHand()
{
return hand.size();
}
public Card getCard(int position)
{
if(position >= 0 && position < hand.size())
return (Card)hand.elementAt(position);
else
return null;
}
public int getScore()
{
int value = 0;
boolean ace = false;
for (int i = 0; i < hand.size(); i++)
{
Card c;
c = getCard(i);
value = value + c.getRankValue();
if(c.getRankValue() == 1)
{
ace = true;
}
}
if(ace == true && value + 10 <= 21)
{
value = value + 10;
}
return value;
}
public static void main (String [] args)
{
Hand h = new Hand();
System.out.println(h);
h.displayCardsinHand();
System.out.println(h.getCardsinHand());
h.addCard(new Card(Suit.HEARTS, CardRank.ACE));
System.out.println(h.getCardsinHand());
h.addCard(new Card(Suit.SPADES, CardRank.JACK));
System.out.println(h.getCardsinHand());
h.addCard(new Card(Suit.DIAMONDS, CardRank.QUEEN));
System.out.println(h.getCardsinHand());
h.addCard(new Card(Suit.CLUBS, CardRank.KING));
System.out.println(h.getCardsinHand());
System.out.println(h.getCardsinHand());
h.displayCardsinHand();
h.getCard(1);
System.out.println(h.getScore());
}
}
I have tried modifying the p1.setPlayerHand testing numerous times. I appreciate any advice and tips on how to solve this issue, thank you.
If my code is too long for this post then I will gladly accept any advice on what I should do to cut it short (for future reference).
If anyone here required to see any other classes that I wrote (that may help them help me solve this error) then please notify me on here, thank you.
The method addCard doesn't return anything (void). So you can't pass the result of this method to setPlayerHand(Hand). That's what you're doing.
The code should compile and run if you change
p1.setPlayerHand(h.addCard(new Card(Suit.CLUBS, CardRank.ACE)));
to
h.addCard(new Card(Suit.CLUBS, CardRank.ACE));
p1.setPlayerHand(h);
This is because the setPlayerHand method needs to be passed an object of type Hand, but the addCard method doesn't return anything (it's declared as void).