BPS #20: Kopfrechnen-Spiel - Auswertung

Übersicht BlitzMax, BlitzMax NG Beginners-Corner

Neue Antwort erstellen

Xeres

Moderator

Betreff: BPS #20: Kopfrechnen-Spiel - Auswertung

BeitragSo, Mai 27, 2012 10:20
Antworten mit Zitat
Benutzer-Profile anzeigen
Das war die Aufgabe

Postet hier eure Ergebnisse, Codes, Gedanken. Lernt von den anderen, seht euch deren Quelltext an und versucht euren eigenen zu verbessern.

Diskussion
Postet zu euren Codes stets eine kurze Erklärung mit euren Gedanken in denen ihr simpel gesagt die Frage "Wieso habe ich XY auf diese Art gelöst?" beantwortet. Beiträge, die nur den Code enthalten werden wir aus dem Thread entfernen.

Nächste Aufgabe
In einer Woche wird die Musterlösung nach editiert und in 2 die nächste Aufgabe eingestellt.

Viel Spaß & viel Erfolg!

Musterlösung:
BlitzMax: [AUSKLAPPEN]
SuperStrict
' BPS: Holzchopf - Kopfrechnen-Spiel

Rem
Eine mögliche Lösung ist, dem Benutzer fix 10 Aufgaben zu stellen.
Eine richtige Antwort gibt Pluspunkte, eine falsche Punkteabzug,
die Punkte sind dabei abhängig von der Zeit, die fürs Beantworten
benötigt wurde.
Dazu wird beim Eröffnen der Frage die Zeit genommen, ebenso zum
Zeitpunkt der Eingabe (Eingabe = Beantworten der Frage, unabhängig
davon, ob etwas sinnvolles oder überhaupt etwas eingegeben wurde),
die Zeiten werden dann subtrahiert und man erhält so die benötigte
Zeit für die Aufgabe.
Um nun etwas damit anfangen zu können, wird pro aufgabe eine Zeit
vorgegeben. Kommt die richtige Antwort bevor die Richtzeit durch
ist, ist der Punktezuschlag höher, nach der einfachen Formel:
Punktezuschlag = Richtzeit - Benötigte Zeit
Um dabei nicht Punkteabzug für eine richtige, aber zu langsam be-
antwortete Frage zu kriegen, wird der Punktezuschlag auf ein mini-
mum angehoben, sollte dieser darunter liegen.
Der Punkteabzug für falsche Antworten errechnet sich ähnlich:
Punkteabzug = Benötigte Zeit
Hierbei gibts keine Limite. Braucht der Benutzer eine Minute, um
auf ein falsches Resultat zu kommen, ist das nun mal weniger gut,
als in einer Sekunde die selbe falsche Antwort zu geben.
Die Vorgabezeit ist unabhängig von der Art der Rechnung immer
gleich. Egal ob Addition, Subtraktion, Multiplikation oder Divi-
sion.
Die Richtzeit ist durch die Konstante TIME_PER_TURN und der mini-
male Punktezuschlag durch MIN_SCORE festgelegt.
EndRem


SeedRnd MilliSecs()

' Richtzeit pro Rechung in ms
Const TIME_PER_TURN:Int = 10000
' Mindestpunktezuschlag für eine richtige Antwort
Const MIN_SCORE:Int = 1000
' Rechnungen pro Spiel
Const TURNS_PER_GAME:Int = 10

Local score:Int ' Punktestand
Local turn:Int ' Frage

