| 
 Laboration 3 - Sten, sax, påseEtt grafiskt klientprogram där en användare spelar mot en serverPå föreläsning 6 eller 7 visas ett serverprogram som spelar sten, sax, 
påse med alla villiga klienter. Koden finns här:
Server4713.java. Uppgiften här är att skriva ett
grafiskt klientprogram som låter en användare spela sten, sax och påse
mot serverprogrammet.
Spelet är känt över hela världen. På webbsidan
Rock, paper, scissors,
kan man bland annat hitta tre gif-bilder att använda i sitt program.
 
Om servern skulle vara nere eller uppvisa något annat problem så går det
bra att som nödlösning kopiera server-programmet till den egna datorn och 
köra det där. Instruktioner finns här: 
lokalserver.html
 
 En enkel klientBörja med att testa en enkel klient utan grafik, som öppnar en förbindelse med
   try {
       Socket socket=new Socket("u3.csc.kth.se",4713);
       BufferedReader in=new BufferedReader
           (new InputStreamReader(socket.getInputStream()));
       PrintWriter ut=new PrintWriter(socket.getOutputStream());
       ut.println("Charlotta"); ut.flush();
       System.out.println(in.readLine());
   }
Klienten ska sända ett namn (här sänds Charlotta) till den server som
lyssnar på port 4713 och skriva ut det svar den får. Kom ihågut.flush();annars sänds inte namnet iväg. 
Koden ovan behöver kompletteras en hel del för att gå att köra överhuvudtaget
men även för att testa servern. 
Bland annat bör man skicka ytterligare några meddelanden till servern
och som svar få "STEN", "SAX" eller "PÅSE". För att avsluta förbindelsen
ska man skicka något som servern läser somnulleller 
tom sträng. Det fungerar t.ex. med tom sträng (""), Ctrl-D eller Ctrl-Z.
Se till att den enkla klienten fungerar innan ni går vidare och ägnar er
helt åt det grafiska gränssnittet.SwingkomponenternaDitt program kan (men behöver inte) vara enpublic class Klient extends JFrame implements ActionListener{
där vänstra halvan av fönstret är din spelplan och högra halvan är datorns
spelplan. 
De två halvorna är tillräckligt lika för att kunna representeras av objekt
av samma klass, här kalladSpelplan.
Spelplanen ska innehålla många knappar och rutor så enLayoutManagerär nödvändig. 
Det går definitivt att få en tillräckligt snygg layout genom att användaJPanelmedGridLayouti flera nivåer.
Ett alternativ ärBoxLayoutfrån swing-paketet, den är lite
svårare men också flexiblare. MedBoxLayoutså bör varje 
spelplan vara en vertikalBox. Oavsett layoutmanager
så bör varje spelplan innehålla följande:
Det går att använda Rubrik, en JLabelmed texten Jag: eller Datorn:. Meddelande, en JTextFielddär det som sänds från 
dej och från datorn syns. Först visas hälsningen, därefter det senaste draget,
dvs STEN, SAX eller PÅSE. En knapp med en stenbild 
 En knapp med en saxbild 
 En knapp med en pappersbild
 Resultat, en JLabelsom efter ett tryck visarETT...,
     efter andra trycketTVÅ...och efter tredjeVINNER,OAVGJORTellerFÖRLORAR(förklaras mer i 
stycket om Spelet). Poäng, en JTextFieldsom visar t.ex.Poäng: 7 JLabelför alla de små textfälten ovan men i
vissa sammanhang är det lättare medJTextFieldnär man
måste ha fält som är tomma från början.
En egen klass förSpelplanska definieras. Tips för Spelplan med Box och BoxLayoutSpelplankan vara subklass tillBoxoch i sin 
konstruktor anropasuper(BoxLayout.Y_AXIS);för att markera
att den är vertikal. Två objekt av den skapas och läggs bredvid varandra i 
t.ex. en horisontell box. En av fördelarna med en box är att man kan lägga 
in fasta mellanrum mellan komponenterna Om man deklarerat
 
   Box box=Box.createHorizontalBox();kan man göra så här. 
   Spelplan jag = new Spelplan("Jag:");
   Spelplan du = new Spelplan("Datorn:");
   box.add(jag);
   box.add(Box.createHorizontalStrut(20)); //Ett mellanrum
   box.add(du);
Box-objektet läggs därefter in i JFrame-objektet med metoden add.
 Tips för Spelplan med JPanel och GridLayoutOm du är ovan vid Javas grafik kan det vara lika bra att använda
enJPanelmedGridLayoutför spelplanerna.
Det går att få riktigt snyggt det också!
Varje spelplan kan delas in i 5 lika stora fält där knapparna
läggs i de tre mittersta. Översta och nedersta fälten får var sinJPanelsom i sin tur delas in 
flera fält. Om man lägger in en tomJPanelså fungerar det som ett 
mellanrum. Inte fullt så flexibelt som i enBoxmen helt OK.
Om du väljer detta alternativ för spelplanerna så använd även en
JPanelmedGridLayoutför det omgivande fönstret,
alltså det fönster där "jag" och "du" läggs in i exemplet ovan. SpeletSpelet går till så att användaren trycker på sten, sax och
påse-knapparna och vid tredje trycket läser programmet
av vilken knapp som tryckts på och draget STEN, SAX eller PÅSE registreras.
Det spelar ingen roll vilka knappar man trycker på de två första gångerna
och de knapparna behöver inte markeras med färgskifte men texten "ETT..."
respektive "TVÅ..." ska visas i resultatrutan.
De verkningslösa tryckningarna ska efterlikna att man i det manuella
spelet slår med en knuten hand i luften två gånger (räknar ett, två)
och därefter (på tredje slaget) visar sitt drag.
I samband med användarens tredje tryck ger också datorn sitt drag
(dvs programmet läser av draget från servern).
Programmet
avgör om det är oavgjort eller vem som vunnit samt uppdaterar Resultat-rutan
och Poäng-rutan.
 Några tips
 Bilderna kan tillverkas redan i deklarationen 
     ImageIcon sten=new ImageIcon("rock.gif")och samlas i en arrayIcon[] bild={sten,sax,påse}. Man kan ha användning för en textarray String[]text={"STEN","SAX","PÅSE"}. I spelplansklassen finns det nog en knapparray. Fastän
det inte står text på knapparna kan man anknyta en text med
knapp[i].setActionCommand(text[i]). Den kan man sedan
få fram iactionPerformedmede.getActionCommand()(Trevligt, men inte absolut nödvändigt i labben). Avgivna drag ska markeras så att den valda knappen ändrar färg
(eller annat utseende). Då kan en metod 
public void markera(...)i 
spelplansklassen vara lämplig. Någon eller några parametrar behövs 
i metoden men det beror ju på hur mycket metoden ska göra (bara markera
färg eller även uppdatera fälten). För varje gång användaren avger sitt drag tar programmet emot ett 
servermeddelande som skickas till metoden
     markerai datorfönstret. 
Det behövs en global variabel som räknar till tre och sedan återgår till noll.
Varje spelare ska ha en poängvariabel. Var läggs den lämpligen?
 Varje klick som är ett drag skall föregås av två 
verkningslösa klick. Klicken räknas och deras enda effekt är att
texterna "ETT..." respektive "TVÅ..." visas i resultatrutan.
 Här ställs inte kravet att hålla strikt på Model-View-Control 
(som i förra labben) och göra en modell som kan köras fristående i 
terminalfönstret. Skälet är att modellen korrekt representrad är så 
försvinnande liten, det mesta handlar här om View och Control som hänger
intimt ihop. Det är dock inte alls fel att göra en egen modell,
särskilt om man tycker att den verkar lite krånglig.
 En knapp som kopplar ner förbindelsen med servern och avslutar
programmet är trevligt att ha men inget krav.
 
 Redovisning och krav på programmet
 Demonstrera SSP-spelet som använder det givna serverprogrammet för 
att få fram datorns drag. Spelplanerna ska se ut så som beskrivs ovan.
 Programmet måste bestå av minst två klasser och de två spelplanerna
ska vara objekt av samma klass.
 Vid varje drag skall det synas hur användaren respektive datorn har
 spelat genom att knapparna ändrar färg (se tipsen!) och genom att 
dragets text skrivs ut i meddelanderutan.
 Efter varje drag visas också vem som vunnit (eller om det är OAVGJORT) 
samt aktuell poängställning.
 Ett drag utförs vid var tredje av användarens knapptryckningar.
Första trycket visar "ETT..." i resultatrutan, andra trycket 
visar "TVÅ..." och tredje trycket ger draget.
 Logiken i programmet ska vara noga genomtänkt så att det inte blir
onödigt långt och krångligt. T.ex. att ta redo på vem som har vunnit
eller om det var oavgjort kan skrivas med 9 if-satser eller med 
bara två. Lösningar utan if är också möjliga.
Kodupprepning skall undvikas!
 Uppdatering av spelplanerna ska ske genom anrop av ett fåtal metoder.
 Även punkterna 1 och 2 från 
checklistan ska redovisas.
 
 
 
  Som extrauppgift väljes en av följandeExtrauppgift, alternativ 1: Lägg till ljudeffekter!
Kan kräva hörlurar. Det bör vara minst tre olika ljud (spel, vinst, förlust).
Ljudet ska kunna slås av och på interaktivt medan man kör programmet.
Extrauppgift, alternativ 2: Bygg ut det grafiska gränssnittet så
att uppkopplingen till servern styrs därifrån. Låt användaren välja serverdator
och portnummer, antingen genom att det finns några explicita att välja på
eller skriva in namnet (t.ex. "u3.csc.kth.se") och portnumret i 
inmatningsfält.
 
 |