mirror of
https://github.com/Febbweiss/rabbits-vs-hunter.git
synced 2026-03-04 14:15:39 +00:00
Feature: initial commit
This commit is contained in:
23
README.md
Normal file
23
README.md
Normal file
@@ -0,0 +1,23 @@
|
||||
# Rabbits vs Hunter
|
||||
|
||||
## Goal
|
||||
|
||||
This projects manages a rabbit hunt.
|
||||
It's possible to change some criteria such as trees, burrows and rabbits counts.
|
||||
|
||||
|
||||
## Building
|
||||
|
||||
Using maven, just execute the following command :
|
||||
```
|
||||
mvn clean package
|
||||
```
|
||||
|
||||
In the new _target_ folder, you will find the _rabbits-vs-hunter-[version]-jar-with-dependencies.jar_ jar file. This jar contains all dependencies.
|
||||
|
||||
## Running
|
||||
|
||||
Execute the built jar :
|
||||
```
|
||||
java -jar rabbits-vs-hunter-[version]-jar-with-dependencies.jar
|
||||
```
|
||||
63
pom.xml
Normal file
63
pom.xml
Normal file
@@ -0,0 +1,63 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>fr.pavnay</groupId>
|
||||
<artifactId>rabbits-vs-hunter</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
<packaging>jar</packaging>
|
||||
<dependencies>
|
||||
<!-- Tools -->
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-collections4</artifactId>
|
||||
<version>4.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>log4j</groupId>
|
||||
<artifactId>log4j</artifactId>
|
||||
<version>1.2.17</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Testing -->
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>4.12</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<properties>
|
||||
<maven.compiler.source>1.7</maven.compiler.source>
|
||||
<maven.compiler.target>1.7</maven.compiler.target>
|
||||
</properties>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<artifactId>maven-assembly-plugin</artifactId>
|
||||
<version>3.1.0</version>
|
||||
<configuration>
|
||||
<descriptorRefs>
|
||||
<descriptorRef>jar-with-dependencies</descriptorRef>
|
||||
</descriptorRefs>
|
||||
<archive>
|
||||
<manifest>
|
||||
<mainClass>fr.pavnay.rabbits.Main</mainClass>
|
||||
</manifest>
|
||||
</archive>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>make-assembly</id>
|
||||
<!-- this is used for inheritance merges -->
|
||||
<phase>package</phase>
|
||||
<!-- bind to the packaging phase -->
|
||||
<goals>
|
||||
<goal>single</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
17
src/main/java/fr/pavnay/rabbits/Main.java
Normal file
17
src/main/java/fr/pavnay/rabbits/Main.java
Normal file
@@ -0,0 +1,17 @@
|
||||
package fr.pavnay.rabbits;
|
||||
|
||||
import fr.pavnay.rabbits.ui.FormFrame;
|
||||
|
||||
/**
|
||||
*
|
||||
* The main class to run
|
||||
*
|
||||
*/
|
||||
public class Main {
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
new FormFrame();
|
||||
|
||||
}
|
||||
}
|
||||
202
src/main/java/fr/pavnay/rabbits/engine/HuntEngine.java
Normal file
202
src/main/java/fr/pavnay/rabbits/engine/HuntEngine.java
Normal file
@@ -0,0 +1,202 @@
|
||||
package fr.pavnay.rabbits.engine;
|
||||
|
||||
import java.awt.Point;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import fr.pavnay.rabbits.model.Burrow;
|
||||
import fr.pavnay.rabbits.model.Character;
|
||||
import fr.pavnay.rabbits.model.Forest;
|
||||
import fr.pavnay.rabbits.model.Hunter;
|
||||
import fr.pavnay.rabbits.model.Rabbit;
|
||||
import fr.pavnay.rabbits.model.enums.Speed;
|
||||
import fr.pavnay.rabbits.model.enums.Status;
|
||||
|
||||
/**
|
||||
*
|
||||
* This class provides the hunt mechanisms like moving, shooting, etc...
|
||||
*
|
||||
*/
|
||||
public class HuntEngine {
|
||||
|
||||
private static final Logger logger = Logger.getLogger(HuntEngine.class);
|
||||
|
||||
private Forest forest;
|
||||
private Hunter hunter;
|
||||
|
||||
private int stepCount = 0;
|
||||
private int lastShotStep = -4;
|
||||
private Status status = Status.RUNNING;
|
||||
|
||||
public HuntEngine(Forest forest, Hunter hunter) {
|
||||
this.forest = forest;
|
||||
this.hunter = hunter;
|
||||
}
|
||||
public Forest getForest() {
|
||||
return forest;
|
||||
}
|
||||
public Hunter getHunter() {
|
||||
return hunter;
|
||||
}
|
||||
public Status getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* The core engine method. To have a full hunt cycle, call this method in a loop still the HuntEngine.getStatus() returns a value different than RUNNING.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public Status step() {
|
||||
logger.debug("Step " + stepCount);
|
||||
boolean hunterHasShot = false; // Only one shot per step
|
||||
int stepSinceLastShot = stepCount - lastShotStep;
|
||||
|
||||
move(hunter);
|
||||
|
||||
Random rand = new Random();
|
||||
for (Rabbit rabbit : forest.getRabbits() ) {
|
||||
|
||||
if( stepSinceLastShot > 3 && !rabbit.isScared() ) {
|
||||
if( rabbit.getSpeed() > Speed.MEDIUM.getSpeed() ) {
|
||||
rabbit.slowDown();
|
||||
} else {
|
||||
rabbit.setSpeed(rand.nextInt(Speed.RUNNING.getSpeed()));
|
||||
}
|
||||
} else if( stepSinceLastShot > 5 && rabbit.isScared() ) {
|
||||
rabbit.setScared(false);
|
||||
}
|
||||
|
||||
move(rabbit);
|
||||
|
||||
boolean canShoot = !hunterHasShot && stepSinceLastShot > 5; // One shot per step and only 5 steps after the last shot.
|
||||
|
||||
if( canShoot && forest.canView( hunter, rabbit ) && hunter.isInRange(rabbit) ) {
|
||||
hunterHasShot = true;
|
||||
lastShotStep = stepCount;
|
||||
if( hunter.shoot(rabbit) ) {
|
||||
forest.killedRabbit(rabbit);
|
||||
} else {
|
||||
logger.info(String.format("Hunter missed a shot. %d ammos remaining", hunter.getAmmos()));
|
||||
hunter.purchase(rabbit);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// A shot occurs, so rabbits must escape
|
||||
if( hunterHasShot ) {
|
||||
logger.debug("Escape from the hunter");
|
||||
forest.escape(hunter);
|
||||
}
|
||||
|
||||
stepCount++;
|
||||
return updateStatus();
|
||||
}
|
||||
|
||||
/**
|
||||
* The rabbit must choose a destination - Random, the last one or a burrow
|
||||
*
|
||||
* @param rabbit The rabbit to move
|
||||
*/
|
||||
protected void move( Rabbit rabbit ) {
|
||||
Point location = rabbit.getLocation();
|
||||
Point destination = rabbit.getDestination();
|
||||
|
||||
if( location.distance(destination) <= rabbit.getSpeed() ) {
|
||||
List<Burrow> refuges = rabbit.getRefuges();
|
||||
if( refuges.size() > 0 ) { // Purchased rabbit
|
||||
Burrow refuge = refuges.get( refuges.size() -1 );
|
||||
if( refuge.isFree() ) { // Only one rabbit per burrow
|
||||
refuge.setFree(false);
|
||||
forest.savedRabbit( rabbit );
|
||||
} else {
|
||||
Burrow burrow = forest.getNearestBurrow(hunter, rabbit); // Find another burrow
|
||||
rabbit.setRefuge(burrow); // Keep in mind this burrow is full
|
||||
rabbit.setDestination(burrow.getLocation());
|
||||
}
|
||||
} else {
|
||||
setRandomDestination(rabbit);
|
||||
}
|
||||
}
|
||||
|
||||
if( rabbit.getDestination() != null ) {
|
||||
go(rabbit);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The hunter must choose a destination : the last one or a new randomized destination.
|
||||
*
|
||||
* @param hunter
|
||||
*/
|
||||
protected void move( Hunter hunter ) {
|
||||
Point location = hunter.getLocation();
|
||||
Point destination = hunter.getDestination();
|
||||
|
||||
if( location.distance(destination) < hunter.getSpeed() ) {
|
||||
destination = setRandomDestination(hunter);
|
||||
}
|
||||
|
||||
go(hunter);
|
||||
}
|
||||
|
||||
/**
|
||||
* Move the given character (Hunter or Rabbit)
|
||||
*
|
||||
* @param character
|
||||
*/
|
||||
protected void go(Character character) {
|
||||
Point location = character.getLocation();
|
||||
Point destination = character.getDestination();
|
||||
|
||||
double x = destination.getX() - location.getX();
|
||||
double y = destination.getY() - location.getY();
|
||||
|
||||
double rate = character.getSpeed() / location.distance(destination);
|
||||
|
||||
double newX = Math.max(0, location.getX() + x * rate);
|
||||
double newY = Math.max(0, location.getY() + y * rate);
|
||||
Point newLocation = new Point((int) Math.min(newX, forest.getEdgeArea()), (int) Math.min(newY, forest.getEdgeArea()));
|
||||
character.increaseDistance((int) location.distance(newLocation));
|
||||
location.setLocation( newLocation );
|
||||
}
|
||||
|
||||
/**
|
||||
* "Choose" a random destination for the given character (Hunter or Rabbit)
|
||||
*
|
||||
* @param character The character to move
|
||||
* @return The new destination
|
||||
*/
|
||||
protected Point setRandomDestination(Character character) {
|
||||
Random rand = new Random();
|
||||
Point destination = new Point(rand.nextInt(forest.getEdgeArea()), rand.nextInt(forest.getEdgeArea()));
|
||||
character.setDestination(destination);
|
||||
|
||||
return destination;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the hunt status
|
||||
*
|
||||
* @return The new Status
|
||||
*/
|
||||
protected Status updateStatus() {
|
||||
if( forest.getRabbits().size() == 0 ) { // No more running rabbits, so the hunt ends
|
||||
if( (forest.getRabbits().size() + forest.getSavedRabbits().size()) < forest.getDeadRabbits().size() ) { // Too many dead rabbit, the hunter wins
|
||||
status = Status.HUNTER_WINS;
|
||||
} else {
|
||||
status = Status.RABBITS_WIN; // else, rabbits win
|
||||
}
|
||||
logger.info("Hunt ended : " + status);
|
||||
} else if( hunter.getAmmos() == 0 ) { // No more ammos, rabbits win
|
||||
status = Status.RABBITS_WIN;
|
||||
logger.info("Hunt ended : " + status);
|
||||
} else { // Hunt still running
|
||||
status = Status.RUNNING;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
}
|
||||
36
src/main/java/fr/pavnay/rabbits/model/Burrow.java
Normal file
36
src/main/java/fr/pavnay/rabbits/model/Burrow.java
Normal file
@@ -0,0 +1,36 @@
|
||||
package fr.pavnay.rabbits.model;
|
||||
|
||||
import java.awt.Point;
|
||||
|
||||
/**
|
||||
*
|
||||
* A rabbit burrow - Only one rabbit per burrow.
|
||||
* Burrows are filled when a rabbit is purchased.
|
||||
*
|
||||
*/
|
||||
public class Burrow {
|
||||
|
||||
private Point location;
|
||||
private boolean free;
|
||||
|
||||
public Burrow( Point location ) {
|
||||
this.location = location;
|
||||
free = true;
|
||||
}
|
||||
|
||||
public Point getLocation() {
|
||||
return location;
|
||||
}
|
||||
public void setFree(boolean free) {
|
||||
this.free = free;
|
||||
}
|
||||
public boolean isFree() {
|
||||
return free;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Burrow [location=" + location + ", free=" + free + "]";
|
||||
}
|
||||
|
||||
}
|
||||
18
src/main/java/fr/pavnay/rabbits/model/Character.java
Normal file
18
src/main/java/fr/pavnay/rabbits/model/Character.java
Normal file
@@ -0,0 +1,18 @@
|
||||
package fr.pavnay.rabbits.model;
|
||||
|
||||
import java.awt.Point;
|
||||
|
||||
/**
|
||||
*
|
||||
* An interface to manage hunter and rabbits in the same way.
|
||||
*
|
||||
*/
|
||||
public interface Character {
|
||||
|
||||
public Point getLocation();
|
||||
public Point getDestination();
|
||||
public void setDestination(Point destination);
|
||||
|
||||
public int getSpeed();
|
||||
public void increaseDistance(int distance);
|
||||
}
|
||||
295
src/main/java/fr/pavnay/rabbits/model/Forest.java
Normal file
295
src/main/java/fr/pavnay/rabbits/model/Forest.java
Normal file
@@ -0,0 +1,295 @@
|
||||
package fr.pavnay.rabbits.model;
|
||||
|
||||
import java.awt.Point;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import fr.pavnay.rabbits.model.predicate.RangePredicate;
|
||||
|
||||
/**
|
||||
*
|
||||
* The main "entity" where rabbits live.
|
||||
*
|
||||
*/
|
||||
public class Forest {
|
||||
|
||||
private static final Logger logger = Logger.getLogger(Forest.class);
|
||||
|
||||
private List<Tree> trees = new ArrayList<Tree>();
|
||||
private List<Rabbit> rabbits = new CopyOnWriteArrayList<Rabbit>();
|
||||
private List<Rabbit> savedRabbits = new CopyOnWriteArrayList<Rabbit>();
|
||||
private List<Rabbit> deadRabbits = new CopyOnWriteArrayList<Rabbit>();
|
||||
private List<Burrow> burrows = new ArrayList<Burrow>();
|
||||
|
||||
private int edgeArea;
|
||||
|
||||
public Forest( int area, int treesCount, int burrowsCount, int rabbitsCount ) {
|
||||
if( area <= 0 || area > 10) {
|
||||
throw new IllegalArgumentException("Area must be between 1 and 10 ");
|
||||
}
|
||||
|
||||
if( treesCount <= 0 || treesCount > 1000) {
|
||||
throw new IllegalArgumentException("Tree count must be between 1 and 1000 ");
|
||||
}
|
||||
|
||||
if( rabbitsCount <= 0 ) {
|
||||
throw new IllegalArgumentException("Add some rabbits");
|
||||
}
|
||||
|
||||
if( burrowsCount <= 0 || burrowsCount < rabbitsCount) {
|
||||
throw new IllegalArgumentException("Add some burrows. Greater or equals than rabbits count.");
|
||||
}
|
||||
|
||||
|
||||
edgeArea = (int) Math.sqrt(area * 1000);
|
||||
|
||||
populate(treesCount, burrowsCount, rabbitsCount);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add trees, burrows and rabbits to the forest. These entities have random location (and rabbits random destination)
|
||||
*
|
||||
* @param treesCount Number of trees to create
|
||||
* @param burrowsCount Number of burrows to create
|
||||
* @param rabbitsCount Number of rabbits to create
|
||||
*/
|
||||
private void populate(int treesCount, int burrowsCount, int rabbitsCount) {
|
||||
Random rand = new Random();
|
||||
for( int i = 0; i < treesCount; i++ ) {
|
||||
trees.add(new Tree(new Point(rand.nextInt(edgeArea), rand.nextInt(edgeArea))));
|
||||
}
|
||||
|
||||
for( int i = 0; i < burrowsCount; i++ ) {
|
||||
burrows.add(new Burrow(new Point(rand.nextInt(edgeArea), rand.nextInt(edgeArea))));
|
||||
}
|
||||
|
||||
for( int i = 0; i < rabbitsCount; i++ ) {
|
||||
Rabbit rabbit = new Rabbit(new Point(rand.nextInt(edgeArea), rand.nextInt(edgeArea)));
|
||||
rabbit.setDestination(new Point(rand.nextInt(edgeArea), rand.nextInt(edgeArea)));
|
||||
rabbits.add(rabbit);
|
||||
}
|
||||
}
|
||||
|
||||
public int getEdgeArea() {
|
||||
return edgeArea;
|
||||
}
|
||||
|
||||
public List<Rabbit> getRabbits() {
|
||||
return rabbits;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param hunter
|
||||
* @return Rabbits in hunter range
|
||||
*/
|
||||
public List<Rabbit> getRabbitsInRange(Hunter hunter) {
|
||||
return (List<Rabbit>) CollectionUtils.select(rabbits, new RangePredicate(hunter));
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return Dead rabbits
|
||||
*/
|
||||
public List<Rabbit> getDeadRabbits() {
|
||||
return deadRabbits;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return Rabbits in burrows
|
||||
*/
|
||||
public List<Rabbit> getSavedRabbits() {
|
||||
return savedRabbits;
|
||||
}
|
||||
|
||||
/**
|
||||
* Move a rabbit from "running" to "dead"
|
||||
* @param rabbit
|
||||
*/
|
||||
public void killedRabbit(Rabbit rabbit) {
|
||||
if( rabbits.remove(rabbit) ) {
|
||||
logger.info("Poor rabbit... Killed...");
|
||||
deadRabbits.add(rabbit);
|
||||
} else {
|
||||
throw new RuntimeException("Unable to kill a poor rabbit...");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Move a rabbit from "running" to "saved"
|
||||
* @param rabbit
|
||||
*/
|
||||
public void savedRabbit(Rabbit rabbit) {
|
||||
if( rabbits.remove(rabbit) ) {
|
||||
logger.info("In a burrow... Rabbit saved");
|
||||
rabbit.setDestination(null);
|
||||
savedRabbits.add(rabbit);
|
||||
} else {
|
||||
throw new RuntimeException("Unable to save a poor rabbit...");
|
||||
}
|
||||
}
|
||||
|
||||
public List<Burrow> getBurrows() {
|
||||
return burrows;
|
||||
}
|
||||
|
||||
/**
|
||||
* Rabbits in hunter range must escape
|
||||
* @param hunter
|
||||
*/
|
||||
public void escape(Hunter hunter) {
|
||||
for( Rabbit rabbit : getRabbitsInRange(hunter) ) {
|
||||
escape(hunter, rabbit);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Choose a rabbit destination to escape. If the given rabbit is scared (the one on which the hunter shot), it must find a burrow.
|
||||
* The others must go at the opposite of hunter location.
|
||||
*
|
||||
* @param hunter
|
||||
* @param rabbit
|
||||
*/
|
||||
protected void escape( Hunter hunter, Rabbit rabbit ) {
|
||||
Point target = null;
|
||||
if( rabbit.isScared() ) {
|
||||
logger.debug("Rabbit's searching a burrow");
|
||||
Burrow refuge = getNearestBurrow(hunter, rabbit);
|
||||
rabbit.setRefuge(refuge);
|
||||
} else {
|
||||
logger.debug("Go away from the hunter");
|
||||
// Hunter -> Rabbit vector
|
||||
double a = rabbit.getLocation().getX() - hunter.getLocation().getX();
|
||||
double b = rabbit.getLocation().getY() - hunter.getLocation().getY();
|
||||
|
||||
// Keep in forest
|
||||
double x = Math.max(0, rabbit.getLocation().getX() + a);
|
||||
double y = Math.max(0, rabbit.getLocation().getY() + b);
|
||||
target = new Point((int) Math.min(x, edgeArea), (int) Math.min(y, edgeArea));
|
||||
rabbit.setDestination(target);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Compute 2 nearest burrows. One with back to the hunter and another more safe. The last one is preferred
|
||||
*
|
||||
* @param hunter
|
||||
* @param rabbit
|
||||
* @return
|
||||
*/
|
||||
public Burrow getNearestBurrow(Hunter hunter, Rabbit rabbit) {
|
||||
logger.debug("Searching the nearest burrow");
|
||||
double distance = Double.MAX_VALUE, worthDistance = Double.MAX_VALUE;
|
||||
Burrow nearest = null, worthNearest = null;
|
||||
|
||||
for( Burrow burrow : burrows ) {
|
||||
if( rabbit.getRefuges().contains(burrow) ) {
|
||||
continue;
|
||||
}
|
||||
double tmpDistance = burrow.getLocation().distance(rabbit.getLocation());
|
||||
double dotProduct = dotProduct(hunter.getLocation(), rabbit.getLocation(), burrow.getLocation());
|
||||
if( dotProduct <= 0 && tmpDistance < distance ) {
|
||||
distance = tmpDistance;
|
||||
nearest = burrow;
|
||||
}
|
||||
else if( dotProduct > 0 && tmpDistance < worthDistance ) { // Back to the hunter
|
||||
worthDistance = tmpDistance;
|
||||
worthNearest = burrow;
|
||||
}
|
||||
}
|
||||
|
||||
return distance <= worthDistance ? nearest : worthNearest;
|
||||
}
|
||||
|
||||
public List<Tree> getTrees() {
|
||||
return trees;
|
||||
}
|
||||
|
||||
/**
|
||||
* A rabbit is viewed when there are no trees between the hunter and it.
|
||||
*
|
||||
* @param hunter
|
||||
* @param rabbit
|
||||
* @return
|
||||
*/
|
||||
public boolean canView(Hunter hunter, Rabbit rabbit) {
|
||||
for( Tree tree : trees ) {
|
||||
if( isBetween(hunter.getLocation(), rabbit.getLocation(), tree.getLocation())) {
|
||||
logger.debug("Rabbit is hidden");
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private static final int EPSILON = 5;
|
||||
|
||||
/**
|
||||
* Checks if a tree is between a rabbit and the hunter.
|
||||
*
|
||||
* @param hunter
|
||||
* @param rabbit
|
||||
* @param tree
|
||||
* @return
|
||||
*/
|
||||
protected boolean isBetween(Point hunter, Point rabbit, Point tree) {
|
||||
double crossproduct = (tree.getY() - hunter.getY()) * (rabbit.getX() - hunter.getX()) - (tree.getX() - hunter.getX()) * (rabbit.getY() - hunter.getY());
|
||||
if (Math.abs(crossproduct) > EPSILON ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
double dotproduct = dotProduct(hunter, rabbit, tree); // Tree is far away
|
||||
if ( dotproduct < 0 ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
double squaredlengthba = (rabbit.getX()- hunter.getX())*(rabbit.getX() - hunter.getX()) + (rabbit.getY() - hunter.getY())*(rabbit.getY() - hunter.getY());
|
||||
if ( dotproduct > squaredlengthba) { // Tree is too far
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* dotProduct to know if the tree is between the hunter and the rabbit.
|
||||
*
|
||||
* @param hunter
|
||||
* @param rabbit
|
||||
* @param tree
|
||||
* @return If positive, the tree is between.
|
||||
*/
|
||||
private double dotProduct(Point hunter, Point rabbit, Point tree) {
|
||||
return (tree.getX() - hunter.getX()) * (rabbit.getX() - hunter.getX()) + (tree.getY() - hunter.getY())*(rabbit.getY() - hunter.getY());
|
||||
}
|
||||
|
||||
|
||||
public void printStats() {
|
||||
logger.debug("Running rabbits");
|
||||
printRabbits(rabbits);
|
||||
logger.debug("Saved rabbits");
|
||||
printRabbits(savedRabbits);
|
||||
logger.debug("Dead rabbits");
|
||||
printRabbits(deadRabbits);
|
||||
}
|
||||
private void printRabbits(List<Rabbit> rabbits) {
|
||||
for( Rabbit rabbit : rabbits ) {
|
||||
logger.debug(rabbit);
|
||||
}
|
||||
|
||||
}
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Forest [trees=" + trees + ", rabbits=" + rabbits + ", burrows=" + burrows + ", edgeArea=" + edgeArea
|
||||
+ "]";
|
||||
}
|
||||
|
||||
}
|
||||
129
src/main/java/fr/pavnay/rabbits/model/Hunter.java
Normal file
129
src/main/java/fr/pavnay/rabbits/model/Hunter.java
Normal file
@@ -0,0 +1,129 @@
|
||||
package fr.pavnay.rabbits.model;
|
||||
|
||||
import java.awt.Point;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import fr.pavnay.rabbits.model.enums.Speed;
|
||||
|
||||
public class Hunter implements Character {
|
||||
|
||||
private static final Logger logger = Logger.getLogger(Hunter.class);
|
||||
|
||||
private final static int INITIAL_AMMOS = 10;
|
||||
|
||||
private int ammos = INITIAL_AMMOS;
|
||||
private int hungryLevel = 0;
|
||||
private int distance = 0;
|
||||
private Point location;
|
||||
private int range;
|
||||
private int speed;
|
||||
|
||||
private Point destination;
|
||||
|
||||
public Hunter( Point location, int range ) {
|
||||
this.location = location;
|
||||
this.range = range;
|
||||
this.speed = Speed.MEDIUM.getSpeed();
|
||||
}
|
||||
|
||||
public int getAmmos() {
|
||||
return ammos;
|
||||
}
|
||||
public void setAmmos(int ammos) {
|
||||
this.ammos = ammos;
|
||||
}
|
||||
public int getHungryLevel() {
|
||||
return hungryLevel;
|
||||
}
|
||||
public void setHungryLevel(int hungryLevel) {
|
||||
this.hungryLevel = hungryLevel;
|
||||
}
|
||||
public int getDistance() {
|
||||
return distance;
|
||||
}
|
||||
@Override
|
||||
public Point getLocation() {
|
||||
return location;
|
||||
}
|
||||
@Override
|
||||
public Point getDestination() {
|
||||
return destination;
|
||||
}
|
||||
@Override
|
||||
public void setDestination(Point destination) {
|
||||
this.destination = destination;
|
||||
}
|
||||
@Override
|
||||
public int getSpeed() {
|
||||
return speed;
|
||||
}
|
||||
/**
|
||||
* Increasing the walked distance increases the hungry level
|
||||
*
|
||||
*/
|
||||
@Override
|
||||
public void increaseDistance(int distance) {
|
||||
this.distance += distance;
|
||||
setHungryLevel(Math.min(10, (int) (this.distance / 15)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tries to shoot a rabbit
|
||||
*
|
||||
* @param rabbit
|
||||
* @return
|
||||
*/
|
||||
public boolean shoot(Rabbit rabbit) {
|
||||
if( ammos == 0 ) {
|
||||
logger.info("Click... No more ammos");
|
||||
return false;
|
||||
}
|
||||
double rate = getAccuracyRate(rabbit);
|
||||
ammos--;
|
||||
return Math.random() < rate; // If the random value is less than the computed accuracy, the shot is good
|
||||
}
|
||||
|
||||
/**
|
||||
* The hunter finds a rabbit. He goes to its last position.
|
||||
*
|
||||
* @param rabbit
|
||||
*/
|
||||
public void purchase(Rabbit rabbit) {
|
||||
rabbit.purchased();
|
||||
destination = rabbit.getLocation();
|
||||
}
|
||||
|
||||
/**
|
||||
* Accuracy depends to the distance with the target, the number of leaving ammos and the hungry level.
|
||||
*
|
||||
* @param rabbit
|
||||
* @return
|
||||
*/
|
||||
protected double getAccuracyRate(Rabbit rabbit) {
|
||||
double rate = 1 - getLocation().distance(rabbit.getLocation()) / range;
|
||||
|
||||
rate -= 0.005 * (INITIAL_AMMOS - ammos);
|
||||
rate -= 0.01 * hungryLevel;
|
||||
|
||||
return rate;
|
||||
}
|
||||
|
||||
/**
|
||||
* The given rabbit is in range if the distance between the hunter and the rabbit is less than the hunter range.
|
||||
*
|
||||
* @param rabbit
|
||||
* @return
|
||||
*/
|
||||
public boolean isInRange(Rabbit rabbit) {
|
||||
logger.debug(location.distance(rabbit.getLocation()) + "<=" + range);
|
||||
return location.distance(rabbit.getLocation()) <= range;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Hunter [ammos=" + ammos + ", hungryLevel=" + hungryLevel + ", distance=" + distance + ", location="
|
||||
+ location + ", range=" + range + "]";
|
||||
}
|
||||
|
||||
}
|
||||
91
src/main/java/fr/pavnay/rabbits/model/Rabbit.java
Normal file
91
src/main/java/fr/pavnay/rabbits/model/Rabbit.java
Normal file
@@ -0,0 +1,91 @@
|
||||
package fr.pavnay.rabbits.model;
|
||||
|
||||
import java.awt.Point;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import fr.pavnay.rabbits.model.enums.Color;
|
||||
import fr.pavnay.rabbits.model.enums.Speed;
|
||||
|
||||
public class Rabbit implements Character {
|
||||
|
||||
private Point location;
|
||||
private int speed;
|
||||
private Color color;
|
||||
private int distance;
|
||||
|
||||
private Point destination;
|
||||
|
||||
private List<Burrow> refuges = new ArrayList<Burrow>();
|
||||
private boolean scared;
|
||||
|
||||
public Rabbit(Point location) {
|
||||
this.color = Math.random() < 0.5 ? Color.BROWN : Color.WHITE;
|
||||
this.location = location;
|
||||
speed = Speed.SLOW.getSpeed();
|
||||
distance = 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Point getLocation() {
|
||||
return location;
|
||||
}
|
||||
@Override
|
||||
public int getSpeed() {
|
||||
return speed;
|
||||
}
|
||||
@Override
|
||||
public void increaseDistance(int distance) {
|
||||
this.distance += distance;
|
||||
}
|
||||
public void setSpeed(int speed) {
|
||||
this.speed = speed;
|
||||
}
|
||||
public Color getColor() {
|
||||
return color;
|
||||
}
|
||||
public int getDistance() {
|
||||
return distance;
|
||||
}
|
||||
public boolean isScared() {
|
||||
return scared;
|
||||
}
|
||||
public void setScared(boolean scared) {
|
||||
this.scared = scared;
|
||||
}
|
||||
@Override
|
||||
public void setDestination(Point destination) {
|
||||
this.destination = destination;
|
||||
}
|
||||
@Override
|
||||
public Point getDestination() {
|
||||
return destination;
|
||||
}
|
||||
|
||||
/**
|
||||
* The rabbit finds a burrow. So it keeps in mind its location and to go it.
|
||||
*
|
||||
* @param refuge
|
||||
*/
|
||||
public void setRefuge(Burrow refuge) {
|
||||
this.refuges.add( refuge );
|
||||
destination = refuge.getLocation();
|
||||
}
|
||||
public List<Burrow> getRefuges() {
|
||||
return refuges;
|
||||
}
|
||||
public void slowDown() {
|
||||
speed = Math.max(0, speed - 1);
|
||||
}
|
||||
|
||||
public void purchased() {
|
||||
scared = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Rabbit [location=" + location + ", speed=" + speed + ", color=" + color + ", distance=" + distance
|
||||
+ "]";
|
||||
}
|
||||
|
||||
}
|
||||
22
src/main/java/fr/pavnay/rabbits/model/Tree.java
Normal file
22
src/main/java/fr/pavnay/rabbits/model/Tree.java
Normal file
@@ -0,0 +1,22 @@
|
||||
package fr.pavnay.rabbits.model;
|
||||
|
||||
import java.awt.Point;
|
||||
|
||||
public class Tree {
|
||||
|
||||
private Point location;
|
||||
|
||||
public Tree( Point location ) {
|
||||
this.location = location;
|
||||
}
|
||||
|
||||
public Point getLocation() {
|
||||
return location;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Tree [location=" + location + "]";
|
||||
}
|
||||
|
||||
}
|
||||
22
src/main/java/fr/pavnay/rabbits/model/enums/Color.java
Normal file
22
src/main/java/fr/pavnay/rabbits/model/enums/Color.java
Normal file
@@ -0,0 +1,22 @@
|
||||
package fr.pavnay.rabbits.model.enums;
|
||||
|
||||
/**
|
||||
*
|
||||
* An utility enum to give color to rabbits
|
||||
*
|
||||
*/
|
||||
public enum Color {
|
||||
|
||||
WHITE(java.awt.Color.WHITE),
|
||||
BROWN(new java.awt.Color(149, 86, 40));
|
||||
|
||||
private java.awt.Color color;
|
||||
|
||||
private Color( java.awt.Color color) {
|
||||
this.color = color;
|
||||
}
|
||||
|
||||
public java.awt.Color getColor() {
|
||||
return color;
|
||||
}
|
||||
}
|
||||
25
src/main/java/fr/pavnay/rabbits/model/enums/Speed.java
Normal file
25
src/main/java/fr/pavnay/rabbits/model/enums/Speed.java
Normal file
@@ -0,0 +1,25 @@
|
||||
package fr.pavnay.rabbits.model.enums;
|
||||
|
||||
/**
|
||||
*
|
||||
* An utility enum to give some default speeds
|
||||
*
|
||||
*/
|
||||
public enum Speed {
|
||||
|
||||
STOPPED(0),
|
||||
SLOW(1),
|
||||
MEDIUM(5),
|
||||
RUNNING(10);
|
||||
|
||||
private int speed;
|
||||
|
||||
private Speed(int speed) {
|
||||
this.speed = speed;
|
||||
}
|
||||
|
||||
public int getSpeed() {
|
||||
return speed;
|
||||
}
|
||||
|
||||
}
|
||||
18
src/main/java/fr/pavnay/rabbits/model/enums/Status.java
Normal file
18
src/main/java/fr/pavnay/rabbits/model/enums/Status.java
Normal file
@@ -0,0 +1,18 @@
|
||||
package fr.pavnay.rabbits.model.enums;
|
||||
|
||||
/**
|
||||
*
|
||||
* The hunt status
|
||||
*
|
||||
*/
|
||||
public enum Status {
|
||||
|
||||
RUNNING,
|
||||
HUNTER_WINS,
|
||||
RABBITS_WIN;
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return name().charAt(0) + name().substring(1).toLowerCase().replace('_', ' ');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package fr.pavnay.rabbits.model.predicate;
|
||||
|
||||
import org.apache.commons.collections4.Predicate;
|
||||
|
||||
import fr.pavnay.rabbits.model.Hunter;
|
||||
import fr.pavnay.rabbits.model.Rabbit;
|
||||
|
||||
/**
|
||||
*
|
||||
* An utility class to check if a rabbit is in the hunter range
|
||||
*
|
||||
*/
|
||||
public class RangePredicate implements Predicate<Rabbit> {
|
||||
|
||||
private Hunter hunter;
|
||||
|
||||
public RangePredicate(Hunter hunter) {
|
||||
this.hunter = hunter;
|
||||
}
|
||||
|
||||
public boolean evaluate(Rabbit rabbit) {
|
||||
return hunter.isInRange(rabbit);
|
||||
}
|
||||
|
||||
}
|
||||
115
src/main/java/fr/pavnay/rabbits/ui/FormFrame.java
Normal file
115
src/main/java/fr/pavnay/rabbits/ui/FormFrame.java
Normal file
@@ -0,0 +1,115 @@
|
||||
package fr.pavnay.rabbits.ui;
|
||||
|
||||
import java.awt.Dimension;
|
||||
import java.awt.GridBagLayout;
|
||||
import java.awt.Point;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.text.NumberFormat;
|
||||
import java.util.Random;
|
||||
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JFormattedTextField;
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JOptionPane;
|
||||
import javax.swing.text.NumberFormatter;
|
||||
|
||||
import fr.pavnay.rabbits.engine.HuntEngine;
|
||||
import fr.pavnay.rabbits.model.Forest;
|
||||
import fr.pavnay.rabbits.model.Hunter;
|
||||
|
||||
/**
|
||||
*
|
||||
* The entry point in which forest area, trees, burrows and rabbit numbers are set.
|
||||
*
|
||||
*/
|
||||
public class FormFrame extends JFrame implements ActionListener, PropertyChangeListener {
|
||||
|
||||
private static final long serialVersionUID = 4594334659003442873L;
|
||||
|
||||
private JFormattedTextField areaInput; // Only number with specificities (min, max)
|
||||
private JFormattedTextField treeInput;
|
||||
private JFormattedTextField rabbitInput;
|
||||
private JFormattedTextField burrowInput;
|
||||
|
||||
private JButton validateBtn;
|
||||
|
||||
public FormFrame() {
|
||||
setTitle("Rabbits vs Hunter");
|
||||
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
||||
|
||||
setLayout(new GridBagLayout());
|
||||
UiUtils.add(this, new JLabel("Area"), 0, 0, 1, 1);
|
||||
areaInput = new JFormattedTextField(getFormatter(1, 10));
|
||||
areaInput.setValue(10);
|
||||
areaInput.addActionListener(this);
|
||||
UiUtils.add(this, areaInput, 1, 0, 1, 1);
|
||||
UiUtils.add(this, new JLabel("Trees"), 0, 1, 1, 1);
|
||||
|
||||
treeInput = new JFormattedTextField(getFormatter(0, 300));
|
||||
treeInput.setValue(20);
|
||||
treeInput.addActionListener(this);
|
||||
UiUtils.add(this, treeInput, 1, 1, 1, 1);
|
||||
UiUtils.add(this, new JLabel("Rabbits"), 0, 2, 1, 1);
|
||||
rabbitInput = new JFormattedTextField(getFormatter(1, 20));
|
||||
rabbitInput.setValue(5);
|
||||
rabbitInput.addActionListener(this);
|
||||
UiUtils.add(this, rabbitInput, 1, 2, 1, 1);
|
||||
UiUtils.add(this, new JLabel("Burrows"), 0, 3, 1, 1);
|
||||
burrowInput = new JFormattedTextField(getFormatter(1, 20));
|
||||
burrowInput.setValue(10);
|
||||
burrowInput.addPropertyChangeListener(this);
|
||||
UiUtils.add(this, burrowInput, 1, 3, 1, 1);
|
||||
|
||||
validateBtn = new JButton("Validate");
|
||||
validateBtn.addActionListener(this);
|
||||
|
||||
UiUtils.add(this, validateBtn, 0, 4, 2, 1);
|
||||
pack();
|
||||
setLocationRelativeTo(null);
|
||||
setVisible(true);
|
||||
}
|
||||
|
||||
private NumberFormatter getFormatter( int min, int max) {
|
||||
NumberFormat format = NumberFormat.getInstance();
|
||||
NumberFormatter formatter = new NumberFormatter(format);
|
||||
formatter.setValueClass(Integer.class);
|
||||
formatter.setMinimum(min);
|
||||
formatter.setMaximum(max);
|
||||
formatter.setAllowsInvalid(false);
|
||||
return formatter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent event) {
|
||||
if( Integer.parseInt(burrowInput.getText()) < Integer.parseInt(rabbitInput.getText()) ) {
|
||||
JOptionPane.showMessageDialog(this, "Add some burrows. Greater or equals than rabbits count.", "Error", JOptionPane.ERROR_MESSAGE);
|
||||
} else {
|
||||
Forest forest = new Forest(Integer.parseInt(areaInput.getText()), Integer.parseInt(treeInput.getText()),
|
||||
Integer.parseInt(burrowInput.getText()), Integer.parseInt(rabbitInput.getText()));
|
||||
|
||||
Random rand = new Random();
|
||||
Hunter hunter = new Hunter(new Point(rand.nextInt(forest.getEdgeArea()), rand.nextInt(forest.getEdgeArea())), 20);
|
||||
hunter.setDestination(new Point(rand.nextInt(forest.getEdgeArea()), rand.nextInt(forest.getEdgeArea())));
|
||||
HuntEngine engine = new HuntEngine(forest, hunter);
|
||||
|
||||
new MainFrame(engine);
|
||||
dispose();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void propertyChange(PropertyChangeEvent arg0) {
|
||||
validateBtn.setEnabled(!"".equals(areaInput.getText()) && !"".equals(treeInput.getText())
|
||||
&& !"".equals(rabbitInput.getText()) && !"".equals(burrowInput.getText()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension getPreferredSize() {
|
||||
return new Dimension(250, 200);
|
||||
}
|
||||
|
||||
}
|
||||
98
src/main/java/fr/pavnay/rabbits/ui/HuntWorker.java
Normal file
98
src/main/java/fr/pavnay/rabbits/ui/HuntWorker.java
Normal file
@@ -0,0 +1,98 @@
|
||||
package fr.pavnay.rabbits.ui;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import javax.swing.SwingWorker;
|
||||
|
||||
import org.apache.log4j.AppenderSkeleton;
|
||||
import org.apache.log4j.Level;
|
||||
import org.apache.log4j.LogManager;
|
||||
import org.apache.log4j.Logger;
|
||||
import org.apache.log4j.spi.LoggingEvent;
|
||||
|
||||
import fr.pavnay.rabbits.engine.HuntEngine;
|
||||
import fr.pavnay.rabbits.model.enums.Status;
|
||||
|
||||
/**
|
||||
*
|
||||
* This worker provides the loop to play HuntEngine.step() until the status is different to RUNNING
|
||||
*
|
||||
*/
|
||||
public class HuntWorker extends SwingWorker<Status, String> {
|
||||
|
||||
private static final Logger logger = Logger.getLogger(HuntWorker.class);
|
||||
|
||||
public final static long SLEEP_TIME = 500;
|
||||
|
||||
private HuntEngine engine;
|
||||
private MainFrame mainFrame;
|
||||
|
||||
public HuntWorker(HuntEngine engine, MainFrame mainFrame ) {
|
||||
this.engine = engine;
|
||||
this.mainFrame = mainFrame;
|
||||
HuntLogAppender appender = new HuntLogAppender(this);
|
||||
LogManager.getLogger("fr.pavnay.rabbits").addAppender(appender);
|
||||
}
|
||||
|
||||
public void appendLog(String log) {
|
||||
publish(log);
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides some hunt event from logs to UI
|
||||
*/
|
||||
@Override
|
||||
protected void process(List<String> logs) {
|
||||
for(String log : logs) {
|
||||
mainFrame.report(log);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Status doInBackground() throws Exception {
|
||||
Status status = engine.getStatus();
|
||||
try {
|
||||
while( status == Status.RUNNING ) {
|
||||
status = engine.step();
|
||||
Thread.sleep(SLEEP_TIME);
|
||||
}
|
||||
}catch( Exception e) {
|
||||
logger.error(e.getMessage(), e);
|
||||
}
|
||||
logger.debug("Hunt ended : " + engine.getStatus());
|
||||
return engine.getStatus();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void done() {
|
||||
super.done();
|
||||
logger.debug("Done - " + engine.getStatus());
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* A log appender to retrieve hunt logs and give them to UI.
|
||||
*
|
||||
*/
|
||||
public class HuntLogAppender extends AppenderSkeleton {
|
||||
private final HuntWorker worker;
|
||||
|
||||
public HuntLogAppender( HuntWorker slurperWorker) {
|
||||
this.worker = slurperWorker;
|
||||
}
|
||||
protected void append(LoggingEvent event)
|
||||
{
|
||||
if(event.getLevel().equals(Level.INFO)){
|
||||
worker.appendLog(event.getMessage().toString());
|
||||
}
|
||||
}
|
||||
public void close()
|
||||
{
|
||||
}
|
||||
public boolean requiresLayout()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
114
src/main/java/fr/pavnay/rabbits/ui/MainFrame.java
Normal file
114
src/main/java/fr/pavnay/rabbits/ui/MainFrame.java
Normal file
@@ -0,0 +1,114 @@
|
||||
package fr.pavnay.rabbits.ui;
|
||||
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
|
||||
import javax.swing.BorderFactory;
|
||||
import javax.swing.Box;
|
||||
import javax.swing.BoxLayout;
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JScrollPane;
|
||||
import javax.swing.SwingWorker;
|
||||
import javax.swing.Timer;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import fr.pavnay.rabbits.engine.HuntEngine;
|
||||
import fr.pavnay.rabbits.ui.panel.Canvas;
|
||||
import fr.pavnay.rabbits.ui.panel.CanvasLegend;
|
||||
import fr.pavnay.rabbits.ui.panel.CharacterPanel;
|
||||
import fr.pavnay.rabbits.ui.panel.LogPanel;
|
||||
|
||||
/**
|
||||
*
|
||||
* The frame to see the hunt.
|
||||
*
|
||||
*/
|
||||
public class MainFrame extends JFrame implements PropertyChangeListener, ActionListener {
|
||||
|
||||
private static final long serialVersionUID = -5070100141993068939L;
|
||||
|
||||
private static final Logger logger = Logger.getLogger(MainFrame.class);
|
||||
|
||||
private HuntEngine engine;
|
||||
|
||||
private Timer timer; // Timer used to refresh UI periodically
|
||||
|
||||
private JPanel canvas; // The hunt panel
|
||||
private CharacterPanel characterPanel; // Characters stats panel
|
||||
private LogPanel logPanel; // Hunt event panel
|
||||
private JLabel statusLabel; // Hunt status
|
||||
|
||||
private HuntWorker worker;
|
||||
|
||||
public MainFrame( HuntEngine engine ) {
|
||||
setTitle("Rabbits vs Hunter");
|
||||
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
||||
|
||||
setLayout(new BorderLayout());
|
||||
|
||||
this.engine = engine;
|
||||
|
||||
JPanel statusPanel = new JPanel();
|
||||
statusPanel.add(new JLabel("Status :"));
|
||||
statusLabel = new JLabel(engine.getStatus().toString());
|
||||
statusPanel.add(statusLabel);
|
||||
add(statusPanel, BorderLayout.NORTH);
|
||||
|
||||
canvas = new Canvas(engine.getForest(), engine.getHunter());
|
||||
timer = new Timer((int) HuntWorker.SLEEP_TIME, this);
|
||||
add(canvas, BorderLayout.CENTER);
|
||||
|
||||
characterPanel = new CharacterPanel(engine.getHunter(), engine.getForest());
|
||||
logPanel = new LogPanel();
|
||||
|
||||
int VERT_GAP = 10;
|
||||
int EB_GAP = 5;
|
||||
JPanel sidePanel = new JPanel();
|
||||
sidePanel.setBorder(BorderFactory.createEmptyBorder(EB_GAP, EB_GAP, EB_GAP, EB_GAP));
|
||||
sidePanel.setLayout(new BoxLayout(sidePanel, BoxLayout.PAGE_AXIS));
|
||||
sidePanel.add(characterPanel);
|
||||
sidePanel.add(Box.createVerticalStrut(VERT_GAP));
|
||||
sidePanel.add(Box.createVerticalStrut(VERT_GAP));
|
||||
sidePanel.add(new JScrollPane(logPanel));
|
||||
add(sidePanel, BorderLayout.EAST);
|
||||
|
||||
add( new CanvasLegend(engine.getForest()), BorderLayout.SOUTH );
|
||||
|
||||
worker = new HuntWorker(engine, this);
|
||||
worker.addPropertyChangeListener(this);
|
||||
worker.execute();
|
||||
timer.start();
|
||||
|
||||
pack();
|
||||
setLocationRelativeTo(null);
|
||||
setVisible(true);
|
||||
}
|
||||
|
||||
public void propertyChange(PropertyChangeEvent event) {
|
||||
if ("state".equals(event.getPropertyName()) && SwingWorker.StateValue.DONE == event.getNewValue()) { // Worker ends
|
||||
statusLabel.setText(engine.getStatus().toString());
|
||||
statusLabel.repaint();
|
||||
|
||||
logger.debug(engine.getHunter());
|
||||
engine.getForest().printStats();
|
||||
}
|
||||
}
|
||||
|
||||
public void actionPerformed(ActionEvent event) {
|
||||
if(event.getSource()==timer){
|
||||
canvas.repaint();
|
||||
characterPanel.refresh();
|
||||
}
|
||||
}
|
||||
|
||||
public void report(String log) {
|
||||
logPanel.addLog(log);
|
||||
}
|
||||
|
||||
}
|
||||
40
src/main/java/fr/pavnay/rabbits/ui/UiUtils.java
Normal file
40
src/main/java/fr/pavnay/rabbits/ui/UiUtils.java
Normal file
@@ -0,0 +1,40 @@
|
||||
package fr.pavnay.rabbits.ui;
|
||||
|
||||
import java.awt.Container;
|
||||
import java.awt.GridBagConstraints;
|
||||
import java.awt.Insets;
|
||||
|
||||
import javax.swing.JComponent;
|
||||
|
||||
/**
|
||||
*
|
||||
* An utility class for UI
|
||||
*
|
||||
*/
|
||||
public class UiUtils {
|
||||
|
||||
/**
|
||||
* Add a component in a container with a GridBagLayout
|
||||
*
|
||||
* @param container
|
||||
* @param component
|
||||
* @param x
|
||||
* @param y
|
||||
* @param w
|
||||
* @param h
|
||||
*/
|
||||
public static void add(Container container, JComponent component, int x, int y,
|
||||
int w, int h) {
|
||||
GridBagConstraints bagConstraints = new GridBagConstraints();
|
||||
bagConstraints.gridx = x;
|
||||
bagConstraints.gridy = y;
|
||||
bagConstraints.gridwidth = w;
|
||||
bagConstraints.gridheight = h;
|
||||
bagConstraints.anchor = (x == 0) ? GridBagConstraints.EAST
|
||||
: GridBagConstraints.WEST;
|
||||
bagConstraints.fill = (x == 0) ? GridBagConstraints.BOTH
|
||||
: GridBagConstraints.HORIZONTAL;
|
||||
bagConstraints.insets = new Insets(5, 5, 5, 5);
|
||||
container.add(component, bagConstraints);
|
||||
}
|
||||
}
|
||||
71
src/main/java/fr/pavnay/rabbits/ui/panel/Canvas.java
Normal file
71
src/main/java/fr/pavnay/rabbits/ui/panel/Canvas.java
Normal file
@@ -0,0 +1,71 @@
|
||||
package fr.pavnay.rabbits.ui.panel;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics;
|
||||
|
||||
import javax.swing.JPanel;
|
||||
|
||||
import fr.pavnay.rabbits.model.Burrow;
|
||||
import fr.pavnay.rabbits.model.Forest;
|
||||
import fr.pavnay.rabbits.model.Hunter;
|
||||
import fr.pavnay.rabbits.model.Rabbit;
|
||||
import fr.pavnay.rabbits.model.Tree;
|
||||
|
||||
/**
|
||||
*
|
||||
* This class draws all hunt elements : trees, burrows, hunter and rabbits
|
||||
*
|
||||
*/
|
||||
public class Canvas extends JPanel {
|
||||
|
||||
private static final long serialVersionUID = 4209640358977009595L;
|
||||
|
||||
protected static int RATE = 5;
|
||||
protected static int ITEM_RATIO = 2;
|
||||
|
||||
private Forest forest;
|
||||
private Hunter hunter;
|
||||
|
||||
public Canvas( Forest forest, Hunter hunter) {
|
||||
this.hunter = hunter;
|
||||
this.forest = forest;
|
||||
}
|
||||
|
||||
public void paintComponent(Graphics graphics) {
|
||||
super.paintComponent(graphics);
|
||||
|
||||
graphics.setColor(Color.RED);
|
||||
graphics.fillOval((int) hunter.getLocation().getX() * RATE, (int) hunter.getLocation().getY() * RATE, 3 * ITEM_RATIO, 3 * ITEM_RATIO);
|
||||
|
||||
graphics.setColor(Color.GREEN);
|
||||
for( Tree tree : forest.getTrees() ) {
|
||||
graphics.fillOval((int) tree.getLocation().getX() * RATE, (int) tree.getLocation().getY() * RATE, 5 * ITEM_RATIO, 5 * ITEM_RATIO);
|
||||
}
|
||||
|
||||
for( Burrow burrow : forest.getBurrows() ) {
|
||||
if( burrow.isFree() ) {
|
||||
graphics.setColor(Color.GRAY);
|
||||
} else {
|
||||
graphics.setColor(Color.DARK_GRAY);
|
||||
}
|
||||
graphics.fillOval((int) burrow.getLocation().getX() * RATE, (int) burrow.getLocation().getY() * RATE, 4 * ITEM_RATIO, 2 * ITEM_RATIO);
|
||||
}
|
||||
|
||||
for( Rabbit rabbit : forest.getRabbits() ) {
|
||||
if( rabbit.getColor() == fr.pavnay.rabbits.model.enums.Color.WHITE ) {
|
||||
graphics.setColor(Color.BLACK);
|
||||
graphics.drawOval((int) rabbit.getLocation().getX() * RATE, (int) rabbit.getLocation().getY() * RATE, 3 * ITEM_RATIO, 3 * ITEM_RATIO);
|
||||
} else {
|
||||
graphics.setColor(rabbit.getColor().getColor());
|
||||
graphics.fillOval((int) rabbit.getLocation().getX() * RATE, (int) rabbit.getLocation().getY() * RATE, 3 * ITEM_RATIO, 3 * ITEM_RATIO);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension getPreferredSize() {
|
||||
return new Dimension(forest.getEdgeArea() * RATE, forest.getEdgeArea() * RATE);
|
||||
}
|
||||
|
||||
}
|
||||
54
src/main/java/fr/pavnay/rabbits/ui/panel/CanvasLegend.java
Normal file
54
src/main/java/fr/pavnay/rabbits/ui/panel/CanvasLegend.java
Normal file
@@ -0,0 +1,54 @@
|
||||
package fr.pavnay.rabbits.ui.panel;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics;
|
||||
|
||||
import javax.swing.JPanel;
|
||||
|
||||
import fr.pavnay.rabbits.model.Forest;
|
||||
|
||||
/**
|
||||
*
|
||||
* This class draws the Canvas elements legend
|
||||
*
|
||||
*/
|
||||
public class CanvasLegend extends JPanel {
|
||||
|
||||
private static final long serialVersionUID = 1307357862666434838L;
|
||||
|
||||
private int width;
|
||||
|
||||
public CanvasLegend(Forest forest) {
|
||||
this.width = forest.getEdgeArea() * Canvas.RATE;
|
||||
}
|
||||
|
||||
public void paintComponent(Graphics graphics) {
|
||||
super.paintComponent(graphics);
|
||||
|
||||
graphics.setColor(Color.RED);
|
||||
graphics.fillOval(5, 10, 3 * Canvas.ITEM_RATIO, 3 * Canvas.ITEM_RATIO);
|
||||
graphics.drawString("Hunter", 12, 15);
|
||||
|
||||
graphics.setColor(Color.GREEN);
|
||||
graphics.fillOval(width / 5 + 5, 10, 5 * Canvas.ITEM_RATIO, 5 * Canvas.ITEM_RATIO);
|
||||
graphics.drawString("Trees", width / 5 + 12, 15);
|
||||
|
||||
graphics.setColor(Color.GRAY);
|
||||
graphics.fillOval(2 * width / 5 + 5, 10, 4 * Canvas.ITEM_RATIO, 2 * Canvas.ITEM_RATIO);
|
||||
graphics.drawString("Burrows", 2 * width / 5 + 12, 15);
|
||||
|
||||
graphics.setColor(Color.BLACK);
|
||||
graphics.drawOval(3 * width / 5 + 5, 10, 3 * Canvas.ITEM_RATIO, 3 * Canvas.ITEM_RATIO);
|
||||
graphics.drawString("Rabbits", 3 * width / 5 + 12, 15);
|
||||
|
||||
graphics.setColor(fr.pavnay.rabbits.model.enums.Color.BROWN.getColor());
|
||||
graphics.fillOval(4 * width / 5 + 5, 10, 3 * Canvas.ITEM_RATIO, 3 * Canvas.ITEM_RATIO);
|
||||
graphics.drawString("Rabbits", 4 * width / 5 + 12, 15);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension getPreferredSize() {
|
||||
return new Dimension(width, 20);
|
||||
}
|
||||
}
|
||||
98
src/main/java/fr/pavnay/rabbits/ui/panel/CharacterPanel.java
Normal file
98
src/main/java/fr/pavnay/rabbits/ui/panel/CharacterPanel.java
Normal file
@@ -0,0 +1,98 @@
|
||||
package fr.pavnay.rabbits.ui.panel;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Font;
|
||||
import java.awt.GridBagLayout;
|
||||
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JPanel;
|
||||
|
||||
import fr.pavnay.rabbits.model.Forest;
|
||||
import fr.pavnay.rabbits.model.Hunter;
|
||||
import fr.pavnay.rabbits.ui.UiUtils;
|
||||
|
||||
/**
|
||||
*
|
||||
* This class gives some hunt statistics
|
||||
*
|
||||
*/
|
||||
public class CharacterPanel extends JPanel {
|
||||
|
||||
private static final long serialVersionUID = -7823773213443395686L;
|
||||
|
||||
private Hunter hunter;
|
||||
private Forest forest;
|
||||
|
||||
private JLabel ammosCountLabel;
|
||||
private JLabel hungryLevelLabel;
|
||||
private JLabel distanceLabel;
|
||||
|
||||
private JLabel runningRabbitsLabel;
|
||||
private JLabel savedRabbitsLabel;
|
||||
private JLabel deadRabbitsLabel;
|
||||
|
||||
public CharacterPanel(Hunter hunter, Forest forest) {
|
||||
|
||||
this.hunter = hunter;
|
||||
this.forest = forest;
|
||||
|
||||
JPanel innerPanel = new JPanel(new GridBagLayout());
|
||||
|
||||
UiUtils.add(innerPanel, new JLabel("Hunter"), 0, 0, 3, 1);
|
||||
JPanel tmpPanel = new JPanel(new GridBagLayout());
|
||||
UiUtils.add(tmpPanel,new JLabel("Ammos"), 0, 0, 1, 1);
|
||||
ammosCountLabel = new JLabel(String.valueOf(hunter.getAmmos()));
|
||||
Font plainFont = ammosCountLabel.getFont().deriveFont(Font.PLAIN);
|
||||
ammosCountLabel.setFont(plainFont);
|
||||
UiUtils.add(tmpPanel, ammosCountLabel, 1, 0, 1, 1);
|
||||
|
||||
UiUtils.add(tmpPanel, new JLabel("Hungry"), 2, 0, 1, 1);
|
||||
hungryLevelLabel = new JLabel(String.valueOf(hunter.getHungryLevel()));
|
||||
hungryLevelLabel.setFont(plainFont);
|
||||
UiUtils.add(tmpPanel, hungryLevelLabel, 3, 0, 1, 1);
|
||||
|
||||
UiUtils.add(tmpPanel, new JLabel("Distance"), 4, 0, 1, 1);
|
||||
distanceLabel = new JLabel(String.valueOf(hunter.getDistance()));
|
||||
distanceLabel.setFont(plainFont);
|
||||
UiUtils.add(tmpPanel, distanceLabel, 5, 0, 1, 1);
|
||||
|
||||
UiUtils.add(innerPanel, tmpPanel, 0, 1, 1, 1);
|
||||
|
||||
UiUtils.add(innerPanel, new JLabel("Rabbits"), 0, 2, 3, 1);
|
||||
tmpPanel = new JPanel(new GridBagLayout());
|
||||
UiUtils.add(tmpPanel,new JLabel("Running"), 0, 0, 1, 1);
|
||||
runningRabbitsLabel = new JLabel(String.valueOf(forest.getRabbits().size()));
|
||||
plainFont = runningRabbitsLabel.getFont().deriveFont(Font.PLAIN);
|
||||
runningRabbitsLabel.setFont(plainFont);
|
||||
runningRabbitsLabel.setForeground(Color.BLACK);
|
||||
UiUtils.add(tmpPanel, runningRabbitsLabel, 1, 0, 1, 1);
|
||||
|
||||
UiUtils.add(tmpPanel, new JLabel("Saved"), 2, 0, 1, 1);
|
||||
savedRabbitsLabel = new JLabel(String.valueOf(forest.getSavedRabbits().size()));
|
||||
savedRabbitsLabel.setFont(plainFont);
|
||||
savedRabbitsLabel.setForeground(Color.GREEN);
|
||||
UiUtils.add(tmpPanel, savedRabbitsLabel, 3, 0, 1, 1);
|
||||
|
||||
UiUtils.add(tmpPanel, new JLabel("Dead"), 4, 0, 1, 1);
|
||||
deadRabbitsLabel = new JLabel(String.valueOf(forest.getDeadRabbits().size()));
|
||||
deadRabbitsLabel.setFont(plainFont);
|
||||
deadRabbitsLabel.setForeground(Color.RED);
|
||||
UiUtils.add(tmpPanel, deadRabbitsLabel, 5, 0, 1, 1);
|
||||
|
||||
UiUtils.add(innerPanel, tmpPanel, 0, 3, 1, 1);
|
||||
|
||||
add(innerPanel);
|
||||
|
||||
}
|
||||
|
||||
public void refresh() {
|
||||
ammosCountLabel.setText(String.valueOf(hunter.getAmmos()));
|
||||
hungryLevelLabel.setText(String.valueOf(hunter.getHungryLevel()));
|
||||
distanceLabel.setText(String.valueOf(hunter.getDistance()));
|
||||
|
||||
runningRabbitsLabel.setText(String.valueOf(forest.getRabbits().size()));
|
||||
savedRabbitsLabel.setText(String.valueOf(forest.getSavedRabbits().size()));
|
||||
deadRabbitsLabel.setText(String.valueOf(forest.getDeadRabbits().size()));
|
||||
}
|
||||
|
||||
}
|
||||
28
src/main/java/fr/pavnay/rabbits/ui/panel/LogPanel.java
Normal file
28
src/main/java/fr/pavnay/rabbits/ui/panel/LogPanel.java
Normal file
@@ -0,0 +1,28 @@
|
||||
package fr.pavnay.rabbits.ui.panel;
|
||||
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Font;
|
||||
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JPanel;
|
||||
|
||||
/**
|
||||
*
|
||||
* This class provides some hunt events
|
||||
*
|
||||
*/
|
||||
public class LogPanel extends JPanel {
|
||||
|
||||
private static final long serialVersionUID = 3786097551382633033L;
|
||||
|
||||
public void addLog(String log) {
|
||||
JLabel label = new JLabel(log);
|
||||
label.setFont(label.getFont().deriveFont(Font.PLAIN));
|
||||
add(label);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension getPreferredSize() {
|
||||
return new Dimension(200, 400);
|
||||
}
|
||||
}
|
||||
8
src/main/resources/log4j.properties
Normal file
8
src/main/resources/log4j.properties
Normal file
@@ -0,0 +1,8 @@
|
||||
log4j.rootLogger=INFO, CONSOLE
|
||||
|
||||
# CONSOLE is set to be a ConsoleAppender using a PatternLayout
|
||||
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
|
||||
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
|
||||
log4j.appender.CONSOLE.layout.ConversionPattern=%d [%-5p] %c - %m%n
|
||||
|
||||
log4j.logger.fr.pavnay.rabbits=INFO
|
||||
248
src/test/java/fr/pavnay/rabbits/engine/HuntEngineTest.java
Normal file
248
src/test/java/fr/pavnay/rabbits/engine/HuntEngineTest.java
Normal file
@@ -0,0 +1,248 @@
|
||||
package fr.pavnay.rabbits.engine;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.awt.Point;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import fr.pavnay.rabbits.model.Burrow;
|
||||
import fr.pavnay.rabbits.model.Forest;
|
||||
import fr.pavnay.rabbits.model.Hunter;
|
||||
import fr.pavnay.rabbits.model.Rabbit;
|
||||
import fr.pavnay.rabbits.model.enums.Speed;
|
||||
import fr.pavnay.rabbits.model.enums.Status;
|
||||
|
||||
public class HuntEngineTest {
|
||||
|
||||
@Test
|
||||
public void testUpdateStatusRunning() {
|
||||
Hunter hunter = new Hunter(new Point(3, 2), 10);
|
||||
Forest forest = new Forest(10, 1, 2, 1);
|
||||
HuntEngine engine = new HuntEngine(forest, hunter);
|
||||
engine.updateStatus();
|
||||
|
||||
assertEquals( "Default status is RUNNING", Status.RUNNING, engine.getStatus());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateStatusRabbitsWin() {
|
||||
Hunter hunter = new Hunter(new Point(3, 2), 10);
|
||||
Forest forest = new Forest(10, 1, 2, 1);
|
||||
HuntEngine engine = new HuntEngine(forest, hunter);
|
||||
hunter.setAmmos(0);
|
||||
engine.updateStatus();
|
||||
|
||||
assertEquals( "Default status is RUNNING", Status.RABBITS_WIN, engine.getStatus());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateStatusHunterWins() {
|
||||
Hunter hunter = new Hunter(new Point(3, 2), 10);
|
||||
Forest forest = new Forest(10, 1, 2, 1);
|
||||
HuntEngine engine = new HuntEngine(forest, hunter);
|
||||
forest.getDeadRabbits().addAll(forest.getRabbits());
|
||||
forest.getRabbits().clear();
|
||||
engine.updateStatus();
|
||||
|
||||
assertEquals( "Default status is RUNNING", Status.HUNTER_WINS, engine.getStatus());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateStatusHunterLoose() {
|
||||
Hunter hunter = new Hunter(new Point(3, 2), 10);
|
||||
Forest forest = new Forest(10, 1, 2, 2);
|
||||
HuntEngine engine = new HuntEngine(forest, hunter);
|
||||
forest.getDeadRabbits().add(forest.getRabbits().get(0));
|
||||
forest.getSavedRabbits().add(forest.getRabbits().get(1));
|
||||
forest.getRabbits().clear();
|
||||
engine.updateStatus();
|
||||
|
||||
assertEquals( "Default status is RUNNING", Status.RABBITS_WIN, engine.getStatus());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMoveHunterCloseToDestination() {
|
||||
Hunter hunter = new Hunter(new Point(0, 0), 10);
|
||||
hunter.setDestination(new Point(2, 0));
|
||||
Forest forest = new Forest(10, 1, 2, 1);
|
||||
HuntEngine engine = new HuntEngine(forest, hunter);
|
||||
|
||||
engine.move(hunter);
|
||||
assertNotEquals("Destination has changed - X", 2, hunter.getDestination().getX());
|
||||
assertNotEquals("Destination has changed - Y", 0, hunter.getDestination().getY());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMoveHunterFarFromDestination() {
|
||||
Hunter hunter = new Hunter(new Point(0, 0), 10);
|
||||
hunter.setDestination(new Point(20, 0));
|
||||
Forest forest = new Forest(10, 1, 2, 1);
|
||||
HuntEngine engine = new HuntEngine(forest, hunter);
|
||||
|
||||
engine.move(hunter);
|
||||
assertNotEquals("Destination has changed - X", 20, hunter.getDestination().getX());
|
||||
assertNotEquals("Destination has changed - Y", 0, hunter.getDestination().getY());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMoveRabbitCloseToFreeBurrow() {
|
||||
Hunter hunter = new Hunter(new Point(0, 0), 10);
|
||||
Forest forest = new Forest(10, 1, 2, 1);
|
||||
HuntEngine engine = new HuntEngine(forest, hunter);
|
||||
|
||||
Burrow burrow = forest.getBurrows().get(0);
|
||||
burrow.getLocation().setLocation(2, 0);
|
||||
|
||||
Rabbit rabbit = forest.getRabbits().get(0);
|
||||
rabbit.getLocation().setLocation(new Point(0, 0));
|
||||
rabbit.setSpeed(Speed.MEDIUM.getSpeed());
|
||||
rabbit.setRefuge(burrow);
|
||||
|
||||
engine.move(rabbit);
|
||||
assertFalse("Lucky rabbit doesn't run anymore", forest.getRabbits().contains(rabbit));
|
||||
assertNull("No more destination", rabbit.getDestination());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMoveRabbitCloseToNotFreeBurrow() {
|
||||
Hunter hunter = new Hunter(new Point(0, 0), 10);
|
||||
Forest forest = new Forest(10, 1, 2, 1);
|
||||
HuntEngine engine = new HuntEngine(forest, hunter);
|
||||
|
||||
Burrow burrow = forest.getBurrows().get(0);
|
||||
burrow.getLocation().setLocation(2, 0);
|
||||
burrow.setFree(false);
|
||||
|
||||
Rabbit rabbit = forest.getRabbits().get(0);
|
||||
rabbit.getLocation().setLocation(new Point(0, 0));
|
||||
rabbit.setSpeed(Speed.MEDIUM.getSpeed());
|
||||
rabbit.setRefuge(burrow);
|
||||
|
||||
engine.move(rabbit);
|
||||
assertTrue("Rabbit still running", forest.getRabbits().contains(rabbit));
|
||||
assertEquals("New destination : next burrow",forest.getBurrows().get(1).getLocation(), rabbit.getDestination());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMoveRabbitToFarFromBurrow() {
|
||||
Hunter hunter = new Hunter(new Point(0, 0), 10);
|
||||
Forest forest = new Forest(10, 1, 2, 1);
|
||||
HuntEngine engine = new HuntEngine(forest, hunter);
|
||||
|
||||
Burrow burrow = forest.getBurrows().get(0);
|
||||
burrow.getLocation().setLocation(20, 0);
|
||||
|
||||
Rabbit rabbit = forest.getRabbits().get(0);
|
||||
rabbit.getLocation().setLocation(new Point(0, 0));
|
||||
rabbit.setSpeed(Speed.MEDIUM.getSpeed());
|
||||
rabbit.setRefuge(burrow);
|
||||
|
||||
engine.move(rabbit);
|
||||
assertTrue("Rabbit still running", forest.getRabbits().contains(rabbit));
|
||||
assertEquals("Burrow still the destination", burrow.getLocation(), rabbit.getDestination());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMoveRabbitCloseToDestination() {
|
||||
Hunter hunter = new Hunter(new Point(0, 0), 10);
|
||||
Forest forest = new Forest(10, 1, 2, 1);
|
||||
HuntEngine engine = new HuntEngine(forest, hunter);
|
||||
|
||||
Rabbit rabbit = forest.getRabbits().get(0);
|
||||
rabbit.getLocation().setLocation(new Point(0, 0));
|
||||
rabbit.setSpeed(Speed.MEDIUM.getSpeed());
|
||||
rabbit.setDestination(new Point(3, 0));
|
||||
engine.move(rabbit);
|
||||
assertNotEquals("New destination", new Point(3, 0), rabbit.getDestination());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMoveRabbitFarFromDestination() {
|
||||
Hunter hunter = new Hunter(new Point(0, 0), 10);
|
||||
Forest forest = new Forest(10, 1, 2, 1);
|
||||
HuntEngine engine = new HuntEngine(forest, hunter);
|
||||
|
||||
Rabbit rabbit = forest.getRabbits().get(0);
|
||||
rabbit.getLocation().setLocation(new Point(0, 0));
|
||||
rabbit.setSpeed(Speed.MEDIUM.getSpeed());
|
||||
rabbit.setDestination(new Point(13, 0));
|
||||
|
||||
engine.move(rabbit);
|
||||
assertEquals("Same destination", new Point(13, 0), rabbit.getDestination());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetRandomDestinationHunter() {
|
||||
Hunter hunter = new Hunter(new Point(0, 0), 10);
|
||||
hunter.setDestination(null);
|
||||
Forest forest = new Forest(10, 1, 2, 1);
|
||||
HuntEngine engine = new HuntEngine(forest, hunter);
|
||||
|
||||
engine.setRandomDestination(hunter);
|
||||
assertNotNull("Destination set", hunter.getDestination());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetRandomDestinationRabbit() {
|
||||
Hunter hunter = new Hunter(new Point(0, 0), 10);
|
||||
Forest forest = new Forest(10, 1, 2, 1);
|
||||
HuntEngine engine = new HuntEngine(forest, hunter);
|
||||
Rabbit rabbit = forest.getRabbits().get(0);
|
||||
rabbit.setDestination(null);
|
||||
engine.setRandomDestination(rabbit);
|
||||
assertNotNull("Destination set", rabbit.getDestination());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGoHunter() {
|
||||
Hunter hunter = new Hunter(new Point(0, 0), 10);
|
||||
hunter.setDestination(new Point(20, 20));
|
||||
Forest forest = new Forest(10, 1, 2, 1);
|
||||
HuntEngine engine = new HuntEngine(forest, hunter);
|
||||
|
||||
engine.go(hunter);
|
||||
|
||||
assertEquals("Location has changed", new Point(3, 3), hunter.getLocation());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGoRabbit() {
|
||||
Hunter hunter = new Hunter(new Point(0, 0), 10);
|
||||
Forest forest = new Forest(10, 1, 2, 1);
|
||||
HuntEngine engine = new HuntEngine(forest, hunter);
|
||||
|
||||
Rabbit rabbit = forest.getRabbits().get(0);
|
||||
rabbit.getLocation().setLocation(new Point(0, 0));
|
||||
rabbit.setSpeed(Speed.MEDIUM.getSpeed());
|
||||
rabbit.setDestination(new Point(13, 13));
|
||||
|
||||
engine.go(rabbit);
|
||||
|
||||
assertEquals("Location has changed", new Point(3, 3), rabbit.getLocation());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSavedRabbit() {
|
||||
Hunter hunter = new Hunter(new Point(0, 0), 10);
|
||||
Forest forest = new Forest(10, 1, 2, 1);
|
||||
HuntEngine engine = new HuntEngine(forest, hunter);
|
||||
|
||||
Burrow burrow = forest.getBurrows().get(0);
|
||||
burrow.getLocation().setLocation(2, 0);
|
||||
|
||||
Rabbit rabbit = forest.getRabbits().get(0);
|
||||
rabbit.getLocation().setLocation(new Point(0, 0));
|
||||
rabbit.setSpeed(Speed.MEDIUM.getSpeed());
|
||||
rabbit.setRefuge(burrow);
|
||||
|
||||
engine.go(rabbit);
|
||||
|
||||
assertEquals("Destination has not changed", new Point(5, 0), rabbit.getLocation());
|
||||
}
|
||||
}
|
||||
246
src/test/java/fr/pavnay/rabbits/model/ForestTest.java
Normal file
246
src/test/java/fr/pavnay/rabbits/model/ForestTest.java
Normal file
@@ -0,0 +1,246 @@
|
||||
package fr.pavnay.rabbits.model;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.awt.Point;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.matchers.JUnitMatchers;
|
||||
import org.junit.rules.ExpectedException;
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public class ForestTest {
|
||||
|
||||
@Rule
|
||||
public ExpectedException thrown = ExpectedException.none();
|
||||
|
||||
@Test
|
||||
public void testInitSuccess() {
|
||||
Forest forest = new Forest(10, 1, 1, 1);
|
||||
assertNotNull("Forest created", forest);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInitFailureAreaMin() {
|
||||
thrown.expect(IllegalArgumentException.class);
|
||||
thrown.expectMessage(JUnitMatchers.containsString("Area"));
|
||||
|
||||
new Forest(0, 1, 1, 1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInitFailureAreaMax() {
|
||||
thrown.expect(IllegalArgumentException.class);
|
||||
thrown.expectMessage(JUnitMatchers.containsString("Area"));
|
||||
|
||||
new Forest(11, 1, 1, 1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInitFailureTreesMin() {
|
||||
thrown.expect(IllegalArgumentException.class);
|
||||
thrown.expectMessage(JUnitMatchers.containsString("Tree"));
|
||||
|
||||
new Forest(1, 0, 1, 1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInitFailureTreesMax() {
|
||||
thrown.expect(IllegalArgumentException.class);
|
||||
thrown.expectMessage(JUnitMatchers.containsString("Tree"));
|
||||
|
||||
new Forest(10, 1001, 1, 1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInitFailureNoRabbits() {
|
||||
thrown.expect(IllegalArgumentException.class);
|
||||
thrown.expectMessage(JUnitMatchers.containsString("rabbits"));
|
||||
|
||||
new Forest(10, 100, 1, 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInitFailureNotEnoughBurrows() {
|
||||
thrown.expect(IllegalArgumentException.class);
|
||||
thrown.expectMessage(JUnitMatchers.containsString("burrow"));
|
||||
|
||||
new Forest(10, 100, 1, 2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsBetweenSuccess() {
|
||||
Hunter hunter = new Hunter(new Point(0,0), 10);
|
||||
Forest forest = new Forest(10, 1, 1, 1);
|
||||
Rabbit rabbit = new Rabbit(new Point(4, 4));
|
||||
Tree tree = new Tree(new Point(2, 2));
|
||||
assertTrue("Tree is between hunter and rabbit", forest.isBetween(hunter.getLocation(), rabbit.getLocation(), tree.getLocation()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCanViewSuccess() {
|
||||
Hunter hunter = new Hunter(new Point(0,0), 10);
|
||||
Forest forest = new Forest(10, 2, 1, 1);
|
||||
forest.getTrees().get(0).getLocation().setLocation(10, 0);
|
||||
forest.getTrees().get(1).getLocation().setLocation(20, 0);
|
||||
Rabbit rabbit = new Rabbit(new Point(4, 4));
|
||||
assertTrue("No Tree between hunter and rabbit", forest.canView(hunter, rabbit));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCanViewFailure() {
|
||||
Hunter hunter = new Hunter(new Point(0,0), 10);
|
||||
Forest forest = new Forest(10, 2, 1, 1);
|
||||
forest.getTrees().get(0).getLocation().setLocation(2, 2);
|
||||
forest.getTrees().get(1).getLocation().setLocation(2, 0);
|
||||
Rabbit rabbit = new Rabbit(new Point(4, 4));
|
||||
assertFalse("Tree is between hunter and rabbit", forest.canView(hunter, rabbit));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsBetweenFailureTreeBehind() {
|
||||
Hunter hunter = new Hunter(new Point(0,0), 10);
|
||||
Forest forest = new Forest(10, 1, 1, 1);
|
||||
Rabbit rabbit = new Rabbit(new Point(4, 4));
|
||||
Tree tree = new Tree(new Point(5, 5));
|
||||
assertFalse("Tree is behind the rabbit", forest.isBetween(hunter.getLocation(), rabbit.getLocation(), tree.getLocation()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsBetweenFailureTreeSomewhere() {
|
||||
Hunter hunter = new Hunter(new Point(0,0), 10);
|
||||
Forest forest = new Forest(10, 1, 1, 1);
|
||||
Rabbit rabbit = new Rabbit(new Point(4, 4));
|
||||
Tree tree = new Tree(new Point(10, 5));
|
||||
assertFalse("Tree is not in the hunter-rabbit aligment", forest.isBetween(hunter.getLocation(), rabbit.getLocation(), tree.getLocation()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testKilledRabbitSuccess() {
|
||||
Forest forest = new Forest(10, 1, 2, 2);
|
||||
Rabbit rabbit = forest.getRabbits().get(0);
|
||||
forest.killedRabbit(rabbit);
|
||||
|
||||
assertFalse("Poor killed rabbit still running", forest.getRabbits().contains(rabbit));
|
||||
assertEquals("Still one rabbit alive", 1, forest.getRabbits().size());
|
||||
assertTrue("Poor killed rabbit can't run", forest.getDeadRabbits().contains(rabbit));
|
||||
assertEquals("One dead rabbit", 1, forest.getDeadRabbits().size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSavedRabbitSuccess() {
|
||||
Forest forest = new Forest(10, 1, 1, 1);
|
||||
Rabbit rabbit = forest.getRabbits().get(0);
|
||||
forest.savedRabbit(rabbit);
|
||||
|
||||
assertFalse("Poor saved rabbit still running", forest.getRabbits().contains(rabbit));
|
||||
assertTrue("Lucky rabbit can't run", forest.getSavedRabbits().contains(rabbit));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetRabbitsInRangeSuccess() {
|
||||
Hunter hunter = new Hunter(new Point(0,0), 10);
|
||||
Forest forest = new Forest(10, 1, 2, 2);
|
||||
forest.getRabbits().get(0).getLocation().setLocation(0, 5); // First rabbit in range
|
||||
forest.getRabbits().get(1).getLocation().setLocation(0, 15); // Seconde one out of range
|
||||
|
||||
List<Rabbit> rabbitsInRange = forest.getRabbitsInRange(hunter);
|
||||
assertEquals("One rabbit in range", 1, rabbitsInRange.size());
|
||||
assertTrue("First rabbit in range", rabbitsInRange.contains(forest.getRabbits().get(0)));
|
||||
assertFalse("Second rabbit out of range", rabbitsInRange.contains(forest.getRabbits().get(1)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetNearestBurrowFirst() {
|
||||
Hunter hunter = new Hunter(new Point(0, 1), 10);
|
||||
Forest forest = new Forest(10, 1, 2, 1);
|
||||
forest.getBurrows().get(0).getLocation().setLocation(7, 2);
|
||||
forest.getBurrows().get(1).getLocation().setLocation(9, 0);
|
||||
Rabbit rabbit = forest.getRabbits().get(0);
|
||||
rabbit.getLocation().setLocation(4, 1);
|
||||
|
||||
assertEquals("Second burrow is nearest from rabbit", forest.getBurrows().get(0), forest.getNearestBurrow(hunter, rabbit));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetNearestBurrowSecond() {
|
||||
Hunter hunter = new Hunter(new Point(0, 1), 10);
|
||||
Forest forest = new Forest(10, 1, 2, 1);
|
||||
forest.getBurrows().get(0).getLocation().setLocation(9, 0);
|
||||
forest.getBurrows().get(1).getLocation().setLocation(7, 2);
|
||||
Rabbit rabbit = forest.getRabbits().get(0);
|
||||
rabbit.getLocation().setLocation(4, 1);
|
||||
|
||||
assertEquals("Second burrow is nearest from rabbit", forest.getBurrows().get(1), forest.getNearestBurrow(hunter, rabbit));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetNearestBurrowWorstIsBetter() {
|
||||
Hunter hunter = new Hunter(new Point(0, 1), 10);
|
||||
Forest forest = new Forest(10, 1, 2, 1);
|
||||
forest.getBurrows().get(0).getLocation().setLocation(7, 2);
|
||||
forest.getBurrows().get(1).getLocation().setLocation(3, 2);
|
||||
Rabbit rabbit = forest.getRabbits().get(0);
|
||||
rabbit.getLocation().setLocation(4, 1);
|
||||
|
||||
assertEquals("Second burrow is nearest from rabbit", forest.getBurrows().get(1), forest.getNearestBurrow(hunter, rabbit));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetNearestBurrowNotVisited() {
|
||||
Hunter hunter = new Hunter(new Point(0, 1), 10);
|
||||
Forest forest = new Forest(10, 1, 2, 1);
|
||||
forest.getBurrows().get(0).getLocation().setLocation(7, 2);
|
||||
forest.getBurrows().get(1).getLocation().setLocation(9, 0);
|
||||
Rabbit rabbit = forest.getRabbits().get(0);
|
||||
rabbit.getLocation().setLocation(4, 1);
|
||||
rabbit.setRefuge(forest.getBurrows().get(0));
|
||||
|
||||
assertEquals("Second burrow was not visited by the rabbit", forest.getBurrows().get(1), forest.getNearestBurrow(hunter, rabbit));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEscapeScared() {
|
||||
Hunter hunter = new Hunter(new Point(3, 2), 10);
|
||||
Forest forest = new Forest(10, 1, 1, 1);
|
||||
Rabbit rabbit = forest.getRabbits().get(0);
|
||||
rabbit.getLocation().setLocation(6, 3);
|
||||
rabbit.setScared(true);
|
||||
|
||||
forest.escape(hunter, rabbit);
|
||||
Burrow burrow = forest.getBurrows().get(0);
|
||||
assertEquals("Right location X", burrow.getLocation().getX(), rabbit.getDestination().getX(), 0);
|
||||
assertEquals("Right location Y", burrow.getLocation().getY(), rabbit.getDestination().getY(), 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEscapeNotScared() {
|
||||
Hunter hunter = new Hunter(new Point(3, 2), 10);
|
||||
Forest forest = new Forest(10, 1, 2, 1);
|
||||
Rabbit rabbit = forest.getRabbits().get(0);
|
||||
rabbit.getLocation().setLocation(6, 3);
|
||||
|
||||
forest.escape(hunter, rabbit);
|
||||
|
||||
assertEquals("Right location X", 9, rabbit.getDestination().getX(), 0);
|
||||
assertEquals("Right location Y", 4, rabbit.getDestination().getY(), 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEscapeNotScaredOutOfForest() {
|
||||
Hunter hunter = new Hunter(new Point(5, 3), 10);
|
||||
Forest forest = new Forest(10, 1, 2, 1);
|
||||
Rabbit rabbit = forest.getRabbits().get(0);
|
||||
rabbit.getLocation().setLocation(2, 2);
|
||||
|
||||
forest.escape(hunter, rabbit);
|
||||
|
||||
assertEquals("Right location X", 0, rabbit.getDestination().getX(), 0);
|
||||
assertEquals("Right location Y", 1, rabbit.getDestination().getY(), 0);
|
||||
}
|
||||
}
|
||||
108
src/test/java/fr/pavnay/rabbits/model/HunterTest.java
Normal file
108
src/test/java/fr/pavnay/rabbits/model/HunterTest.java
Normal file
@@ -0,0 +1,108 @@
|
||||
package fr.pavnay.rabbits.model;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.awt.Point;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
public class HunterTest {
|
||||
|
||||
@Test
|
||||
public void testInRangeSuccess() {
|
||||
Hunter hunter = new Hunter(new Point(0, 0), 10);
|
||||
Rabbit rabbit = new Rabbit(new Point(10, 0));
|
||||
assertTrue("Rabbit is in hunter range", hunter.isInRange(rabbit));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInRangeFailure() {
|
||||
Hunter hunter = new Hunter(new Point(0, 0), 10);
|
||||
Rabbit rabbit = new Rabbit(new Point(11, 0));
|
||||
assertFalse("Rabbit is out of hunter range", hunter.isInRange(rabbit));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testShootSuccess() {
|
||||
Hunter hunter = new Hunter(new Point(0, 0), 10);
|
||||
Rabbit rabbit = new Rabbit(new Point(0, 0));
|
||||
assertTrue("Rabbit is close to the hunter. Shot successfully", hunter.shoot(rabbit));
|
||||
assertEquals("Hunter's ammos decreases", 9, hunter.getAmmos());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testShootNoMoreAmmosFailure() {
|
||||
Hunter hunter = new Hunter(new Point(0, 0), 10);
|
||||
Rabbit rabbit = new Rabbit(new Point(0, 0));
|
||||
hunter.shoot(rabbit);
|
||||
hunter.shoot(rabbit);
|
||||
hunter.shoot(rabbit);
|
||||
hunter.shoot(rabbit);
|
||||
hunter.shoot(rabbit);
|
||||
hunter.shoot(rabbit);
|
||||
hunter.shoot(rabbit);
|
||||
hunter.shoot(rabbit);
|
||||
hunter.shoot(rabbit);
|
||||
hunter.shoot(rabbit);
|
||||
assertFalse("No more ammos. Shot failure", hunter.shoot(rabbit));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testShootFailure() {
|
||||
Hunter hunter = new Hunter(new Point(0, 0), 10);
|
||||
Rabbit rabbit = new Rabbit(new Point(10, 0));
|
||||
assertFalse("Rabbit is out of hunter's range. Shot failure", hunter.shoot(rabbit));
|
||||
assertEquals("Hunter's ammos decreases", 9, hunter.getAmmos());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetAccuracyRate() {
|
||||
Hunter hunter = new Hunter(new Point(0, 0), 10);
|
||||
Rabbit rabbit = new Rabbit(new Point(5, 0));
|
||||
assertEquals("Hunter's half rate to shot", hunter.getAccuracyRate(rabbit), 0.5, 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetAccuracyRateHalfAmmo() {
|
||||
Hunter hunter = new Hunter(new Point(0, 0), 10);
|
||||
Rabbit rabbit = new Rabbit(new Point(5, 0));
|
||||
hunter.setAmmos(5);
|
||||
assertEquals("Hunter's half rate to shot", hunter.getAccuracyRate(rabbit), 0.475, 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetAccuracyRateHalfHungryLevel() {
|
||||
Hunter hunter = new Hunter(new Point(0, 0), 10);
|
||||
Rabbit rabbit = new Rabbit(new Point(5, 0));
|
||||
hunter.setHungryLevel(5);
|
||||
assertEquals("Hunter's half hungry level", hunter.getAccuracyRate(rabbit), 0.45, 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetAccuracyRateFullHungryLevel() {
|
||||
Hunter hunter = new Hunter(new Point(0, 0), 10);
|
||||
Rabbit rabbit = new Rabbit(new Point(5, 0));
|
||||
hunter.setHungryLevel(10);
|
||||
assertEquals("Hunter's half hungry level", hunter.getAccuracyRate(rabbit), 0.4, 0.001);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetAccuracyRateHalfAmmosHalfHungryLevel() {
|
||||
Hunter hunter = new Hunter(new Point(0, 0), 10);
|
||||
Rabbit rabbit = new Rabbit(new Point(5, 0));
|
||||
hunter.setAmmos(5);
|
||||
hunter.setHungryLevel(5);
|
||||
assertEquals("Hunter's half hungry level", hunter.getAccuracyRate(rabbit), 0.425, 0.001);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetAccuracyRateHalfAmmosFullHungryLevel() {
|
||||
Hunter hunter = new Hunter(new Point(0, 0), 10);
|
||||
Rabbit rabbit = new Rabbit(new Point(5, 0));
|
||||
hunter.setAmmos(5);
|
||||
hunter.setHungryLevel(10);
|
||||
assertEquals("Hunter's half hungry level", hunter.getAccuracyRate(rabbit), 0.375, 0);
|
||||
}
|
||||
}
|
||||
29
src/test/java/fr/pavnay/rabbits/model/RabbitTest.java
Normal file
29
src/test/java/fr/pavnay/rabbits/model/RabbitTest.java
Normal file
@@ -0,0 +1,29 @@
|
||||
package fr.pavnay.rabbits.model;
|
||||
|
||||
import java.awt.Point;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import fr.pavnay.rabbits.model.enums.Speed;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
public class RabbitTest {
|
||||
|
||||
@Test
|
||||
public void testSlowDown() {
|
||||
Rabbit rabbit = new Rabbit(new Point(0,0));
|
||||
rabbit.setSpeed(Speed.MEDIUM.getSpeed());
|
||||
rabbit.slowDown();
|
||||
assertEquals("Rabbit slow down", Speed.MEDIUM.getSpeed() - 1, rabbit.getSpeed());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSlowDownStopped() {
|
||||
Rabbit rabbit = new Rabbit(new Point(0,0));
|
||||
rabbit.setSpeed(Speed.SLOW.getSpeed());
|
||||
rabbit.slowDown();
|
||||
rabbit.slowDown();
|
||||
assertEquals("Rabbit stopped", Speed.STOPPED.getSpeed(), rabbit.getSpeed());
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user