Programexempel: tärningsspel Programexempel: tärningsspel
Transcription
Programexempel: tärningsspel Programexempel: tärningsspel
Programexempel: tärningsspel Programexempel: tärningsspel Kasta tärning tills etta Vi börjar med att lösa det enklare delproblemet att kasta en tärning tills den visar en etta. Därefter utökar vi programmet stegvis. Skriv ett program som låter en användare spela detta tärningsspel: Spelaren gör första tärningsslaget och får samma poäng som tärningen visar. Sedan fortsätter spelet enligt följande regler: Algoritm: Om tärningen visar något annat än en etta adderas antal prickar tärningen visar till spelaren poäng. Om spelaren slår en etta sätts poängsumman till 0 och spelet avbryts. Spelaren kan inför varje tärningsslag välja att avbryta spelet och nöja sig med den poäng som uppnåtts. EDAA20 (F5-7 programmering) HT 2015 25 / 48 kasta tärningen int sum = antal prickar så länge summan ej är lika med 0 kasta tärningen om tärningen visar en etta sum = 0 annars sum = sum + antal prickar EDAA20 (F5-7 programmering) Klassen Die Slumptalsgenerator Specifikation Klassen Random Vi behöver en klass som beskriver en tärning. Den ska ha metoder för att kasta tärningen och för att läsa av antal prickar: ↵ /** Skapar en tärning. */ public Die(); 26 / 48 Inuti klassen Die behöver vi dra slumpmässiga tal mellan 1 och 6. Slumptal får man med hjälp av standardklassen java.util.Random. ↵ /** En slumptalsgenerator med slumptalsfröet seed. */ Random(long seed); /** En slumptalsgenerator med ett slumpmässigt slumptalsfrö. */ Random(); /** Kastar tärningen. */ public void roll(); /** Slumpmässigt heltal i intervallet [0,n). */ int nextInt(int n); /** Tar reda på resultatet av det senaste kastet. */ public int getResult(); ⌦ EDAA20 (F5-7 programmering) HT 2015 HT 2015 27 / 48 /** Slumpmässigt reellt tal i intervallet [0,1.0). */ double nextDouble(); ⌦ EDAA20 (F5-7 programmering) HT 2015 28 / 48 Övning Slumptal Dra slumptal inom ett heltalsintervall Exempel: krona eller klave Lägg till programkoder för att dra ett slumptal i intervallet [0,5] och ett slumptal i intervallet [1,6]. Random rand = new Random(); EDAA20 (F5-7 programmering) HT 2015 29 / 48 Random rand = new Random(); if (rand.nextDouble() < 0.5) { System.out.println("krona"); } else { System.out.println("klave"); } EDAA20 (F5-7 programmering) Slumptal Tärning Exempel: tippa 1, x eller 2 Klassen Die 30 / 48 public class Die { private static Random rand = new Random(); private int pips; // antal prickar som visas Sannolikhet för 1 ska vara 55% -”x -”- 15% -”2 -”- 30% /** Skapar en tärning. */ public Die() { roll(); // så att pips får ett värde 1..6 } Random rand = new Random(); double nbr= rand.nextDouble(); char res; if (nbr < 0.55) { res = ’1’; } else if (nbr < 0.7) { res = ’x’; } else { res = ’2’; } /** Kastar tärningen. */ public void roll() { pips = 1 + rand.nextInt(6); } } EDAA20 (F5-7 programmering) HT 2015 HT 2015 31 / 48 /** Tar reda på resultatet av det senaste kastet. */ public int getResult() { return pips; } EDAA20 (F5-7 programmering) HT 2015 32 / 48 Klassen Die – kommentarer Anropa metod på objektet självt För att tärningen ska få ett vettigt startvärde anropas metoden roll inuti konstruktorn: Slumptalsgeneratorn rand är ett statiskt attribut. Det betyder att rand hör till själva klassen Die och inte till något enskilt tärningsobjekt. Alla tärningsobjekt man skapar delar på samma slumptalsgenerator. Man får då en bättre fördelning av slumptalen jämfört med om varje tärning har sin egen slumptalsföljd. /** Skapar en tärning. */ public Die() { roll(); } Ett anrop av nextInt(6) ger ett heltal mellan 0 och 5. För att få ett slumptal mellan 1 och 6 får vi göra så här: pips = rand.nextInt(6) + 1; För att tärningen ska få ett vettigt startvärde anropas metoden roll inuti konstruktorn. EDAA20 (F5-7 programmering) HT 2015 33 / 48 Normalt anger man med punktnotation vilket objekt en metod ska utföras på. Det behövs inte i det här fallet. Metoden roll är deklarerad i den här klassen och utförs på det aktuella objektet. Man kan också anropa metoden så här: this.roll(); EDAA20 (F5-7 programmering) Programexempel: tärningsspel Summering Kasta tills tärningen visar en etta Mönster 34 / 48 Uppgift: Beräkna summan av ett antal termer. Die d = new Die(); d.roll(); int sum = d.getResult(); System.out.println("Poäng: " + sum); while (sum != 0) { d.roll(); if (d.getResult() == 1) { sum = 0; } else { sum = sum + d.getResult(); System.out.println("Poäng: " + sum); } Lösning: Deklarera och nollställ en variabel som håller reda på det aktuella värdet av summan. Gå sedan igenom termerna en efter en och addera varje term till summan. Algoritmen i pseudokod: sum = 0; för alla termer { term = "nästa term" sum = sum + term; } } EDAA20 (F5-7 programmering) HT 2015 HT 2015 35 / 48 EDAA20 (F5-7 programmering) HT 2015 36 / 48 Programexempel: tärningsspel Programexempel: tärningsspel Låt spelaren välja när det är dags att avbryta Låt spelaren välja när det är dags att avbryta Lägg till programkod som låter användaren av programmet avgöra när det är dags att sluta slå tärningen. Algoritm: kasta tärningen int sum = antal prickar fråga om användaren vill fortsätta så länge sum är skild från 0 och användaren vill fortsätta kasta tärningen om tärningen visar en etta sum = 0 annars sum = sum + antal prickar fråga om användaren vill fortsätta EDAA20 (F5-7 programmering) HT 2015 37 / 48 Die d = new Die(); d.roll(); int sum = d.getResult(); Scanner scan = new Scanner(System.in); System.out.println("Poäng: " + sum); System.out.println("Vill du fortsätta (ja/nej)"); String answer = scan.next(); while (sum != 0 && answer.equals("ja")) { d.roll(); if (d.getResult() == 1) { sum = 0; } else { sum = sum + d.getResult(); System.out.println("Poäng: " + sum); System.out.println("Vill du fortsätta (ja/nej)?"); answer = scan.next(); } } System.out.println("Du fick " + sum + " poäng."); EDAA20 (F5-7 programmering) Programexempel: tärningsspel Programexempel: tärningspel Alternativ – avbryt med break Antal tärningsslag, max antal poäng Die d = new Die(); d.roll(); int sum = d.getResult(); Scanner scan = new Scanner(System.in); while (sum != 0) { System.out.println("Poäng: " + sum); System.out.println("Vill du fortsätta (ja/nej)?"); String answer = scan.next(); if (!answer.equals("ja")) { break; } d.roll(); if (d.getResult() == 1) { sum = 0; break; } else { sum = sum + d.getResult(); } } EDAA20 (F5-7 programmering) HT 2015 HT 2015 38 / 48 Hur mycket poäng kan det vara rimligt att förvänta sig (maximalt och i genomsnitt)? Låt programmet simulera ett stort antal spelomgångar och skriv ut den största poängumman som uppnåddes samt den genomsnittliga poängsumman. Utgå från programmet som kastar tärningen tills det blir en etta. Ändra stegvis koden på följande sätt: Låt programmet skriva ut antal poäng som uppnåtts innan kastet med den avslutande ettan. Tag bort alla övriga utskrifter. Låt programmet upprepa antal spelomgångar ett stort antal gånger. Istället för att skriva ut en poängsumma per spelomgång ska nu programmet ändras så att det skriver ut den största poängsumman som uppnåddes. Lägg till kod för att beräkna och skriva ut den genomsnittliga poängsumman. 39 / 48 EDAA20 (F5-7 programmering) HT 2015 40 / 48 Beräkna maximum Konstanter för minsta och största tal Mönster Uppgift: Beräkna det största talet i en följd av tal. Lösning: Deklarera en variabel max som ska hålla reda på det hittills största värdet. Låt max få ett litet startvärde. Gå sedan igenom talen och jämför med max. Uppdatera max ifall det aktuella talet är större. Konstanter för minsta respektive största värde ett int-tal kan ha: Algoritmen i pseudokod: max = "litet värde"; för alla värden { value = "nästa värde"; if (value > max) { max = value; } } EDAA20 (F5-7 programmering) int i1 = Integer.MIN_VALUE; int i2 = Integer.MAX_VALUE; // -2147483648 // 2147483647 double d1 = Double.MIN_VALUE; double d2 = Double.MAX_VALUE; double d3 = -Double.MAX_VALUE // 4.9E-324 (OBS! >0) // 1.8E308 // -1.8E308 Med E menas ”gånger 10 upphöjt till” HT 2015 41 / 48 EDAA20 (F5-7 programmering) Beräkna minimum Beräkna maximum Mönster Övning Uppgift: Beräkna det minsta talet i en följd av tal. Lösning: Deklarera en variabel min som ska hålla reda på det hittills minsta värdet. Låt min få ett stort startvärde. Gå sedan igenom talen och jämför med min. Uppdatera min ifall det aktuella talet är mindre. Algoritmen i pseudokod: HT 2015 42 / 48 Beräkna och skriv ut det största talet av ett antal heltal som läses in från tangentbordet. Fyll i den kod som saknas. Scanner scan = new Scanner(System.in); int max = Integer.MIN_VALUE; while (scan.hasNext()) { int nbr = scan.nextInt(); min = "stort värde"; för alla värden { value = "nästa värde"; if (value < min) { min = value; } } EDAA20 (F5-7 programmering) HT 2015 43 / 48 EDAA20 (F5-7 programmering) HT 2015 44 / 48 Programexempel: tärningspel Heltalsdivision och rest Antal tärningsslag, max antal poäng, forts Det färdiga programmet finns på kursens hemsida. a / b ger ett heltal som resultat om både a och b är heltal. För att beräkna den genomsnittliga poängsumman ska man dividera totala poängsumman med antal spelomgångar. Exempel: 17 / 3 är lika med 5 (heltalsdivision) 17 % 3 är lika med 2 (rest vid heltalsdivision) Tänk på att Java vid division ger resultatet i form av ett heltal om bägge operanderna är heltal. Se därför till att en av operanderna har typen double. Ex: 3 personer ska rättvist dela på 17 kakor. Alla får 5 kakor var och 2 kakor blir över. System.out.println(totalSum / (double) n); EDAA20 (F5-7 programmering) HT 2015 45 / 48 EDAA20 (F5-7 programmering) Heltalsdivision och rest Heltalsdivision och rest Exempel på användning Exempel på användning Avgör om x är udda eller jämnt: 46 / 48 Skriv ut antal timmar och minuter mellan start- och sluttid. if (x % 2 == 0) { System.out.println("jämnt" ); } else { System.out.println("udda"); } System.out.println("Skriv starttid och sluttid " + "(timmar och minuter):"); Scanner scan = new Scanner(System.in); int startHour = scan.nextInt(); int startMin = scan.nextInt(); int stopHour = scan.nextInt(); int stopMin = scan.nextInt(); int minutes = 60 * (stopHour - startHour) + (stopMin - startMin); Avgör om x är jämnt delbart med 10: if (x % 10 == 0) { System.out.println("x är jämnt delbar med 10"); } EDAA20 (F5-7 programmering) HT 2015 HT 2015 System.out.println("Tidsavstånd " + minutes/60 + " timmar och " + minutes % 60 + " minuter"); 47 / 48 EDAA20 (F5-7 programmering) HT 2015 48 / 48