Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

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.

...

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

Utgansposisjon Utgangsposisjon 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

 

...

Implementasjon 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å kunne lese av brett på samme format som brettene oppgitt i Java-filen under.
  • Brett-klassen må ha en toString()-metode som skriver ut brettet slik det er beskrevet under.
  • Spillet må kunne spilles gjennom konsollen. 
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:

Hint:
  • I representasjonen av brettet kan det være lurt å skille mellom de faste (vegger ++) og de bevelige (spilleren ++) delene av brettet
  • For interaksjon med spilleren er det lurt å bruke en Scanner
  • 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

...

.
#######
#.

...

  # #
#$* $ #

...

 $@ 

...

#
# ..

...

  #

...

 

...

*  

...

#
#######

...


Vurdering

Oppgaven blir vurdert etter hvorvidt spillet kan

  • Nivå 0 (10%): skrive ut brettet ved oppstart.
  • Nivå 1 (30%): flytte spilleren (med input fra brukeren) i et tomt brett; altså ingen vegger, bokser eller mål.
  • Nivå 2 (40%): utvide med vegger, men fortsatt ingen bokser eller mål.
  • Nivå 3 (60%): utvide med bokser som kan flyttes, men ingen mål.
  • Nivå 4 (80%): full støtte for alt ruteinnhold.
  • Nivå 5 (100%): logikk for spillets gang, dvs. oppdage at alle målrutene er dekket av bokser.
Eksempel

Eksempel på et

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):

...