TDDC74 Programmering, abstraktion och modellering Projektspecifikation Äventyrsspel Riket 2014-03-22 Projektmedlemmar: Ron Gilbert <rongi123@student.liu.se> Donald Knuth <donkn007@student.liu.se> Handledare: Anders Mörak Leffler <anders.marak.leffler@liu.se>
Innehåll 1 Projektplanering...1 1.1 Spelhistoria...1 1.2 Tänkt användarfall...2 1.3 Utvecklingsmetodik...3 1.4 Grov tidplan...3 1.5 Betygsambitioner...4 2 Krav och mål...4 2.1 Kravlista...4 3 Implementation...5 3.1 Algoritmer...5 3.2 Abstrakta datatyper...5 3.2.1 World...5 3.2.2 Character...6 3.2.3 Place...6 3.2.4 Thing...6 3.3 Testning...6 4 Tidrapportering...7 4.1 Donald Knuth...7 4.2 Ron Gilbert...7
1 Projektplanering Det här projektet går ut på att skapa ett textbaserat äventyrsspel. Spelaren kommer interagera med spelet genom att skriva in olika kommandon med hjälp av tangentbordet, och spelet kommer skriva ut text på skärmen spelaren kan läsa. Detta kommer ske i en read-eval-print-loop. 1.1 Spelhistoria Spelet består av en värld som är uppbyggd av olika platser som är utplacerade på olika rutor i ett rutnät. På varje plats kan det finnas karaktärer och föremål. Karaktärer kan...:...interagera med varandra, till exempel prata....nyttja föremål, till exempel använda en kniv för att döda en annan karaktär....gå mellan två intilliggande platser, till exempel mellan Gatan och Hem i figur 1 nedan. Y ^ +-----------+ 2 Kyrkan +-----------+ +-----------+ +-----------+ +-----------+ 1 Gatan Marknaden Butiken +-----------+ +-----------+ +-----------+ +-----------+ 0 Hem +-----------+ --+--------------------------------------------> X 0 1 2 Figur 1, Exempel på hur en spelvärld kan se ut. Historien utspelar sig i ett rike lång, långt borta, där ens framgång mäts i ens talang i spelet sten-sax-påse. I detta rike lever tronarvingen Robin, som inom kort ska gifta sig med rikets främste sten-sax-påse-spelare. Till följd av Robins skönhet anstränger sig alla (kvinna som man, släkting som främling) i hela riket till sitt yttersta för att bli den främste sten-sax-påse-spelaren. Hur bra sten-sax-påse-spelare man är framgår av hur många ssp-mynt (sten-sax-påse-mynt) man har, så den som har flest ssp-mynt när bröllopet äger rum blir den andra huvudpersonen i bröllopet, och den lyckligaste människan i världen. Spelaren kommer styra en av karaktärerna i riket, och spelets mål är så klart att vara den bäste sten-sax-påse-spelaren i hela riket när bröllopet äger rum, så man får gifta sig med Robin. Genom att utmana andra karaktärer i spelet på sten-sax-påse-dueller, som spelas bäst av 10 omgångar, har man chans att vinna ssp-mynt från andra karaktärer. Självklart förlorar man ssp-mynt till ens motståndare om man förlorar duellen. 1
De datorstyrda karaktärerna i spelet kommer inte göra helt slumpmässiga drag när de spelar sten-sax-påse, utan på olika sätt kan man alltid vinna över dem om man listat ut deras strategi. Till exempel kan en karaktär med namnet Rocker alltid att välja sten, och en karaktär som råkat peta ut sitt ena öga med en sax när denne var liten kommer aldrig välja sax. Desto mer svårupptäckt strategi karaktären har, desto fler ssp-mynt spelar man om i duellen. Speciella föremål i spelet kan användas för öka sina chanser till att äga flest ssp-mynt när bröllopet äger rum. Till exempel kan man använda en kniv för att få en färre konkurrent att oroa sig för. 1.2 Tänkt användarfall Användaren öppnar huvudfilen i DrRacket och skriver (play-game) för att starta spelet. Spelaren möts direkt av en kort introduktionstext, varefter read-eval-print-loopen tar vid. Det kommer se ut som något i stil med detta (text inmatad från användaren är fetstilt): (play-game) Välkommen till Riket! Om 5 minuter kommer tronarvingen Robins bröllop att hållas. Se till att du är den karaktär med flest ssp-mynt i hela riket då, annars gifter sig Robin med någon annan! Skriv 'hjälp' för spelinstruktioner. >> status Du har 0 ssp-mynt. Bröllopet börjar om 4 minuter och 53 sekunder. >> titta runt Du är i ditt hem. På golvet finns en plånbok. Åt norr ligger gatan. >> plocka upp plånbok Plånboken innehöll 5 ssp-mynt. Jippi! >> status Du har 5 ssp-mynt. Bröllopet börjar om 4 minuter och 45 sekunder. >> gå åt norr >> titta runt Du är på gatan. En tiggare ser förväntansfullt på dig. Åt söder ligger ditt hem. Åt öster ligger marknaden. >> prata med tiggare tiggare säger: Hej där! Vill du duellera med mig? Ska vi satsa 1 ssp-mynt? >> titta på tiggare Den stackars människan saknar en hand och har bara lång- och pekfingret kvar på den andra. >> duellera med tiggare Game on! Round 1 Vad väljer du? >> sax tiggare valde sax Round 1 slutar lika. Det står 0-0. 2
Round 2 Vad väljer du? >> sten tiggare valde sax Du vinner Round 2! Du leder med 1-0! Round 3 Vad väljer du? >> sten tiggare valde sax Du vinner Round 3! Du leder med 2-0! Round 10 Vad väljer du? >> sten tiggare valde sax Du vinner Round 10. Du vann duellen med 9-0! Du vann ett ssp-mynt av tiggare. >> status Du har 6 ssp-mynt. Bröllopet börjar om 4 minuter och 3 sekunder. >> gå mot butiken Du gick åt öster. 1.3 Utvecklingsmetodik Vi planerar i första hand att arbeta under schemalagd tid, men även under övrig tid om det skulle visa sig nödvändigt. Vi träffar varandra dagligen i skolan, så vi bör ha ganska bra koll på vad den andre har gjort. Vi kommer att använda SVN för att versionshantera vår kod. 1.4 Grov tidplan Till en början arbetar vi tillsammans för att få en bra struktur på koden som vi båda är införstådda med (read-eval-print-loopen/spelmotorn), och fortsätter sedan med att arbeta mer individuellt med olika uppgifter (de olika kommandona) för att bli mer effektiva. Det gemensamma arbetet försöker vi få klart så snart som möjligt, så vi får chans att planera det individuella arbetet mer individuellt. Vi kommer behöva lära oss hur man arbetar med input/output i racket. Eventuellt försöker vi även lära oss hur arrayer fungerar, vilket vi tror kan förenkla vårt arbete. Till halvtidsmötet bör vi vara klara med read-eval-print-loopen och ha platser och karaktärer i spelet, så att man kan spela igenom spelet från början till slut, även om man inte kan göra så mycket i spelet. Efter halvtidsmötet kommer fokus ligga på att få igång 3
sten-sax-påse-duellerna och att lägga till olika föremål som kan användas. 1.5 Betygsambitioner Vi har båda fått betyget 3 på duggorna och GT på alla labbarna, så vi hoppas uppnå betyget 4 på projektet så att vi får betyget 4 som slutbetyg i kursen. OBS! Detta dokument ska demonstrera hur en specifikation kan se ut. Detta exempelprojekt är inte nödvändigtvis tillräckligt omfattande för detta betyg. Tolka det inte som en betygsriktlinje. 2 Krav och mål Utöver kraven i kravlistan nedan bör spelaren aldrig kunna krascha spelet genom att skriva in något olämpligt. 2.1 Kravlista # Beskrivning Prioritet 1 Man skall kunna starta spelet genom att skriva (play-game). 1 2 Spelaren skall kunna skriva kommandon i en read-eval-print-loop (kommandona avsluta och spelinstruktioner). 3 Det skall finnas platser i spelet. 3 4 Det skall finnas karaktärer (på platser) i spelet. 4 5 Spelaren skall kunna styra en av karaktärerna i spelet genom olika kommandon (titta och prata). 6 Rummen i spelet skall vara sammankopplade. 6 7 Kommandot gå åt (norr öster söder väster) skall finnas. 7 8 Spelet skall avslutas efter ett visst antal minuter. 8 9 De datorstyrda karaktärerna skall gå runt (byta plats) i spelet. 9 10 De datorstyrda karaktärerna skall duellera mot varandra. 9 11 Kommandot gå mot plats-namn skall finnas (flyttar spelaren en plats närmre plats-namn). 12 Det bör finnas en kniv i spelet som man kan döda en annan karaktär med. 13 Det bör finnas en leader board i spelet man kan titta på för att se hur många sst-mynt alla karaktärer har. 14 Man bör kunna duellera med spelet tre-i-rad. 11 15 Man bör kunna se en karta över alla platser. 11......... 2 5 9 10 10 4
42 Den hemliga symbolen UUDDLRLRBA bör slå alla andra symboler i sten-sax-påse-spelet. 18 3 Implementation 3.1 Algoritmer Vi behöver en algoritm för att avgöra vem som vinner en omgång i spelet sten-sax-påse. Eftersom det inte finns så många kombinationer (två spelare med 3 olika val vardera = 9 kombinationer) kan man ganska enkelt hårdkoda alla olika fall som kan uppstå, men vi tänker försöka oss på en mer generell lösning. Genom att byta ut sten mot 0, sax mot 1 och påse mot 2 tror vi man kan skapa ett matematiskt uttryck som beräknar utfallet åt oss. Vi behöver bara komma på hur detta uttryck ska se ut. För kommandot gå mot behöver vi en algoritm som hittar den kortaste vägen mellan två platser. Efter lite efterforskning på Internet har vi kommit fram till att det verkar vara ett känt problem inom programmering med många kända lösningsmetoder, som till exempel bredd-först-sökning, djup-först-sökning och A*. Vi ska titta närmare på dessa och sedan försöka använda den av dem som verkar mest lämplig i vårt fall. 3.2 Abstrakta datatyper 3.2.1 World Datatypen world representerar hela världen i spelet. Den kommer i princip hålla koll på vart i rutnätet platserna i spelet ligger. Det som är håll/direction i tabellen nedan är antingen norr, öster, söder eller väster. Method add-place! place x y get-place x y get-neighbour direction place-name get-directions from-name to-name get-exists place-name Beskrivning Lägger till platsen place på koordinaten (x, y). Returnerar platsen på koordinaten (x, y). Returnerar grannen till platsen med namnet place-name åt hållet direction, alternativt #f. Returnerar en lista med håll man ska gå för att komma från platsen med namnet from-name till platsen med namnet to-name. Returnerar en lista med håll man kan gå om man är på platsen med namnet place-name. 5
3.2.2 Character Datatypen character representerar en människa i spelet. Method get-name get-description has-ssp-mynt? decrease-ssp-mynt! amount increase-ssp-mynt! amount Beskrivning Returnerar namnet karaktären har. Returnerar en beskrivning av karaktären. Returnerar #t om karaktären har några (fler än 0) ssp-mynt, annars #f. Minskar antalet ssp-mynt karaktären har med amount. Ökar antalet ssp-mynt karaktären har med amount. 3.2.3 Place Datatypen place representerar en plats i spelet. Method add-character! character delete-agent! character-name get-characters get-character-names has-character? character-name get-character character-name Beskrivning Lägger till karaktären character på platsen. Tar bort karaktären med namnet character-name från platsen. Returnerar en lista med alla karaktärer på platsen. Returnerar en lista med namnen på alla karaktärerna på platsen. Returnerar #t om det finns en karaktär på platsen med namnet character-name, annars #f. Returnerar karaktären på platsen med namnet character-name. 3.2.4 Thing För föremålen kommer vi behöva ytterligare en klass, klassen thing, samt eventuell utökning av klasserna character och place som ska kunna bära/innehålla föremål, men detta lägger vi tid på längre fram. 3.3 Testning Vi kommer att ha en fil med en stor funktion som kör en massa tester när man anropar den. Den kommer i princip se ut så här: 6
(define (run-tests) (display "Börjar köra alla tester.\n") ; Testar om get-neighbour fungerar som den ska. (let ((world (new world [width 5] [height 5])) (place-a (new place [name 'place-a] [description ""])) (place-b (new place [name 'place-b] [description ""]))) (send-world add-place! place-b 0 1) (send world add-place! place-a 0 0) (unless (eq? (send world get-neighbour 'north 'place-a) place-b) (display "get-neighbour fel #1.\n")) (unless (eq? (send world get-neighbour 'south 'place-b) place-a) (display "get-neighbour fel #2.\n")) (unless (boolean? (send world get-neighbour 'north 'place-b)) (display "get-neighbour fel #3.\n")) ; Och så vidare... ) ; Testar om get-directions fungerar som den ska. (let ((world (new world [width 5] [height 5])) (place-a (new place [name 'place-a] [description ""])) (place-b (new place [name 'place-b] [description ""])) (place-c (new place [name 'place-c] [description ""]))) (send-world add-place! place-b 0 1) (send-world add-place! place-c 1 1) (send world add-place! place-a 0 0) (unless (equal? (send world get-directions 'place-a 'place-c) '(north east)) (display "get-directions fel #1\n")) ; Och så vidare... ) ; Och så vidare... (display "Alla tester är körda.\n")) Förhoppningsvis kan man även testa kommandona spelaren ska skriva in på detta sättet. 4 Tidrapportering 4.1 Donald Knuth Vecka Arbetsuppgift Tid [h] 12 Arbetat med kravspecifikation. 5 13 Läst på om objektsystemet i Racket. 0.5 4.2 Ron Gilbert Vecka Arbetsuppgift Tid [h] 12 Arbetat med kravspecifikation. 4 13 Planerat spelvärld. 0.5 7