' einfache Hauptschleife
While Not KeyHit(KEY_ESCAPE)
Print
Print "**************************************************"
Print
' Eröffnungsbild anzeigen
If turn=0
Print
Print "Willkommen zum Kopfrechnen-Spiel!"
Print
Print "Anschliessend werden dir "+TURNS_PER_GAME+" Rechenaufgaben"
Print "gestellt. Für eine richtige Antwort erhälst du"
Print "Punkte, abhängig davon wie schnell du warst. Eine"
Print "falsche Antwort führt jedoch zu Punkteabzug."
Print
Print "Drücke Enter, um das Spiel zu starten."
Input("")
turn = 1
' Gameover-Bild anzeigen
ElseIf turn>TURNS_PER_GAME
Print
Print "Das Spiel ist um."
Print
Print "Du hast "+score+" Punkte erreicht."
Print
Print "Drücke Enter, um nochmal zu spielen."
Input("")
turn = 1
score = 0
' Fragen anzeigen
Else
Print
Print "Aufgabe "+turn
turn :+ 1
Print
' Startzeit merken
Local startTime:Int = MilliSecs()
' Aufgabe generieren
Local v1:Int,v2:Int,result:Int
Local op:Int=Rand(1,100)
' Addition
If op<=50
v1 = Rand(1,100)
v2 = Rand(1,100)
result = v1+v2
Print v1+"+"+v2+"=?"
' Subtraktion
ElseIf op<=75
v1 = Rand(1,100)
v2 = Rand(1,100)
result = v1-v2
Print v1+"-"+v2+"=?"
' Multiplikation
ElseIf op<=90
v1 = Rand(1,10)
v2 = Rand(1,20)
result = v1*v2
Print v1+"*"+v2+"=?"
' Division
Else
v1 = Rand(1,10)
v2 = Rand(1,20)
result = v1*v2
Print v1+"*?="+result
result = v2
EndIf
Print
' Eingabe speichern
Local in:String = Input("Eingabe:")
Print
' Endzeit (nach Input) merken
Local endTime:Int = MilliSecs()
Local time:Int = endTime-startTime
' eingegebenen Text als Zahl speichern
Local inVal:Int = Int(in)
' Resultat prüfen
Local addscore:Int
If inVal=result ' richtig
' Punktezuschlag
addscore = TIME_PER_TURN-time
' Mindespunkte anrechnen
addscore = Max(addscore,MIN_SCORE)
Print "Richtig!"
Print "Du erhälst "+addscore+" Punkte"
Print
Print
Else ' falsch
addscore = -time
Print "Falsch."
Print "Das gibt "+Abs(addscore)+" Punkte Abzug"
Print
Print "Richtig wäre: "+result
EndIf
score :+ addscore
Print "Punktestand: "+score
EndIf
Wend
End
Win10 Prof.(x64)/Ubuntu 16.04|CPU 4x3Ghz (Intel i5-4590S)|RAM 8 GB|GeForce GTX 960
Wie man Fragen richtig stellt || "Es geht nicht" || Video-Tutorial: Sinus & Cosinus
T
HERE IS NO FAIR. THERE IS NO JUSTICE. THERE IS JUST ME. (Death, Discworld)
  • Zuletzt bearbeitet von Xeres am Mo, Jun 11, 2012 0:06, insgesamt 2-mal bearbeitet
 

bizzl

Betreff: Hier meine Lösung

BeitragMo, Mai 28, 2012 16:29
Antworten mit Zitat
Benutzer-Profile anzeigen
Ich habe mir vor kurzem BlitzMax gekauft und experimentiere ein wenig damit herum.

Das ist dabei herausgekommen:
Code: [AUSKLAPPEN]

Rem
   Ich habe einen -zugegeben primitiven- Formelparser geschrieben, um die Rechenaufgaben
   per Zufallsgenerator erstellen zu können.
   Der Formelparser beherrscht nur die 4 Grundrechenarten (Punkt- vor Strichrechnung)
   und kann mit negativen Zahlen umgehen.
   Es fehlen Klammerrechnug und Trigonometrie, das war für diese Aufgabe allerdings
   auch nicht gefordert.
endrem

SuperStrict

Global a:TList = New TList 'hier wird der Term eingetragen

'Die Funktion "Rechne" ist die Startfunktion des Formelparsers.
'Hier wird die als String übergeben Rechenaufgabe in eine Liste umgewandelt.
'In dieser Liste stehen abwechselnd die Zahlen und die Operatoren.
Function Rechne:String(Ausdruck:String)
   Local e:String
   a.clear()
   For Local c:Int=0 Until Ausdruck.length
      Local z:Byte = Ausdruck[c]
      If z = Asc("-") And e = "" e = "-" ; Continue 'negatives Vorzeichen?
      If z >= Asc("0") And z <= Asc("9") 'Ziffer ?
         e:+ Chr(z)   
         Else   'Operator ?
         a.addlast(e) 'Zahl und...
         e = ""
         a.addlast(Chr(z)) '...Rechenzeichen in Liste schreiben
      EndIf
   Next
   a.addlast(e) 'Letzte Zahl anhängen
   Pri() 'Liste nach Priorität abarbeiten
   Return a.first().tostring() 'und Ergebnis zurückgeben
