bild
Skolan för
elektroteknik
och datavetenskap

Laboration 2 - Hoppsansa

I den här labben ska du göra ett knepigt spel för att träna mer på komponenter, inre klasser, layouter, lyssnare och designmönstret Model-View-Control. Spelet heter Hoppsansa och ser ut så här. Det finns tre gröna pjäser (knappar) till höger, tre röda till vänster och en tom plats i mitten. Man flyttar omväxlande gröna och röda. I varje drag får en pjäs flytta till den tomma rutan om den är alldeles intill eller det finns precis en pjäs av motsatt färg mellan den man vill flytta och den tomma rutan. Först skrivs en textbaserad version av spelet och därefter den grafiska. Programmet (programmen) ska hålla reda på vilken färg som ska flyttas härnäst och inte tillåta två flyttningar i rad av samma färg. Det är ett enpersonsspel, röda och gröna spelar inte mot varandra. Det kan vara intressant att räkna hur många drag man behöver för att lösa uppgiften (och se om man kan förbätta sig) men det krävs inte. I grunduppgiften krävs inte heller att något meddelande skrivs om man försöker göra en otillåten flyttning.

Spellogiken i Model

Spellogiken ska läggas i en egen klass. Klassen ska ha åtminstone dessa två metoder som är de väsentliga för spelet:
 move(k) // flyttar pjäsen på plats k till tomma platsen om det är tillåtet
 get(k)  // returnerar innehållet (dvs färgen) på plats k
Ni får införa fler metoder om ni tycker att det behövs. Hur spelets pjäser och tom ruta ska representeras får ni bestämma själva men 0, 1 och 2 är naturliga val. Information om vems tur det är måste också finnas. Det är listigt när man skriver Model att ha en variabel tom som anger index för den tomma rutan. Tänk igenom spellogiken noga så att klassen Model blir både kort och tydlig! Observera att själva spelandet inte utförs i Spellogiksklassen. Klassen tillhandahåller metoder för att uföra spelets drag och spelandet görs av andra programdelar. Spellogiken utgör Model i Model-View-Control-mönstret och i uppgiften ingår att skriva program som spelar spelet med två olika View-Control-delar, en textbaserad och en grafisk.

Textversionen av spelet.

Så här kan det se ut när man spelar:
  GGG RRR   Välj 0-6: 2
  GG GRRR   Välj 0-6: 4
  GGRG RR   Välj 0-6:
Det texbaserade spelet kan man skriva i en egen klass eller lägga det i en main-metod i Model-klassen. Spelet spelas genom att man anropar metoder ur Model-klassen. Vi kan se det textbaserade spelet som en test av Model-klassens funktionalitet innan vi använder Model i vårt grafiska program.

Inläsning av från terminalfönster: Inläsning av text från terminalfönstret görs enklast med klassen Scanner som finns i paketet java.util. Klicka här för ett exempel på hur man använder Scanner: HejMedFragor.java.

En grafisk klass för View & Control med en inre knappklass

I den grafiska versionen av spelet måste man ha klickbara rutor som kan ändra färg. Använd en utökad version av JButton (jfr labb1) som heter t.ex. Ruta och ges en metod för att sätta knappens färg till grön, röd eller vit (för tom ruta), t.ex. så här:
   ruta[i].set(0); //Knappen blir vit
   ruta[i].set(1); //Knappen blir grön
   ruta[i].set(2); //Knappen blir röd
eller tydligare genom att definiera    static final int WHITE = 0, RED = 1, GREEN = 2;
   ruta[i].set(WHITE); //Knappen blir vit
   ruta[i].set(GREEN); //Knappen blir grön
   ruta[i].set(RED); //Knappen blir röd
I det här programmet har man antagligen inte så mycket nytta av variablerna WHITE, RED och GREEN därför att man inte sätter färgerna explicit någon gång utan läser av dem från variabler i modellen men det är en bra princip ändå.

