Commit 7b1a8572 authored by Anna Maria Eilertsen's avatar Anna Maria Eilertsen
Browse files

initial commit with mixture of code that may/will be provided

parents
# Compiled source #
###################
*.com
*.class
*.dll
*.exe
*.o
*.so
/bin/
bin
tmp
# Packages #
############
# it's better to unpack these files and commit the raw source
# git has its own built in compression methods
*.7z
*.dmg
*.gz
*.iso
*.jar
*.rar
*.tar
*.zip
# Binaries
*.7z
*.dmg
*.gz
*.iso
*.jar
*.rar
*.tar
*.zip
*.war
*.ear
*.sar
*.class
# Maven
target/
/target/
# IntelliJ project files
*.iml
*.iws
*.ipr
*.idea/
# Eclipse project files
.settings/
.classpath
.project
# Logs and databases #
######################
*.log
*.sql
*.sqlite
# OS generated files #
######################
.DS_Store
.DS_Store?
._*
.Spotlight-V100
.Trashes
ehthumbs.db
Thumbs.db
# Authors
* Anya Helene Bagge, UiB (graphics, maintenance)
* Lars Jaffke, UiB (Langton's Ant)
* *you*, UiB (the rest!)
\ No newline at end of file
MIT License
Copyright (c) 2015-2018 University of Bergen
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
# Semesteroppgave 2: “Fire på rad”
* **README**
* [Oppgavetekst](SEM-2.md)
**Innleveringsfrist:**
* Hele oppgaven skal være ferdig til **X Y. april kl. 2359** ([AoE](https://www.timeanddate.com/worldclock/fixedtime.html?msg=4&iso=20180427T2359&p1=3399))
* [TODO:LINK Ekstra tips til innlevering](https://retting.ii.uib.no/inf101/inf101.v18/wikis/innlevering)
(Kryss av under her, i README.md, så kan vi følge med på om du anser deg som ferdig med ting eller ikke.)
**Utsettelse:** Hvis du trenger forlenget frist er det mulig å be om det (spør gruppeleder – evt. foreleser/assistenter hvis det er en spesiell situasjon). Hvis du ber om utsettelse bør du være i gang (ha gjort litt ting, og pushet) før fristen
* En dag eller to går greit uten begrunnelse.
* Eksamen er relativt tidlig i år, så vi vil helst unngå lange utsettelser.
* Om det er spesielle grunner til at du vil trenge lengre tid, så er det bare å ta kontakt, så kan vi avtale noe. Ta også 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
* Levert av: *NAVN* (*BRUKERNAVN*)
* [ ] hele semesteroppgaven er ferdig og klar til retting!
* Code review:
* [ ] jeg har fått tilbakemelding underveis fra @brukernavn, ...
* [ ] jeg har gitt tilbakemelding underveis til @brukernavn, ...
* Sjekkliste:
* [ ] Kjørbart Fire på Rad-spill
* [ ] Forklart designvalg, hvordan koden er organisert, abstraksjon, og andre ting
* [ ] Tester
* [ ] Dokumentasjon (JavaDoc, kommentarer, diagrammer, README, etc.)
* [ ] Fornuftige navn på klasser, interfaces, metoder og variabler
* [ ] Fornuftige abstraksjoner og innkapsling (bruk av klasser, interface, metoder, etc.)
## Oversikt
*(oversikt over koden din og det du har gjort)*
### Bruk
* For å starte programmet kjør: `fyll.inn.her`
## Designvalg
*(hvordan du har valgt å løse oppgaven)*
### Bruk av abstraksjon
*(hvordan du har valgt objekter/klasser for å representere ting i spillet)*
### Erfaring – hvilke valg viste seg å være gode / dårlige?
*(designerfaringer – er det noe du ville gjort annerledes?)*
## Testing
*(hvordan du har testet ting)*
## Funksjonalitet, bugs
*(hva virker / virker ikke)*
## Evt. erfaring fra code review
*(lærte du noe av å gå gjennom din eller andres kode?)*
## Annet
*(er det noe du ville gjort annerledes?)*
This diff is collapsed.
# Svar på spørsmål
*I denne filen legger du inn svar på spørsmålene som stilles i oppgaveteksten, eventuelt kommentarer og informasjon om kreative løsninger*
## Kommentarer
(Eventuelle kommentarer på oppgaven eller koden her).
## Spørsmål
## Oppgave 1 - Abstrakte Ting
### 1.1) - 2%
1. (svar her)
2. (svar her)
3. (svar her)
4. (svar her)
5. (svar her)
### 1.2) - 2%
1. (svar her)
2. (svar her)
3. (svar her)
4. (svar her)
5. (svar her)
### 1.3) - 3%
1. (svar her)
2. (svar her)
3. (svar her)
4. (svar her)
5. (svar her)
### 1.4) - 3%
(svar her)
### 1.4) - 5%
(svar her)
## Oppgave 2 - The Rabbit
### 2.1) - 2%
(Svar her)
### 2.2) - 3%
(Svar her)
### 2.3) - 5%
(Svar her)
### 2.4) - 5%
(Svar her)
## Oppgave 3 - Objektfabrikken
### 3.1) - 5%
(svar her)
### 3.2) - 5%
(svar her)
### 3.3) - 5%
(svar her)
## Oppgave 4 - Et smartere kart
### 4.1) - 5%
(svar her)
### 4.2) - 5%
(svar her)
### 4.3) - 10%
(svar her)
## Oppgave 5
### 5.1) - 2%
(svar her)
### 5.2) - 5%
(svar her)
### 5.3) - 5%
(svar her)
### 5.4) - 5%
(svar her)
### 5.5) - 3%
(svar her)
## Oppgave 6
### 6.1 - 5% (5% bonus for multiple items)
(Svar her)
### 6.2 - 5%
(Svar her)
### 6.3 - 5%
(Svar her)
## Fri oppgave (Oppg. 7) - (20% bonus totalt 120% mulig)
### Plan
(Skriv planen her)
### Utførelse
(Forklar i korte trekk hva du har gjort)
### Flere utvidelser
(Legg inn eventuelle flere utvidelser du har gjort her)
\ No newline at end of file
## Kunnskap/konsepter du har bruk for til denne delen
* *Abstraksjon* – å se bort fra uvesentlige detaljer og konsentrere seg om de tingene som er viktig (for det vi holder på med / fra vårt synspunkt)
* *Modellering* – en modell er en (som regel forenklet) representasjon av noe. Vi bruker modeller for å
* prøve ut / leke med / teste ting når vi ikke kan/vil gjøre direkte med det vi modellerer (f.eks.: en klimamodell lar oss forstå hvordan klimaet kan utvikle seg i forskjellige scenarier uten at vi trenger å teste det i virkeligheten; en prototype lar deg se hvordan at produkt kan bli; en modell lar deg se hvordan klær ser ut uten å måtte prøve dem på deg selv; et dataspill lar deg gjøre ting du ikke kunne gjort (eller hatt lov til) i virkeligheten; lek lar barn bygge “romskip” og utføre medisinsk behandling på “spedbarn” uten å svi av plenen eller skade lillebror).
* ha et eksempel som vi kan bruke når vi skal lage flere ting (f.eks.: [kilogramprototypen](https://en.wikipedia.org/wiki/Kilogram#International_prototype_kilogram), arkitekttegninger, 3D designmodeller (CAD/CAM))
* *Objekter* (`new C()`) – med oppførsel (metoder) og innkapslet tilstand (feltvariabler), og relasjoner til og interaksjon med andre objekter.
* *Interface* (`interface I`, `class C implements I`) – hvordan du kan bruke objekter som du har (og hvilke metoder objektenes klasse må implementere)
### Ting som (kanskje) er nytt:
* `interface I extends J` – både `I` og `J` må være grensesnitt
* Alle metodene i `J` er også med i `I` (som om du hadde listet dem opp i `I`)
* `I` blir en *subtype* av `J` – hvis noe er en `I` (er av en klasse som implementerer `I`) så kan det også brukes som en `J` (i en variabel av type `J`, f.eks.). (Det motsatte er *ikke* tilfelle – ikke alle `J`-er er `I`-er.)
* `default`-metoder i `interface`/grensesnitt – disse gir deg kode for en metode så du slipper å implementere den selv i klassen din.
* Default-metodene har ikke tilgang til feltvariabler, og de kan bare bruke metodene i grensesnittet.
* Typiske default-metoder er ekstrametoder som bygger på de andre metodene (metoder som er praktisk for bruk uten å være helt nødvendige). Det er også praktisk når man senere skal legge til flere metoder i et grensesnitt, for å slippe å måtte oppdatere en hel haug med klasser.
\ No newline at end of file
## Oversikt – Modellering
Vi kan tenke på programmet vårt som en “modell” av et dungeon crawler spill.
For å finne ut hvilke klasser og interfaces vi trenger, må vi
* a) først tenke oss hvilke elementer som inngår i spill-verdenen;
* b) finne ut hvordan vi representerer og implementerer disse på datamaskinen.
Dette er likende til prosessen vi snakket om på de første forelesningene:
1. Vi har et problemdomene, *dungeon crawling*
2. Vi analyserer domenet, og lager en abstrakt beskrivelse av det, f.eks. spillreglene skrevet på papir.
3. Vi designer programmet, og prøver å lage en konkret implementasjon.
4. Vi tester programmet vårt mot forventingene, og justerer på ting og gjentar prosessen.
Mesteparten av denne jobben er allerede gjort for deg. Din jobb er nå å sette deg inn i koden og vår dungeon crawling modell. Vi har gjort analyse og design og en god del implementasjon, så vi er ca. på slutten av punkt 3. Du må bli kjent med koden og komfortabel med å gjøre endringer, og så gå videre med implementasjonen. I siste del av oppgaven er det du som er “sjefen”, og kan gjøre (nesten) som du vil med design og regler.
### Analyse – hva er de essensielle bitene av Rogue-101?
Basert på tidligere erfaringer med slike spill, samt grunding tenking og lesing av de relevante Wikipedia-sidene, ser vi for oss følgende:
* Alt foregår på et ruteformet kart (2D grid)
* Hver celle/rute på kartet kan inneholde enten:
* en vegg
* 0 eller flere ting
* En “ting” i denne sammenhengen er:
* et objekt som spilleren/noen kan plukke opp og bruke til noe – f.eks. en gulrot, et papirark, et sverd, en brunostskive, osv.
* *eller* en aktør – en “levende” ting som kan bevege seg rundt på kartet
* For enkelhets skyld sier vi at det bare kan være maks én aktør i hver kartrute – men en aktør kan dele plass med andre ting.
* Aktørene er enten styrt av datamaskinen, eller styrt av spilleren.
* For å gjøre ting litt mer spill-aktig, har vi følgende regler for ting og aktører:
* alle ting (inkl aktører) har “helse-poeng” som indikerer i hvor god form/stand aktøren/tingen er; negative helsepoeng betyr at tingen er helt ødelagt og skal fjernes fra brettet
* alle ting (inkl aktører) har “forsvars-poeng” som indikerer hvor god den er til å forsvare seg (mot å bli angrepet, plukket opp, vasket bak ørene, e.l.)
* alle aktører har "angreps-poeng" som indikerer hvor god den er til å overgå andres forsvar (og f.eks. skade dem, plukke dem opp, vaske dem bak ørene, e.l.)
* merk deg at alle ting har helse og forsvar, selv ting som er ikke er levende – dette kan vi f.eks. bruke til å gjøre det mulig å ødelegge ting eller gjøre enkelte ting vanskelige å plukke opp
### Design – hvordan lager vi dette i Java?
Basert på dette tenker vi oss følgende typer objekter:
* [IMapView](src/inf101/v20/rogue101/map/IMapView.java), [IGameMap](src/inf101/v20/rogue101/map/IGameMap.java) – spillkartet
* [IGame](src/inf101/v20/rogue101/game/IGame.java) – selve spillet, som styrer reglene i spillverdenen
* [IItem](src/inf101/v20/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](src/inf101/v20/rogue101/objects/Wall.java) – en `IItem` som ikke kan dele plass med noe annet
* [IActor](src/inf101/v20/rogue101/objects/IActor.java) – en `IItem` som bevege seg og ikke kan dele plass med en annen `IActor`
* [IPlayer](src/inf101/v20/rogue101/objects/IPlayer.java) – en `IActor` som styres ved at brukeren trykker på tastene
* [INonPlayer](src/inf101/v20/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å:
* [ILocation](src/inf101/v20/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](src/inf101/v20/grid/GridDirection.java) – en retning (NORTH, SOUTH, ...), til bruk sammen med ILocation
* [IArea](src/inf101/v20/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>](src/inf101/v20/grid/IGrid.java) og [IMultiGrid<T>](src/inf101/v20/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.)
UML:
<a href="https://retting.ii.uib.no/inf101/inf101.v18/wikis/img/RogueInterface.png">
<img src="https://retting.ii.uib.no/inf101/inf101.v18/wikis/img/RogueInterface.png" width="200">
</a>
### *(4%)* 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.*
Alle grensesnittene beskriver *hvordan du kan håndtere objekter* (dvs. 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 ([IGame](src/inf101/v20/rogue101/game/IGame.java), [IMapView](src/inf101/v20/rogue101/map/IMapView.java), [IItem](src/inf101/v20/rogue101/objects/IItem.java), [IActor](src/inf101/v20/rogue101/objects/IActor.java), [INonPlayer](src/inf101/v20/rogue101/objects/INonPlayer.java), [IPlayer](src/inf101/v20/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):
* **a)** **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. De må også vite om eller være koblet til et `IArea`, siden en `ILocation` ser ut til å “vite” hvilke koordinater som er gyldige.)*
* **b)** **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?
* **c)** Det er to grensesnitt for kart, både [IGameMap](src/inf101/v20/rogue101/map/IGameMap.java) og [IMapView](src/inf101/v20/rogue101/map/IMapView.java). **Hvorfor har vi gjort det slik?**
* **d)** **Hvorfor tror du [INonPlayer](src/inf101/v20/rogue101/objects/INonPlayer.java) og [IPlayer](src/inf101/v20/rogue101/objects/IPlayer.java) er forskjellige?** Ville du gjort det annerledes?
### *(3%)* Deloppgave A2: Eksempler på IItem og IActor
**Til denne deloppgaven kan du se først på [Carrot](src/inf101/v20/rogue101/objects/Carrot.java) og [Rabbit](src/inf101/v20/rogue101/objects/Rabbit.java).** Svar på spørsmålene (skriv svarene i [README.md](../README.md), det holder med én eller noen få setninger):
* **e)** **Stemmer implementasjonen overens med hva du tenkte om tilstanden i Spørsmål 1 (over)?** Hva er evt. likt / forskjellig?
**Se på [Game](src/inf101/v20/rogue101/game/Game.java) og [GameMap](src/inf101/v20/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.
* **f)** **Hvordan finner Rabbit ut hvor den er, hvilke andre ting som er på stedet og hvor den har lov å gå?**
* **g)** **Hvordan vet `Game` hvor `Rabbit` er når den spør / hvordan vet `Game` *hvilken* `Rabbit` som kaller `getLocation()`?**
### *(8%)* Deloppgave A3: Litt endringer
**Husk att du kan kjøre programmet ved å kjøre `inf101.v19.rogue101.Main`.**
* *Return* – gjør ett steg (selv om vi foreløpig ikke har en IPlayer på brettet)
* Ctrl-Q / Cmd-Q – avslutt
* F11 eller Ctrl/Cmd-F – bytt til/fra fullskjerm
* Ctrl-R / Cmd-R – bytt mellom forskjellige varianter av 40- og 80-tegn tekstskjerm
#### Smart kanin
Hvis du ser på koden for [Rabbit.java](src/inf101/v20/rogue101/examples/Rabbit.java) finner du gjerne også ut hvorfor ting oppfører seg slik: kaninenes helse er avhengig av at de finner noe å spise, og bevegelsene er helt tilfeldige. Prøv ut noen forskjellige endringer:
* **a)** **Juster maksimale helsepoeng på kaninene** (evt. også på gulrøttene), og om du merker noen forskjell (husk at programmet foreløpig ikke gjør noe før du trykker retur/enter)
* **b)** **La kaninene alltid gå i samme retning** (f.eks. `game.move(GridDirection.NORTH` – kommenter ut den gamle koden). Prøv ut hva som skjer når de treffer vegger.
* **c)** **En annen mulighet er å alltid gå i første tilgjengelige retning;** dvs. samme som den opprinnelige implementasjonen, men plukk første retning i stedet for en tilfeldig en. Prøv dette. Ser det ut som de blir bedre eller dårligere til å finne gulrøtter?
* **d)** **En enda bedre strategi er å sjekke alle nabofeltene,** se om det ligger en gulrot der, og såfall gå dit (hvis den ikke ser en gulrot kan den f.eks. gå tilfeldig). Implementer dette. Tips:
* når du har funnet ut hvilke retninger (GridDirection) du kan gå i, kan du finne nabofeltene med `ILocation loc = game.getLocation(dir)` (evt `game.getLocation().go(dir)`).
* du kan finne ut hva som ligger i nabofeltet ved hjelp av kartet (`game.getMap()`); f.eks. med metoden `getItems()`.
* kaninen har allerede kode for å sjekke gjennom tingene og se om den finner en `Carrot` – du kan kopiere og tilpasse denne
* hvis kaninen finner en gulrot kan den gjøre `game.move(...)` og så returnere med en gang
* **e)** Kaninens jobb blir litt enklere om den får litt hjelp fra `Game` med å finne ut hvor den kan gå. **Implementer metoden `getPossibleMoves()` i `Game`.**
#### Bedre gulrøtter
Prøv også å justere gulrøttene litt ([Carrot](src/inf101/v20/rogue101/examples/Carrot.java)):
* **a)** Gulrøttene får helsen satt til -1 når de blir spist – etter helsereglene våre vil de derfor bli fjernet fra kartet. Prøv å sette helsen til 0 i stedet. Hvorfor går det ikke bedre med kaninene selv om gulrøttene nå blir værende på kartet?
* **b)** Det hadde kanskje vært praktisk (ihvertfall for kaninene) om gulrøttene vokste seg store og fine igjen etter en stund; for eksempel ved at de “helbreder” ett helsepoeng for hver runde som går – men `Carrot` har ingen `doTurn()` metode slik `Rabbit` har, så den får ikke med seg at rundene går eller at kaninene hopper rundt (rent bortsett fra at det går an å “jukse” ved å regne med / håpe på at `draw()` blir kalt en gang per runde).
* ~~Lag en `doTurn()`-metode i `Carrot` som øker `hp` med 1 for hver runde (opp til `getMaxHealth()`).~~ (Denne fulgte med fra før.)
* Hva skjer, ser det ut til å virke?
* Hvis det ikke virker, hva må du eventuelt gjøre for å få `Carrot` til å gjøre noe hver runde?
* **c)** Du kan også prøve å la `Game` legge til nye, tilfeldig plasserte gulrøtter av og til:
* `random.nextInt(100) < 20` er en grei test hvis du f.eks. vil gjøre noe med 20% sannsynlighet
* For å finne en tilfeldig `ILocation` kan du bruke `map.getLocation(x, y)` med tilfeldig x og y (innenfor `getWidth()`/`getHeight()`). Du kan også plukke et tilfeldig element fra `map.getArea().locations()`.
* Før du evt. putter en `new Carrot()` på kartet må du også passe på at kartruten du har funnet er ledig (ihvertfall at den ikke inneholder en vegg).
### *(0%*) Deloppgave A4: Oversikt
**Tegn en liten oversikt over det du tenker er de viktigste grensesnittene/klassene i programmet.**
* Hvis noe `implements`/`extends` noe, tegn en pil til det det implementerer/utvider.
* Du kan skrive ned f.eks. de viktigste metodenavnene eller noen stikkord om rollen til den aktuelle typen.
* Tegn også en liten oversikt over objekter i forskjellige situasjoner (f.eks. Rabbit, Carrot, Game, GameMap og hvordan de (evt) kommuniserer når kaninen holder på å gjøre noe).
(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)
* 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/v20/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.
\ No newline at end of file
# Om semesteroppgaven
*Denne filen inneholder praktisk info om [Semesteroppgave 1: “Rogue One oh one”](https://retting.ii.uib.no/inf101.v20.sem1/blob/master/SEM-1.md)* Semesteroppgaven er *obligatorisk*, og er ment å gi innsikt i og erfaring med
teknikkene vi har lært hittil i semesteret, og å teste en del praktiske
ferdigheter som ikke er så lette å teste på eksamen. Se under angående
karakter.
### Innlevering
Oppgaven skal leveres inn via GitLab **fredag 6. mars kl. 2359**.
*Hvis du ikke har brukt GitLab enda, bør du gå gjennom lab 0 og lab 2*.
Hvis du får mindre enn 40 poeng på én eller begge av semesteroppgaven **får du ikke ta eksamen**.
* **Semesteroppgaven vil være mye lettere å løse når du har ferdighetene og teorien fra lab-oppgavene** – det er best å ta seg tid til å løse disse først!
### Læringsmål
Målene for denne semesteroppgaven er:
* Å kunne sette seg inn i et eksisterende program/rammeverk, og utvide det ut ifra *spesifikasjoner* (beskrivelsen i oppgavene).
* Å bruke *interfaces* til å kommunisere mellom objekter.
* Å lage programmer hvor objektene selv styrer sin egen oppførsel
* Å beskrive komplekse objekt-orienterte systemer på en forståelig måte.
### Retting og poeng
Semesteroppgaven blir rettet av en gruppeleder, som gir tilbakemeldinger på
innleveringen. Semesteroppgaven gir deg poeng, og til sammen teller de to
semesteroppgavene 30 % på karakteren i faget.
Ved poengsetting legger vi vekt
på følgende:
* At du har fungerende løsninger på de forskjellige deloppgavene
* At koden din er ryddig og at eventuelle deler som er vanskelig å forstå er forklart i kommentarer
* At du har laget tester for koden din
* At tekst-svarene er riktige og forståelige
* Kreativitet, og at du gjør mer enn minimum for å fullføre oppgaven
Du kan regne med en godt gjennomført innlevering som oppfyller minimumskravene gir en
poengsum ca. tilsvarende B. For høyere poengsum må man ha gjort en del av bonusoppgavene. Manglende /
svært mangelfull innlevering gir 0 poeng.
### Samarbeid
Innleveringen er *individuell* og kan ikke løses i grupper. Dere står likevel fri
til å samarbeide om utarbeiding av ideer, diskutere løsninger og å hjelpe
hverandre med å finne og løse problemer (vi oppfordrer faktisk til det!) – men programmeringen må du gjøre selv, og du er selv ansvarlig for din egen kode og at du vet og kan forklare hvordan den virker.
Hvis du har diskutert ideer eller løsninger med noen, gi en kort redegjørelse for det i `Svar.md` og evt. i commit-meldingen hvis det er relatert til en konkret commit. F.eks. *“‘Kaniner-og-aliens’-konseptet er tenkt ut sammen med Helene Harepus, men vi har kodet det hver for oss”; “Sorter elementene i riktig rekkefølge (fixes #23, takk til bestemor som la merke til feilen)”.*
### Fusk og opphavsrett
Forøvrig gjelder [UiBs regler om fusk og plagiat](http://www.uib.no/studiekvalitet/77864/fusk-hva-er-det-og-hvilke-konsekvenser-f%C3%A5r-det-deg-som-student). Akademisk uredelighet og (forsøk på) fusk reguleres av Universitetsloven, og mulige konsekvenser er blant annet annullering av eksamen og utestenging (evt. tilbaketrekking av vitnemålet om ting blir oppdaget i ettertid).
(*Men:* Så lenge det er klart og tydelig hvem som har skrevet hva, hva kilden er og hvem som evt. har hjulpet til med hva, er det *ikke* fusk eller plagiat – men du får selvfølgelig bare poeng for ting du har gjort selv.)
Opphavsrett er et separat spørsmål – du kan generelt ikke klippe kode eller bruke bilder/lyd/media fra nettet [uten at du har tillatelse](https://retting.ii.uib.no/inf101/inf101.v19/wikis/opphavsrett-lisenser). Hvis du bruker ting du har funnet på nettet e.l. må du opplyse i `README.md` om hva det er, hvem som har laget det og hvor du har funnet det. For grafikk/lyd som du har rett til å gjenbruke, se gjerne etter ting med [Creative Commons lisens](https://creativecommons.org/licenses/). Vi har en liste med greie kilder på slutten av oppgaven. (Og om du er nysgjerrig, finner du lisensen for koden du har fått utlevert i filen [LICENSE](../LICENSE).)
### Innlevering
Du finner koden din i repositoriet med URIen:
https://retting.ii.uib.no/<brukernavn>/inf101.v20.sem1.git
Oppgaven leveres inn ved å pushe til retting.ii.uib.no, [slik du har gjort med alle tidligere INF101-oppgaver](https://retting.ii.uib.no/inf101/inf101.v20/wikis/hente-levere-oppgaver). Husk å få med eventuelle nye filer du har opprettet (hvis testene virker hos deg, men ikke i innleveringssystemet, er det gjerne det som er feil).
**VIKTIG:** *Sjekk kvitteringssiden som kommer opp når du pusher, i tilfelle det skjer feil!* Du må evt. gjøre Pull før Push, slik du så i (TODO link).
Vi anbefaler at du gjør commit hver dag, eller hver gang du er ferdig med en
deloppgave, i tilfelle du mister det du jobber med på din egen maskin.
* Du kan levere inn så mye og ofte du vil. Versjonen som teller er den **siste du
pushet før innleveringsfristen**.
* *VIKTIG:* Hvis du ikke allerede har prøvd ut GitLab / https://retting.ii.uib.no/ og pushing av
innleveringer, må du gjøre det *med en gang* (gjør labbene!). Du kan ikke regne med å få hjelp til
dette på innleveringsdagen, så gå på gruppetimer **så tidlig som mulig**.
* Alle testene bør passere (være grønne). Det blir i tillegg lagt betydelig
vekt på kodekvalitet og dokumentasjon. Dvs. koden din skal ikke bare *virke*,
den være *lett å forstå og å endre*.
* Du kan selv sjekke status i
[innleveringssystemet](http://retting.ii.uib.no:81/) – det vil gi rask
tilbakemelding hver gang du pusher til Gitlab, også før innleveringsfristen.
Alt skal være *grønt* der. Hvis du ser feil der som du ikke finner ut av, er det bare å spørre om hjelp.
## Symboler i oppgaveteksten
Vi har lagt inn en del symboler i oppgaveteksten for å markere viktige ting i deloppgavene. Det kan være at disse ikke vises skikkelig hvis du leser README-filen inne i Eclipse, da anbefaler vi at dere leser de på Retting (INF101 sin GitLab-instanse).
- 👉: Dette er selve oppgavesetningen som sier hva som skal gjøres.
- ✅: Dette er en test som (sannsynligvis) er rød for du gjør oppgaven, og skal bli grønn når oppgaven er ferdig.
- 🤔: Dette er et spørsmål til refleksjon. Du skal ikke levere noe her, men forståelse for dette vil hjelpe deg til å løse oppgaven.
## Sjekkliste:
TODO: liker ideen om sjekkeliste, fyll ut eller slett
### Tips
* Selv om det kanskje bare er litt mer å gjøre enn i en vanlig ukeoppgave, er
det *veldig mye* å sette seg inn i. Du bør begynne tidlig og jobbe jevnt. Du må
også regne med å jobbe utenom labtimene.
**Utsettelse:**
* Hvis du trenger forlenget frist er det mulig å be om det (spør gruppeleder – evt. assistenter/underviser hvis det er en spesiell situasjon). Hvis du ber om utsettelse bør du helst være i gang (ha gjort litt ting, og pushet) innen den første fristen.
* Om det er spesielle grunner til at du vil trenge lengre tid, så er det bare å ta kontakt, så kan vi avtale noe. Ta også kontakt om du [trenger annen tilrettelegging](http://www.uib.no/student/49241/trenger-du-tilrettelegging-av-ditt-studiel%C3%B8p).
\ No newline at end of file
## Rogue 101
Denne filen beskriver det [Rogue](https://en.wikipedia.org/wiki/Rogue_(video_game))-like spillet "Rogue One-Oh-One" fra semesteroppgave 1 i INF101.v20.
Spillet vårt er inspirert av [Rogue](https://en.wikipedia.org/wiki/Rogue_(video_game)), et tekstbasert spill laget av to computer science-studenter ved UCSC på slutten av 70-tallet. Les mer om det originale spillet [her](https://docs.freebsd.org/44doc/usd/30.rogue/paper.pdf).
![original game screen shot](https://upload.wikimedia.org/wikipedia/commons/1/17/Rogue_Screen_Shot_CAR.PNG)
# Introduksjon
I Rogue One-Oh-One styrer du en spiller rundt i en to-dimensjonal labyrint. Labyrinten inneholder ting som spilleren kan plukke opp, som gull og amuletter, og andre aktører, som edderkopper og kaniner. Aktører kan angripe ting, og både aktører og ting dør dersom de tar nok skade.
Vi kjører spillet som et grafisk grensesnitt så du kan se spilleren og monstrene bevege seg rundt på brettet. Noen spill-elementer er representert som symboler (for eksempel spilleren), mens andre er tegnet grafisk (for eksempel edderkopper). Hendelser i spillet beskrives ved hjelp av tekst på skjermen (ikke til terminalen):
`You hear a faint crunching (rabbit monster eats a a juicy carrot)`
### Likhet til lab 3 og lab 4
Du kjenner kanskje igjen ideen om en labyrint som to-dimensjonal grid fra lab 4. Vi bruker den samme typen generisk datastruktur `Grid<T>` i denne oppgaven som i lab 4, og spiller fungerer nokså likt som celleautomatene:
- spillet er runde-basert
- spillet foregår på et todimensjonalt grid
- hver rute på gridden har "ting" på seg
- hver runde får alle "ting" på brettet gjør noe
- hver "ting" har sin egen logikk for å bestemme hva den skal gjøre, med unntak av spilleren
I oppgavene som handlet om celleautomater, så inneholdt alle posisjonene på gridden celler, og alle cellene brukte samme logikk for å oppdatere seg. I Rogue så inneholder gridden forskjellige ting, og hver type ting har sin egen logikk. "Dumme" ting som gull og støv har lite logikk og gjør kanskje ingenting per runde, mens "smartere" ting kan flytte på seg, spise og angripe. Monster-"ting" har egen logikk for hvordan de flytter seg, basert på hva som ligger i nabo-rutene på brettet, og spiller-"tingen" styres ved hjelp av input fra tastaturet.
## Spill-elementer
### Spillet
Rogue-spillet går ut på å flytte spilleren rundt i et kart, finne og plukke opp en medaljong, og nå slutt-posisjonen som lar den slippe ut av labyrinten. Spilleren kommer seg ikke ut av labyrinten uten medaljongen. Dersom spilleren dør er spillet over. Spillet inneholder regler for hvordan spilleren kan bevege seg på kartet og hvordan den interagerer med andre _aktører_ og _ting_. Spillet har et grafisk grensesnitt, så kartet og aktører og ting vises på skjermen ved hjelp av grafikk og tekst; hendelser skrives ut til skjermen.
### Spillekartet
Rogue 101 består av en labyrint med _ting_ og _aktører_. Kartet er et [todimensjonalt rutenett](https://en.wikipedia.org/wiki/Tile-based_video_game) der hver rute inneholder maks én aktør, og et varierende antall ting. Hver runde kan aktørene bevege seg rundt i labyrinten. Eksempler på aktører er edderkopper og spilleren; eksempel på ting er gull og støv. Hver rute har kun plass til én aktør, men det kan ligge mange ting på samme sted. Veggene i labyrinten er også ting: det vil si at en rute kan for eksempel inneholde en vegg, eller en spiller og en gulrot, eller en kanin, en gulrot og støv. Hvilke ting og aktører vi ønsker å plassere på brettet er helt opp til oss selv. Vi er utviklerne, og det finnes ingen begrensninger.
Kartet og inneholdet kan representeres både grafisk og som tekst: for et eksempel på et tekstrepresentasjon, se på filen `level1.txt`.
### Ting
Kartet inneholder "ting". Tingene typisk i ro, og har på egenhånd ingen effekt på spillet. Det utleverte spillet inneholder tingene støv, gulrot, vegger og amuletten. I tillegg skal du legge til gull.
Alle ting har en HP - health points - som indikerer om de er ødelagt eller ikke. Noe som har negativ HP er ødelagt, og når ting tar skade reduseres HP-verdien deres.
#### Gulrot
På brettet ligger det noen gulrøtter strødd. Vi kan se at på egenhånd har disse ingen effekt på spillet. Gulrøttene, samt de andre tingene våre, gjør seg nyttig på en annen måte:
### Aktører
_Aktører_ i spillet arver alle trekkene til tingene, men kan i tillegg bevege seg rundt på brettet. De kan også bruke stasjonære ting de finner på kartet, og bruke dem for å ha en effekt på spillet. Ulike aktører kan være interessert i ulike ting, og ulike ting kan ha ulik effekt på spillet.
Den utleverte koden inneholder aktørene kanin, edderkopp og spiller.
Alle aktørene har, som tingene, en HP - health points. Denne indikerer hvor mye helse aktøren har igjen. Når en aktør tar skade reduseres HP-verdien, og om den kommer lavt nok vil aktøren dø. Akkurat som i så mange andre spill!
#### Kanin
Når du kjører koden som den er nå, er kartet fylt med massevis av kaniner. Hver runde kan kaninen flytte seg rundt på kartet. Etter et par runder dør kaninene av sult! <b>Herregud så trist!</b> _Kaninenes HP reduseres hver runde, og de må spise gulrøtter for å holde seg i live._
#### Edderkopp
Hver runde kan edderkoppen flytte seg rundt på kartet. Edderkopper er som kjent skumle vesener, og spilleren må selvfølgelig passe seg for dem. Om spilleren heller vil møte sin store frykt, skal det også kunne være mulig å sloss mot dem. (Men her må du kanskje hjelpe oss med litt implementasjon, akkurat nå er edderkoppene egentlig ganske harmløse...)
#### Spiller
Spiller-klassen er hvor du som spiller kommer inn.
Du kan navigere et spiller-objekt fritt rundt på kartet, og utforske den nye verdenen du har blitt plassert i. Men du må også være forsiktig! Spilleren har også en HP-verdi, og om du ikke spiller godt nok, kan spilleren også dø.
Hver runde leser spilleren input fra tastaturet. Avhengig av inputet kan den enten
- bevege seg NORD/SØR/ØST/VEST på kartet
- angripe en annen aktør på en rute som spilleren kan bevege seg i retning av
- plukke opp en ting fra samme rute som den selv
- legge fra seg en ting på samme rute som den selv
## Interaksjoner
### Regler for angrep og defens
Hver i hver celle på kartet kan det befinne seg maks 1 aktør.
Se for deg at en aktør A står i cellen (x, y). A prøver å bevege seg inn i en nabo-celle (dx, dy), hvor det står en aktør B.
I dette tilfellet vil A _angripe_ B.
Hver aktør har en "attack"-verdi, og en "defense"-verdi.
Angrepet lykkes hvis "attack"-verdien til A er høyere enn "defense"-verdien til B. (Og er dermed mislykket om "attack"-verdien til A er lavere eller lik "defense"-verdien til B)
Om angrepet er mislykket skjer ingen ting.
Om angrepet lykkes, vil A gjøre skade på B basert på skade-verdien til A. Om a gjøre x skade, vil B sin HP = gammel HP - x.
Hvis HP-verdien til B kommer _under 0_, blir B "ødelagt" og dør. I dette tilfellet, hvor B dør som følge av et angrep fra A, vil a bevege seg inn i cellen B sto i.