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.
Related
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).
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 have JXButton[][] array (gridLayout) and each JXButton holds an icon, a piece,which player belongs to and has a mouseListener.
I am currently trying to make the Stratego Game(Two Players-I handle both).
I set up the icons,pieces and how a piece should move alright.
Now i wish to make it play by turn.
For example when is Player1 Turn i need all Players2' pieces to change icon to Hidden(hidden.png) and vice versa.
I have tried something like this.
tmp1, tmp2 are Icon arrays
pieceimgsB,R hold the Hidden Icon
allbuttons is my JXButton[][] array
public void makeHidden(int iD){
if(iD==1){
for (int i=0;i<8;i++){
for(int y=0;y<10;y++){
if(allbuttons[i][y].getPlayerID()==iD){
tmp1[i][y]=allbuttons[i][y].getIcon();
allbuttons[i][y].setIcon(new ImageIcon(pieceimgsB[12]));
}
}
}
}
else if(iD==2){
for (int i=0;i<8;i++){
for(int y=0;y<10;y++){
if(allbuttons[i][y].getPlayerID()==iD){
tmp2[i][y]=allbuttons[i][y].getIcon();
allbuttons[i][y].setIcon(new ImageIcon(pieceimgsR[12]));
}
}
}
}
}
public void restoreHidden(int iD){
if(iD==1){
for (int i=0;i<8;i++){
for(int y=0;y<10;y++){
if(allbuttons[i][y].getPlayerID()==iD){
allbuttons[i][y].setIcon(tmp1[i][y]);
}
}
}
}
else if(iD==2){
for (int i=0;i<8;i++){
for(int y=0;y<10;y++){
if(allbuttons[i][y].getPlayerID()==iD){
allbuttons[i][y].setIcon(tmp2[i][y]);
}
}
}
}
}
I my mind makeHidden Player2 pieces hidden when its Players1 turn.
And restoreHidden should change back the Icons when its Players2 turn.
If these two methods seem ok , where my problem lies is how to implement the turns.
I must say that (When i click on a JXButton and then click on another one, the
piece moves on the board as it should). I tried having a flag in my mouseListener that when one actually moves the turn changes, but i cant make it work by turns.
I have wrote this :
public void letsPlay(){
switch (turn){
case 1:
getsb().makeHidden(2);
//getsb().restoreHidden(1);
if(getsb().getPlayerMoved()==true){
setTurn(2);
}
break;
case 2:
getsb().makeHidden(1);
//getsb().restoreHidden(2);
if(getsb().getPlayerMoved()==true){
setTurn(1);
//;
}
break;
}
}
I need to know if these two methods seem ok according to what they should do and a little insight on how to get it to work by turns.
Should i have the getPlayerMoved() (which returns the flag in the mouseListener in a while outside the switch case)?
Maybe i am tired and i dont see it but any insight would be helpful.
If someone needs it i can provide my mouseListener Code too although its a bit messy.
This seems to be an XY problem, the main point is not to specialize your listener to manage such behavior (and other inherent behaviors) but how to design something that is modular and easily maintainable.
I'd suggest you to try to workaround your problem by thinking how you could design your game and UI structure. Let's make a simple example:
First of all you have a game piece which has a type and a player, so why don't you use a specific object type for this? Eg:
class PieceType {
String name;
String iconName;
}
class Player {
String name;
}
class Piece {
PieceType type;
Player owner;
class BoardCell {
Piece piece;
}
Then you surely need a Board class able to manage the game board, eg:
class Board {
private BoardCell [][] pieces = new Piece[10][10];
public BoardCell cellAtPiece(int x, int y) { return pieces[x][y]; }
/* other functions */
}
Finally you should have a Game class which manages the whole thing, eg:
class Game {
Board board;
Player[] players = new Player[2];
Player currentPlayer;
Player getCurrentPlayer() { return currentPlayer; }
/* other methods, eg turn advance, check for correct position, eat piece etc */
}
Now you reached a point in which you have the structure of the game, and you can think about the UI, which should rely on the Game instance without the need of additional inputs (and Game shouldn't even know about the UI). You could extend a JXButton and provide custom behavior, eg:
class BoardButton extends JXButton {
final private Game game;
final private BoardCell cell;
public BoardButton(Game game, int x, int y) {
this.game = game;
this.cell = game.cellAtPiece(x,y);
}
public void refreshIcon() {
if (cell.piece == null) { setIcon(null); }
else if (cell.piece.owner != game.getCurrentPlayer()) { setIcon(hidden); }
else setIcon(cell.piece.type.icon);
}
/* other utilities, like checking if a piece can be moved from here for current player and such */
Mind, I didn't answer directly to your question, but I explained some tools which would allow it to be solved easily together with all problems that you could find in implementation.
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.