You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 7 Next »

Oppgaven handler om en Sokoban-klasse som holder representasjon, logikk og funksjonalitet for å spille spilllet Sokoban gjennom konsollen.

Oppgaven handler om spillet Sokoban. Sokoban består av et brett som inneholder mål, bokser, vegger og en spiller. Spilleren skal forsøke å flytte alle boksene til et mål. Spilleren vinner spillet når alle boksene står på et mål.

Sokoban forklares enklest ved demonastrasjon (for en nærmere forklaring, se http://sokobano.de/wiki/index.php?title=Main_Page):  

Brett som bildeBrett som tesktForklaring
#######
#.@ # #
#$* $ #
#   $ #
# ..  #
#  *  #
#######

Utgansposisjon for et brett

#######
#.  # #
#$* $ #
#  $@ #
# ..  #
#  *  #
#######

Spilleren har flyttet en

boks mot venstre / øst

#######
#*$ # #
# @ $ #
#   $ #
# ..  #
#  *  #
#######

Spilleren har skjøvet en

boks mot en vegg og kan

ikke lenger flytte den

#######
#*  # #
# *   #
#     #
# **@ #
#  *  #
#######

Spilleren har plassert alle

boksene på et mål og har

vunnet spillet

 

Implementering av Sokoban

Sokoban-oppgaven er en åpen oppgave, hvor man selv velger løsninger for hvordan spillet skal implementeres. Det stilles likevel følgende krav:

  • Programmet må bestå av minst tre klasser; en klasse for å representere et felt på brettet, en klasse for brettet med ruter og ett hovedprogram for interaksjon med spilleren
  • Brett-klassen må ha en toString()-metode som skriver ut brettet slik det er beskrevet under
TegnBetydning

'#'

vegg
'.'mål
'$'boks
'*'boks på mål
'@'spiller
'+'spiller på mål
' 'tomt felt

Cell-klassen må ha følgende metoder:

  • void RemoveBox() – fjerner en boks fra feltet.
  • void RemovePlayer() – fjerner spilleren fra feltet.
  • void AddPlayer() – setter spilleren på feltet.
  • boolean isTarget() – returnerer hvorvidt feltet er et mål eller ikke.
  • boolean isFree() – returnerer hvorvidt det er mulig å flytte en boks eller spilleren til feltet.
  • boolean containsPlayer() – returnerer om spilleren står på feltet.
  • boolean containsBox() – returnerer om en boks står på feltet.
  • String toString() – skriver tegnet på feltet til en streng.
  • int getX(), getY() – returnerer henholdsvis x- og y- koordinatene til feltet

Merk at man i alle metoder må sikre at det spillet er i gyldig tilstand før man og etter man utfører en operasjon. Ved behov kan også andre tilgangsmetoder legges til.

Implementer støtte for tilstand og metoder beskrevet over slik at JExercise-testkoden fullfører feilfritt. Testkoden finner du her: 

Del 2 – Logikk og representasjon av brett (60 %)

Tilstanden i Sokoban-klassen må holde rede på flere ting. Man må håndtere hvordan brettet ser ut til enhver tid. Videre må man holde styr på hvor målene på brettet befinner seg. Spillerens posisjon må også lagres.

Det finnes mange ulike brett av forskjellig størrelse. Tilstanden bør derfor lagre størrelsen på brettet, både høyde og bredde. Brettet utgjør et koordinatsystem med følgende innhold:

*###########*
#           #
#  ... ...  #
#  *$$ $.$  #
# $*+$ $*$$ #
#  *$$ $.$  #
#  ...  .   #
#           #
*###########* 

 

 

 

 

Et trekk ned (sør) gir følgende brett

*###########*
#           #
#  ... ...  #
#  *$$ $.$  #
# $*.$ $*$$ #
#  *@$ $.$  #
#  .*.  .   #
#           #
*###########*

Sokoban-klassen må ha følgende metoder:

  • Sokoban(String[]) – konstruktøren skal ta inn en array med strenger som utgjør brettet. Strengene må leses og angi starttilstanden for hvert felt på brettet.
  • boolean canMove(int) – denne metoden tar inn en retning og angir om spilleren kan bevege seg i denne retningen eller ikke.
  • void doMove(int) – denne metoden tar inn en retning og flytter spilleren og en eventuell boks i den angitte retningen på brettet.
  • boolean hasWon() – denne metoden returnerer hvorvidt spilleren har vunnet eller ikke; med andre ord om alle målene har bokser på.
  • String toString() – denne metoden returnerer brettet som en streng, hvor hver linje er adskilt med ”\n”.

Det ligger fire testbrett du kan bruke i filen: objectstructures/SampleLevels.java. Ved å kalle Sokoban(SampleLevels.level3) vil du opprette dette brettet:

#######
#.@ # #
#$* $ #
# $ #
# .. #
# * #
#######

Implementer støtte for tilstand og metoder beskrevet over slik at JExercise-testkoden fullfører feilfritt. Testkoden finner du her: 

Del 3 - Fullt fungerende spill, med tekstlig interaksjon (25 %)

Lag SokobanProgram klasse som lar deg spille spillet gjennom konsollen. Programmet må:

  • skrive ut brettet.
  • be om og lese inn retningen spilleren skal bevege seg med en Scanner. Vanlig spillkutyme er at ’w’, ’s’, ’a’ og ’d’ representerer henholdsvis bevegelse fremover (nord), bakover (sør), venstre (vest) og høyre (øst). Hvis spilleren forsøker et ulovlig trekk, e.g. gå inn i en vegg eller skyve en boks på en annen boks, skal det skrives ut en beskjed om at trekket er ulovlig.
  • utføre trekket.
  • gjenta dette helt til spilleren har vunnet eller valgt å avslutte. Hvis spilleren vinner må dette skrives ut til konsollen.

Eksempel på fungerende spill (input er vist i grønt):

 


JExercise lar deg sjekke din egen kode vha. forhåndslagde JUnit-tester og JExercise-panelet

Bruk av JExercise:

  1. Sørg for at jexercise-standalone.jar er lagt til i ditt prosjekts Build Path. Dette må gjøres hver gang du oppretter et nytt prosjekt, og det er derfor lurt å gjenbruke samme prosjekt til alle oppgaver.
  2. JExercise-tillegget må være installert. Installer tillegget fra følgende oppdateringsadresse: http://folk.ntnu.no/hal/dev/updatesite.
  3. Åpne JExercise-panelet via Window -> Show View -> Other, og navigere deg fram til JExercise i vinduet som kommer opp, velge det og klikke OK.
  4. Klikke og dra oppgavens testklasse, <oppgavenavn>Test.java fra pakkeoversikten og slippe den i JExercise panelet. 
  5. Testene kan så kjøres ved å dobbeltklikke på testen som ønskes kjørt.

Ved trøbbel, se først om du finner løsningen i Løsninger på trøbbel med JExercise.

Unknown macro: {html}

Twitre gjerne om oppgaven når du er ferdig: <a href="https://twitter.com/share" class="twitter-share-button" data-hashtags="jexercise">Tweet</a>
<script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+'://platform.twitter.com/widgets.js';fjs.parentNode.insertBefore(js,fjs);}}(document, 'script', 'twitter-wjs');</script>

 

 

  • No labels