Obligatorisk innlevering uke 10 (oblig nr. 8)
Frist for innlevering: 03.11. kl 23:59
OBS: Denne innleveringen er obligatorisk og må være godkjent for at man skal kunne ta eksamen i faget.
Det er mulig å levere innleveringen før fristen og få den rettet tidligere ved å skrive "Klar til retting" i kommentarfeltet i Devilry. Man vil da ikke kunne få ny retting senere.
Spørsmål eller kommentarer til oppgaveteksten sendes til ivargry@ifi.uio.no.
Introduksjon
Denne innleveringen bygger litt videre på forrige innlevering, og målet nå er å prøve å lage inteligente sauer som spiser så mye gress som mulig og som unngår å bli spist av ulver. Det vil være en valgfri konkurranse som går ut på å lage den smarteste sauen (se detaljer til slutt i oppgave).
Å få en sau til å bevege seg noenlunde intelligent rundt på spillbrettet er krevende. Det er mange ting man må ta hensyn til, slik som:
- Hvor er ulven, og må jeg passe meg for den nå eller er jeg trygg?
- Hvor er det gress?
- Hvordan beveger jeg meg mest effektivt for å spise mest mulig gress?
- Er det steiner jeg må unngå på veien?
- Kan jeg klare å spise et stykke gress uten å bli spist av ulven?
- Risikerer jeg å bli fanget hvis jeg beveger meg i en viss retning nå?
- osv ..
Å ta hensyn til alle disse tingene er krevende, og å lage en kunstig intelligens som fører til optimale valg uansett bane vil være tilnærmet umulig. I problemer som dette er det derfor vanlig å gjøre en del forenklinger og lage en forenklet modell av problemet med en del antakelser. Dermed kan man løse enklere og mer isolerte problemer som sammen delvis løser det større problemet. Vi kommer til å gjøre disse forenklingene:
- Vi tenker oss at sauer, ulver, gress og stein ikke kan befinne seg hvor som helst, men at banen består av 18 x 14 ruter på 50x50px hver, og at hvert element befinner seg i en slik rute. Vi kan altså tenke på banen som et rutenett bestående av relativt få ruter og ikke som pixler på en skjerm (slik det var i forrige innlevering).
- Sauer og ulver kan kun bevege seg én rute opp, ned, til venstre og til høyre på dette rutenettet. Vi kunne tillatt skrå bevegelser, men det vil gjøre ting en del mer komplisert.
- Det er til enhver tid kun én sau og én ulv på banen. De som ønsker kan gjerne eksperimentere med flere sauer (det vil fungere fint, men åpner opp for veldig mye mer avanserte metoder for å unngå ulvene, sånn som samarbeid mellom sauene).
- Sauen skal slippe å tenke på fart, hvilken pixel den er på osv. Alt sauen trenger er å vite hvor ting befinner seg på brettet, og deretter bestemme seg for å gå opp, ned, til venstre eller til høyre. Det vil være prekode (som man ikke trenger å røre) som sørger for at ting ser visuelt fint ut på brettet og at dyrene beveger seg "smooth". I denne innleveringen skal man heller ikke gjøre noe med ulven eller andre objekter.
Prekode
Start med å laste ned disse filene. Du trenger ikke å sette deg inn i koden (den ligner mye på det man skrev i forrige innlevering), men det kan være greit å vite følgende:
- Spillbrettet tar nå ansvar for å sjekke kollisjoner og bevege objektene pixel for pixel (sånn at bevegelsene ikke blir hakkete). Sauen og ulven sier kun hvilken retning de skal gå, og spillbrettet beveger deretter objektene pixel for pixel i den retningen til de har kommet til en ny rute på brettet. Man kan altså tenke seg at alle objekter egentlig til enhver tid befinner seg i én rute (men det vil se ut som de glir over brettet).
- Sauen beveger seg nøyaktig dobbelt så raskt som ulven. Når sauen har flyttet seg to ruter, har ulven flyttet seg én rute.
- I prekoden ligger en implementasjon av en Ulv som er ganske god på å spise sauer. Det er denne ulven som vil bli brukt gjennom hele obligen og i den valgfrie konkuransen. Ulven vil alltid gå korteste vei mot nærmeste sau (i vårt tilfelle den ene sauen som er på brettet) og ta hensyn til alle hindre når korteste veie beregnes. Der det er flere mulige veier som er like korte, vil en tilfeldig vei velges (men alltid den samme). Vi skal ikke røre Ulv-klassen i denne obligen.
PS: En endring fra forrige innlevering er at ulver nå heller ikke kan gå på steiner. Det gjør det litt vanskeligere for ulven.
Oppgave 1: Lese baner fra fil
Sjekk først at prekoden kjører uten å krasje og at du får opp et spillbrett på skjermen. Alt du skal trenge å gjøre er å kjøre:
python3 hovedprogram.py
(evt. kjøre hovedprogram.py på den måten du vanligvis kjører et Python-program)
Øverst i hovedprogram.py ser du at vi kaller spillbrett.legg_til_objekter_fra_fil("testbane1.txt")
, men metoden legg_til_objekter_fra_fil
i klassen Spillbrett gjør ikke det den skal. Implementer denne metoden (fjern først koden som er i metoden fra før):
- Du må åpne filen som tas inn som parameter og gå gjennom linje for linje
- Hver linje er på formatet type[mellomrom]posisjon_venstre[mellomrom]posisjon_topp.
- Typen er enten "gress", "ulv", "sau" eller "stein"
- Opprett hvert objekt ved å kalle riktig metode på Spillbrett-objektet. Metodene fra forrige innlevering finnes (opprett_gress, opprett_ulv, opprett_stein og opprett_sau).
Kjør hovedprogram.py og sjekk at du får opp dette på skjermen:
Oppgave 2: Sauehjerne
Hvis man har kode som skal utføre én konkret oppgave kan det være lurt å separere ut denne koden i en egen klasse. Det gjør ting mer ryddig og det er enklere å teste koden.
Koden som avgjør hvordan sauen beveger seg er et eksempel på slik kode. Tidligere har vi hatt denne koden i Sau-klassen, men Sau-klassen har også andre oppgaver. Koden som skal bestemme hvordan sauen beveger seg trenger kun å ha kjennskap til spillbrettet, og oppgaven til denne koden er å fortelle sauen hvilken retning den skal bevege seg.
- Lag en ny klasse
Sauehjerne
i en filsauehjerne.py
. Konstruktøren til klassen skal tasau
ogspillbrett
som parametere og lagre disse i instansvariable.sau
vil være en variabel som peker påSau
-objektet som denne sauehjernen hører til.spillbrett
peker påSpillbrett
-objektet som sauen hører til. - Klassen skal ha en metode
velg_retning
som skal bli kalt når sauen "spør" hjernen sin om hvilken retning den skal gå. Implementervelg_retning
nå slik at den bare alltid returnerer "venstre". - Endre klassen
Sau
slik at det i konstruktøren blir opprettet etSauehjerne
-objekt som lagres i en instansvariabelself._sauehjerne
. - I klassen Sau finner du en metode
tenk
som nå setterself._retning
til å være "ned". Endre koden her slik at du i stedet kaller sauehjernen sin metodevelg_retning
med riktig parametere og settself._retning
til å være det som returneres fra den metoden. Spillbrettet vil alltid bevege sauen i den retningen somself._retning
er satt til. - Lag en metode
sauehjerne
i klassen Sau som bare returnerer sauehjernen (slik at vi kan få tilgang til hjernen til en sau via et Sau-objekt).
Kjør hovedprogram.py og sjekk at sauen beveger seg mot venstre. Det betyr i så fall at sauen nå bruker hjernen sin og går den retningen hjernen sier at den skal gå.
Oppgave 3: Forbedre sauehjernen
Vi har nå en klasse Sauehjerne
som har et konkret sett med informasjon (et spillbrett og en sau den hører til) og en konkret oppgave: Å bestemme en retning å gå.
Vi kan dermed steg for steg jobbe med denne klassen uten å bry oss om resten av koden. Vi kan også teste at hjernen fungerer som forventet uten å måtte kjøre hele programmet. Merk at vi også kan lage ulike klasser som følger samme oppsett som Sauehjerne
(flere Sauehjerner) for å teste ut ulike implementasjoner. Det eneste vi krever er at alle disse klassene tar samme parametere i konstruktøren (dvs at de har samme signatur) og at de implementerer metoden velg_retning
.
Sauehjernen kommer til å måtte ta en del avgjørelser basert på hvor andre ting befinner seg på spillbrettet. Vi kommer ofte til å måtte vurdere avstander og retninger på spillbrettet. Implementer disse metodene:
avstand_til_objekt
Metoden skal ta et parameter objekt
og returnere antall ruter sauen må gå for å komme til objektet. Husk at sauehjernen har tilgang til sauen gjennom self._sau
. Husk også at vi nå ikke bryr oss om posisjonen i pixler til hvert objekt. Vi har forenklet ting ved å anta at hvert objekt finnes i en rute. Alle klasser implementere nå metodene rute_venstre()
og rute_topp()
som gir antall ruter objektet befinner seg fra hhv. venstre side og toppen av brettet.
Ettersom sauer og ulver bare kan bevege seg mot venstre/høyre og opp/ned ønsker vi at avstanden skal reflektere det. Dette kalles "Manhatten distance". Se for deg at du står på Manhatten hvor alle gater går opp/ned eller til siden og man ikke kan gå skrått. Avstanden fra et gatehjørne til et annet blir antall gater man må gå opp/ned pluss antall gater man må gå til venstre/høyre.
I vårt tilfelle vil for eksempel antall ruter man må gå til venstre/høyre mellom to objekter være abs(objekt1.rute_venstre() - objekt2.rute_venstre())
. Bruk dette til å implementere avstanden mellom objektet som tas inn som parameter og sauen som hjernen har tilgang til.
retninger_mot_objekt
Lag også en metode retninger_mot_objekt
som tar et objekt som parameter og som returnerer en liste over alle "retninger" sauen kan gå for å komme nærmere objektet. Hvis objektet er rett over sauen skal listen [opp]
returneres. Hvis f. eks objektet er skrått over og til venstre for sauen skal listen ["opp", "venstre"]
returneres (rekkefølgen i listen har ingen betydning), osv. Ignorer steiner og kanten på spillbrettet her, metoden skal kun tenke at det finnes en sau og et objekt.
retninger_fra_objekt
Lag tilsvarende en metode retninger_fra_objekt
som returnerer en liste med alle retninger sauen kan gå for å øke avstanden fra objektet. Retningene her vil være de motsatte retningene av de som returneres i retninger_mot_objekt
. Du kan altså enten implementere denne metoden fra scratch, eller kalle retninger_mot_objekt
og gå gjennom retningene derifra og snu dem.
Oppgave 4: Test sauehjernen vi har laget så langt
Sauehjernen vår har nå noen metoder for å "tenke" (dvs beregne avstander og retninger) men ber fortsatt alltid sauen gå mot venstre. Før vi fortsetter ønsker vi å teste at hjernen tenker riktig.
Lag en fil test.py
. Importer Sauehjerne, Sau og Spillbrett øverst i filen.
Test avstandsberegning
Lag en prosedyre test_avstand
. I prosedyren gjør du følgende:
- Opprett et Spillbrett-objekt
- Lag et Sau-objekt (dette kan opprettes ved å kalle
Sau
-klassen direkte, og trenger ikke å legges til i spillbrettet). Sauen skal ha posisjon 400 fra venstre og 500 fra toppen av brettet. Dette tilsvarer rute nr. 8 fra venstre og rute nr. 10 fra toppen. - Lag et nytt Gress-objekt på posisjon 100, 100 (dette trenger heller ikke å legges til i spillbrettet, for vi skal kun bruke det til å teste sauehjernen)
- Hent ut hjernen til Sauen ved å kalle sauehjerne-metoden som du skrev i oppgave 2.
- Kall metoden
beregn_avstand
med gress-objektet som parameter og sjekk at avstanden som returneres er 14 (sauen må bevege seg fra rute 8 til rute 2 mot venstre og fra rute 10 til rute 2 oppover, altså 14 ruter).
Gjenta det over med 3 andre gress-objekter som befinner seg andre steder på brettet. Regn ut avstanden for hånd først, gjerne ved å tegne på et ark, og sjekk at avstanden som Sauehjernen beregner stemmer med det du mener er riktig.
Bruk gjerne assert til å gjøre disse sjekkene, f. eks slik:
assert hjerne.beregn_avstand(gress) == 14, "Avstanden er feil"
Hvis du er ukomfortabel med å bruke assert, kan du bruke en if-test til å printe en feilmelding hvis resultatet er feil:
if hjerne.beregn_avstand(gress) != 14:
print("Avstanden er feil, den skulle vært 14 men er ", hjerne.beregn_avstand(gress))
Test retningsberegning
Lag en prosedyre test_retning
. I prosedyren gjør du følgende:
- Opprett et Spillbrett-objekt, et Sau-objekt og et Gress-objekt på samme måte som i
test_avstand
. - Kall metoden
retninger_mot_objekt
og sjekk at det som returneres stemmer. Gjør dette flere ganger med ulike posisjoner, og la også noen av disse testene testeretninger_fra_objekt
.
PS: Ettersom rekkefølgen ikke spiller noen rolle kan du gjøre om det som returneres til en mengde ("set") og sammenligne mot en annen mengde for å sjekke likhet (hvis du sammenligner lister vil Python si at listene er ulike om rekkefølgen er ulik):
retninger = sauehjerne.retninger_mot_objekt(gress)
assert set(retninger) == set(["opp", "venstre"])
Oppgave 5: GÃ¥ mot gress
Vi er nå klare for å bruke det vi har laget av hjerne til å la sauen få gjøre noen smarte valg. Det første vi ønsker er å prøve å få sauen vår til å bevege seg mot gress.
Finne nærmeste gress
Lag først en metode naermeste_gress()
i klassen Sauehjerne
. Denne metoden skal gå gjennom alle "gress" som ikke er spist i spillbrettet og returnere det gresset som er nærmest sauen (her skal metoden beregn_avstand
brukes). Hvis mer enn ett gress har samme avstand og er nærmest, har det ingenting å si hvilket av de som returneres.
Gress-klassen har en metode er_spist()
som kan brukes for å sjekke om gresset er spist eller ikke fra før. Hvis det ikke finnes noe gress igjen som ikke er spist, skal metoden returnere None
.
Gå mot nærmeste gress
Gjør følgende i metoden velg_retning
i klassen Sauehjerne:
- Finn nærmeste gress.
- Hvis nærmeste gress ikke er None:
- Finn retningene som sauen kan gå for å komme nærmere dette gresset ved å kalle metoden
retninger_mot_objekt
. - Sørg for at sauen beveger seg mot en av disse retningene ved å returnere vilkårlig en av disse retningene (det er helt greit å bare returnere den første retningen hvis det er flere).
- Finn retningene som sauen kan gå for å komme nærmere dette gresset ved å kalle metoden
Kjør hovedprogram.py og sjekk at sauen ser ut til å bevege seg mot gress. At sauen blir spist på et punkt er helt greit, men hvis sauen beveger seg vekk fra gresset er noe galt. Sørg for at dette ser ut til å fungere før du fortsetter.
Oppgave 6: Unngå ulver
Vi har nå en sauehjerne som klarer å tenke seg frem til hvilken retning den skal gå for å spise gress (nærmeste gress), men vi ønsker gjerne at sauen også skal prøve å bevege seg vekk fra ulven.
Det er nå bare én ulv på brettet, og denne kan hentes ut ved å kalle ulv()
på spillbrettet.
a
Utvid metoden velg_retning
slik at hvis ulven har avstand til sauen mindre eller lik 6, så henter du ut retningene sauen må bevege seg for å komme seg vekk fra ulven. Slå disse sammen med listen over retninger sauen vil bevege seg for å komme til nærmeste gress, men gang listen med to først (slik at retningene vekk fra ulven kommer to ganger, du vil skjønne hvorfor snart). Koden din vil altså se litt slik ut (pseudokode):
retninger = []
# finn nærmeste gress
# hvis det er noe nærmeste gress, finn retningene mot nærmeste gress:
retninger_mot_gress = self.retninger_mot_objekt(gress) # gress er her en variabel som peker på det nærmeste gresset
retninger.extend(retninger_mot_gress)
if [... ulv er nærmere enn 6 ruter ...]:
retninger_vekk_fra_ulv = self.retninger_fra_objekt(self._spillbrett.ulv())
# gang retningene med 2 (gir en liste der hvert element kommer to ganger)
retninger_vekk_fra_ulv = retninger_vekk_fra_ulv * 2
# legg til retningene i listen over alle retninger
retninger.extend(retninger_vekk_fra_ulv)
Listen retninger
vil da inneholde en haug av retninger, der retningene vekk fra ulven kommer to ganger. Vi vil se på denne listen som et sett med "stemmer" og ønsker å finne den retningen som har flest stemmer og følge den retningen. Vi lar ulve-stemmene telle dobbelt fordi vi anser det som viktigere å unngå ulven enn å spise gress.
b
Skriv en funksjon finn_vanligste_element_i_liste
som tar en liste som parameter og returnerer det elementet som finnes flest ganger i listen. Denne funksjonen trenger ikke noe informasjonen fra klassen Sauehjerne
så den kan bare lages som en enslig funksjon i filen sauehjerne.py
utenfor klassen. Det gjør det enklere å teste den.
Lag en prosedyre test_finn_vanligste_element_i_liste
i filen test.py
som tester denne funksjonen, f. eks slik:
from sauehjerne import finn_vanligste_element_i_liste
def test_finn_vanligste_element_i_liste():
assert finn_vanligste_element_i_liste(["ned", "ned", "opp"]) == "opp"
assert finn_vanligste_element_i_liste(["ned", "venstre", "opp", "venstre"]) == "venstre"
## Legg gjerne inn et par tester til
c
Fullfør metoden velg_retning
ved å finne det vanligste element i listen retninger
. Dette vil være retningen som sauehjernen har mest lyst til å bevege seg. Returner denne retningen.
Kjør hovedprogram.py og sjekk at Sauen beveger seg mot gress helt til den er i nærheten av ulven. Da bør den bevege seg bort fra Ulven.
Oppgave 6: Komme seg rundt ulven
Hvis du har fått til oppgave 5 riktig, vil du merke at sauen beveger seg fra ulven, men ender opp på enden av spillbrettet og blir stående og stange der. Dette skjer fordi den vil bort fra ulven, men ikke har noe annet som får den til å gå til siden når den har kommet til enden av brettet.
En enkel og naiv måte å unngå dette problemet på er få sauen til å forsøke å følge kanten av spillbrettet hvis den er ved kanten av spillbrettet.
Utvid velg_retning
metoden slik:
- Hvis sauen befinner seg på høyre kant av brettet (sauen sin
rute_venstre()
metode returnerer 17, som er den siste kolonnen) OG det er flest stemmer for å gå til høyre, endre valgt retning til å være "ned". - Hvis ikke forrige punkt stemmer og sauen befinner seg helt øverst på brettet (sauen sin
rute_topp()
returnerer 0)) OG det er flest stemmer for å gå oppover, endre valgt retning til å være "hoeyre". - Hvis ikke de forrige punktene stemmer og sauen befinner seg på venstre side av brettet OG det er flest stemmer for å gå til venstre, endre valgt retning til å være "opp".
- Hvis ikke de forrige punktene stemmer og sauen befinner seg på bunnen av brettet (
rute_topp()
er 13) OG det er flest stemmer for å gå nedover, endre valgt retning til å være "venstre".
OBS: Reglene over bør implementeres i den rekkefølgen de står for å fungere optimalt. Poenget er å først sjekke høyre side før man sjekker toppen slik at første regel vil slå inn om sauen er i øverste høyre hjørne (da ønsker vi at sauen skal gå nedover og ikke mot høyre for å unngå å stå fast).
Kjør hovedprogram.py igjen. Hvis reglene dine virker bør sauen bevege seg nedover når den kommer til enden av brettet og deretter komme seg forbi ulven (og ikke bli fanget på en stund på testbane1.txt).
Oppgave 7: Unngå hindre
Sauen vår blir nå trukket mot gress, beveger seg vekk fra ulven og den unngår å låse seg fast på kantene til brettet (ved at den følger kanten i retning med klokka). Men sauen vår er fortsatt dårlig på å unngå hindre.
Endre hovedprogram.py slik at testbane2.txt brukes i stedet for testbane1.txt og kjør programmet. Du vil trolig se at sauen etter hvert vil ønske å gå til venstre (mot nærmeste gress) men stange i en stein som står i veien:
a
Lag en metode stein_finnes_i_retning
som tar et parameter retning
og som returnerer True
hvis det finnes en stein på neste rute i den gitte retningen fra sauen og False
hvis ikke. I tilfellet vist på bildet over skal f. eks metoden returnere True
hvis retningen som gis er "venstre" og False for alle andre retninger.
PS: Husk at du kan kalle metodene rute_venstre()
og rute_topp()
på et Stein-objekt.
b
Lag en metode hinder_finnes_i_retning
som returnerer True
hvis det enten er en stein på neste rute i den retningen eller hvis man er utenfor banen på neste rute i den retningen. Den første sjekken har du allerede gjort i metoden stein_finnes_i_retning
, så unngå å kopiere kode fra den metoden og kall heller stein_finnes_i_retning
fra hinder_finnes_i_retning
.
c
Utvid velg_retning
-metoden slik at det helt til slutt (etter at sjekken mot kanter er gjort) sjekkes om det finnes en stein i retningen som det er bestemt at sauen skal gå. Hvis det gjør det, velg en annen retning ved å velge en hvilken som helst retning hvor det ikke finnes et hinder (sjekk dette ved å kalle hinder_finnes_i_retning
for de ulike mulige retningene som er igjen).
Hvis koden din fungerer som den skal nå, bør sauen fint klare å overleve på testbane2.txt og gjøre det ganske bra på testbane3.txt. Det er ikke noe krav at sauen din skal gjøre det bra på alle banene, men reglene over bør være implementert.
Prøv gjerne ut de andre testbanene og se hva som skjer.
Oppgave 8: Valgfri oppgave, lag din egen sauehjerne
Lag din egen sauehjerne:
- Sauehjernen må ligge i en fil
konkurranse.py
og klassenavnet må væreSauehjerneBrukernavn
der Brukernavn er ditt brukernavn. Hvis du vil være anonym når konkurransen kjører kan du gjerne bytte ut Brukernavn med et valgfritt deltakernavn som ikke er brukernavnet ditt. - All kode må skrives i den filen. Du kan skrive metoder i klassen og også ha andre funksjoner/prosedyrer som ligger i filen, men ikke lag flere filer.
- Klassen MÅ ha en konstruktør som tar sau og spillbrett som parametere og den må ha en metode
velg_retning
som returnerer enten opp, ned, hoeyre eller venstre. - Du velger selv hvordan du vil implementere denne hjernen. Du kan ta utgangspunkt i reglene og fremgangsmåten i denne obligen, eller starte helt på scratch med dine egne ideer.
Regler for konkurransen:
- Hvert spill utføres med én sau og én ulv på en ukjent bane. Sauen får 1 i score for hvert gress den spiser og 10 ekstra i score hvis den lever når spillet er ferdig.
- Hvert spill skjer over 3000 "runder". En runde er én kjøring av oppdater-funksjonen i Pygame Zero, og sauen flytter 5 px på en slik oppdatering. Sauen bruker altså 10 runder på å flytte seg en rute. Du kan kalle
runde
-metoden til Spillbrett for å hente ut rundenummeret, og i enkelte scenarioer kan det være greit å vite hvor mye tid man har igjen. - Formatet på konkurransen kan variere litt avhengig av antall bidrag som blir levert, men vil sannsynligvis være noe slikt:
- Alle sauer spiller først på en ganske enkel bane og de med lavest score ryker ut av konkurransen (f. eks de 3 dårligste, litt avhengig av antall bidrag).
- De sauene som er igjen spiller videre på enten én ny bane eller flere baner (der scoren legges sammen for alle banene), og igjen ryker de med lavest score ut.
- Denne prosessen fortsetter på gradvis vanskeligere baner til alle sauene har røket ut og det står igjen én vinner.
- Det kan altså lønne seg å passe på å ikke gjøre det veldig dårlig på noen banetyper hvis man skal komme langt (i stedet for å bruke for mye tid på å perfeksjonere spillet på enkelte baner).
- Banene som brukes er ukjente, men vil kunne ligne litt på banene som ligger i testbane1-7.txt.
- Sauen har ikke lov til å bruke mer enn 0.2 sekunder på å "tenke". Prekoden vil printe en advarsel hvis det brukes for lang tid. Husk at kjøretiden kan variere litt avhengig av maskinen koden kjøres på, så det kan være lurt å sørge for å ha litt å gå på. Under konkurransen vil enkelte tilfeller av kjøretid over 0.2 sekunder tillates, men hvis det skjer for ofte (eller man er langt over 0.2 sekunder) kan man bli diskvalifisert.
- Det er ikke lov å aksessere Ulv-objektet via spillbrettet for å finne ut hva ulven tenker eller har tenkt til å gjøre.
- Det er ikke lov å teleportere sauen (dvs endre posisjonen).
- Andre ting som åpenbart er "juks" og gir en stor fordel er ikke tillatt (spør gjerne om du er usikker) :)
Noen tips:
- Du kan endre tallet 3000 der Spillbrett-objektet blir opprettet i hovedprogram.py for å kjøre et spill lenger. Men husk at tallet 3000 vil brukes i selve konkurransen.
- Lag gjerne dine egne baner for å teste. Viktig: ulv må alltid være den siste linjen i banen (fordi når ulven opprettes scanner den alle elementene som allerede er i banen).
- Fokuser på å få så høy score som mulig på så mange baner som mulig. Scoren blir printet når et spill er over eller sauen dør.
Lykke til!
Krav til innleveringen
- Spørsmålene til innleveringen (nedenfor) skal besvares i kommentarfeltet i Devilry.
- Koden skal inneholde gode kommentarer som forklarer hva programmet gjør.
Hvordan levere oppgaven
Lever følgende filer:
- sauehjerne.py (og evt. andre filer hvis du har delt opp koden i flere filer)
- spillbrett.py
- test.py
- konkurranse.py (hvis du har et bidrag i konkurransen)
- Hvis du har endret noe i andre deler av prekoden (skal ikke være nødvendig), lever også de filene og kommenter hva du har endret.
Kommenter på følgende spørsmål i kommentarfeltet i Devilry. Spørsmålene skal besvares.
- Hvordan synes du innleveringen var? Hva var enkelt og hva var vanskelig?
- Hvor lang tid (ca) brukte du på innleveringen?
- Var det noen oppgaver du ikke fikk til? Hvis ja: i. Hvilke(n) oppave(r) er det som ikke fungerer i innleveringen? ii. Hvorfor tror du at oppgaven ikke fungerer? iii. Hva ville du gjort for å få oppgaven til å fungere hvis du hadde mer tid?
For å levere:
- Logg inn på Devilry.
- Lever alle filene, og husk å svare på spørsmålene i kommentarfeltet.
- Husk å trykke lever/add delivery og sjekk deretter at innleveringen din er komplett. Du kan levere flere ganger, men alle filer må være med i hver innlevering.
- Den obligatoriske innleveringen er minimum av hva du bør ha programmert i løpet av en uke. Du finner flere oppgaver for denne uken på semestersiden.