EndFunction

Function Pri()
   Local rz:String
   For rz = EachIn a 'Hier wird die Liste zuerst nach Punkt...
      If rz = "*" Scan("*")
      If rz = "/" Scan("/")
   Next
   For rz = EachIn a '...und dann nach Strichrechnung durchgegangen
      If rz = "+" Scan("+")
      If rz = "-" Scan("-")
   Next
EndFunction

Function Scan(z:String)
   Local t:TLink = a.findlink(z) 'Rechenzeichen suchen   
   Local l:TLink = t.prevlink() 'Zahlen links und...
   Local r:TLink = t.nextlink() '... rechts davon bestimmen
   Local links:String = l.value().tostring()
   Local rechts:String = r.value().tostring()
   Local ergebnis:String
   Select z 'je nach Rechenzeichen Berechnung ausführen
      Case "*" ergebnis = links.toint() * rechts.toint()
      Case "/"
         If rechts.toint() = 0 Notify("Division durch Null!") ; End
         ergebnis = links.toint() / rechts.toint()
      Case "+" ergebnis = links.toint() + rechts.toint()
      Case "-" ergebnis = links.toint() - rechts.toint()
   EndSelect    
   t.remove 'den berechneten Ausdruck...
   l.remove
   a.insertafterlink(ergebnis , r) 'durch das Ergebnis...
   r.remove   'ersetzen
EndFunction

'Spielstart
Local r:String[] = ["+" , "-" , "*" , "+"] , jn:String
'Um es nicht zu schwer zu machen, habe ich die Division draußen gelassen,
'dafür die Chance auf Addition verdoppelt
SeedRnd MilliSecs()
Local maximum:Int
Repeat
   Local schwer:Int   
   Local pGes:Int = 0 , richtig:Int = 0
   Repeat
      schwer = Input("~n~nSchwierigkeitsgrad (1-5) ?").toint()
   Until schwer > 0 And schwer < 6
   For Local aufgabe:Int = 1 To 10 'wir wollen 10 Aufgaben lösen
      Local    l:Int = Rand(Schwer) 'Anzahl der Rechenzeichen
      Local p:Int = l + 1 'je länger die Aufgabe ist, desto meht Punkte gibt es
      Local e:String
      While l
         Local z:String = r[Rand(0 , 3)]
         maximum = 99 'Bei Strichrechnung sind Zahlen von 1-99 zugelassen,
         If z = "*" Or z = "/" maximum = 9 'bei Punktrechnung Zahlen von 1-9
         e:+ Rand(maximum) 'Rechenaufgabe zusammensetzen
         e:+ z
         l:- 1
      EndWhile
      e:+ Rand(maximum)
      Local loesung:Int=Rechne(e).toint() 'Die Lösung
      Print "~nAufgabe " + aufgabe + ":"
      Print "~t"+e+" = ?"
      Local eingabe:Int = Input("~t>").toint()
         If eingabe = loesung
         Print "~tRichtig!"
         Print "~t" + p + " Punkte."
         pGes:+ p
         richtig:+ 1
         Else
         Print "~tLeider falsch!"
         Print "~t" + e + "=" + loesung
      EndIf   
   Next
   Print "~n~tSie haben " + richtig + " mal richtig geantwortet und " + pges + " Punkte erreicht."
    jn = Input("~tNoch ein Spiel ? (j/n)")
   If jn <> "j" Exit
Forever

Xeres

Moderator

BeitragMi, Mai 30, 2012 12:10
Antworten mit Zitat
Benutzer-Profile anzeigen
Sehr hübsch! Die vielen einbuchstabigen Variablen könnten etwas länger und selbsterklärender sein, aber bis auf die Kosmetik sehr Vorbildlich.
Win10 Prof.(x64)/Ubuntu 16.04|CPU 4x3Ghz (Intel i5-4590S)|RAM 8 GB|GeForce GTX 960
Wie man Fragen richtig stellt || "Es geht nicht" || Video-Tutorial: Sinus & Cosinus
T
HERE IS NO FAIR. THERE IS NO JUSTICE. THERE IS JUST ME. (Death, Discworld)

Neue Antwort erstellen


Übersicht BlitzMax, BlitzMax NG Beginners-Corner

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group