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