From 655ac88f4e73b2df532a451aedf5a561ea1b0d2c Mon Sep 17 00:00:00 2001 From: Pacien TRAN-GIRARD Date: Sat, 21 Nov 2015 10:36:18 +0100 Subject: Import project structure --- src/ch/epfl/maze/tests/AnimalTest.java | 100 ++++++++++ src/ch/epfl/maze/tests/Competition.java | 163 +++++++++++++++ src/ch/epfl/maze/tests/DaedalusTest.java | 123 ++++++++++++ src/ch/epfl/maze/tests/GhostsTest.java | 149 ++++++++++++++ src/ch/epfl/maze/tests/MazeTest.java | 91 +++++++++ src/ch/epfl/maze/tests/WorldTest.java | 330 +++++++++++++++++++++++++++++++ src/ch/epfl/maze/tests/ZooTest.java | 209 ++++++++++++++++++++ 7 files changed, 1165 insertions(+) create mode 100644 src/ch/epfl/maze/tests/AnimalTest.java create mode 100644 src/ch/epfl/maze/tests/Competition.java create mode 100644 src/ch/epfl/maze/tests/DaedalusTest.java create mode 100644 src/ch/epfl/maze/tests/GhostsTest.java create mode 100644 src/ch/epfl/maze/tests/MazeTest.java create mode 100644 src/ch/epfl/maze/tests/WorldTest.java create mode 100644 src/ch/epfl/maze/tests/ZooTest.java (limited to 'src/ch/epfl/maze/tests') diff --git a/src/ch/epfl/maze/tests/AnimalTest.java b/src/ch/epfl/maze/tests/AnimalTest.java new file mode 100644 index 0000000..c4c9220 --- /dev/null +++ b/src/ch/epfl/maze/tests/AnimalTest.java @@ -0,0 +1,100 @@ +package ch.epfl.maze.tests; + +import junit.framework.TestCase; + +import org.junit.Test; + +import ch.epfl.maze.physical.Animal; +import ch.epfl.maze.util.Direction; +import ch.epfl.maze.util.Vector2D; + +/** + * Test case for {@code Animal} implementation. + * + */ + +public class AnimalTest extends TestCase { + + /** + * Test case for {@code getPosition()}. + */ + + @Test + public void testGetPosition() { + Animal animal = new MockAnimal(new Vector2D(2, 1)); + + // checks getPosition() + assertEquals(new Vector2D(2, 1), animal.getPosition()); + } + + /** + * Test case for {@code setPosition(Vector2D position)}. + */ + + @Test + public void testSetPosition() { + Animal animal = new MockAnimal(new Vector2D(2, 1)); + + // checks setPosition(Vector2D position) + animal.setPosition(new Vector2D(3, 5)); + assertEquals(new Vector2D(3, 5), animal.getPosition()); + } + + /** + * Test case for {@code update(Direction dir)}. + */ + + @Test + public void testUpdate() { + Animal animal = new MockAnimal(new Vector2D(2, 1)); + + // checks update(Direction dir) with NONE + animal.update(Direction.NONE); + assertEquals(new Vector2D(2, 1), animal.getPosition()); + + // checks update(Direction dir) with DOWN + animal.update(Direction.DOWN); + assertEquals(new Vector2D(2, 2), animal.getPosition()); + + // checks update(Direction dir) with UP + animal.update(Direction.UP); + assertEquals(new Vector2D(2, 1), animal.getPosition()); + + // checks update(Direction dir) with RIGHT + animal.update(Direction.RIGHT); + assertEquals(new Vector2D(3, 1), animal.getPosition()); + + // checks update(Direction dir) with LEFT + animal.update(Direction.LEFT); + assertEquals(new Vector2D(2, 1), animal.getPosition()); + } + + /** + * Mock class that makes {@code Animal} concrete. + * + */ + + private class MockAnimal extends Animal { + + /** + * Creates a concrete instance of the {@code Animal} class. + * + * @param labyrinth + * Actual maze + */ + + public MockAnimal(Vector2D position) { + super(position); + } + + @Override + public Direction move(Direction[] choices) { + return null; + } + + @Override + public Animal copy() { + return null; + } + } +} diff --git a/src/ch/epfl/maze/tests/Competition.java b/src/ch/epfl/maze/tests/Competition.java new file mode 100644 index 0000000..4ed42b6 --- /dev/null +++ b/src/ch/epfl/maze/tests/Competition.java @@ -0,0 +1,163 @@ +package ch.epfl.maze.tests; + +import static org.junit.Assert.assertTrue; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.junit.BeforeClass; +import org.junit.Test; + +import ch.epfl.maze.physical.Animal; +import ch.epfl.maze.physical.Maze; +import ch.epfl.maze.physical.zoo.Bear; +import ch.epfl.maze.physical.zoo.Hamster; +import ch.epfl.maze.physical.zoo.Monkey; +import ch.epfl.maze.physical.zoo.Mouse; +import ch.epfl.maze.physical.zoo.Panda; +import ch.epfl.maze.physical.zoo.SpaceInvader; +import ch.epfl.maze.simulation.MazeSimulation; +import ch.epfl.maze.simulation.Simulation; +import ch.epfl.maze.util.LabyrinthGenerator; + +/** + * Competition of the {@code SpaceInvader} against the other animals. + *

+ * The rules are the following : + *

+ * + */ + +public class Competition { + + static final String COMPETITION_MAZE_FILE = "labyrinth.txt"; + static final int NUMBER_OF_ROUNDS = 1000; + static HashMap rivalries; + + /** + * Launches the competition between the {@code SpaceInvader} and the other + * animals. + */ + + @BeforeClass + public static void setUpClass() { + int[][] labyrinth = LabyrinthGenerator.readFromFile(COMPETITION_MAZE_FILE); + Maze m = new Maze(labyrinth); + Simulation simulation = new MazeSimulation(m); + + // adds a Mouse + m.addAnimal(new Mouse(m.getStart())); + + // adds a Monkey + m.addAnimal(new Monkey(m.getStart())); + + // adds a Hamster + m.addAnimal(new Hamster(m.getStart())); + + // adds a Bear (if coded) + // m.addAnimal(new Bear(m.getStart())); + + // adds a Panda + m.addAnimal(new Panda(m.getStart())); + + // adds a Space Invader + m.addAnimal(new SpaceInvader(m.getStart())); + + rivalries = new HashMap(); + rivalries.put("Mouse", 0); + rivalries.put("Hamster", 0); + rivalries.put("Monkey", 0); + //rivalries.put("Bear", 0); // if coded + rivalries.put("Panda", 0); + + System.out.print("Launching competition, please wait... "); + for (int i = 0; i < NUMBER_OF_ROUNDS; i++) { + simulation.restart(); + while (!simulation.isOver()) { + simulation.move(null); + } + + int result = MazeSimulation.COUNTER_LIMIT; + Map> arrivalTimes = simulation.getArrivalTimes(); + for (Map.Entry> entry : arrivalTimes.entrySet()) { + for (Animal a : entry.getValue()) { + if (a.getClass() == SpaceInvader.class) { + result = entry.getKey(); + } + } + } + + for (Map.Entry> entry : arrivalTimes.entrySet()) { + for (Animal a : entry.getValue()) { + String animalName = a.getClass().getSimpleName(); + if (!"SpaceInvader".equals(animalName)) { + int score = rivalries.get(animalName); + int adversary = entry.getKey(); + if (adversary < result) { + rivalries.put(animalName, --score); + } else if (adversary > result) { + rivalries.put(animalName, ++score); + } + } + } + } + } + System.out.println("done !"); + } + + /** + * Determines if the {@code SpaceInvader} has beaten the {@code Mouse}. + */ + + @Test + public void testVSMouse() { + assertTrue("The SpaceInvader has not beaten the Mouse", rivalries.get("Mouse") > 0); + } + + /** + * Determines if the {@code SpaceInvader} has beaten the {@code Hamster}. + */ + + @Test + public void testVSHamster() { + assertTrue("The SpaceInvader has not beaten the Hamster", rivalries.get("Hamster") > 0); + } + + /** + * Determines if the {@code SpaceInvader} has beaten the {@code Monkey}. + */ + + @Test + public void testVSMonkey() { + assertTrue("The SpaceInvader has not beaten the Monkey", rivalries.get("Monkey") > 0); + } + + /** + * Determines if the {@code SpaceInvader} has beaten the {@code Bear}. + */ + + @Test + public void testVSBear() { + assertTrue("The SpaceInvader has not beaten the Bear", rivalries.get("Bear") > 0); + } + + /** + * Determines if the {@code SpaceInvader} has beaten the {@code Panda}. + */ + + @Test + public void testVSPanda() { + assertTrue("The SpaceInvader has not beaten the Panda", rivalries.get("Panda") > 0); + } +} diff --git a/src/ch/epfl/maze/tests/DaedalusTest.java b/src/ch/epfl/maze/tests/DaedalusTest.java new file mode 100644 index 0000000..34e302f --- /dev/null +++ b/src/ch/epfl/maze/tests/DaedalusTest.java @@ -0,0 +1,123 @@ +package ch.epfl.maze.tests; + +import junit.framework.TestCase; + +import org.junit.Test; + +import ch.epfl.maze.physical.Animal; +import ch.epfl.maze.physical.Daedalus; +import ch.epfl.maze.physical.Predator; +import ch.epfl.maze.physical.Prey; +import ch.epfl.maze.physical.pacman.Blinky; +import ch.epfl.maze.physical.pacman.PacMan; +import ch.epfl.maze.util.Vector2D; + +/** + * Test case for {@code Daedalus} implementation. + * + */ + +public class DaedalusTest extends TestCase { + + private final static int[][] LABYRINTH = { + { 1, 1, 1, 1, 1 }, + { 1, 0, 0, 0, 1 }, + { 1, 1, 1, 1, 1 } + }; + + /** + * Test case for several methods in {@code Daedalus}. + */ + + @Test + public void testGeneral() { + Daedalus daedalus = new Daedalus(LABYRINTH); + + // initial maze should be solved + assertTrue("Initial maze should be solved", daedalus.isSolved()); + assertTrue("Initial maze should NOT have animals in it", + daedalus.getAnimals().size() == 0); + + // adds dummy predator and prey + Predator dummyPred = new Blinky(new Vector2D(3, 1)); + Prey dummyPrey = new PacMan(new Vector2D(3, 1)); + daedalus.addPredator(dummyPred); + daedalus.addPrey(dummyPrey); + + assertTrue("Daedalus Predators should contain one Predator", + daedalus.getPredators().size() == 1); + assertTrue("Daedalus Preys should contain one Prey", + daedalus.getPreys().size() == 1); + assertTrue("Daedalus Animals should contain one Predator and one Prey", + daedalus.getAnimals().size() == 2); + + // retrieves dummy predator and prey from Daedalus + Predator retrievedPred = daedalus.getPredators().get(0); + Prey retrievedPrey = daedalus.getPreys().get(0); + + assertTrue("Daedalus should contain the added Blinky", + daedalus.hasPredator(dummyPred)); + assertTrue("Daedalus should contain the added PacMan", + daedalus.hasPrey(dummyPrey)); + assertTrue("Predator inside the Daedalus should be the same as Predator added", + retrievedPred == dummyPred); + assertTrue("Prey inside the Daedalus should be the same as Prey added", + retrievedPrey == dummyPrey); + assertFalse("Daedalus with one Prey should NOT be solved", + daedalus.isSolved()); + + // removes dummy predator + daedalus.removePredator(dummyPred); + daedalus.removePrey(dummyPrey); + + assertFalse("Daedalus should NOT contain Blinky anymore", + daedalus.hasPredator(dummyPred)); + assertFalse("Daedalus should NOT contain PacMan anymore", + daedalus.hasPrey(dummyPrey)); + assertTrue("Daedalus should NOT have anymore Predator in it", + daedalus.getPredators().size() == 0); + assertTrue("Daedalus should NOT have anymore Prey in it", + daedalus.getPreys().size() == 0); + assertTrue("Daedalus should NOT have anymore Animal in it", + daedalus.getAnimals().size() == 0); + assertTrue("Daedalus without any animal should be solved", daedalus.isSolved()); + } + + /** + * Test case for {@code reset()}. + */ + + @Test + public void testReset() { + Daedalus daedalus = new Daedalus(LABYRINTH); + + // adds dummy predator and prey + Predator dummyPred = new Blinky(new Vector2D(3, 1)); + Prey dummyPrey = new PacMan(new Vector2D(3, 1)); + daedalus.addPredator(dummyPred); + daedalus.addPrey(dummyPrey); + + // removes dummy animal + daedalus.removePredator(dummyPred); + daedalus.removePrey(dummyPrey); + + // checks reset method + daedalus.reset(); + + assertFalse("Daedalus should NOT be solved anymore", + daedalus.isSolved()); + assertTrue("Daedalus should contain Blinky again", + daedalus.getPredators().size() == 1); + assertTrue("Daedalus should contain PacMan again", + daedalus.getPreys().size() == 1); + assertTrue("Daedalus should contain Blinky and PacMan again", + daedalus.getAnimals().size() == 2); + + // checks that predator in maze is not null + Animal retrievedPred = daedalus.getAnimals().get(0); + Animal retrievedPrey = daedalus.getAnimals().get(1); + + assertTrue("Animals in Daedalus should be not null", retrievedPred != null); + assertTrue("Animals in Daedalus should be not null", retrievedPrey != null); + } +} diff --git a/src/ch/epfl/maze/tests/GhostsTest.java b/src/ch/epfl/maze/tests/GhostsTest.java new file mode 100644 index 0000000..4929b5d --- /dev/null +++ b/src/ch/epfl/maze/tests/GhostsTest.java @@ -0,0 +1,149 @@ +package ch.epfl.maze.tests; + +import junit.framework.TestCase; + +import org.junit.Test; + +import ch.epfl.maze.graphics.Display; +import ch.epfl.maze.physical.Animal; +import ch.epfl.maze.physical.Daedalus; +import ch.epfl.maze.physical.Prey; +import ch.epfl.maze.physical.pacman.Blinky; +import ch.epfl.maze.physical.pacman.Clyde; +import ch.epfl.maze.physical.pacman.Inky; +import ch.epfl.maze.physical.pacman.Pinky; +import ch.epfl.maze.simulation.DaedalusSimulation; +import ch.epfl.maze.simulation.Simulation; +import ch.epfl.maze.util.Direction; +import ch.epfl.maze.util.LabyrinthGenerator; +import ch.epfl.maze.util.Vector2D; + +/** + * Test suite for ghosts implementation. + * + */ + +public class GhostsTest extends TestCase { + + /** + * Tests the behavior of Blinky. + *

+ * In this case, Blinky should go straight to the PacMan's position. + */ + + @Test + public void testBlinky() { + int[][] labyrinth = LabyrinthGenerator.getDebugBlinky(); + + Daedalus d = new Daedalus(labyrinth); + Simulation simulation = new DaedalusSimulation(d); + + d.addPredator(new Blinky(new Vector2D(6, 1))); + d.addPrey(new PacMan(new Vector2D(1, 5), false)); + + Display display = new Display(simulation); + display.setDebug(true); + display.run(); + } + + /** + * Tests the behavior of Pinky. + *

+ * In this case, Pinky should go back and forth. + */ + + @Test + public void testPinky() { + int[][] labyrinth = LabyrinthGenerator.getDebugPinky(); + + Daedalus d = new Daedalus(labyrinth); + Simulation simulation = new DaedalusSimulation(d); + + d.addPredator(new Pinky(new Vector2D(1, 1))); + d.addPrey(new PacMan(new Vector2D(6, 3), true)); + + Display display = new Display(simulation); + display.setDebug(true); + display.run(); + } + + /** + * Tests the behavior of Inky. + *

+ * In this case, Inky should target the red tile of the labyrinth. + */ + + @Test + public void testInky() { + int[][] labyrinth = LabyrinthGenerator.getDebugInky(); + + Daedalus d = new Daedalus(labyrinth); + Simulation simulation = new DaedalusSimulation(d); + + d.addPredator(new Inky(new Vector2D(9, 9))); + d.addPredator(new Blinky(new Vector2D(7, 7))); + d.addPrey(new PacMan(new Vector2D(5, 5), false)); + + Display display = new Display(simulation); + display.setDebug(true); + display.run(); + } + + /** + * Tests the behavior of Clyde. + *

+ * In this case, Clyde should go back and forth. + */ + + @Test + public void testClyde() { + int[][] labyrinth = LabyrinthGenerator.getDebugClyde(); + + Daedalus d = new Daedalus(labyrinth); + Simulation simulation = new DaedalusSimulation(d); + + d.addPredator(new Clyde(new Vector2D(1, 3))); + d.addPrey(new PacMan(new Vector2D(8, 3), false)); + + Display display = new Display(simulation); + display.setDebug(true); + display.run(); + } + + /** + * Mock class to create a dummy PacMan in our testing unit. + * + */ + + private class PacMan extends Prey { + + private boolean mMoves; + + /** + * Constructs a dummy PacMan that can move back and forth. + * + * @param position + * Starting position of PacMan in the labyrinth + * @param moves + * Determines if the dummy PacMan will move back and forth + */ + + public PacMan(Vector2D position, boolean moves) { + super(position); + mMoves = moves; + } + + @Override + public Direction move(Direction[] choices, Daedalus daedalus) { + if (mMoves) { + return getPosition().getX() % 2 == 0 ? Direction.RIGHT : Direction.LEFT; + } + return Direction.NONE; + } + + @Override + public Animal copy() { + return new PacMan(getPosition(), mMoves); + } + } +} diff --git a/src/ch/epfl/maze/tests/MazeTest.java b/src/ch/epfl/maze/tests/MazeTest.java new file mode 100644 index 0000000..09cbd01 --- /dev/null +++ b/src/ch/epfl/maze/tests/MazeTest.java @@ -0,0 +1,91 @@ +package ch.epfl.maze.tests; + +import junit.framework.TestCase; + +import org.junit.Test; + +import ch.epfl.maze.physical.Animal; +import ch.epfl.maze.physical.Maze; +import ch.epfl.maze.physical.zoo.Mouse; +import ch.epfl.maze.util.Vector2D; + +/** + * Test case for {@code Maze} implementation. + * + */ + +public class MazeTest extends TestCase { + + private final static int[][] LABYRINTH = { + { 1, 1, 1, 3, 1 }, + { 1, 0, 0, 0, 1 }, + { 1, 2, 1, 1, 1 } + }; + + /** + * Test case for several methods in {@code Maze}. + */ + + @Test + public void testGeneral() { + Maze maze = new Maze(LABYRINTH); + + // initial maze should be solved + assertTrue("Initial maze should be solved", maze.isSolved()); + assertTrue("Initial maze should NOT have animals in it", + maze.getAnimals().size() == 0); + + // adds dummy animal + Animal dummy = new Mouse(new Vector2D(3, 0)); + maze.addAnimal(dummy); + + assertTrue("Maze Animals should contain one Animal", + maze.getAnimals().size() == 1); + + // retrieves dummy anima from Maze + Animal retrieved = maze.getAnimals().get(0); + + assertTrue("Maze should contain the Mouse, even at the exit", + maze.hasAnimal(dummy)); + assertTrue("Mouse inside the Maze should be the same as Mouse added", + retrieved == dummy); + assertFalse("Maze with one Mouse even at the exit should NOT be solved", + maze.isSolved()); + + // removes dummy animal + maze.removeAnimal(dummy); + + assertFalse("Maze should NOT contain the Mouse anymore", + maze.hasAnimal(dummy)); + assertTrue("Maze should NOT have anymore Animal in it", + maze.getAnimals().size() == 0); + assertTrue("Maze without any animal should be solved", maze.isSolved()); + } + + /** + * Test case for {@code reset()}. + */ + + @Test + public void testReset() { + Maze maze = new Maze(LABYRINTH); + + // adds dummy animal + Animal dummy = new Mouse(new Vector2D(2, 2)); + maze.addAnimal(dummy); + + // removes dummy animal + maze.removeAnimal(dummy); + + // checks reset method + maze.reset(); + + assertFalse("Maze should NOT be solved anymore", maze.isSolved()); + assertTrue("Maze should contain the Mouse again", maze.getAnimals().size() == 1); + + // checks that animal in maze is not null + Animal retrieved = maze.getAnimals().get(0); + + assertTrue("Animal in Maze should be a Mouse", retrieved != null); + } +} diff --git a/src/ch/epfl/maze/tests/WorldTest.java b/src/ch/epfl/maze/tests/WorldTest.java new file mode 100644 index 0000000..6d551b1 --- /dev/null +++ b/src/ch/epfl/maze/tests/WorldTest.java @@ -0,0 +1,330 @@ +package ch.epfl.maze.tests; + +import static org.junit.Assert.assertArrayEquals; + +import java.util.Arrays; +import java.util.List; + +import junit.framework.TestCase; + +import org.junit.Test; + +import ch.epfl.maze.physical.Animal; +import ch.epfl.maze.physical.World; +import ch.epfl.maze.util.Direction; +import ch.epfl.maze.util.Vector2D; + +/** + * Test case for {@code World} implementation. + * + */ + +public class WorldTest extends TestCase { + + /* sample labyrinth */ + private static final int[][] LABYRINTH_SAMPLE = { + {1, 1, 1, 1, 1, 3, 1}, + {1, 0, 0, 0, 0, 0, 1}, + {1, 2, 1, 1, 1, 1, 1} + }; + + /* constants labyrinth for testing getChoices(Vector2D) */ + private static final int[][] LABYRINTH_STUCK = { + {1, 1, 1}, + {1, 0, 1}, + {1, 1, 1} + }; + private static final int[][] LABYRINTH_CORRIDOR = { + {1, 1, 1, 1, 1, 1}, + {1, 0, 1, 0, 0, 1}, + {1, 0, 1, 1, 1, 1}, + {1, 1, 1, 1, 1, 1} + }; + private static final int[][] LABYRINTH_DOGHNUT = { + {1, 1, 1, 1, 1}, + {1, 0, 0, 0, 1}, + {1, 0, 1, 0, 1}, + {1, 0, 0, 0, 1}, + {1, 1, 1, 1, 1} + }; + private static final int[][] LABYRINTH_SQUARE = { + {1, 1, 1, 1, 1}, + {1, 0, 0, 0, 1}, + {1, 0, 0, 0, 1}, + {1, 0, 0, 0, 1}, + {1, 1, 1, 1, 1} + }; + + /** + * Test case for {@code getTile(int x, int y)}. + */ + + @Test + public void testGetTile() { + World world = new ConcreteWorld(LABYRINTH_SAMPLE); + + // checks if positions are reversed + assertTrue("You reversed the coordinates in your method !", + world.getTile(5, 1) != World.NOTHING); + + // checks every position on the sample labyrinth + assertEquals(World.WALL, world.getTile(0, 0)); + assertEquals(World.FREE, world.getTile(1, 1)); + assertEquals(World.START, world.getTile(1, 2)); + assertEquals(World.EXIT, world.getTile(5, 0)); + assertEquals(World.NOTHING, world.getTile(0, 3)); + } + + /** + * Test case for {@code isFree(int x, int y)}. + */ + + @Test + public void testIsFree() { + World world = new ConcreteWorld(LABYRINTH_SAMPLE); + + // checks FREE, START and EXIT positions + assertTrue("FREE tile should be free", world.isFree(3, 1)); + assertTrue("START tile should be free", world.isFree(1, 2)); + assertTrue("EXIT tile should be free", world.isFree(5, 0)); + + // checks WALL and NOTHING positions + assertFalse("WALL tile should NOT be free", world.isFree(0, 0)); + assertFalse("NOTHING tile should NOT be free", world.isFree(0, 3)); + } + + /** + * Test case for {@code getWidth()}. + */ + + @Test + public void testGetWidth() { + World world = new ConcreteWorld(LABYRINTH_SAMPLE); + + // checks width + assertEquals(7, world.getWidth()); + } + + /** + * Test case for {@code getHeight()}. + */ + + @Test + public void testGetHeight() { + World world = new ConcreteWorld(LABYRINTH_SAMPLE); + + // checks height + assertEquals(3, world.getHeight()); + } + + /** + * Test case for {@code getStart()}. + */ + + @Test + public void testGetStart() { + World world = new ConcreteWorld(LABYRINTH_SAMPLE); + + // checks starting position + assertEquals(new Vector2D(1, 2), world.getStart()); + } + + /** + * Test case for {@code getExit()}. + */ + + @Test + public void testGetExit() { + World world = new ConcreteWorld(LABYRINTH_SAMPLE); + + // checks exiting position + assertEquals(new Vector2D(5, 0), world.getExit()); + } + + // ========================================================== + + /** + * Test case for {@code getChoices(Vector2D position)} + * when there are 0 choices. + */ + + @Test + public void testZeroChoice() { + World world = new ConcreteWorld(LABYRINTH_STUCK); + Direction[] choices = world.getChoices(new Vector2D(1, 1)); + + // checks that the only choice is not to move + checkChoices(choices, new Direction[] { Direction.NONE }); + } + + /** + * Test case for {@code getChoices(Vector2D position)} + * when there is 1 choice. + */ + + @Test + public void testOneChoice() { + World world = new ConcreteWorld(LABYRINTH_CORRIDOR); + Direction[] choices; + + // checks when the only choice is to move down + choices = world.getChoices(new Vector2D(1, 1)); + checkChoices(choices, new Direction[] { Direction.DOWN }); + + // checks when the only choice is to move up + choices = world.getChoices(new Vector2D(1, 2)); + checkChoices(choices, new Direction[] { Direction.UP }); + + // checks when the only choice is to move right + choices = world.getChoices(new Vector2D(3, 1)); + checkChoices(choices, new Direction[] { Direction.RIGHT }); + + // checks when the only choice is to move left + choices = world.getChoices(new Vector2D(4, 1)); + checkChoices(choices, new Direction[] { Direction.LEFT }); + } + + /** + * Test case for {@code getChoices(Vector2D position)} + * when there are 2 choices. + */ + + @Test + public void testTwoChoices() { + World world = new ConcreteWorld(LABYRINTH_DOGHNUT); + Direction[] choices; + + // checks when the available choices are to move down and right + choices = world.getChoices(new Vector2D(1, 1)); + checkChoices(choices, + new Direction[] { Direction.DOWN, Direction.RIGHT }); + + // checks when the available choices are to move down and up + choices = world.getChoices(new Vector2D(1, 2)); + checkChoices(choices, + new Direction[] { Direction.DOWN, Direction.UP }); + + // checks when the available choices are to move up and right + choices = world.getChoices(new Vector2D(1, 3)); + checkChoices(choices, + new Direction[] { Direction.UP, Direction.RIGHT }); + + // checks when the available choices are to move right and left + choices = world.getChoices(new Vector2D(2, 1)); + checkChoices(choices, + new Direction[] { Direction.RIGHT, Direction.LEFT }); + + // checks when the available choices are to move down and left + choices = world.getChoices(new Vector2D(3, 1)); + checkChoices(choices, + new Direction[] { Direction.DOWN, Direction.LEFT }); + + // checks when the available choices are to move up and left + choices = world.getChoices(new Vector2D(3, 3)); + checkChoices(choices, + new Direction[] { Direction.UP, Direction.LEFT }); + } + + /** + * Test case for {@code getChoices(Vector2D position)} + * when there are 3 choices. + */ + + @Test + public void testThreeChoices() { + World world = new ConcreteWorld(LABYRINTH_SQUARE); + Direction[] choices; + + // checks when the available choices are to move right, left, and down + choices = world.getChoices(new Vector2D(2, 1)); + checkChoices(choices, + new Direction[] { Direction.RIGHT, Direction.LEFT, Direction.DOWN }); + + // checks when the available choices are to move right, left, and up + choices = world.getChoices(new Vector2D(2, 3)); + checkChoices(choices, + new Direction[] { Direction.RIGHT, Direction.LEFT, Direction.UP }); + + // checks when the available choices are to move down, up, and right + choices = world.getChoices(new Vector2D(1, 2)); + checkChoices(choices, + new Direction[] { Direction.DOWN, Direction.UP, Direction.RIGHT }); + + // checks when the available choices are to move down, up, and left + choices = world.getChoices(new Vector2D(3, 2)); + checkChoices(choices, + new Direction[] { Direction.DOWN, Direction.UP, Direction.LEFT }); + } + + /** + * Test case for {@code getChoices(Vector2D position)} + * when there are 4 choices. + */ + + @Test + public void testFourChoices() { + World world = new ConcreteWorld(LABYRINTH_SQUARE); + Direction[] choices; + + // checks when all the directions are available + choices = world.getChoices(new Vector2D(2, 2)); + checkChoices(choices, + new Direction[] { Direction.DOWN, Direction.UP, Direction.RIGHT, Direction.LEFT }); + } + + // ========================================================== + + /** + * Checks if there are the same choices in {@code result} as in {@code + * expected} + * + * @param result + * The choices computed with method {@code getChoices(position)} + * @param expected + * The choices expected to be present + */ + + private void checkChoices(Direction[] result, Direction[] expected) { + // checks that array was initialized + assertNotNull(result); + + // checks whether array has correct length and values + Arrays.sort(result); + Arrays.sort(expected); + assertArrayEquals(expected, result); + } + + /** + * Mock class that makes {@code World} concrete. + * + */ + + private final class ConcreteWorld extends World { + + /** + * Creates a concrete instance of the {@code World} class. + * + * @param labyrinth + * Actual maze + */ + + public ConcreteWorld(int[][] labyrinth) { + super(labyrinth); + } + + @Override + public boolean isSolved() { + return false; + } + + @Override + public void reset() { + // do nothing + } + + @Override + public List getAnimals() { + return null; + } + } +} diff --git a/src/ch/epfl/maze/tests/ZooTest.java b/src/ch/epfl/maze/tests/ZooTest.java new file mode 100644 index 0000000..a86fd73 --- /dev/null +++ b/src/ch/epfl/maze/tests/ZooTest.java @@ -0,0 +1,209 @@ +package ch.epfl.maze.tests; + +import org.junit.Test; + +import ch.epfl.maze.graphics.Display; +import ch.epfl.maze.physical.Maze; +import ch.epfl.maze.physical.zoo.Bear; +import ch.epfl.maze.physical.zoo.Hamster; +import ch.epfl.maze.physical.zoo.Monkey; +import ch.epfl.maze.physical.zoo.Mouse; +import ch.epfl.maze.physical.zoo.Panda; +import ch.epfl.maze.simulation.MazeSimulation; +import ch.epfl.maze.simulation.Simulation; +import ch.epfl.maze.util.LabyrinthGenerator; +import junit.framework.TestCase; + +/** + * Test cases for animals implementation. + * + */ + +public class ZooTest extends TestCase { + + /** + * Tests the behaviour of the Mouse A.I. + *

+ * The Mouse should go forward and never retrace its steps. + */ + + @Test + public void testMouse() { + int[][] labyrinth = LabyrinthGenerator.getDebugMouse(); + + Maze m = new Maze(labyrinth); + Simulation simulation = new MazeSimulation(m); + + m.addAnimal(new Mouse(m.getStart())); + + Display display = new Display(simulation); + display.setDebug(true); + display.run(); + } + + /** + * Tests the behaviour of the Hamster A.I. + *

+ * The Hamster should never revisit a dead-end it has already visited. + */ + + @Test + public void testHamster() { + int[][] labyrinth = LabyrinthGenerator.getDebugHamster(); + + Maze m = new Maze(labyrinth); + Simulation simulation = new MazeSimulation(m); + + m.addAnimal(new Hamster(m.getStart())); + + Display display = new Display(simulation); + display.setDebug(true); + display.run(); + } + + /** + * Tests the behaviour of the Monkey A.I. + *

+ * The Monkey should go directly to the exit without taking any dead-end. + */ + + @Test + public void testMonkey() { + int[][] labyrinth = LabyrinthGenerator.getDebugMonkey(); + + Maze m = new Maze(labyrinth); + Simulation simulation = new MazeSimulation(m); + + m.addAnimal(new Monkey(m.getStart())); + + Display display = new Display(simulation); + display.setDebug(true); + display.run(); + } + + /** + * Tests the behaviour of the Bear A.I. + *

+ * The Bear must follow the entire wall in front of him until the exit. If + * it loops infinitely in this maze, it means that it does not properly + * count the turns it makes. + */ + + @Test + public void testBear1() { + int[][] labyrinth = LabyrinthGenerator.getDebugBear1(); + + Maze m = new Maze(labyrinth); + Simulation simulation = new MazeSimulation(m); + + m.addAnimal(new Bear(m.getStart())); + + Display display = new Display(simulation); + display.setDebug(true); + display.run(); + } + + /** + * Tests the behaviour of the Bear A.I. + *

+ * If the Bear loops infinitely in this maze, it means that it does not + * properly count the turns it makes. + */ + + @Test + public void testBear2() { + int[][] labyrinth = LabyrinthGenerator.getDebugBear2(); + + Maze m = new Maze(labyrinth); + Simulation simulation = new MazeSimulation(m); + + m.addAnimal(new Bear(m.getStart())); + + Display display = new Display(simulation); + display.setDebug(true); + display.run(); + } + + /** + * Tests the behaviour of the Panda A.I. + *

+ * When the Panda comes back to the intersection, then it must leave the + * position marked once and go back into the loop. + */ + + @Test + public void testPanda1() { + int[][] labyrinth = LabyrinthGenerator.getDebugPanda1(); + + Maze m = new Maze(labyrinth); + Simulation simulation = new MazeSimulation(m); + + m.addAnimal(new Panda(m.getStart())); + + Display display = new Display(simulation); + display.setDebug(true); + display.run(); + } + + /** + * Tests the behaviour of the Panda A.I. + *

+ * The Panda must mark the intersection twice only the very last time it + * walks on it. + */ + + @Test + public void testPanda2() { + int[][] labyrinth = LabyrinthGenerator.getDebugPanda2(); + + Maze m = new Maze(labyrinth); + Simulation simulation = new MazeSimulation(m); + + m.addAnimal(new Panda(m.getStart())); + + Display display = new Display(simulation); + display.setDebug(true); + display.run(); + } + + /** + * Tests the behaviour of the Bear A.I versus the Monkey A.I. + *

+ * The Bear should leave the maze while the Monkey should loop infinitely. + */ + + @Test + public void testBearVsMonkey() { + int[][] labyrinth = LabyrinthGenerator.getBearVsMonkey(); + + Maze m = new Maze(labyrinth); + Simulation simulation = new MazeSimulation(m); + + m.addAnimal(new Bear(m.getStart())); + m.addAnimal(new Monkey(m.getStart())); + + Display display = new Display(simulation); + display.run(); + } + + /** + * Tests the behaviour of the Panda A.I versus the Hamster A.I. + *

+ * The Panda should leave the maze earlier than the Hamster with a higher + * probability than the Hamster. + */ + + @Test + public void testPandaVsHamster() { + int[][] labyrinth = LabyrinthGenerator.getPandaVsHamster(); + + Maze m = new Maze(labyrinth); + Simulation simulation = new MazeSimulation(m); + + m.addAnimal(new Panda(m.getStart())); + m.addAnimal(new Hamster(m.getStart())); + + Display display = new Display(simulation); + display.run(); + } +} -- cgit v1.2.3