From b2883a1c80a9e58378d5ba25eb7bad0620e81eed Mon Sep 17 00:00:00 2001 From: Kristian Knarvik Date: Thu, 1 Mar 2018 21:13:25 +0100 Subject: [PATCH] =?UTF-8?q?=C3=86=C3=86=C3=86=C3=86=20Eg=20er=20lei=20av?= =?UTF-8?q?=20=C3=A5=20skrive?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Del A er implementert sånn omtrentlig ok. Tester har blitt fikset slik at de fungerer med Intellij. Noen kommentarer har blitt fikset. En del dårlig kode har blitt fikset. --- .gitignore | 1 + README.md | 30 +++++++++++++++++-- SEM-1_DEL-A.md | 2 +- flowchart.txt | 8 +++++ .../v18/gfx/textmode/BlocksAndBoxes.java | 4 +-- src/inf101/v18/gfx/textmode/DemoPages.java | 2 +- src/inf101/v18/gfx/textmode/TextFont.java | 18 ++++------- src/inf101/v18/gfx/textmode/TextMode.java | 2 +- src/inf101/v18/grid/GridDirection.java | 2 +- src/inf101/v18/grid/IGrid.java | 6 ++-- src/inf101/v18/grid/MyGrid.java | 4 +-- src/inf101/v18/grid/RectArea.java | 10 ++----- src/inf101/v18/grid/tests/AreaRetting.java | 2 +- src/inf101/v18/grid/tests/GridRetting.java | 2 +- src/inf101/v18/rogue101/examples/Carrot.java | 6 ++-- src/inf101/v18/rogue101/examples/Rabbit.java | 28 ++++++++++------- src/inf101/v18/rogue101/game/Game.java | 18 +++++++++-- src/inf101/v18/rogue101/game/IGame.java | 2 +- .../v18/rogue101/tests/GameMapTest.java | 2 +- src/inf101/v18/rogue101/tests/PlayerTest.java | 2 +- .../v18/util/generators/DoubleGenerator.java | 4 +-- .../v18/util/generators/GridGenerator.java | 4 +-- 22 files changed, 96 insertions(+), 63 deletions(-) create mode 100644 flowchart.txt diff --git a/.gitignore b/.gitignore index 07a846b..3d7c373 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ /bin/ .DS_Store +*.xml \ No newline at end of file diff --git a/README.md b/README.md index 8b47d1d..1bd58cc 100644 --- a/README.md +++ b/README.md @@ -22,15 +22,39 @@ Dette prosjektet inneholder [Semesteroppgave 1](SEM-1.md). Du kan også [lese op # Fyll inn egne svar/beskrivelse/kommentarer til prosjektet under -* Levert av: *NAVN* (*BRUKERNAVN*) -* Del A: [ ] helt ferdig, [ ] delvis ferdig +* Levert av: *Kristian Knarvik* (*kkn015*) +* Del A: [x] helt ferdig, [ ] delvis ferdig * Del B: [ ] helt ferdig, [ ] delvis ferdig * Del C: [ ] helt ferdig, [ ] delvis ferdig * [ ] hele semesteroppgaven er ferdig og klar til retting! # Del A ## Svar på spørsmål -* ... +a) +* IGame trenger et game map (IMapView) der ting kan plasseres. Den trenger også en referanse til brukergrensesnittet for å endre tekst og grafikk. Den trenger en TurtlePainter for å tegne grafikk. Den trenger en referanse til et Printer objekt til å (antagelig) printe fancy tekst. +* IMapView må ha en referanse til et objekt som implementerer IArea. +* Et IItem må ha et navn, en int som representerer hp, en annen int som representerer maksimal hp, en int som representerer størrelsen, og en int som representerer forsvar. Den må også ha et symbol som representerer en ting når den blir tegnet. +* En IActor er lik et IItem, men har i tillegg to int som representerer angrepsstyrke mot et IItem og en IIactor. Den kunne lagret en posisjon, men om det er en fordel spørs på implementasjonen av utførelsen av en tur. +* En INonPlayer ser ut til å være lik en IActor, men kan flytte seg selv. +* En IPlayer ser ut til å være lik en IActor, men kan gjøre mye rart ut ifra hvilken tast spilleren trykker. + +b) +* IGame ser ut til å være på toppen, og behandler IMapView. IMapView holder styr på områder IArea. Hvert IArea holder styr på alle IItem (som også inneholder alt som utvider IItem). Noen typer IItem er av type IActor. Alle IActor er enten av type IPlayer eller INonPlayer. IPlayer og INonPlayer kan forsåvidt direkte manipulere IGame, så alt går egentlig litt i ring. + +c) +* Jeg tror splittingen av IGameMap og IMapView er for å lettere kunne lage tester. IGameMap trenger en TurtlePainter, og da også en GUI. GUI er ikke særlig kompetibelt med tester. Den eneste andre logiske grunnen vil være for å kunne bruke IMapView til andre formål. For eksempel å simulere et kart med bare INonPlayer, gi dem lov til å drepe hverandre, og se hva som skjer etter 10000 steg. + +d) +* Jeg tror INonPlayer og IPlayer er forskjellige for å ikke blande dem når en skal sjekke om hvem som kan flyttes hvor, og hvem som kan angripe hvem. De kunne alltids hatt en boolean player (dersom fiender ikke skal begynne å angripe hverandre) og en metode som tok inn game, og en annen som tok inn game og keypress. Det er litt teit å ha en boolean som er lik for alle objekter bortsett fra en. En fordel med å splitte dem opp, er at jeg enkelt kan lage en IImmovablePlayer som kan overskrive metoden som angriper den til at han/hun åpner butikken sin, eller gir meg et quest. + +e) +* Det var uforventa at nesten alle tilstandsverdier ble hardkodet i stedet for å lagres i en variabel. Det gir mening når alle objekter er helt identiske (til å begynne med). Fordelen er at ting kan ha ganske unike implementeringer, men det virker litt "skittent". + +f) +* Rabbit finner ut hvor den er ved å bruke Game sin getLocation(). Rabbit finner ut hvilke andre ting som er på stedet ved å bruke game sin getLocalItems(). Rabbit finner ut hvor den har lov å gå ved å bruke game sin canGo() (senere kan getPossibleMoves() hjelpe til). + +g) +* GetLocation blir brukt når Game utfører turns. Game henter hvert objekt IActor og henter med en gang posisjonen fra Gamemap sin getLocation som henter verdien fra en hashmap. Jeg har aldri vært borti hashmaps i java, men det virker ekvivalent med måten Arrays virker i php. For eksempel: $items = array(rabbit1 => pos1). Når en da henter $items[rabbit1], vil en få pos1. # Del B ## Svar på spørsmål diff --git a/SEM-1_DEL-A.md b/SEM-1_DEL-A.md index a1b0834..a8a4cde 100644 --- a/SEM-1_DEL-A.md +++ b/SEM-1_DEL-A.md @@ -171,7 +171,7 @@ Prøv også å justere gulrøttene litt ([Carrot](src/inf101/v18/rogue101/exampl (Du trenger ikke legge ved tegningen din, men du kan gjerne lage og legge ved en oppdatert utgave når du har fått bedre/full forståelse av systemet.) -### *(0%)* Deloppgave A5: Ting du ikke trenger å se på (0/100) +### *(0%)* Deloppgave A5: Ting du ikke trenger å se på * Du trenger ikke se på koden i `gfx` (grafikkbibliotek), `grid` (utvidet IGrid) eller `util` (generering av testdata). * Hvis du lager grafikk selv, vil du gjerne komme til å *bruke* [`ITurtle`](src/inf101/v18/gfx/gfxmode/ITurtle.java) (fra `gfx`), men du trenger ikke se på implementasjone. diff --git a/flowchart.txt b/flowchart.txt new file mode 100644 index 0000000..8591ba7 --- /dev/null +++ b/flowchart.txt @@ -0,0 +1,8 @@ +Game -> IGame +GameMap -> IGameMap -> IMapView +IPlayer, INonPlayer -> IActor -> IItem -> Comparable +GameEvent -> Event + + +Game - Rabbit.doTurn(Game) - Game.move() +Game.doTurn() - Game.beginTurn() \ No newline at end of file diff --git a/src/inf101/v18/gfx/textmode/BlocksAndBoxes.java b/src/inf101/v18/gfx/textmode/BlocksAndBoxes.java index f958f3e..0f8f975 100644 --- a/src/inf101/v18/gfx/textmode/BlocksAndBoxes.java +++ b/src/inf101/v18/gfx/textmode/BlocksAndBoxes.java @@ -12,7 +12,7 @@ public class BlocksAndBoxes { private List order; - private PixelOrder(int a, int b, int c, int d) { + PixelOrder(int a, int b, int c, int d) { order = Arrays.asList(a, b, c, d); } @@ -44,7 +44,7 @@ public class BlocksAndBoxes { public static final String BLOCK_REVERSE_BOTTOM_RIGHT = "▛"; public static final String BLOCK_FULL = "█"; - public static final String BLOCK_HALF = "▒";; + public static final String BLOCK_HALF = "▒"; public static String blockAddOne(String s, PixelOrder order) { int i = BlocksAndBoxes.unicodeBlocksString.indexOf(s); diff --git a/src/inf101/v18/gfx/textmode/DemoPages.java b/src/inf101/v18/gfx/textmode/DemoPages.java index 1b8d658..935480c 100644 --- a/src/inf101/v18/gfx/textmode/DemoPages.java +++ b/src/inf101/v18/gfx/textmode/DemoPages.java @@ -74,7 +74,7 @@ public class DemoPages { printer.println(" 0123456789ABCDEF 0123456789ABCDEF"); for (int y = 0; y < 16; y++) { printer.print(String.format(" %X", y)); - int c = 0x00 + y * 0x010; + int c = y * 0x010; for (int x = 0; x < 16; x++) { printer.print(c >= 0x20 ? Character.toString((char) (c + x)) : " "); } diff --git a/src/inf101/v18/gfx/textmode/TextFont.java b/src/inf101/v18/gfx/textmode/TextFont.java index 2644b4a..f872d33 100644 --- a/src/inf101/v18/gfx/textmode/TextFont.java +++ b/src/inf101/v18/gfx/textmode/TextFont.java @@ -305,8 +305,6 @@ public class TextFont { * @param font * Name of the font file. Will search for the file in the same folder * as the TextFont class, as well as ".." and "../fonts". - * @param size - * Point size of the font. * @param squareSize * The width and height of a square defining the bounds of letters * @param xTranslate @@ -350,10 +348,7 @@ public class TextFont { * {@link #setGraphicsContext(GraphicsContext, double)} for extra on-the-fly * horizontal scaling, e.g. to make half-width letters ("hires" mode). * - * - * @param font - * Name of the font file. Will search for the file in the same folder - * as the TextFont class, as well as ".." and "../fonts". + * * @param size * Point size of the font. * @param squareSize @@ -400,10 +395,7 @@ public class TextFont { * {@link #setGraphicsContext(GraphicsContext, double)} for extra on-the-fly * horizontal scaling, e.g. to make half-width letters ("hires" mode). * - * - * @param font - * Name of the font file. Will search for the file in the same folder - * as the TextFont class, as well as ".." and "../fonts". + * * @param size * Point size of the font. * @param squareSize @@ -739,13 +731,13 @@ public class TextFont { case '0': return -2 * thin; case '2': - ctx.setLineDashes(new double[] { 14.75, 2.5 }); + ctx.setLineDashes(14.75, 2.5); break; case '3': - ctx.setLineDashes(new double[] { 9, 2.5 }); + ctx.setLineDashes(9, 2.5); break; case '4': - ctx.setLineDashes(new double[] { 6.125, 2.5 }); + ctx.setLineDashes(6.125, 2.5); break; case '.': return 0.0; diff --git a/src/inf101/v18/gfx/textmode/TextMode.java b/src/inf101/v18/gfx/textmode/TextMode.java index 61e87d2..c3aecde 100644 --- a/src/inf101/v18/gfx/textmode/TextMode.java +++ b/src/inf101/v18/gfx/textmode/TextMode.java @@ -55,7 +55,7 @@ public enum TextMode { private int vIndex; - private TextMode(int w, int h, int aspect) { + TextMode(int w, int h, int aspect) { this.hIndex = w; this.vIndex = h; this.aspect = aspect; diff --git a/src/inf101/v18/grid/GridDirection.java b/src/inf101/v18/grid/GridDirection.java index 2f55ae2..cae813b 100644 --- a/src/inf101/v18/grid/GridDirection.java +++ b/src/inf101/v18/grid/GridDirection.java @@ -32,7 +32,7 @@ public enum GridDirection { private final int dy; private final int mask; - private GridDirection(double degrees, int dx, int dy, int mask) { + GridDirection(double degrees, int dx, int dy, int mask) { this.degrees = degrees; this.dx = dx; this.dy = dy; diff --git a/src/inf101/v18/grid/IGrid.java b/src/inf101/v18/grid/IGrid.java index 355baa7..2f1a415 100644 --- a/src/inf101/v18/grid/IGrid.java +++ b/src/inf101/v18/grid/IGrid.java @@ -52,8 +52,8 @@ public interface IGrid extends Iterable { * // clear the grid * grid.setAll(null); * - * - * @param initialiser + * + * @param element */ void fill(T element); @@ -203,8 +203,6 @@ public interface IGrid extends Iterable { * y must be greater than or equal to 0 and less than getHeight(). x must be * greater than or equal to 0 and less than getWidth(). * - * @param pos - * The (x,y) position of the grid cell to get the contents of. * @param element * The contents the cell is to have. * @throws IndexOutOfBoundsException diff --git a/src/inf101/v18/grid/MyGrid.java b/src/inf101/v18/grid/MyGrid.java index d4e7bc7..aa1540e 100644 --- a/src/inf101/v18/grid/MyGrid.java +++ b/src/inf101/v18/grid/MyGrid.java @@ -95,9 +95,7 @@ public class MyGrid implements IGrid { @Override public IGrid copy() { - MyGrid newGrid = new MyGrid<>(getWidth(), getHeight(), (l) -> get(l)); - - return newGrid; + return new MyGrid<>(getWidth(), getHeight(), (l) -> get(l)); } @Override diff --git a/src/inf101/v18/grid/RectArea.java b/src/inf101/v18/grid/RectArea.java index 0814980..7ceab6b 100644 --- a/src/inf101/v18/grid/RectArea.java +++ b/src/inf101/v18/grid/RectArea.java @@ -80,10 +80,7 @@ public class RectArea implements IArea { if (x != other.getX()) { return false; } - if (y != other.getY()) { - return false; - } - return true; + return y == other.getY(); } @Override @@ -304,10 +301,7 @@ public class RectArea implements IArea { @Override public String toString() { - StringBuilder builder = new StringBuilder(); - builder.append("RectArea [width=").append(width).append(", height=").append(height).append(", hWrap=") - .append(hWrap).append(", vWrap=").append(vWrap).append("]"); - return builder.toString(); + return "RectArea [width=" + width + ", height=" + height + ", hWrap=" + hWrap + ", vWrap=" + vWrap + "]"; } @Override diff --git a/src/inf101/v18/grid/tests/AreaRetting.java b/src/inf101/v18/grid/tests/AreaRetting.java index fff1aa7..b6a6c1b 100644 --- a/src/inf101/v18/grid/tests/AreaRetting.java +++ b/src/inf101/v18/grid/tests/AreaRetting.java @@ -12,7 +12,7 @@ import static org.junit.Assert.*; import java.util.HashSet; import java.util.List; import java.util.Set; -import org.junit.jupiter.api.Test; +import org.junit.Test; public class AreaRetting { private static final int N = 10000; diff --git a/src/inf101/v18/grid/tests/GridRetting.java b/src/inf101/v18/grid/tests/GridRetting.java index 85dec01..def9aeb 100644 --- a/src/inf101/v18/grid/tests/GridRetting.java +++ b/src/inf101/v18/grid/tests/GridRetting.java @@ -11,7 +11,7 @@ import static org.junit.Assert.assertEquals; import java.util.function.Function; -import org.junit.jupiter.api.Test; +import org.junit.Test; public class GridRetting { private static final int N = 10000; diff --git a/src/inf101/v18/rogue101/examples/Carrot.java b/src/inf101/v18/rogue101/examples/Carrot.java index 2235961..86d6d9b 100644 --- a/src/inf101/v18/rogue101/examples/Carrot.java +++ b/src/inf101/v18/rogue101/examples/Carrot.java @@ -8,7 +8,7 @@ import javafx.scene.paint.Color; public class Carrot implements IItem { private int hp = getMaxHealth(); - public void doTurn(IGame game) { + public void doTurn() { hp = Math.min(hp + 1, getMaxHealth()); } @@ -50,7 +50,7 @@ public class Carrot implements IItem { @Override public int getMaxHealth() { - return 10; + return 23; } @Override @@ -74,7 +74,7 @@ public class Carrot implements IItem { if (hp < 0) { // we're all eaten! - hp = -1; + hp = 0; } return amount; } diff --git a/src/inf101/v18/rogue101/examples/Rabbit.java b/src/inf101/v18/rogue101/examples/Rabbit.java index 8cf7205..a4392f5 100644 --- a/src/inf101/v18/rogue101/examples/Rabbit.java +++ b/src/inf101/v18/rogue101/examples/Rabbit.java @@ -1,11 +1,11 @@ package inf101.v18.rogue101.examples; -import java.util.ArrayList; import java.util.Collections; import java.util.List; import inf101.v18.gfx.gfxmode.ITurtle; import inf101.v18.grid.GridDirection; +import inf101.v18.grid.ILocation; import inf101.v18.rogue101.game.IGame; import inf101.v18.rogue101.objects.IItem; import inf101.v18.rogue101.objects.INonPlayer; @@ -16,12 +16,14 @@ public class Rabbit implements INonPlayer { @Override public void doTurn(IGame game) { - if (food == 0) + if (food == 0) { hp--; - else + } else { food--; - if (hp < 1) + } + if (hp < 1) { return; + } for (IItem item : game.getLocalItems()) { if (item instanceof Carrot) { @@ -36,12 +38,18 @@ public class Rabbit implements INonPlayer { } } } - // TODO: prøv forskjellige varianter her - List possibleMoves = new ArrayList<>(); - for (GridDirection dir : GridDirection.FOUR_DIRECTIONS) { - if (game.canGo(dir)) - possibleMoves.add(dir); + + List possibleMoves = game.getPossibleMoves(); + for (GridDirection dir : possibleMoves) { + ILocation loc = game.getLocation(dir); + for (IItem item : game.getMap().getItems(loc)) { + if (item instanceof Carrot) { + game.move(dir); + return; + } + } } + if (!possibleMoves.isEmpty()) { Collections.shuffle(possibleMoves); game.move(possibleMoves.get(0)); @@ -75,7 +83,7 @@ public class Rabbit implements INonPlayer { @Override public int getMaxHealth() { - return 10; + return 30; } @Override diff --git a/src/inf101/v18/rogue101/game/Game.java b/src/inf101/v18/rogue101/game/Game.java index a72f273..682c9f6 100644 --- a/src/inf101/v18/rogue101/game/Game.java +++ b/src/inf101/v18/rogue101/game/Game.java @@ -148,6 +148,13 @@ public class Game implements IGame { beginTurn(); } + if (random.nextInt(100) < 20) { + ILocation loc = map.getLocation((int)(Math.random() * map.getWidth()), (int)(Math.random() * map.getHeight())); + if (!map.hasActors(loc) && !map.hasItems(loc) && !map.hasWall(loc)) { + map.add(loc, new Carrot()); + } + } + // process actors one by one; for the IPlayer, we return and wait for keypresses // Possible TODO: for INonPlayer, we could also return early (returning // *false*), and then insert a little timer delay between each non-player move @@ -231,6 +238,8 @@ public class Game implements IGame { } } else if (item instanceof IActor) { actors.add((IActor) item); // add other actors to the end of the list + } else if (item instanceof Carrot) { + ((Carrot) item).doTurn(); } } }); @@ -356,8 +365,13 @@ public class Game implements IGame { @Override public List getPossibleMoves() { - // TODO - throw new UnsupportedOperationException(); + List moves = new ArrayList<>(); + for (GridDirection dir : GridDirection.FOUR_DIRECTIONS) { + if (canGo(dir)) { + moves.add(dir); + } + } + return moves; } @Override diff --git a/src/inf101/v18/rogue101/game/IGame.java b/src/inf101/v18/rogue101/game/IGame.java index 3964a1a..ee69f9a 100644 --- a/src/inf101/v18/rogue101/game/IGame.java +++ b/src/inf101/v18/rogue101/game/IGame.java @@ -187,7 +187,7 @@ public interface IGame { double[] getFreeGraphicsAreaBounds(); /** - * Get the bounds of the free texxt area. + * Get the bounds of the free text area. *

* You can fill this with whatever you want, using {@link #getPrinter()} and * {@link #clearFreeTextArea()}. diff --git a/src/inf101/v18/rogue101/tests/GameMapTest.java b/src/inf101/v18/rogue101/tests/GameMapTest.java index 13a697f..d4a6bef 100644 --- a/src/inf101/v18/rogue101/tests/GameMapTest.java +++ b/src/inf101/v18/rogue101/tests/GameMapTest.java @@ -2,7 +2,7 @@ package inf101.v18.rogue101.tests; import static org.junit.Assert.*; -import org.junit.jupiter.api.Test; +import org.junit.Test; import inf101.v18.grid.ILocation; import inf101.v18.rogue101.map.GameMap; diff --git a/src/inf101/v18/rogue101/tests/PlayerTest.java b/src/inf101/v18/rogue101/tests/PlayerTest.java index 2682473..d089f93 100644 --- a/src/inf101/v18/rogue101/tests/PlayerTest.java +++ b/src/inf101/v18/rogue101/tests/PlayerTest.java @@ -2,7 +2,7 @@ package inf101.v18.rogue101.tests; import static org.junit.Assert.*; -import org.junit.jupiter.api.Test; +import org.junit.Test; import inf101.v18.grid.GridDirection; import inf101.v18.grid.ILocation; diff --git a/src/inf101/v18/util/generators/DoubleGenerator.java b/src/inf101/v18/util/generators/DoubleGenerator.java index f4a91cb..1848cbb 100644 --- a/src/inf101/v18/util/generators/DoubleGenerator.java +++ b/src/inf101/v18/util/generators/DoubleGenerator.java @@ -82,8 +82,6 @@ public class DoubleGenerator extends AbstractGenerator { public Double generate(Random rng) { double d = rng.nextDouble(); - double r = minValue + (d * diff); - - return r; + return minValue + (d * diff); } } diff --git a/src/inf101/v18/util/generators/GridGenerator.java b/src/inf101/v18/util/generators/GridGenerator.java index acd63ed..ea1485b 100644 --- a/src/inf101/v18/util/generators/GridGenerator.java +++ b/src/inf101/v18/util/generators/GridGenerator.java @@ -73,8 +73,6 @@ public class GridGenerator extends AbstractGenerator> { int w = widthGenerator.generate(r); int h = heightGenerator.generate(r); - IGrid grid = new MyGrid<>(w, h, (l) -> elementGenerator.generate(r)); - - return grid; + return new MyGrid<>(w, h, (l) -> elementGenerator.generate(r)); } }