Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import java.awt.Color;
- import javalib.funworld.World;
- import javalib.funworld.WorldScene;
- import javalib.worldimages.CircleImage;
- import javalib.worldimages.OutlineMode;
- import javalib.worldimages.Posn;
- import javalib.worldimages.RectangleImage;
- import javalib.worldimages.WorldImage;
- import tester.Tester;
- class Utility {
- // pins the given Posn to the nearest tile center
- Posn pin(Posn p) {
- int dx = p.x % 10;
- int x = p.x - dx + 5;
- int dy = p.y % 10;
- int y = p.y - dy + 5;
- return new Posn(x, y);
- }
- }
- class CentipedeWorld extends World {
- /* TEMPLATE
- * Fields:
- * ... this.width ... -- int
- * ... this.height ... -- int
- * ... this.listItems ... -- ILoItem
- * Methods:
- * ... this.makeScene() ... -- WorldScene
- * ... this.onTick() ... -- CentipedeWorld
- * ... this.onMouseClicked(Posn p, String buttonName) ... -- CentipedeWorld
- * Methods of Fields:
- * ... this.listItems.drawItems() ... -- WorldScene
- * ... this.listItems.isOccupied(Posn p) ... -- boolean
- * ... this.listItems.remove(Posn p) ... -- ILoItem
- */
- // the number of pixels in the x- (width) and y- (height) directions
- int width, height;
- // the list of IItem in the world
- ILoItem listItems;
- // constructor
- CentipedeWorld(int width, int height, ILoItem listItems) {
- // throws an exception if the scene bounds aren't within 50 and 800 for width,
- // and 100 and 800 for height
- if (width <= 50 || width >= 800 || height <= 100 || height >= 800) {
- throw new IllegalArgumentException("The game scene size is either too small or too large. "
- + "Please keep game scene limits between 50 and 800 for width, "
- + "and 100 and 800 for height.");
- }
- // initializes the fields
- this.width = width;
- this.height = height;
- this.listItems = listItems;
- }
- // convenience constructor that just takes in the scene dimensions and uses an MtLoItem
- CentipedeWorld(int width, int height) {
- this(width, height, new MtLoItem());
- }
- // displays the current state of the CentipedeWorld
- public WorldScene makeScene() {
- return this.listItems.drawItems(this.getEmptyScene());
- }
- // updates the CentipedeWorld
- public CentipedeWorld onTick() {
- return this;
- }
- // operations for when the left mouse button is clicked
- public CentipedeWorld onMouseClicked(Posn p, String buttonName) {
- Utility util = new Utility();
- Posn pinned = util.pin(p);
- // removes the Item from the current ILoItem if the left mouse is clicked and there is an
- // IItem on the current tile
- if (buttonName.equals("LeftButton") && this.listItems.isOccupied(pinned)) {
- return new CentipedeWorld(this.width, this.height, this.listItems.remove(pinned));
- // adds a new Dandelion if the left mouse is clicked and there is no IItem on the current
- // tile
- } else if (buttonName.equals("LeftButton") && !this.listItems.isOccupied(pinned)) {
- return new CentipedeWorld(this.width, this.height,
- new ConsLoItem(new Dandelion(pinned), this.listItems));
- // adds a new Rock if the right mouse is clicked and there is no IItem on the current tile
- } else if (buttonName.equals("RightButton") && !this.listItems.isOccupied(pinned)) {
- return new CentipedeWorld(this.width, this.height,
- new ConsLoItem(new Rock(util.pin(pinned)), this.listItems));
- // returns the same list if nothing is clicked
- } else {
- return this;
- }
- }
- }
- interface ILoItem {
- // draws this list ILoItem onto the scene
- WorldScene drawItems(WorldScene bgScene);
- // is the given Posn occupied by an IItem in this ILoItem?
- boolean isOccupied(Posn p);
- // removes the IItem with the given Posn from this ILoItem
- ILoItem remove(Posn p);
- }
- class ConsLoItem implements ILoItem {
- /* TEMPLATE
- * Fields:
- * ... this.first ... -- IItem
- * ... this.rest ... -- ILoItem
- * Methods:
- * ... this.drawItems(WorldScene bgScene) ... -- WorldScene
- * ... this.isOccupied(Posn p) ... -- boolean
- * ... this.remove(Posn p) ... -- ILoItem
- * Methods of Fields:
- * ... this.first.drawItem(WorldScene bgScene) ... -- WorldScene
- * ... this.first.isOccupied(Posn p) ... -- boolean
- * ... this.rest.drawItems(WorldScene bgScene) ... -- WorldScene
- * ... this.rest.isOccupied(Posn p) ... -- boolean
- * ... this.rest.remove(Posn p) ... -- ILoItem
- */
- IItem first;
- ILoItem rest;
- // constructor
- ConsLoItem(IItem first, ILoItem rest) {
- this.first = first;
- this.rest = rest;
- }
- // draws this ILoItem onto the given scene
- public WorldScene drawItems(WorldScene bgScene) {
- /* TEMPLATE
- * Everything in ConsLoItem template, including:
- * Parameters:
- * ... bgScene ... -- WorldScene
- * Fields of Parameters:
- * ... bgScene.width ... -- int
- * ... bgScene.height ... -- int
- * Methods of Parameters:
- * ... bgScene.placeImageXY(WorldImage image, int x, int y) ... -- WorldScene
- */
- return this.first.drawItem(this.rest.drawItems(bgScene));
- }
- public boolean isOccupied(Posn p) {
- /* TEMPLATE
- * Everything in ConsLoItem template, including:
- * Parameters:
- * ... p ... -- Posn
- * Fields of Parameters:
- * ... p.x ... -- int
- * ... p.y ... -- int
- * Methods of Parameters:
- */
- return this.first.isOccupied(p) || this.rest.isOccupied(p);
- }
- public ILoItem remove(Posn p) {
- /* TEMPLATE
- * Everything in ConsLoItem template, including:
- * Parameters:
- * ... p ... -- Posn
- * Fields of Parameters:
- * ... p.x ... -- int
- * ... p.y ... -- int
- * Methods of Parameters:
- */
- if (this.first.isOccupied(p)) {
- return this.rest;
- } else {
- return new ConsLoItem(this.first, this.rest.remove(p));
- }
- }
- }
- class MtLoItem implements ILoItem {
- /* TEMPLATE
- * Fields:
- * Methods:
- * ... this.drawItems(WorldScene bgScene) ... -- WorldScene
- * ... this.isOccupied(Posn p) ... -- boolean
- * Methods of Fields:
- */
- // draws the background image onto the given scene
- public WorldScene drawItems(WorldScene bgScene) {
- /* TEMPLATE
- * Everything in MtLoItem template, including:
- * Parameters:
- * ... bgScene ... -- WorldScene
- * Fields of Parameters:
- * ... bgScene.width ... -- int
- * ... bgScene.height ... -- int
- * Methods of Parameters:
- * ... bgScene.placeImageXY(WorldImage image, int x, int y) ... -- WorldScene
- */
- WorldImage bgImage =
- new RectangleImage(bgScene.width, bgScene.height, OutlineMode.SOLID, Color.GREEN);
- return bgScene.placeImageXY(bgImage, bgScene.width / 2, bgScene.height / 2);
- }
- // return false since this list does not have an item
- public boolean isOccupied(Posn p) {
- /* TEMPLATE
- * Everything in MtLoItem template, including:
- * Parameters:
- * ... p ... -- Posn
- * Fields of Parameters:
- * ... p.x ... -- int
- * ... p.y ... -- int
- * Methods of Parameters:
- */
- return false;
- }
- // return this since empty can't be removed
- public ILoItem remove(Posn p) {
- /* TEMPLATE
- * Everything in ConsLoItem template, including:
- * Parameters:
- * ... p ... -- Posn
- * Fields of Parameters:
- * ... p.x ... -- int
- * ... p.y ... -- int
- * Methods of Parameters:
- */
- return this;
- }
- }
- interface IItem {
- // draws this IItem onto the given scene
- WorldScene drawItem(WorldScene bgScene);
- // is the given Posn equal to this IItem's Posn?
- boolean isOccupied(Posn p);
- }
- class Rock implements IItem {
- /* TEMPLATE
- * Fields:
- * ... this.p ... -- Posn
- * ... this.p.x ... -- int
- * ... this.p.y ... -- int
- * Methods:
- * ... this.drawItem(WorldScene bgScene) ... -- WorldScene
- * ... this.isOccupied(Posn p) ... -- boolean
- * Methods on Fields:
- */
- Posn p;
- // constructor
- Rock(Posn p) {
- this.p = p;
- }
- // returns a scene with this Rock placed at its position on top of the given scene
- public WorldScene drawItem(WorldScene bgScene) {
- /* TEMPLATE
- * Everything in Rock template, including:
- * Parameters:
- * ... bgScene ... -- WorldScene
- * Fields of Parameters:
- * ... bgScene.width ... -- int
- * ... bgScene.height ... -- int
- * Methods of Parameters:
- * ... bgScene.placeImageXY(WorldImage image, int x, int y) ... -- WorldScene
- */
- WorldImage rockImage = new CircleImage(5, OutlineMode.SOLID, Color.GRAY);
- return bgScene.placeImageXY(rockImage, this.p.x, this.p.y);
- }
- public boolean isOccupied(Posn p) {
- /* TEMPLATE
- * Everything in Rock template, including:
- * Parameters:
- * ... p ... -- Posn
- * Fields of Parameters:
- * ... p.x ... -- int
- * ... p.y ... -- int
- * Methods of Parameters:
- */
- return this.p.x == p.x && this.p.y == p.y;
- }
- }
- class Dandelion implements IItem {
- /* TEMPLATE
- * Fields:
- * ... this.p ... -- Posn
- * ... this.p.x ... -- int
- * ... this.p.y ... -- int
- * Methods:
- * ... this.drawItem(WorldScene bgScene) ... -- WorldScene
- * ... this.isOccupied(Posn p) ... -- boolean
- * Methods on Fields:
- */
- Posn p;
- // constructor
- Dandelion(Posn p) {
- this.p = p;
- }
- //returns a scene with this Dandelion placed at its position on top of the given scene
- public WorldScene drawItem(WorldScene bgScene) {
- /* TEMPLATE
- * Everything in Dandelion template, including:
- * Parameters:
- * ... bgScene ... -- WorldScene
- * Fields of Parameters:
- * ... bgScene.width ... -- int
- * ... bgScene.height ... -- int
- * Methods of Parameters:
- * ... bgScene.placeImageXY(WorldImage image, int x, int y) ... -- WorldScene
- */
- WorldImage dandelionImage = new CircleImage(5, OutlineMode.SOLID, Color.YELLOW);
- return bgScene.placeImageXY(dandelionImage, this.p.x, this.p.y);
- }
- public boolean isOccupied(Posn p) {
- /* TEMPLATE
- * Everything in Rock template, including:
- * Parameters:
- * ... p ... -- Posn
- * Fields of Parameters:
- * ... p.x ... -- int
- * ... p.y ... -- int
- * Methods of Parameters:
- */
- return this.p.x == p.x && this.p.y == p.y;
- }
- }
- class ExamplesGameWorld {
- // pixel dimensions of a CentipedeWorld
- int cWidth = 300;
- int cHeight = 500;
- // a CentipedeWorld
- CentipedeWorld c = new CentipedeWorld(this.cWidth, this.cHeight);
- // the tick rate for the CentipedeWorld
- double TICK_RATE = 1;
- //the empty background scene
- WorldScene bgScene = c.getEmptyScene();
- // the green grass background image
- WorldImage bgImage =
- new RectangleImage(bgScene.width, bgScene.height, OutlineMode.SOLID, Color.GREEN);
- // the background scene with green grass
- WorldScene bgGrassScene = this.bgScene.placeImageXY(
- this.bgImage, this.bgScene.width / 2, this.bgScene.height / 2);
- // image of a Dandelion
- WorldImage dandelionImage = new CircleImage(5, OutlineMode.SOLID, Color.YELLOW);
- // image of a Rock
- WorldImage rockImage = new CircleImage(5, OutlineMode.SOLID, Color.GRAY);
- // Dandelions at (5, 5) and (15, 15)
- IItem dand55 = new Dandelion(new Posn(5, 5));
- IItem dand1515 = new Dandelion(new Posn(15, 15));
- // Rocks at (5, 15) and (15, 5)
- IItem rock515 = new Rock(new Posn(5, 15));
- IItem rock155 = new Rock(new Posn(15, 5));
- //a list of one Dandelion
- ILoItem oneDand = new ConsLoItem(this.dand55, new MtLoItem());
- // a list of two Dandelions
- ILoItem twoDand = new ConsLoItem(this.dand1515, this.oneDand);
- // a list of one Rock
- ILoItem oneRock = new ConsLoItem(this.rock515, new MtLoItem());
- // a list of two Rocks
- ILoItem twoRock = new ConsLoItem(this.rock155, this.oneRock);
- // a list of one Dandelion and one Rock
- ILoItem dandRock = new ConsLoItem(
- this.dand55, new ConsLoItem(this.rock515, new MtLoItem()));
- // Centipede worlds
- CentipedeWorld cDandelion = new CentipedeWorld(this.cWidth, this.cHeight, this.oneDand);
- CentipedeWorld cRock = new CentipedeWorld(this.cWidth, this.cHeight, this.oneRock);
- CentipedeWorld cDandRock = new CentipedeWorld(this.cWidth, this.cHeight, this.dandRock);
- boolean testCentipede(Tester t) {
- return
- // tests the game
- c.bigBang(this.c.width, this.c.height, this.TICK_RATE);
- }
- // tests for the CentipedeWorldConstructor
- boolean testCentipedeWorldConstructor(Tester t) {
- Exception invalidRange = new IllegalArgumentException("The game scene size is either too "
- + "small or too large. Please keep game scene limits between 50 and 800 for width, and "
- + "100 and 800 for height.");
- return
- // tests valid inputs for the CentipedeWorldConstructor
- t.checkExpect(this.c.width == this.cWidth, true)
- && t.checkExpect(this.c.height == this.cHeight, true)
- // tests invalid inputs for the CentipedeWorldConstructor
- // tests if the width is too small
- && t.checkConstructorException(invalidRange, "CentipedeWorld", 2, 200)
- // tests if the width is too large
- && t.checkConstructorException(invalidRange, "CentipedeWorld", 1000, 200)
- // tests if the height is too small
- && t.checkConstructorException(invalidRange, "CentipedeWorld", 200, 2)
- // tests if the height is too large
- && t.checkConstructorException(invalidRange, "CentipedeWorld", 200, 1000);
- }
- // tests for the makeScene method which draws the current ILoItem on the screen
- boolean testMakeScene(Tester t) {
- return
- // for a world with Dandelions and Rocks
- t.checkExpect(this.cDandRock.makeScene(), this.bgGrassScene.placeImageXY(
- this.dandelionImage, 5, 5).placeImageXY(this.rockImage, 5, 15));
- }
- // tests for the onTick method which updates the world every tick
- // tests for mouse click updates
- boolean testOnMouseClicked(Tester t) {
- return
- // tests for adding IItems at the correct position
- // tests if a new Dandelion is added on a left mouse click while the mouse is centered on
- // a tile
- t.checkExpect(c.onMouseClicked(new Posn(5, 5), "LeftButton"), this.cDandelion)
- // tests if a new Dandelion is added on a left mouse click to the nearest-by tile since the
- // mouse is not centered on a tile
- && t.checkExpect(c.onMouseClicked(new Posn(9, 9), "LeftButton"), this.cDandelion)
- // tests if a new Rock is added on a left mouse click while the mouse is centered on
- // a tile
- && t.checkExpect(c.onMouseClicked(new Posn(5, 15), "RightButton"), this.cRock)
- // tests if a new Rock is added on a left mouse click to the nearest-by tile since the
- // mouse is not centered on a tile
- && t.checkExpect(c.onMouseClicked(new Posn(9, 10), "RightButton"), this.cRock);
- // TODO: tests for removing items
- }
- // tests for drawItems
- boolean testDrawItems(Tester t) {
- return
- // tests if the background is drawn with an MtLoItem
- t.checkExpect(new MtLoItem().drawItems(this.bgScene), this.bgGrassScene)
- // tests if a ConsLoItem with one Dandelion is drawn onto the background
- && t.checkExpect(this.oneDand.drawItems(this.bgScene), this.bgGrassScene.placeImageXY(
- this.dandelionImage, 5, 5))
- // tests if a ConsLoItem with two Dandelions is drawn onto the background
- && t.checkExpect(this.twoDand.drawItems(this.bgScene), this.bgGrassScene.placeImageXY(
- this.dandelionImage, 15, 15).placeImageXY(this.dandelionImage, 5, 5))
- // tests if a ConsLoItem with one Rock is drawn onto the background
- && t.checkExpect(this.oneRock.drawItems(this.bgScene), this.bgGrassScene.placeImageXY(
- this.rockImage, 5, 15))
- // tests if a ConsLoItem with two Rocks is drawn onto the background
- && t.checkExpect(this.twoRock.drawItems(this.bgScene), this.bgGrassScene.placeImageXY(
- this.rockImage, 15, 5).placeImageXY(this.rockImage, 5, 15))
- // tests if a ConsLoItem with one Dandelion and one Rock is drawn onto the background
- && t.checkExpect(this.dandRock.drawItems(this.bgScene), this.bgGrassScene.placeImageXY(
- this.dandelionImage, 5, 5).placeImageXY(this.rockImage, 5, 15))
- // tests if the given scene is not the background
- && t.checkExpect(this.oneRock.drawItems(
- this.bgGrassScene.placeImageXY(this.rockImage, 15, 5)), this.bgGrassScene.placeImageXY(
- this.rockImage, 15, 5).placeImageXY(this.rockImage, 5, 15));
- }
- // tests for isOccupied
- boolean testIsOccupied(Tester t) {
- return
- // for ILoItem
- // for an MtLoItem
- t.checkExpect(new MtLoItem().isOccupied(new Posn(5, 5)), false)
- // for a ConsLoItem where the given Posn is not occupied
- && t.checkExpect(this.dandRock.isOccupied(new Posn(45, 45)), false)
- // for a ConsLoItem where the given Posn is occupied by a Dandelion
- && t.checkExpect(this.dandRock.isOccupied(new Posn(5, 5)), true)
- // for a ConsLoItem where the given Posn is occupied by a Rock
- && t.checkExpect(this.dandRock.isOccupied(new Posn(5, 15)), true)
- // for IItem
- // for a Dandelion at (5, 5) given a Posn at (15, 15) [x and y don't match]
- && t.checkExpect(this.dand55.isOccupied(new Posn(15, 15)), false)
- // for a Dandelion at (5, 5) given a Posn at (5, 15) [x matches, y doesn't]
- && t.checkExpect(this.dand55.isOccupied(new Posn(5, 15)), false)
- // for a Dandelion at (5, 5) given a Posn at (5, 15) [y matches, x doesn't]
- && t.checkExpect(this.dand55.isOccupied(new Posn(15, 5)), false)
- // for a Dandelion at (5, 5) given a Posn at (5, 5) [x and y both match]
- && t.checkExpect(this.dand55.isOccupied(new Posn(5, 5)), true)
- // for a Rock at (15, 5) given a Posn at (5, 15) [x and y don't match]
- && t.checkExpect(this.rock155.isOccupied(new Posn(5, 15)), false)
- // for a Rock at (15, 5) given a Posn at (15, 5) [x matches, y doesn't]
- && t.checkExpect(this.rock155.isOccupied(new Posn(15, 5)), true)
- // for a Rock at (15, 5) given a Posn at (5, 5) [y matches, x doesn't]
- && t.checkExpect(this.rock155.isOccupied(new Posn(5, 15)), false)
- // for a Rock at (15, 5) given a Posn at (15, 5) [x and y both match]
- && t.checkExpect(this.rock155.isOccupied(new Posn(15, 55)), false);
- }
- // tests for remove
- boolean testRemove(Tester t) {
- return
- // for an MtLoItem
- t.checkExpect(new MtLoItem().remove(new Posn(5, 5)), new MtLoItem())
- // for ILoItems
- // for an ILoItem with one item
- && t.checkExpect(this.oneDand.remove(new Posn(5, 5)), new MtLoItem())
- // for an ILoItem with multiple items
- && t.checkExpect(this.dandRock.remove(new Posn(5, 15)), this.oneDand);
- }
- // tests for drawItem
- boolean testDrawItem(Tester t) {
- return
- // tests if a Dandelion is drawn onto the background
- t.checkExpect(this.dand55.drawItem(this.bgScene), this.bgGrassScene.placeImageXY(
- this.dandelionImage, 5, 5))
- // tests if a Rock is drawn onto the background
- && t.checkExpect(this.rock515.drawItem(this.bgScene), this.bgGrassScene.placeImageXY(
- this.rockImage, 5, 15));
- }
- // TESTS FOR THE Utility CLASS
- // tests for the pin method
- boolean testPin(Tester t) {
- return
- // tests if the mouse location is currently on the center of a tile
- t.checkExpect(new Utility().pin(new Posn(5, 5)), new Posn(5, 5))
- // tests if the mouse location is not currently on the center of a tile
- && t.checkExpect(new Utility().pin(new Posn(9, 9)), new Posn(5, 5))
- && t.checkExpect(new Utility().pin(new Posn(19, 19)), new Posn(15, 15));
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement