use R instead of smiley

This commit is contained in:
Anya Helene Bagge 2018-02-28 17:06:11 +01:00
parent 14ed39ad7b
commit c6692845f5
5 changed files with 91 additions and 36 deletions

View File

@ -1,11 +1,18 @@
# [Semesteroppgave 1: “Rogue One-Oh-One”](https://retting.ii.uib.no/inf101.v18.sem1/blob/master/SEM-1.md) # [Semesteroppgave 1: “Rogue One-Oh-One”](https://retting.ii.uib.no/inf101.v18.sem1/blob/master/SEM-1.md)
**OBS: koden / oppgaveteksen er ikke helt ferdig ennå du kan lese den og se på ting online men ikke laste den ned**
**Innleveringsfrist: Fredag 9. mars kl 2400** (TODO: info om forlengelse)
Dette prosjektet inneholder [Semesteroppgave 1](SEM-1.md). Du kan også [lese oppgaven online](https://retting.ii.uib.no/inf101.v18.oppgaver/inf101.v18.sem1/blob/master/SEM-1.md) (kan evt. ha små oppdateringer i oppgaveteksten som ikke er med i din private kopi). Dette prosjektet inneholder [Semesteroppgave 1](SEM-1.md). Du kan også [lese oppgaven online](https://retting.ii.uib.no/inf101.v18.oppgaver/inf101.v18.sem1/blob/master/SEM-1.md) (kan evt. ha små oppdateringer i oppgaveteksten som ikke er med i din private kopi).
**Innleveringsfrist: Fredag 9. mars kl 2400**
**Utsettelse:** Hvis du trenger forlenget frist kan du få det om du ber om det (spør gruppeleder evt. foreleser/assistenter hvis det er en spesiell situasjon)
* Noen dagers utsettelse går helt fint uten begrunnelse, siden oppgaven er litt forsinket.
* Hvis du jobber med labbene fremdeles (best om du er ferdig med Lab 4), si ifra om det, og så kan du få ekstra tid til å gjøre ferdig labbene før du går i gang med semesteroppgaven.
* Om det er spesielle grunner til at du vil trenge lengre tid, så er det bare å ta kontakt, så kan vi avtale noe. Du kan også ta kontakt om du [trenger annen tilrettelegging](http://www.uib.no/student/49241/trenger-du-tilrettelegging-av-ditt-studiel%C3%B8p).
# Fyll inn egne svar/beskrivelse/kommentarer til prosjektet under # Fyll inn egne svar/beskrivelse/kommentarer til prosjektet under
* Levert av: *NAVN* (*BRUKERNAVN*) * Levert av: *NAVN* (*BRUKERNAVN*)
* Del A: [ ] helt ferdig, [ ] delvis ferdig
* Del B: [ ] helt ferdig, [ ] delvis ferdig
* Del C: [ ] helt ferdig, [ ] delvis ferdig

View File

@ -11,7 +11,24 @@
## Sjekkliste: ## Sjekkliste:
* [ ] Thing to do * [ ] Gjøre Del A
* [ ] Oppdatere README.md, commit og push!
* [ ] Gjøre Del B
* [ ] Oppdatere README.md, commit og push!
* [ ] Gjøre Del C
* [ ] Commit og push ofte!
* [ ] Beskrive hva du har gjort i README.md, fortell om eventuelt idé-samarbeid
* [ ] Sørge for at du har rettigheter til evt. mediafiler du bruker
* [ ] Gjøre klar innlevering
* [ ] Sjekke at alle filer som skal være med er med når du commiter
* [ ] Sjekk *Commits* siden på Retting, og se at ting du har pushet har dukket opp
* [ ] Sjekk teststatus på https://retting.ii.uib.no:81/me
* [ ] Sjekk at du har skrevet JavaDoc for nye metoder / typer du har lagt til
* [ ] Sjekk at du har formattert koden (bruk Source → Format i Eclipse, f.eks.)
* [ ] Sjekk at all bruk av kilder, bilder, lyd, annen kode er spesifisert i README.md
* [ ] Sjekk [README.md](README.md), commit og push!
* [ ] Things to do
* [ ] More things to do
## Om semesteroppgaven ## Om semesteroppgaven

View File

@ -27,7 +27,7 @@ Ting som (kanskje) er nytt:
Semesteroppgaven er en naturlig videreutvikling av Labyrint-oppgaven i stedet for å bare gå rundt i en kjedelig labyrint, skal vi nå kunne gå rundt, plukke opp ting og interagere med ting. Semesteroppgaven er en naturlig videreutvikling av Labyrint-oppgaven i stedet for å bare gå rundt i en kjedelig labyrint, skal vi nå kunne gå rundt, plukke opp ting og interagere med ting.
### Bakgrunn ### Bakgrunn
Et eksempel på et slikt labyrint-spill er [Rogue](https://en.wikipedia.org/wiki/Rogue_(video_game)), som er et gammel [dungeon crawl](https://en.wikipedia.org/wiki/Dungeon_crawl)-spill med “tekst-grafikk”, der du går rundt i en labyrint, plukker opp ting og dreper monstre. De første slike spillene dukket opp på slutten av 1970-tallet; *Rogue* (1980) var et av de første, og har gitt navn til hele sjangeren ([“Roguelike”](https://en.wikipedia.org/wiki/Roguelike)). Dungeon crawls og roguelike spill har vært veldig populære opp gjennom tidene (ikke minst på grunn av fancy 2D-grafikk med tekst-symboler, som var et betydelig steg opp fra [tidligere adventure/fantasy spill](https://en.wikipedia.org/wiki/Colossal_Cave_Adventure) som hvor alt var bare tekst), inkludert gamle klassikere som [NetHack](TODO), [Moria](TODO) og [Larn](TODO). Ofte har disse spillene vært laget som hobbyprosjekter av programmører (informatikk-studenter, for eksempel) og vært mer kompliserte (og mye vanskeligere) enn spill fra kommersielle spillprodusenter, selv om de gjerne ikke har hatt spesielt fancy grafikk. Et eksempel på et slikt labyrint-spill er [Rogue](https://en.wikipedia.org/wiki/Rogue_(video_game)), som er et gammel [dungeon crawl](https://en.wikipedia.org/wiki/Dungeon_crawl)-spill med “tekst-grafikk”, der du går rundt i en labyrint, plukker opp ting og dreper monstre. De første slike spillene dukket opp på slutten av 1970-tallet; *Rogue* (1980) var et av de første, og har gitt navn til hele sjangeren ([“Roguelike”](https://en.wikipedia.org/wiki/Roguelike)). Dungeon crawls og roguelike spill har vært veldig populære opp gjennom tidene (ikke minst på grunn av fancy 2D-grafikk med tekst-symboler, som var et betydelig steg opp fra [tidligere adventure/fantasy spill](https://en.wikipedia.org/wiki/Colossal_Cave_Adventure) som hvor alt var bare tekst), inkludert gamle klassikere som [NetHack](https://en.wikipedia.org/wiki/NetHack), [Moria](https://en.wikipedia.org/wiki/Moria_(video_game)) og [Larn](https://en.wikipedia.org/wiki/Larn_(video_game)). Ofte har disse spillene vært laget som hobbyprosjekter av programmører (informatikk-studenter, for eksempel) og vært mer kompliserte (og mye vanskeligere) enn spill fra kommersielle spillprodusenter, selv om de gjerne ikke har hatt spesielt fancy grafikk.
Moderne roguelike spill (og moderne utgaver av de gamle) kommer gjerne med mer fancy grafikk og er ofte laget av uavhengige utviklere. I de litt bredere kategoriene “dungeon crawls” og “adventure” finner du en haug med vanlige, populære spill f.eks. [Zelda-serien](https://en.wikipedia.org/wiki/The_Legend_of_Zelda_(video_game)) (startet i 1986 med “gå rundt på et 2D-grid/kart, plukk opp ting, sloss med monstre og løs puzzles”; de nyeste versjonene tilbyr en åpen 3D-verden med detaljert fysikk, grafikk og lyd). Moderne roguelike spill (og moderne utgaver av de gamle) kommer gjerne med mer fancy grafikk og er ofte laget av uavhengige utviklere. I de litt bredere kategoriene “dungeon crawls” og “adventure” finner du en haug med vanlige, populære spill f.eks. [Zelda-serien](https://en.wikipedia.org/wiki/The_Legend_of_Zelda_(video_game)) (startet i 1986 med “gå rundt på et 2D-grid/kart, plukk opp ting, sloss med monstre og løs puzzles”; de nyeste versjonene tilbyr en åpen 3D-verden med detaljert fysikk, grafikk og lyd).
@ -78,40 +78,41 @@ Basert på tidligere erfaringer med slike spill, samt grunding tenking og lesing
### Design hvordan lager vi dette i Java? ### Design hvordan lager vi dette i Java?
Basert på dette tenker vi oss følgende typer objekter: Basert på dette tenker vi oss følgende typer objekter:
* [IMapView](src/inf101/v18/rogue101/map/IMapView.java], [IGameMap](src/inf101/v18/rogue101/map/IGameMap.java] spillkartet * [IMapView](src/inf101/v18/rogue101/map/IMapView.java), [IGameMap](src/inf101/v18/rogue101/map/IGameMap.java) spillkartet
* [IGame](src/inf101/v18/rogue101/game/IGame.java) selve spillet, som styrer reglene i spillverdenen
* [IItem](src/inf101/v18/rogue101/objects/IItem.java) en ting. Siden både småobjekter (sverd og gulrøtter), aktører og vegger er ting som befinner seg på kartet, er det praktisk å gjøre alle til IItem. * [IItem](src/inf101/v18/rogue101/objects/IItem.java) en ting. Siden både småobjekter (sverd og gulrøtter), aktører og vegger er ting som befinner seg på kartet, er det praktisk å gjøre alle til IItem.
* Wall en IItem som ikke kan dele plass med noe annet * [Wall](src/inf101/v18/rogue101/objects/Wall.java) en IItem som ikke kan dele plass med noe annet
* IActor en IItem som bevege seg og ikke kan dele plass med en annen IActor * [IActor](src/inf101/v18/rogue101/objects/IActor.java) en IItem som bevege seg og ikke kan dele plass med en annen IActor
* IPlayer en IActor som styres ved at brukeren trykker på tastene * [IPlayer](src/inf101/v18/rogue101/objects/IPlayer.java) en IActor som styres ved at brukeren trykker på tastene
* INonPlayer en IActor som styrer seg selv (datamaskinen styrer) * [INonPlayer](src/inf101/v18/rogue101/objects/INonPlayer.java) en IActor som styrer seg selv (datamaskinen styrer)
Vi har også et par andre mer abstrakte ting vi bør tenke på f.eks. koordinater. Det går an å bruke heltall som koordinater / indekser (`int x`, `int y`), men det er generelt ganske praktisk med en egen abstraksjon for grid-plasseringer; blant annet kan vi da slippe å gjøre kompliserte utregninger på koordinatene for å finne frem til andre koordinater. Vi har derfor også: Vi har også et par andre mer abstrakte ting vi bør tenke på f.eks. koordinater. Det går an å bruke heltall som koordinater / indekser (`int x`, `int y`), men det er generelt ganske praktisk med en egen abstraksjon for grid-plasseringer; blant annet kan vi da slippe å gjøre kompliserte utregninger på koordinatene for å finne frem til andre koordinater. Vi har derfor også:
* ILocation en lovlig (x,y)-koordinat på kartet. Hver ILocation har opptil åtte andre ILocations som naboer, og har metoder for å finne alle eller noen av naboene, og for å finne nabo i en spesifikk retning. * [ILocation](src/inf101/v18/grid/ILocation.java) en lovlig (x,y)-koordinat på kartet. Hver ILocation har opptil åtte andre ILocations som naboer, og har metoder for å finne alle eller noen av naboene, og for å finne nabo i en spesifikk retning.
* GridDirection en retning (NORTH, SOUTH, ...), til bruk sammen med ILocation * [GridDirection](src/inf101/v18/grid/GridDirection.java) en retning (NORTH, SOUTH, ...), til bruk sammen med ILocation
* IArea et rektangulært sett med ILocations. Brukes f.eks. av spillkartet for å lettvint gå gjennom alle cellene/rutene i kartet. * [IArea](src/inf101/v18/grid/IArea.java) et rektangulært sett med ILocations. Brukes f.eks. av spillkartet for å lettvint gå gjennom alle cellene/rutene i kartet.
* (IGrid<T> og IMultiGrid<T> IGrid<T> er tilsvarende til den du har brukt i labbene tidligere; IMultiGrid<T> er et grid der hver celle er en liste av T-er. Den blir brukt av spillkartet, men du trenger neppe bruke den selv.) * ([IGrid<T>](src/inf101/v18/grid/IGrid.java) og [IMultiGrid<T>](src/inf101/v18/grid/IMultiGrid.java) IGrid<T> er tilsvarende til den du har brukt i labbene tidligere; IMultiGrid<T> er et grid der hver celle er en liste av T-er. Den blir brukt av spillkartet, men du trenger neppe bruke den selv.)
### Deloppgave A1: Tilstand, oppførsel og grensesnitt for objektene ### Deloppgave A1: Tilstand, oppførsel og grensesnitt for objektene
*Du vil sikkert finne på lurere svar på spørsmålene etterhvert som du jobber med oppgaven. Det er fint om du lar de opprinnelige svarene stå (det er helt OK om de er totalt feil eller helt på jordet) og heller gjør tilføyelser. Du kan evt. bruke ~~overstryking~~ (putt dobbel tilde rundt teksten, `~~Rabbit.java funker fordi det bor en liten kanin inni datamaskinen~~`) for å markere det du ikke lenger synes er like lurt. *Du vil sikkert finne på lurere svar på spørsmålene etterhvert som du jobber med oppgaven. Det er fint om du lar de opprinnelige svarene stå (det er helt OK om de er totalt feil eller helt på jordet) og heller gjør tilføyelser. Du kan evt. bruke ~~overstryking~~ (putt dobbel tilde rundt teksten, `~~Rabbit.java funker fordi det bor en liten kanin inni datamaskinen~~`) for å markere det du ikke lenger synes er like lurt.
Alle grensesnittene beskriver hvordan du kan håndtere objekter (objekter som er av klasser som implementerer grensesnittene). Selv om tilstanden til objektene er innkapslet (du vet ikke om feltvariablene), så lar metodene deg *observere* tilstanden, så ut fra de tilgjengelige metodene kan du spekulere litt rundt hvordan tilstanden må være. Alle grensesnittene beskriver hvordan du kan håndtere objekter (objekter som er av klasser som implementerer grensesnittene). Selv om tilstanden til objektene er innkapslet (du vet ikke om feltvariablene), så lar metodene deg *observere* tilstanden, så ut fra de tilgjengelige metodene kan du spekulere litt rundt hvordan tilstanden må være.
Les gjennom grensesnittene vi har nevnt over ([IGameMap](TODO), [IItem](TODO), [IActor](TODO), [INonPlayer](TODO), [IPlayer](TODO) vent med å se på klassene) og svar på spørsmålene (skriv svarene i [README.md](README.md), det holder med én eller noen få setninger): Les gjennom grensesnittene vi har nevnt over [IGame](src/inf101/v18/rogue101/game/IGame.java), ([IMapView](src/inf101/v18/rogue101/map/IMapView.java), [IItem](src/inf101/v18/rogue101/objects/IItem.java), [IActor](src/inf101/v18/rogue101/objects/IActor.java), [INonPlayer](src/inf101/v18/rogue101/objects/INonPlayer.java), [IPlayer](src/inf101/v18/rogue101/objects/IPlayer.java) vent med å se på klassene) og svar på spørsmålene (skriv svarene i [README.md](README.md), det holder med én eller noen få setninger):
* **1. Hva vil du si utgjør tilstanden til objekter som implementerer de nevnte grensesnittene?** *(F.eks. hvis du ser på `ILocation` så vil du gjerne se at ILocation-objekter må ha en tilstand som inkluderer `x`- og `y`-koordinater selv om de sikkert kan lagres på mange forskjellige måter)* * **1. Hva vil du si utgjør tilstanden til objekter som implementerer de nevnte grensesnittene?** *(F.eks. hvis du ser på `ILocation` så vil du gjerne se at ILocation-objekter må ha en tilstand som inkluderer `x`- og `y`-koordinater selv om de sikkert kan lagres på mange forskjellige måter)*
* **2. Hva ser ut til å være sammenhengen mellom grensesnittene?** Flere av dem er f.eks. laget slik at de utvider (extends) andre grensesnitt. * **2. Hva ser ut til å være sammenhengen mellom grensesnittene?** Flere av dem er f.eks. laget slik at de utvider (extends) andre grensesnitt. Hvem ser ut til å ta imot / returnere objekter av de andre grensesnittene?
* **3. Det er to grensesnitt for kart, både [IGameMap](TODO) og [IMapView](TODO). Hvorfor har vi gjort det slik?** * **3. Det er to grensesnitt for kart, både [IGameMap](src/inf101/v18/rogue101/map/IGameMap.java) og [IMapView](src/inf101/v18/rogue101/map/IMapView.java). Hvorfor har vi gjort det slik?**
* **4. Hvorfor tror du [INonPlayer](TODO) og [IPlayer](TODO) er forskjellige? Ville du gjort det annerledes?** * **4. Hvorfor tror du [INonPlayer](src/inf101/v18/rogue101/objects/INonPlayer.java) og [IPlayer](src/inf101/v18/rogue101/objects/IPlayer.java) er forskjellige? Ville du gjort det annerledes?**
### Deloppgave A2: Eksempler på IItem og IActor ### Deloppgave A2: Eksempler på IItem og IActor
Til denne deloppgaven kan du se først på [Carrot](TODO) og [Rabbit](TODO). Svar på spørsmålene (skriv svarene i [README.md](README.md), det holder med én eller noen få setninger): Til denne deloppgaven kan du se først på [Carrot](src/inf101/v18/rogue101/objects/Carrot.java) og [Rabbit](src/inf101/v18/rogue101/objects/Rabbit.java). Svar på spørsmålene (skriv svarene i [README.md](README.md), det holder med én eller noen få setninger):
* **5. Stemmer implementasjonen overens med hva du tenkte om tilstanden i Spørsmål 1 (over)? Hva er evt. likt / forskjellig?** * **5. Stemmer implementasjonen overens med hva du tenkte om tilstanden i Spørsmål 1 (over)? Hva er evt. likt / forskjellig?**
Se på [Game](TODO) og [GameMap](TODO) også. Se på [Game](src/inf101/v18/rogue101/game/Game.java) og [GameMap](src/inf101/v18/rogue101/map/GameMap.java) også.
`Rabbit` trenger å vite hvor den er, fordi den skal prøve å spise gulroten (hvis den finner en) og fordi den må finne seg et gyldig sted å hoppe videre til. `Rabbit` trenger å vite hvor den er, fordi den skal prøve å spise gulroten (hvis den finner en) og fordi den må finne seg et gyldig sted å hoppe videre til.
* **6. Hvordan finner Rabbit ut hvor den er, hvilke andre ting som er på stedet og hvor den har lov å gå?** * **6. Hvordan finner Rabbit ut hvor den er, hvilke andre ting som er på stedet og hvor den har lov å gå?**
@ -166,7 +167,7 @@ Prøv også å justere gulrøttene litt ([Carrot](src/inf101/v18/rogue101/exampl
### Deloppgave A5: Ting du ikke trenger å se på (0/100) ### Deloppgave A5: Ting du ikke trenger å se på (0/100)
* Du trenger ikke se på koden i `gfx` (grafikkbibliotek), `grid` (utvidet IGrid) eller `util` (generering av testdata). * 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` (fra `gfx`), men du trenger ikke se på implementasjone. * 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.
* GameMap gjør bruk av `grid`-pakken, men du trenger antakelig ikke gjøre noe med den selv. * GameMap gjør bruk av `grid`-pakken, men du trenger antakelig ikke gjøre noe med den selv.
# Gå videre til Del B
[SEM-1_DEL-B](SEM-1DEL-B.md) # Gå videre til [**DEL B**](SEM-1DEL-B.md)

View File

@ -10,7 +10,7 @@ I denne delen av semesteroppgaven skal du implementere en del konkrete metoder.
### Deloppgave B1: Objekt-fabrikk ### Deloppgave B1: Objekt-fabrikk
* a) Se på konstruktøren i Game-klassen, og se hvordan kartet blir fylt inn. Finn metoden som lager nye objekter basert på strenger ('#', '.', 'R', osv) dette er en såkalt [factory/fabrikk-metode](https://en.wikipedia.org/wiki/Factory_method_pattern). Det er vanlig å bruke når vi har mange klasser som implementerer det samme grensesnittet, og vi vil gjøre det lett for andre deler av programmet å opprette objekter uten å kjenne til klassene. * a) Se på konstruktøren i Game-klassen, og se hvordan kartet blir fylt inn. Finn metoden som lager nye objekter basert på strenger ('#', '.', 'R', osv) dette er en såkalt [factory/fabrikk-metode](https://en.wikipedia.org/wiki/Factory_method_pattern). Det er vanlig å bruke når vi har mange klasser som implementerer det samme grensesnittet, og vi vil gjøre det lett for andre deler av programmet å opprette objekter uten å kjenne til klassene.
* **b)** Lag deg en ny klasse som implementerer IItem. Du kan ta utgangspunkt i en av klassene du har fra før (f.eks. `Carrot`) og du kan velge navn selv (f.eks. `CarrotCake`). Funksjonaliteten kan (foreløpig) være helt lik. * **b)** Lag deg en ny klasse som implementerer [IItem](src/inf101/v18/rogue101/objects/IItem.java). Du kan ta utgangspunkt i en av klassene du har fra før (f.eks. `Carrot`) og du kan velge navn selv (f.eks. `CarrotCake`). Funksjonaliteten kan (foreløpig) være helt lik.
* **c)** Legg klassen til i fabrikk-metoden. Du må velge et tegn som skal representere objekter av klassen (f.eks. `"c"`). Bruk dette tegnet både i fabrikk-metoden i `Game` og i `getSymbol()`-metoden i den nye klassen din (det er ingen direkte sammenheng mellom disse, men greit om de stemmer overens). * **c)** Legg klassen til i fabrikk-metoden. Du må velge et tegn som skal representere objekter av klassen (f.eks. `"c"`). Bruk dette tegnet både i fabrikk-metoden i `Game` og i `getSymbol()`-metoden i den nye klassen din (det er ingen direkte sammenheng mellom disse, men greit om de stemmer overens).
* **d)** Legg til det nye tegnet ditt i standard-kartet (ligger i [src/inf101/v18/rogue101/map/maps/level1.txt](src/inf101/v18/rogue101/map/maps/level1.txt) eventuelt ligger det et innebygget kart i `Main`-klassen hvis vi av en eller annen grunn ikke finner kartfilen), og se at gulrotkaken (eller det du har laget) dukker opp på skjermen. * **d)** Legg til det nye tegnet ditt i standard-kartet (ligger i [src/inf101/v18/rogue101/map/maps/level1.txt](src/inf101/v18/rogue101/map/maps/level1.txt) eventuelt ligger det et innebygget kart i `Main`-klassen hvis vi av en eller annen grunn ikke finner kartfilen), og se at gulrotkaken (eller det du har laget) dukker opp på skjermen.
@ -20,7 +20,7 @@ Symbolene på skjermen blir hentet fra `getSymbol()` (evt. `getPrintSymbol()` om
### Deloppgave B2: Minimal Player ### Deloppgave B2: Minimal Player
Du er sikkert lei av at det bare er kaninene som får lov til å ha det gøy. Du er sikkert lei av at det bare er kaninene som får lov til å ha det gøy.
* **a)** Lag en klasse `Player implements IPlayer`. Du kan følge mønsteret fra de andre IItem-klassene, men du trenger litt andre metoder. Der hvor `Rabbit` har `doTurn()` skal `Player` ha `keyPressed()`. Du kan la denne være tom til å begynne med. * **a)** Lag en klasse `Player implements` [`IPlayer`](src/inf101/v18/rogue101/objects/IPlayer.java) (putt den i `objects` eller en egen ny `player` pakke). Du kan følge mønsteret fra de andre IItem-klassene, men du trenger litt andre metoder. Der hvor `Rabbit` har `doTurn()` skal `Player` ha `keyPressed()`. Du kan la denne være tom til å begynne med.
* **b)** Du må oppdatere fabrikken i `Game` så den også lager `Player`-objekter; de har tradisjonelt symboled `@` (i utlevert kode gir det deg en `ExampleItem`). * **b)** Du må oppdatere fabrikken i `Game` så den også lager `Player`-objekter; de har tradisjonelt symboled `@` (i utlevert kode gir det deg en `ExampleItem`).
* **c)** Metoden `keyPressed()` i `IPlayer` tar et `KeyCode`-object, og kalles hver gang spilleren * **c)** Metoden `keyPressed()` i `IPlayer` tar et `KeyCode`-object, og kalles hver gang spilleren
trykker på en tast. Knappen indikeres med KeyCode-en (en for hver tast på tastaturet + at man kan sjekke f.eks. om *Ctrl*-tasten er trykket inn). F.eks. vil følgende kode sjekke om trykker på en tast. Knappen indikeres med KeyCode-en (en for hver tast på tastaturet + at man kan sjekke f.eks. om *Ctrl*-tasten er trykket inn). F.eks. vil følgende kode sjekke om
@ -52,7 +52,7 @@ En grei løsning er å si at vi vil se den *største* tingen alle IItems har
For å fikse dette vil vi at kartet skal ha tingene liggende i sortert rekkefølge i listene for hver celle. Vi kunne sortert listen hver gang vi hentet den (f.eks. hver gang kaninen kaller `game.getLocalItems()`, slik at den største gulroten kommer først), men det er både raskere og ca. like lettvint å passe på at vi legger ting inn i sortert rekkefølge: Hvis vi skal legge et element *e* inn i listen *l*, så vil vi ha det på den første posisjonen *i* slik at *e.compareTo(l.get(i)) >= 0* (altså, sett inn *e* foran det første elementet *e* er større enn). For å fikse dette vil vi at kartet skal ha tingene liggende i sortert rekkefølge i listene for hver celle. Vi kunne sortert listen hver gang vi hentet den (f.eks. hver gang kaninen kaller `game.getLocalItems()`, slik at den største gulroten kommer først), men det er både raskere og ca. like lettvint å passe på at vi legger ting inn i sortert rekkefølge: Hvis vi skal legge et element *e* inn i listen *l*, så vil vi ha det på den første posisjonen *i* slik at *e.compareTo(l.get(i)) >= 0* (altså, sett inn *e* foran det første elementet *e* er større enn).
* **a)** Legg til alternativet for `"."` i `Game.createItem()` den skal produsere et `Dust`-objekt. * **a)** Legg til alternativet for `"."` i `Game.createItem()` den skal produsere et [`Dust`-objekt](src/inf101/v18/rogue101/objects/Dust.java).
* Hvis du kjører programmet nå, vil du antakelig se at mange av kaninenen “gjemmer seg” de ligger altså under støvet (Dust-objektene; sees som litt mørkere felter). * Hvis du kjører programmet nå, vil du antakelig se at mange av kaninenen “gjemmer seg” de ligger altså under støvet (Dust-objektene; sees som litt mørkere felter).
* **b)** Endre `add`-metoden i `GameMap` slik at nye items blir lagt til i sortert rekkefølge (største først). * **b)** Endre `add`-metoden i `GameMap` slik at nye items blir lagt til i sortert rekkefølge (største først).
* Husk at `a.compareTo(b)` er `< 0` hvis `a` er mindre `b`, `== 0` hvis `a` er lik `b` og `> 0` hvis `a` er større `b`. * Husk at `a.compareTo(b)` er `< 0` hvis `a` er mindre `b`, `== 0` hvis `a` er lik `b` og `> 0` hvis `a` er større `b`.
@ -60,7 +60,7 @@ For å fikse dette vil vi at kartet skal ha tingene liggende i sortert rekkeføl
* Det holder å kalle `add` på listen, siden `list` refererer til samme objektet som ligger inne i kart-cellen. * Det holder å kalle `add` på listen, siden `list` refererer til samme objektet som ligger inne i kart-cellen.
* `Dust`-objektene er ganske små (størrelse 1), så hvis du har gjort det riktig, vil kaninene (og spilleren) bli tegnet i stedet for støvet. * `Dust`-objektene er ganske små (størrelse 1), så hvis du har gjort det riktig, vil kaninene (og spilleren) bli tegnet i stedet for støvet.
* **c)** Test `add`-metoden. * **c)** Test `add`-metoden.
* Finn testklassen [GameMapTest](TODO) og testmetoden vi har begynt på (`testSortedAdd`). * Finn testklassen [GameMapTest](src/inf101/v18/rogue101/tests/GameMapTest.java) og testmetoden vi har begynt på (`testSortedAdd`).
* Du må sette opp et test-scenario: * Du må sette opp et test-scenario:
* du trenger et nytt GameMap (det trenger ikke være fylt med noe) * du trenger et nytt GameMap (det trenger ikke være fylt med noe)
* du trenger også en ILocation, siden de fleste kart-metodene bruker det (kall `getLocation(x,y)` med en kjent, lovlig posisjon) * du trenger også en ILocation, siden de fleste kart-metodene bruker det (kall `getLocation(x,y)` med en kjent, lovlig posisjon)
@ -74,20 +74,20 @@ Vi vil gjerne la brukeren kunne plukke opp og legge fra seg ting på kartet
* **a)** For å få til dette må du legge til flere tastetrykk til `keyPressed`-metoden i `Player` du kan f.eks. bruke `KeyCode.P` og `KeyCode.D`. Lag gjerne egne metoder for å plukke opp/droppe ting i spilleren. * **a)** For å få til dette må du legge til flere tastetrykk til `keyPressed`-metoden i `Player` du kan f.eks. bruke `KeyCode.P` og `KeyCode.D`. Lag gjerne egne metoder for å plukke opp/droppe ting i spilleren.
* *Legg merke til:* andre metoder i `Player` er laget slik at de tar et `IGame`-argument. Det trenger du nok her også fordi du må snakke med spill-objektet for å interagere med kartet og andre ting. Du *kan* lagre `game` som en feltvariabel, så du slipper å sende den rundt som argument. Vi har latt være å gjøre det fordi: a) det er lettere å opprette og teste Player (og andre IItems/IActors) hvis man ikke trenger å lage gi dem et game-objekt (f.eks. kunne du teste GameMap/sortert add uten å bruke `Game`/`IGame` i det hele tatt); og b) det kan være litt forvirrende med sykliske avhengigheter mellom objekter (ikke minst når forholdet endrer seg f.eks. når ting fjernes fra spillet). * *Legg merke til:* andre metoder i `Player` er laget slik at de tar et `IGame`-argument. Det trenger du nok her også fordi du må snakke med spill-objektet for å interagere med kartet og andre ting. Du *kan* lagre `game` som en feltvariabel, så du slipper å sende den rundt som argument. Vi har latt være å gjøre det fordi: a) det er lettere å opprette og teste Player (og andre IItems/IActors) hvis man ikke trenger å lage gi dem et game-objekt (f.eks. kunne du teste GameMap/sortert add uten å bruke `Game`/`IGame` i det hele tatt); og b) det kan være litt forvirrende med sykliske avhengigheter mellom objekter (ikke minst når forholdet endrer seg f.eks. når ting fjernes fra spillet).
* **b)** `Game` har tilsvarende `pickUp()` og `drop()` metoder du kan bruke for å plukke et objekt fra kartet og for å etterlate et objekt på kartet. Metoden `pickUp()` returnerer `null` om du av en eller annen grunn ikke kunne plukke opp tingen. Implementer “plukke opp”-funksjonaliteten. Hint: * **b)** `Game` har tilsvarende `pickUp()` og `drop()` metoder du kan bruke for å plukke et objekt fra kartet og for å etterlate et objekt på kartet. Metoden `pickUp()` returnerer `null` om du av en eller annen grunn ikke kunne plukke opp tingen. Implementér “plukke opp”-funksjonaliteten. Hint:
* `game.pickUp()` plukker opp et spesifikt objekt som ligger i kartruten du står i, så du er nødt til å finne ut *hvilket objekt* du vil prøve å plukke opp hvis det er flere mulighetre (foreløpig har brukeren ingen måte å be om et spesifikt IItem på); * `game.pickUp()` plukker opp et spesifikt objekt som ligger i kartruten du står i, så du er nødt til å finne ut *hvilket objekt* du vil prøve å plukke opp hvis det er flere mulighetre (foreløpig har brukeren ingen måte å be om et spesifikt IItem på);
* du finner alle tingene som ligger i kartruten med `game.getLocalItems()`, og du kan f.eks. prøve å ta den første. Du kan også finne tingene ved å få tak i kartet (game.getMap()) og undersøke det direkte bare pass på at spilleren ikke ender opp med å plukke opp seg selv! (getLocalItems() gir deg bare items som ikke er IActor, så den er “trygg”) * du finner alle tingene som ligger i kartruten med `game.getLocalItems()`, og du kan f.eks. prøve å ta den første. Du kan også finne tingene ved å få tak i kartet (game.getMap()) og undersøke det direkte bare pass på at spilleren ikke ender opp med å plukke opp seg selv! (getLocalItems() gir deg bare items som ikke er IActor, så den er “trygg”)
* husk at ruten kan være tom, dvs at `game.getLocalItems()` gir tom liste da kan du f.eks. gi bruken beskjed om at det ikke er noe å plukke opp. * husk at ruten kan være tom, dvs at `game.getLocalItems()` gir tom liste da kan du f.eks. gi bruken beskjed om at det ikke er noe å plukke opp.
* **c)** For å kunne legge fra deg ting må du ha lagret objektet du plukket opp, f.eks. i en feltvariabel i `Player`. Foreløpig går det greit å tenke seg at du bare kan holde på én ting, så da er det lett å vite hva dus skal legge fra deg. Implementer “dropp / legg fra deg”-funksjonaliteten. Hint: * **c)** For å kunne legge fra deg ting må du ha lagret objektet du plukket opp, f.eks. i en feltvariabel i `Player`. Foreløpig går det greit å tenke seg at du bare kan holde på én ting, så da er det lett å vite hva dus skal legge fra deg. Implementér “dropp / legg fra deg”-funksjonaliteten. Hint:
* Du kan gi en passende melding til brukeren om du ikke har noe å legge fra deg. * Du kan gi en passende melding til brukeren om du ikke har noe å legge fra deg.
* Pass på at når du har lagt fra deg objektet (med `game.drop()`) så sletter du det fra `Player`-objektet ellers kan du massekopiere ting ved å plukke opp én ting og så legge den fra deg mange ganger. * Pass på at når du har lagt fra deg objektet (med `game.drop()`) så sletter du det fra `Player`-objektet ellers kan du massekopiere ting ved å plukke opp én ting og så legge den fra deg mange ganger.
* `game.drop()` kan i prinsippet feile (fullt på bakken, kanskje?), i såfall returnerer den `false` og du bør *ikke* slette tingen fra `Player`-objektet * `game.drop()` kan i prinsippet feile (fullt på bakken, kanskje?), i såfall returnerer den `false` og du bør *ikke* slette tingen fra `Player`-objektet
* **d)** Det er praktisk for brukeren å vite hva man bærer på, så legg inn navnet på objektet i status-meldingen (fra B2.e) * **d)** Det er praktisk for brukeren å vite hva man bærer på, så legg inn navnet på objektet i status-meldingen (fra B2.e)
### Deloppgave B5: Finne synlige ting / ting i nærheten ### Deloppgave B5: Finne synlige ting / ting i nærheten
IGame spesifiserer en metode `getVisible()` som skal gi deg alle locations i nærheten som du kan se. Denne er foreløpig ikke skikkelig implementert. Den kaller `map.getNeighbourhood(currentLocation, dist)`, som mangler implementasjon for dist > 0. [IGame](src/inf101/v18/rogue101/game/IGame.java) spesifiserer en metode `getVisible()` som skal gi deg alle locations i nærheten som du kan se. Denne er foreløpig ikke skikkelig implementert. Den kaller `map.getNeighbourhood(currentLocation, dist)`, som mangler implementasjon for dist > 0.
* **a)** Lag en enkel versjon av `getNeighbourhood()` som bare returnerer alle de direkte naboene til lokasjonen. ILocation har metoder som kan hjelpe deg (men du må kanskje flytte resultatet over i en liste). Med *naboer* mener vi her alle de åtte cellene som er rundt cellene i midten, *unntatt* de av naboene som er utenfor kartet (du vil uansett ikke få tak i ILocations for dissse); og med *nabolag* tenker også på naboene til naboene osv. * **a)** Lag en enkel versjon av `getNeighbourhood()` i [GameMap](src/inf101/v18/rogue101/map/GameMap.java) som bare returnerer alle de direkte naboene til lokasjonen. ILocation har metoder som kan hjelpe deg (men du må kanskje flytte resultatet over i en liste). Med *naboer* mener vi her alle de åtte cellene som er rundt cellene i midten, *unntatt* de av naboene som er utenfor kartet (du vil uansett ikke få tak i ILocations for dissse); og med *nabolag* tenker også på naboene til naboene osv.
* **b)** Det er litt dumt å bare kunne se de aller nærmeste cellene. Endre din `getNeighbourhood()` slik at den finner alle locations som er innenfor <code>dist</code> cellers avstand. (Dette er gjerne mye vanskeligere. Du kan sette begrensninger på <code>dist</code> om vil, men du bør håndtere minst 3.) * **b)** Det er litt dumt å bare kunne se de aller nærmeste cellene. Endre din `getNeighbourhood()` slik at den finner alle locations som er innenfor <code>dist</code> cellers avstand. (Dette er gjerne mye vanskeligere. Du kan sette begrensninger på <code>dist</code> om vil, men du bør håndtere minst 3.)
* **c)** Du bør lage tester for dette også, slik som i B3. Du trenger et GameMap, og en ILocation på kartet. * **c)** Du bør lage tester for dette også, slik som i B3. Du trenger et GameMap, og en ILocation på kartet.
* Du kan sjekke at resultatet fra `getNeighbourhood()` er riktig ved å gå gjennom hele listen og så sjekke at `centre.gridDistanceTo(element) <= dist`. * Du kan sjekke at resultatet fra `getNeighbourhood()` er riktig ved å gå gjennom hele listen og så sjekke at `centre.gridDistanceTo(element) <= dist`.
@ -139,7 +139,7 @@ En grei formel for angrep er f.eks.: `attack+random.nextInt(20)+1 >= defence+10`
* **c)** I en del av metodene burde vi kanskje vært litt mer presise på hva som er “forkravene” hva må være oppfylt for at det skal gå bra å kalle denne metoden? Vi har nevnt litt at `game.move()` krever at feltet i retningen er lovlig og ledig. Se gjennom de andre metodene i `Game` og `GameMap` og se om de har spesielle antakelser rundt parameterne. Ser du noe som burde endres? F.eks., enten metoder som sjekker for ting som kan gå galt, men ikke sier noe om forutsetningene i dokument eller metoder som *burde* sjekket parameterne sine / andre forutsetninger. F.eks., hva med `Game.addItem()` (og `drop()` også, forsåvidt) bør den f.eks. sjekke at feltet ikke allerede er opptatt (f.eks. legge til ny IActor når det allerede er en IActor der, e.l.)? * **c)** I en del av metodene burde vi kanskje vært litt mer presise på hva som er “forkravene” hva må være oppfylt for at det skal gå bra å kalle denne metoden? Vi har nevnt litt at `game.move()` krever at feltet i retningen er lovlig og ledig. Se gjennom de andre metodene i `Game` og `GameMap` og se om de har spesielle antakelser rundt parameterne. Ser du noe som burde endres? F.eks., enten metoder som sjekker for ting som kan gå galt, men ikke sier noe om forutsetningene i dokument eller metoder som *burde* sjekket parameterne sine / andre forutsetninger. F.eks., hva med `Game.addItem()` (og `drop()` også, forsåvidt) bør den f.eks. sjekke at feltet ikke allerede er opptatt (f.eks. legge til ny IActor når det allerede er en IActor der, e.l.)?
* **d)** Det er to kart-grensesnitt, IGameMap og IMapView. Hvorfor tror du vi har gjort det slikt? * **d)** Tenker du annerledes om noen av spørsmålene fra Del A nå?
* **e)** Tenker du annerledes om noen av spørsmålene fra Del A nå?
# Gå videre til [**DEL C**](SEM-1DEL-C.md)

View File

@ -6,16 +6,46 @@
* [Del B: Gjør ferdig nødvendige komponenter](SEM-1_DEL-B.md) * [Del B: Gjør ferdig nødvendige komponenter](SEM-1_DEL-B.md)
* [Del C: Selvvalgt del](SEM-1_DEL-C.md) * [Del C: Selvvalgt del](SEM-1_DEL-C.md)
## Videreutvikling av Rogue-101
Vi overlater nå ansvaret for utviklingen til deg du finner noen forslag under, men du må selv bestemme hva mer som skal legges til av funksjonalitetet, og hva du evt. vil gjøre for å gi spillet litt mer “flavour” (grafikk, kanskje?).
Som nevnt tidligere kan du velge “setting” og “storyline” som du vil du trenger ikke å lage huleutforskning med magi, sverd, orker og hobbiter eller med kaniner og gulrøtter. Skriv ned forklaring til det du gjør i README.md både funksjonalitet som du legger til, og kreative ting du finner på vi legger ikke nødvendigvis merke til alt når vi prøvekjører ting, så det er greit å vite hva vi skal se etter.
### Styling
Du kan kommet et godt stykke på vei med litt kreativ bruk av tekst-symbolene. For enkel blokk-grafikk (til vegger, f.eks.) så finnes det en del forskjellige tegn du kan bruke i [BlocksAndBoxes](inf101/v18/gfx/textmode/BlocksAndBoxes.java).
F.eks. bruker `Wall`-objektene `BlocksAndBoxes.BLOCK_FULL` som symbol. Det kan være litt tricky å få `Wall` til å variere `getSymbol()` avhengig av hvor den har andre vegger som naboer, men du kan i prinsippet lage flere varianter av wall:
* Her er det mest praktisk å bruk *arv*, f.eks.:
```
public class DiagonalWall extends Wall {
// Java vil bruke denne i stedet for getSymbol() fra Wall men alle andre metoder følger
// med fra Wall.
@Override
public String getSymbol() {
return BlocksAndBoxes.DIAG_FORWARD;
}
}
```
* Du trenger også å legge til alle vegg-variantene i `createItem`-metoden.
* Du trenger at alle vegger har `Wall`-typen, fordi kartet bruker det til å se om et felt er opptatt (bla gjennom items på en lokasjon, sjekk om `item instanceof Wall`). Når du sier at `DiagonalWall extends Wall`, så vi alle diagonale vegger også telle som vanlige vekker.
* Alternativet ville vært å enten legge til en metode `isWall()` i `IItem`; eller si at en kartcelle er opptatt hvis det er en veldig stor ting der (`getSize()` større enn 100 eller 1000, f.eks.); eller lage et ekstra grensesnitt `IWall` (og både `Wall` og `DiagonalWall` `implements IWall`) og bruke det istedenfor der hvor man trenger å sjekke etter vegger.
* lage meldings"vindu" * lage meldings"vindu"
# Åpne kilder til grafikk / lyd / media # Diverse
## Åpne kilder til grafikk / lyd / media
* Om du ikke er flink til å tegne selv, kan du finne glimrende grafikk på [OpenGameArt](http://opengameart.org/) **husk å skrive i oversiktsdokumentet hvor du har fått grafikken fra** (webside, opphavsperson, copyright-lisens om du bruker OpenGameArt, finner du opplysningene i *License(s)* og *Copyright/Attribution Notice*). * Om du ikke er flink til å tegne selv, kan du finne glimrende grafikk på [OpenGameArt](http://opengameart.org/) **husk å skrive i oversiktsdokumentet hvor du har fått grafikken fra** (webside, opphavsperson, copyright-lisens om du bruker OpenGameArt, finner du opplysningene i *License(s)* og *Copyright/Attribution Notice*).
* [Wikimedia Commons](https://commons.wikimedia.org/wiki/Main_Page) har en god del bilder og andre mediafiler tilgjengelig du får til og med en “You need to attribute this author show me how” instruks når du laster ned ting. * [Wikimedia Commons](https://commons.wikimedia.org/wiki/Main_Page) har en god del bilder og andre mediafiler tilgjengelig du får til og med en “You need to attribute this author show me how” instruks når du laster ned ting.
* [Kevin MacLeod](https://incompetech.com/music/) er komponist og har masse musikk tilgjengelig som egner seg for spill og småfilmer; du trenger bare å kreditere ham (han bruker vanlig [CC-BY-3.0](http://creativecommons.org/licenses/by/3.0/) lisens). * [Kevin MacLeod](https://incompetech.com/music/) er komponist og har masse musikk tilgjengelig som egner seg for spill og småfilmer; du trenger bare å kreditere ham (han bruker vanlig [CC-BY-3.0](http://creativecommons.org/licenses/by/3.0/) lisens).
* Tidligere INF101-student [Øyvind Aandalen](https://soundcloud.com/user-616269685) har litt musikk han har laget på [SoundCloud](https://soundcloud.com/user-616269685) som han sier dere kan som dere vil. * Tidligere INF101-student [Øyvind Aandalen](https://soundcloud.com/user-616269685) har litt musikk han har laget på [SoundCloud](https://soundcloud.com/user-616269685) som han sier dere kan bruke som dere vil.