Ruta skrivs gärna (men inte nödvändigtvis) som en inre klass i den större grafiska klass som utgör VC-delen av spelet. Lyssnare av typen ActionListener behövs för att detektera knapptryckningarna. Lyssnaren kan vara en yttre klass, en inre klass, en anonym klass eller en redan existerande containerklass. Skall man ha en enda lyssnare som lyssnar på alla knapparna eller ska varje knapp ha en egen lyssnare? Välj själva! En lösning där programmet måste gå igenom alla knapparna för att hitta vilken man tryckt på godtas inte! Efter en knapptryckning ska programmet direkt "veta" vilken knapp det var och vilket nummer den har (för vidare befordran till Model-objektet). getSource() i klassen ActionEvent är användbar.

Välj själv om View-Control-delen av programmet ska skrivas som en applet eller ett fristående program.

Anmärkning: När vi kräver en klass för Model och en klass för View-Control så är det uppdelningen i ansvar som är viktig, inte att det är just en enda klass för varje uppgift. Huvudklassen för VC kan ha flera hjälpklasser om det är ett omfattande GUI. Här föreslår vi att VC-klassen har en liten hjälpklass, Ruta.

Redovisning

Vid redovisning så skall följande visas upp och förklaras
  • En spelbar textversion av spelet med en klass för spellogiken enligt ovan. En lösning utan Model-klass, där t.ex. allt i spelet sköts i en main-metod godkänns ej.
  • En spelbar grafisk version av spelet som använder samma klass för spellogiken som textversionen gör och som har en tydlig uppdelning på Model och View-Control.
  • Ett UML-klassdiagram över den grafiska grunduppgiften enligt checklistan för labbredovisningar som återfinns här: Labbredovisning.html
Visa också att ni förstår Model-View-Control-strukturen och hur den tillämpas i uppgiften.

 

Om ni vill:

Låt det vara grodor som hoppar åt höger och pingviner som hoppar åt vänster i den grafiska versionen av programmet. Det går förstås bra med egna bilder istället för grodor och pingviner! Högerklicka på bilderna nedan om du vill spara dem till det egna programmet!

frog.gif frog.gif frog.gif                 penguin.gif penguin.gif penguin.gif

Extrauppgift för högre betyg:

Utvidga programmet så att man kan se om det är grön eller röd som ska flytta härnäst och så meddelande ges efter varje drag eller försök till drag. Användaren ska få veta om draget var OK eller fel. Om det var fel så meddelas vilken sorts fel det var. Se till att det är Modell-klassen som avgör vilken typ av fel det är, det är ju i den klassen som spellogiken finns. View-delen av programmet måste förstås presentera meddelandet för användaren. Det går utmärkt att skriva programmet inklusive extrauppgift från början!

Alternativuppgift som direkt inkluderar extrauppgiften:

Gör ett femtonspel eller luffarschack (3x3 eller större) eller annat spel som spelas på en rutindelad spelplan. Spelet ska göras enligt samma princip som Hoppsansa-spelet, dvs med en Model-klass för logiken och en grafisk VC-del. Om det är ett alternerade spel ska Model-delen hålla reda på vems tur det är. Det här är en större uppgift än Hoppsansa. En textbaserad spelversion krävs inte för detta spel, inte heller meddelande efter varje drag (även om det är önskvärt och trevligt). Se dock till att ge meddelande om att spelet är slut och vem som vann om det är tvåpersonersspel.

Redovisning av alternativuppgift

Vid redovisning så skall följande visas upp och förklaras
  • En spelbar grafisk version av spelet som är tydligt uppdelad på en klass för spellogiken (Model) och en annan klass för View-Control.
  • Ett UML-klassdiagram enligt checklistan för labbredovisningar som återfinns här: Labbredovisning.html
Visa också att ni förstår Model-View-Control-strukturen och hur den tillämpas i uppgiften.

 

Glöm inte att be om handledarens underskrift på ditt kvittensblad när du är godkänd!

Kvittensbladet finns för utskrift på kurshemsidan under Laborationer.
Copyright © Sidansvarig: Ann Bengtsson <ann@nada.kth.se>
Uppdaterad 2011-04-03