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.
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).
I'm currently working on a Bukkit plugin to claim custom areas, and I'm using rectangles (and .intersect()) to check if regions overlap before creating a claim.
I'm trying to figure a way where I don't need to check every single existing claim (of which there eventually will be tens of thousands) as surely this will take quite some time. I'll also need to check for claim owners when players do things such as break blocks or place blocks.
In my current system (which doesn't allow custom claim sizes, only squares) I only need to check at most about 10 claims because I can detect claims within the vicinity of the claim (at most 64 blocks away which is the max radius of claims in this system) but now the claim sizes can be infinitely large in theory with the new system.
Is checking all the rectangles going to take a massive amount of time? Am I being dumb, is there a way to check for rectangles within the vicinity even while the size is unlimited?
First of all checking thousands of rectangles is not gonna be a big deal for java(or your Plugin). Its simple math and should be done in millisecs. To deal with your owner Problem i would recommend you to create my own rectangle and owner class. So your rectangle can have a defined owner and you can simply check if the player is the owner of the area he is in right now.
public class custom_Area extends Rectangle{
private owner o;
public owner getOwner() {
return o;
}
public void setOwner(owner o) {
this.o = o;
}
}
EDIT:
I just tested it by creating 100.000 random rectangles and checking if one of them intersects with others.
--Custom rectangle class
public class area extends Rectangle{
private owner o;
public area(owner o, int i, int i1, int i2, int i3) {
super(i, i1, i2, i3);
this.o = o;
}
public owner getO() {
return o;
}
public void setO(owner o) {
this.o = o;
}
}
--Custom owner class
public class owner {
String name;
public owner(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
--Main class
public class Rectanglesearch {
public static area a[] = new area[100000];
public static owner o[] = new owner[10];
public static int intersectCounter = 0;
public static int ownerCounter = 0;
public static void main(String[] args) {
for(int y = 0; y<10;y++){
o[y] = new owner("y");
}
for (int i = 0; i < 100000; i++) {
a[i] = new area(o[(int)(Math.random() * 10)],random(),random(),random(),random());
}
checkArea(a[10]);
checkOwner(o[3]);
System.out.println("Area a[10] intersects with "+intersectCounter+" out of "+a.length);
System.out.println("Owner o[3] owns "+ownerCounter+" areas out of "+a.length);
}
public static int random(){
return (int)(Math.random() * 100000) + 1;
}
public static void checkArea(area ab){
for (area a1 : a) {
if (ab.intersects(a1)) {
intersectCounter +=1;
}
}
}
public static void checkOwner(owner ob){
for (area a1 : a){
if(a1.getOwner()==ob){
ownerCounter +=1;
}
}
}
}
method checkArea(area ab) returns you how man areas intersects with area ab
method checkOwner(owner ob) return you how man areas are owned my ob
Consider storing your rectangles in an acceleration structure such as a quadtree. To test a new rectangle against the existing set, you'd navigate down the tree to the node that would contain it, testing against the rectangles in each node along the way, but ignoring the rectangles in all the nodes you don't traverse. This quickly eliminates lots of rectangles that can't possibly intersect the new one, without having to test each one individually.
Other acceleration structures are also possible as alternatives, such as binary space partitioning. Read about spatial indexes for a list of several others that may be relevant.
Adding new rectangles to the set doesn't happen very often, so performance probably isn't a big concern. But I'd imagine that your plugin also needs to check whether a specific coordinate (such as a block) is within one of the claimed regions, and that may happen much more often — potentially every frame — so it really does need to be fast. A quadtree or other acceleration structure will be valuable for that.
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.
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.
I'm making a turn-based RPG game, and my method that sorts all "Actor" objects in the order in which they all attack sorts them completely randomly. I, however, want to improve this method so that an "agility" stat that every actor has is able to improve their roll. I've looked at several methods in the Collections class, and Arrays as well, but didn't seem to find anything that does what I want.
Right now, I'm thinking about getting a random int between 1 and 100, and having the agility score improve the odds. I tried separate ArrayLists for the Integers and a HashMap... but a no go on those.
My method as it is now:
// getFriendlies(), getHostiles(), and attack_order are all ArrayLists
public void calculateAttackOrder() {
attack_order.addAll(getFriendlies());
attack_order.addAll(getHostiles());
Collections.shuffle(attack_order);
}
I appreciate the help!
Your question doesn't go into much detail about the requirements about how agility influences your attack order, but I assume that you meant one of these two:
If one unit has higher agility than another, it always attacks first.
If one unit has higher agility than another, it usually attacks first.
If the first of these is true (units with higher agility always attack first), then what you're looking for is a way of permuting the array subject to the restriction that units with higher agility always end up before units of lower agility, but with everything else done randomly. One way to do this is as follows:
If you have N units, assign the numbers 1 ... N to the units at random. Don't assign the same number twice.
Sort the units into ascending order as follows:
Any unit with higher agility than another unit comes first.
Of two untis that are tied, whichever has the higher random number comes first.
You can show that this approach will arrange the units so that all units of a certain agility are randomly permuted relative to one another, but always come before lower-agility units. This takes time O(n log n) and can be done using Collections.sort, Collections.shuffle, and an appropriate Comparator.
If, on the other hand, you want the ordering to be random but influenced by the agility, you may want to think about using some sort of random distribution that can be controlled by some parameter. For example, you might assign each unit a priority drawn from a normal distribution whose mean is the agility and whose standard deviation is some reasonably large number (say, 20). This would mean that units with more agility are more likely to move before units with less agility, though there is a large amount of randomness. The advantage of this approach is that by tweaking the underlying distribution and its parameters (mean and variance in the case of a normal distribution), you can fine-tune to what extent the agility measure factors in.
As an example of a very simple approach, you might model unit speed as
priority = e(agility / 100) + random(1, 2)
Here, the more agility you have, the greater that your priority is. Increasing the amount of randomness changes the extent to which agility matters. Of course, this might be a bit skewed because each marginal increase in agility has more meaning, so you may want to replace the exponential with something like a logistic function.
Hope this helps!
Use Collections.sort() and provide a Comparator that uses a combination of a random number and agility to compute the rank.
Here's an implementation that would work. Note here that Player is the simplest possible interface that will work:
public interface HasAgility {
/** #return value between 0 and 1 */
double getAgility();
}
public class Player implements HasAgility {
double agility;
double getAgility( return agility; );
// rest of class
}
public class MoveComparator implements Comparator<HasAgility> {
/** Need to calculate the agility once, and keep using that same value, for each player */
private Map<HasAgility, Double> playerAgilities = new HashMap<HasAgility, Double>();
private Double getRandomAgility(HasAgility player) {
Double randomAgility = playerAgilities.get(player);
if (randomAgility == null) {
randomAgility = Math.random() * player.getAgility();
playerAgilities.put(player, randomAgility);
}
return randomAgility;
}
public int compare(HasAgility o1, HasAgility o2) {
return getRandomAgility(o1).compareTo(getRandomAgility(o2));
}
}
public static void main(String args[]) {
List<Player> players= new ArrayList<Player>();
Collections.sort(players, new MoveComparator());
}
The important thing to note is that once calculated, a player's random agile score must be reused again for all later comparisons. This Comparator class s designed to be used once only (the map is required to be empty at the start of its use).
If you can't touch the Actor internals, you need a way of associating a 'roll' for each actor for a complete sort (which probably includes many calls to compare), but which is forgotten by the next sort.
In that case, I would do this:
public class ActorComparable {
Actor actor;
int roll;
public ActorComparable(Actor actor) {
this.actor = actor;
roll = Math.Random(100) + actor.getAgility();
}
public getActor() {
return actor;
}
public getRoll() {
return roll;
}
public int compareTo(Actor that) {
return this.getRoll() - that.getRoll();
}
}
Now when you want to sort an ArrayList of Actors, build an ArrayList of ActorComparables, sort those, and build a resulting list out of the ActorComparables.
class Actor implements Comparable {
private int agility;
private int randomAgility;
private int getInitiative() {
//You can change this method as you see fit
return randomAgility + this.agility;
}
public void generateRandomAgility() {
this.randomAgility = (Math.random() * 100);
}
public int compareTo(Object o) {
Actor other = (Actor)other;
return this.getInitiative() - other.getInitiative();
}
}
Then you can call
for (Actor a : attack_order) {
a.generateRandomAgility();
}
Collections.sort(attack_order);
A whole example using a TreeSet (a SortedSet implementations that guarantees the elements are always ordered, using a Comparator in this case):
class Actor {
private int agility;
private double weight = Math.random();
public Actor(int agility) {
this.agility = agility;
}
public double getComputedAgility() {
return agility * weight;
}
}
public class TestRandomActors {
public static void main(String[] args) {
Collection<Actor> collection = new TreeSet<Actor>(
new Comparator<Actor>() {
#Override
public int compare(Actor a1, Actor a2) {
return
a1.getComputedAgility() > a2.getComputedAgility() ? -1 : 1;
}
}
);
collection.add(new Actor(30));
collection.add(new Actor(31));
collection.add(new Actor(60));
for (Actor actor : collection)
System.out.println("Actor with agility = " + actor.getComputedAgility());
}
}