I'm working on an object-oriented program in Java that allows you to keep track of a horde of zombies. A zombie can be identified either by a unique id number or a single name, and we want to note how many limbs each zombie currently possesses. Zombies may leave the horde either by their own accord or removed by a zombie hunter.
Currently I'm trying to work on the zombie hunter class, I need it to remove objects from an array of zombies in main after it meets a certain condition, and the other classes should be done I believe:
zombieHorde.java
public class ZombieHorde{
int hordeSize = 0;
public ZombieHorde(int hordeSize){
Zombie zombies = new Zombie[hordeSize];
hordeSize++;
}
}
zombie.java
import horde;
public class Zombie {
int hordeSize = 0;
public Zombie(String name, int limbs) {
this.name = name;
this.limbs = limbs;
}
public int loseLimbs() {
limbs--;
}
public int getLimbs() {
return limbs;
}
public void leaveHorde() {
hordeSize--;
}
}
main.java
// accuracy to determine if a zombie hunter kills its mark,
// then if it does I can decrease the horde size and get rid
// of the object/kill the zombie, use random for determining
// # of limbs, and if zombies join a horde, etc.
// main class creates a horde, creates zombies and adds them
// to a horde, and the zombie hunter object
// could also have multiple Hordes, ZombieHunters!
import Zombie;
import ZombieHorde;
import ZombieHunter;
public class MyZombieGame{
public static void main(String[] args){
// creates horde
ZombieHorde h = ZombieHorde(hordeSize);
// create zombies and add them to array
Zombie myZombie = Zombie(Chuck, 4);
// create zombie hunter to remove from array?
}
}
And zombiehunter.java
import horde;
public class ZombieHunter{
public void shootAt(name){
}
}
What I'm thinking is I could have an accuracy assigned to a zombie hunter, and then compare that to a random number, and if the accuracy is higher, then the zombie hunter hits its mark and kills a zombie, then I remove a zombie object from the ZombieHorde array in main! If that makes sense, although I'm a little tripped up by them leaving on their own accords, any ideas would be awesome about an approach to this and how I should go about removing the objects from the array.
I'm brand new to Java so there might be some errors I apologize if this is the case! Just looking for a push in the right direction!
You might want to concider using some sort of map (i.e. a Hashmap) instead of an array.
public class ZombieHorde{
//note that class attributes are usually private
private int hordeSize = 0; //actually no need for hordSize here, you could just use .size();
private HashMap<String, Zombie> zombieHorde;
public ZombieHorde(){
//instanciate Hashmap
this.zombieHorde = new HashMap<String, Zombie>();
}
public void addToHorde(Zombie zombie){
//assuming there is a get name method implemented
this.zombieHorde.put(zombie.getName, zombie);
this.hordeSize++;
}
public void removeFromHorde(Zombie zombie){
//assuming there is a get name method implemented
this.zombieHorde.remove(zombie.getName);
this.hordeSize--;
}
}
On a map you can use functions like add and remoive which makes it useful for usecases like this. If you wanna know the hordeSize you can also just use zombieHodre.size()
(Not sure if my code is 100% correct but you should get the idea).
Related
I know everyone gets skeptical whenever people put homework on here but I've run out of options and could really use some direction. I have a project where I have to create a deck of cards and allow the user to pick the size of the hand and then fill that hand with random cards and display that to the user. I've found plenty of answers using ArrayLists but mine requires an array and I've tried everything I know and my code is either completely wrong or throws a bunch of errors.
So here are the problems I have:
1) The addCard method in the Hand class can be used to add one Card object at a time to the hand array until it is full. It should increment the cardsInHand counter each time a Card object is added to the Hand as long as there is room for the Card to fit into the Hand.
Here is the code for the Hand class:
public class Hand
{
private int handSize; //Holds the size of the hand
private int cardsInHand; //Holds the number of cards allowed in the hand
private Card[] hand; //Array of card objects
public Hand()
{
this.handSize = 5;
this.cardsInHand = 0;
this.hand = new Card[52];
}//end Default Constructor
public Hand(int handSize)
{
this.handSize = handSize;
}//end Parameterized Constructor
public Hand(Hand handIn)
{
this.handSize = handIn.handSize;
this.cardsInHand = handIn.cardsInHand;
this.hand = handIn.hand;
}//end Copy Constructor
public void addCard(Card card)
{
hand[card]; //--> throws a type mismatch exception (change card param to an int)
}//end addCard()
public int getHandSize()
{
return handSize;
}
public void setHandSize(int handSize)
{
this.handSize = handSize;
}
public int getCardsInHand()
{
return cardsInHand;
}
public void setCardsInHand(int cardsInHand)
{
this.cardsInHand = cardsInHand;
}
public Card[] getHand()
{
return hand;
}
public void setHand(Card[] hand)
{
this.hand = hand;
}
public String toString()
{
String msg = "";
return msg;
}//end toString()
}//end class
My addCard method is just all janky and I could really use some help trying to fill it so my program works. Any help or even a pointing in the right direction would be appreciated!
My addCard method is just all janky and I could really use some help trying to fill it so my program works. Any help or even a pointing in the right direction would be appreciated
Sometimes the best thing to do is stop, turn the screen off, get a pen and piece of paper and just nut it out without any code. Try to understand the problem and get the logic straight in your head.
Basically, you have a series of buckets into which you can put a Card. Before you can put a Card in a bucket, you need to know if you have any free buckets available.
If there are, you need to add the Card to the next available bucket (which should be pointed to by cardsInHand) and increment cardsInHand
Your error is because you're trying reference a "bucket" using a Card, but you can only reference a "bucket" by an index (number) so...
hand[card];
should be more like...
hand[cardsInHand] = card;
but only after you've determined if there is a free "bucket" available, and you should increment cardsInHand AFTER this statement
I'd also be worried about your constructors
public Hand(int handSize)
{
this.handSize = handSize;
}//end Parameterized Constructor
isn't initialising hand, so that's going to be null. A better solution might be to use existing constructors where possible to build a common "initialisation" path
public Hand() {
this(5);
}//end Default Constructor
public Hand(int handSize) {
this.handSize = handSize;
this.cardsInHand = cardsInHand;
this.hand = new Card[handSize];
}//end Parameterized Constructor
Also
public Hand(Hand handIn)
{
this.handSize = handIn.handSize;
this.cardsInHand = handIn.cardsInHand;
this.hand = handIn.hand;
}//end Copy Constructor
is worrying, as it's possible for some external class to make a change to handIn's hand and that change will be reflected by this instance as well (as they are pointing to the same array).
A "copy" constructor should be making a "copy" of the data. Realistically, this should probably be a "deep" copy, so any changes to Card don't mess with the Hand as well, but I'll start with a simple "shallow" copy to get you started
public Hand(Hand handIn) {
this.handSize = handIn.handSize;
this.cardsInHand = 0;
this.hand = new Card[this.handSize];
// Yes, I know there is a better way to do this, but
// I want the OP to learn something
for (int index = 0; index < handIn.hand.length; index++) {
Card card = handIn.hand[index];
if (card != null) {
hand[cardsInHand] = card;
cardsInHand++;
}
}
}//end Copy Constructor
#MadProgrammer already give better answer, I only want to chime a little. Knowing the OP project assignment using Java I want to comment a little about the Hand class design.
The task clearly said that user can pick hand with custom size, then the user will add card into the hand until the hand is full. Thus, I would propose the Hand class design like below.
public class Hand {
private int size; // Hold the amount of card can be hold by hand.
private int counter; // Count how many card added.
private Card[] cards; // The card on hand.
public Hand(int size) {
this.counter = 0;
this.size = size;
this.cards = new Card[size];
}
public void addCard(Card card) {
if (this.counter > this.size) {
throw new IllegalStateArgument("The hand is full of card!");
}
this.cards[this.counter] = card;
this.counter++;
}
public String show() {
StringBuilder result = new StringBuilder("The card on hand is: \n");
for (int i=0; i<this.size; i++) {
result.append(this.cards[i].toString()).append("\n");
}
return result.toString();
}
}
In my opinion the Hand class more easy to understand and achieve the goals of the Hand purpose from the task. However, just use this as reference and write code that you understand well.
public class Boss{
public void Attack1(){
int randomspace = (int )(Math.random() * 3 + 1);
System.out.println("Attacking space " + randomspace);
if(space == randomspace){
//Something right here to kill the player
}
}
}
But space is in a different class called Player
public class Player {
int space = 1;
}
I thought about making a separate space variable and change them at the same time, but how would the Boss class know when to increment/decrement at the same time as the Player class. it would be easier to just keep it in the one class for simplicity.
EDIT: I figured it out. public class Boss extends Player{ and that fixed my problem
Use parameters. (and lowercase your methods)
A boss will attack a space.
public void attack(int space){
if(space == randomspace){
//Something right here to kill the player
}
If you need the Player, then you should really be using some abstract class, say Unit, then use Hero to be the main piece.
Then you can have
public void attack(Unit unit){
if(unit.getSpace() == randomspace){
//Something right here to kill the player
}
And ideally unit.getSpace() could also come from some Board class that holds all information about the Unit types
Then, your logic elsewhere says boss.attack(player) or boss.attack(player.getSpace())
So I've been stuck on this issue for quite some time now and I just can't seem to figure out the solution. I'm currently working on a project that simulates a parking garage. The parking garage itself isn't the issue; it's the several types of customers that are supposed to be simulated. To make things a little easier I'll ask for the solution of one and with that I should be able to work out the others myself.
For starters it is a requirement to create a separate class for customers with a parking pass and integrate this in a way that shows which cars are parking pass holders and which aren't.
import java.util.Random;
/* creates a boolean called isPass that is randomly picked to be true or false. */
public interface ParkPass {
public Random rnd = new Random();
public boolean isPass = rnd.nextBoolean();
}
This is the class that allows me to randomly set a parking pass. Since the simulation happens through a different class, all I can do is create the method to set the Pass to true or false; I can't set the Pass itself in this class.
public abstract class Car {
private Location location;
private int minutesLeft;
public boolean isPaying;
public boolean isBlue;
public void setIsPaying(boolean isPaying) {
this.isPaying = isPaying;
}
// added a method to allow us to set the colour of the car to blue for when they have a parking pass.
public void setIsBlue(boolean isBlue) {
this.isBlue = isBlue;
}
This is a small snippet of the Car class that shows which booleans belong to it and might show you which direction I'm trying to go with this simulation.
public class AdHocCar extends Car implements ParkPass{
public AdHocCar() {
setIsBlue(isPass);
setIsPaying(!isPass);
}
}
This is the class that is called when simulating a car going in and out of the parking garage. Here you can see I tried implementing the ParkPass class in order to set the Isblue and IsPaying booleans in the Car class so that I can call upon these in the next bit of code which is the simulation view that I'm currently stuck on trying to fix.
import javax.swing.*;
import java.awt.*;
public class SimulatorView extends JFrame {
private CarParkView carParkView;
private int numberOfFloors;
private int numberOfRows;
private int numberOfPlaces;
private Car[][][] cars;
public void updateView() {
/* Create a new car park image if the size has changed.
added 2 colours to show the difference between the three different customer types.*/
if (!size.equals(getSize())) {
size = getSize();
carParkImage = createImage(size.width, size.height);
}
Graphics graphics = carParkImage.getGraphics();
for(int floor = 0; floor < getNumberOfFloors(); floor++) {
for(int row = 0; row < getNumberOfRows(); row++) {
for(int place = 0; place < getNumberOfPlaces(); place++) {
Location location = new Location(floor, row, place);
Car car = getCarAt(location);
Color color = car == null ? Color.white : Car.isBlue ? Color.blue /*: isReservation == true ? Color.green*/ :Color.red ;
drawPlace(graphics, location, color);
}
}
}
repaint();
}
And here we finally get to the problem I have been facing. If you look at it right now you'll probably notice quite a few things wrong. This is because after 10 hours of research and constant changing of the Color attribute I kind of lost track of the exact way I was trying to implement the booleans that were created earlier in order to show the difference between the two types of customer. I'm not extremely experienced with programming so after awhile I just gave in and decided to ask here.
Now for the question, with all these separate classes creating their own booleans how can I make sure that when I use the simulation the cars using a Parking Pass will be blue while the cars that have to pay normally are shown as red?
public interface ParkPass {
public Random rnd = new Random();
public boolean isPass = rnd.nextBoolean();
}
Problem is in the above part. You can not define instance variables in interfaces. These members becoming static final as default.
Move this members to Car class and it will work.
I should to implmenets an application to control a race of car.
So in a race I have for example 5 car. I want to know the position of this car in every turn, the last time, and best round for all car. Now I wanto to know what structure of data is the best solution for this.
I have create this object:
package Auto;
import java.security.Timestamp;
public class Macchina {
Integer corsia;
Integer giro;
Timestamp ultimoTempo;
Timestamp migliorTempo;
public void setCorsia(Integer corsia) {
this.corsia = corsia;
}
public void setGiro(Integer giro) {
this.giro = giro;
}
public Timestamp getUltimoTempo() {
return ultimoTempo;
}
public void setUltimoTempo(Timestamp ultimoTempo) {
this.ultimoTempo = ultimoTempo;
}
public Timestamp getMigliorTempo() {
return migliorTempo;
}
public void setMigliorTempo(Timestamp migliorTempo) {
this.migliorTempo = migliorTempo;
}
public Macchina(int c, int g)
{
this.corsia=c;
this.giro=g;
}
public int getCorsia(){
return corsia;
}
public int getGiro(){
return giro;
}
}
This class is used to stored the information for the car in the race.
Keep in mind that A car has a speed.
The track has the distance and cars on it.
Your object design should reflect that.
Depending on how many properties a car has, you might not need a car object.
If you plan on extending your car racing program, you might want an abstract vehicle class. Especially if tracks become complicated, and cars become highly varied.
If you just want to find something like the position of a car at a discrete time and when a car reaches a certain distance then following might work for your purposes.
Pseudo code:
track {
int length, time, Maxtime;
array<int> carSpeeds, carPositions;
main(){
Maxtime=100;
for(time=1; time<MaxTime; time++){
for(int j= 0; j < carSpeeds.size(); j++){
carPositions[j] = time*careSpeed // reset for each lap.
// if position is greater than track length, you might have a winner or a tie.
}
}
}
}
You can add in a max distance and other things.
If you want to eventually model warp capable space ship racing to various waypoints, submarine racing between underwater cities, and dirtbike racing with shortcuts, the code should have high cohesion, and low coupling. But the first of many iterations would probably look similar to the above.
Im creating a simple bowling game using OOP, and i want to have a class for each bowl, a Frame class consisting of two bowls, and a Game class consisting of ten frames.
At the moment i have something like this
Bowl.java
public class Bowl {
int bowlScore = 0;
public Bowl(int pinsKnocked){
bowlScore = pinsKnocked;
}
}
Frame.java
public class Frame{
int firstScore;
int secondScore;
public Bowl firstBowl;
public Bowl secondBowl;
public Frame (){
firstBowl = new Bowl(0);
secondBowl = new Bowl(0);
}
public Frame (int firstScore, int secondScore){
firstBowl = new Bowl(firstScore);
secondBowl = new Bowl(secondScore);
}
Game.java
public class Game {
int totalScore;
public Frame firstFrame;
public Frame secondFrame;
...
public Frame tenthFrame;
public Game(){
firstFrame = new Frame();
}
public Game(Frame f){
firstFrame = f;
}
Is this the correct way of using OOP features or how would I be able to improve this?
There is not a 100% correct way for designing a Bowling game; there are many solutions which will work, and even more that won't work.
What you need is a solution that will work well for your, and your goals.
If you want to display a score, then I suggest you start with a getScore() method. If you want to display the Winners, start with a displayWinners() method.
Eventually you will find that these methods naturally bind to various nouns. For example, you might start off with getScore() being attached to a Game object, but then realize that this unnaturally means your game can only have one score. If this occurs, you would then move the getScore() to a Player object, and have the game maintain one or more players.
If you are working with a method that naturally belongs somewhere else, there are a number of hints in your code that will guide you. The most obvious hint is that a method seems to be particularly interested in another object's data, even over it's own data. In the above example, a getScore() in a game object is overly interested in a Player's frames, balls, etc.
To gain skills and direction in how to safely move code from one place to another, I recommend reading Martin Fowler's Refactoring Book.
An excellent example, using exactly your problem is demonstrated here.
Good luck, and after a while you will be able to skip some of this process due to acquired skill; however, when learning for the first time, it is a good idea to not skip such exploratory steps (start at the beginning).
PS. Remember that your code will only be certain to do what you test it to do, if you are not familiar with test driven development, it might be a good idea to look into it (hint, this is a massive understatement).
As Edwin has mentioned they are lot of ways to model Bowling game. However here I'll list possible corrections to your code to improve it.
There are lot of things to improve here
1. score attribute is applicable only to Bowl class. so remove score attributes from Frame and Game.
2. bowlScore in Bowl should be private and provide getter method for it. You will
3. now Frame class should be like:
public class Frame{
private Bowl firstBowl;
private Bowl secondBowl;
public Frame (int firstScore, int secondScore){
firstBowl = new Bowl(firstScore);
secondBowl = new Bowl(secondScore);
}
public int getFrameScore(){
return (firstBowl.getScore()+secondBowl.getScore());
}
}
4.In Game class, you have constructor where you are passing only one frame? One game by one player consist of 10 frames. Also its not good idea to use 10 variables for frames. We hav java collections for this purpose. You can use list.
public class Game {
private java.uti.List<Frame> frames;
public Game(List<Frame> frames){
this.frames = frames;
}
public getGameScore(){
// loop goes here to sum up scores from all frames
//sum = sum+frames.get(i);
}
}
}
5.Also this modeling is valid if you are assuming that this game will be played by only one player. For multiple players, above Game class actually becomes Player class and you will have to create new Game class.
I'd be inclined to drop the multiple instances of Bowl. If you find yourself in this situation, ask yourself - how would I deal with 100 instances of Bowl? Consider the ten instances of Frame that you would have to create and maintain during the lifespan of the game. Keeping multiple instances is not a good idea unless you need multiple instances for some business logic.
public class Bowl {
private int bowlScore;
// Use a no-argument constructor
public Bowl() {
this.bowlScore = 0;
}
public void setBowlScore( int score ) {
this.bowlScore = score;
}
public int getBowlScore() {
return this.bowlScore;
}
}
For the Frame class,
public class Frame {
private int frameScore;
private Bowl bowlArray[];
public Frame() {
this.frameScore = 0;
this.bowlArray = new Bowl[2];
}
public void setScoreForFirstBowl( int score ) {
this.bowlArray[0] = score;
this.frameScore += score;
}
public void setScoreForSecondBowl( int score ) {
this.bowlArray[1] = score;
this.frameScore += score;
}
public void setFrameScore( int score ) {
this.frameScore = score;
}
public int getFrameScore() {
return this.frameScore;
}
// this should not be used, left in for completeness
public Bowl[] getBowlArray() {
return this.bowlArray;
}
}
And for Game
public class Game {
private int gameScore;
private ArrayList<Frame> gameFrames;
public Game() {
this.gameScore = 0;
this.gameFrames = new ArrayList<Frame>();
}
/* There are many ways of implementing the game logic. Here is an example.
You will have to complete the rest :) */
// #frame frame object with bowl data that is appended to list
public void frameCompleted(Frame frame) {
this.gameScore += frame.getFrameScore; // I assume this is what you want to do. Change if not
this.gameFrames.add(frame);
}
/* The method written above can also be implemented by passing integer values
for the score, bowl number and frame number. However, this would not be very
OOP friendly. Essentially, this is 'Encapsulation' of the Frame data into the
Frame object. */
// Add getters and setters for gameScore and gameFrames
}
See the ArrayList documentation for examples on further use. You can replace it with an array if you don't want to use it. I included it simply to showcase the list ability.
Read more on Encapsulation here and here.
You will notice I have not taken 'strikes' into account in the Bowl or Frame classes. This is because it is a special case that needs to catered for and so I have left it for you to implement. My understanding is if you roll a strike on the first bowl you don't get a second bowl.