Kopfnuss Entwicklung Zufällige Aufgaben
Zufällige Aufgaben 02.06.2018 - 23:51 2
Folgenden Nutzern gefällt das Design: damios, krazun

Da das Interesse an #Kopfnuss erstaunlich groß ist, möchte ich einen weiteren kleinen Einblick gewähren. Momentan arbeite ich am Blitzmodus. Der Spieler wählt zunächst eine (oder alle) Grundrechenart aus und dann einen Zeitmodus. Zur Auswahl stehen 5, 10 oder 15 Sekunden. Dies ist dann die Zeit, die man für eine Aufgabe zur Verfügung hat. Nachfolgend erscheint eine Aufgabe und vier Buttons mit Zahlen drauf. Ein Ergebnis ist richtig, die anderen drei sind falsch. Der Spieler verliert, wenn er entweder ein falsches Ergebnis gewählt oder die Zeit verstrichen ist.

Heute habe ich die Spiellogik implementiert und das Additionsverfahren abgeschlossen. Die anderen drei Grundrechenarten werden noch folgen, aber das ist nicht mehr viel Arbeit. Für Interessierte möchte ich schildern, wie die Aufgaben generiert und die falschen Ergebnisse erzeugt werden, schließlich gibt es hier viele Wege, die nach Rom führen. (oder in den RAM)

Zunächst muss man wissen, dass die Aufgaben immer schwieriger werden sollen. Das Spiel orientiert sich an der Aufgabennummer, die mitgezählt wird. Die Aufgaben werden in vier Schwierigkeitsgrade unterteilt:

  1. Aufgabennummer < 5
  2. Aufgabennummer < 10
  3. Aufgabennummer < 20
  4. Aufgabennummer > 20

Da es nicht ganz einfach ist, über einen so langen Zeitraum die Konzentration hoch zu halten, sollte die Unterteilung reichen, lässt sich aber beliebig erweitern.

Addiert werden in diesem Modus immer nur zwei Zahlen. Das Spiel generiert also lediglich zwei Zufallszahlen und zählt diese Zusammen. Was sich bei den vier Schwierigkeitsgraden unterscheidet, ist der Bereich.

  1. Zahl zwischen 3 und 9
  2. Zahl zwischen 3 und 19
  3. Zahl zwischen 3 und 49
  4. Zahl zwischen 3 und 99

Die Wahrscheinlichkeit, dass bei 4. eine Aufgabe wie 3+3 kommt, ist zwar gegeben, aber ich halte das nicht für schlimm, wenn der Spieler mal durchatmen kann.

Nun besteht hier noch die Möglichkeit, dass zwei Mal die selbe Aufgabe gestellt wird. Gerade bei 1. passiert das relativ oft. Da kann man das Ergebnis prüfen und eine Schleife durchlaufen lassen, die so lange läuft, bis eine Aufgabe mit einem anderen Ergebnis generiert wird. Oder man macht es wie ich:

if (ergebnis == altesErgebnis)
{
    zahl1++;
    zahl2++;
    ergebnis = zahl1 + zahl2;
}

Wenn das Ergebnis identisch ist, dann wird den beiden Ausgangszahlen einfach ein Wert hinzugefügt. 

Soweit zur Aufgabe. Nun braucht das Spiel drei falsche Ergebnisse. Das Problem: Die falschen Zahlen müssen in der Nähe der richtigen Zahl sein, sonst kann man das Ergebnis zu leicht "erraten".

Da ich drei verschiedene falsche Zahlen brauche, habe ich drei Verfahren gewählt, um diese zu erzeugen.

// Falsch 1
if (richtig > 9)
{
	var minus = floor(random_range(2, 5));
	falsch[1] = richtig - minus;
} else {
	var plus = floor(random_range(2, 5));
	falsch[1] = richtig + plus;
}

Wenn das Ergebnis größer als 9 ist, wird eine Zufallszahl zwischen 2 und 4 erzeugt und diese vom Ergebnis abgezogen. Ist das Ergebnis <= 9, wird eine eben solche Zahl addiert. Den Code könnte man noch kürzen, aber so bin ich für spätere Verfahren flexibler.

// Falsch 2
if (richtig > 2)
{
	falsch[2] = richtig - 1;
} else {
	falsch[2] = richtig + 1;
}

Okay, das war jetzt extrem einfach. Die zweite falsche Zahl ist meistens eins kleiner als das richtige Ergebnis. Das hat auch den Vorteil, dass die beiden falschen Ergebnisse auf jeden Fall nicht identisch sind.

var moeglichkeit = irandom(1);

// Falsch 3
if (moeglichkeit == 0)
{
	if ((richtig mod 5) = 0)
	{
		falsch[3] = richtig + 5;
	} else {
		falsch[3] = falsch[1] + 5;
	}
} else {
	if (richtig > 10)
	{
		var moeglichkeit2 = irandom(1);
		
		if (moeglichkeit2 == 0)
		{
			falsch[3] = richtig - 10;
		} else {
			falsch[3] = richtig + 10;
		}
	} else {
		falsch[3] = richtig + 10;
	}
}

Die dritte falsche Zahl ist etwas komplexer. Es gibt zunächst zwei Möglichkeiten. Möglichkeit 0 ist, dass zunächst geprüft wird, ob die Zahl durch 5 teilbar ist. Wenn ja, wird 5 dazu addiert. Wenn nein, wird zur ersten falschen Zahl 5 addiert. 5er Werte werden später bei der Multiplikation oft vorkommen und da brauche ich falsche Ergebnisse, die genug "verwirren".

Die zweite Möglichkeit ist, dass geprüft wird, ob das Ergebnis > 10 ist. Wenn nicht, wird einfach 10 addiert. Wenn es größer 10 ist, wird zufällig gewählt, ob 10 addiert oder subtrahiert wird.

Hintergrund: Wenn man das nicht macht, dann kann man jede Additionsaufgabe einfach dadurch lösen, indem man nur die letzten beiden Ziffern addiert und die letzte Ziffer vom Ergebnis mit den vier Zahlen vergleicht.

Beispiel: 98 + 98

8 + 8 = 16, dann muss ich nur schauen, welches Ergebnis am Ende eine 6 hat. Durch falsch[3] kann es aber sein, dass ich eine Zahl habe, die +-10 davon abweicht.

Wir haben also nun die Aufgabe und drei falsche Ergebnisse. Das Spiel muss jetzt nur noch die Buttons erzeugen und die Zahlen zuweisen. Die Buttons stecken im Array button[] . Die Zuweisung erfolgt so:

richtigesErgebnis = floor(random(4));

falschCount = 1;
for(var i=0;i<4;i++)
{
	if (richtigesErgebnis = i)
	{
		button[i].richtig = 1;
		button[i].text = ergebnis;
	} else {
		button[i].richtig = 0;
		button[i].text = falsch[falschCount];
		falschCount++;
	}
}

Im GameMaker hat man noch die Möglichkeit mit dem Befehl ds_list zu arbeiten. Da speichert man die Ergebnisse, mischt dusch und weist die den Buttons zu, aber ich fand die hier gewählte Methode irgendwie eleganter. 

Das war es eigentlich auch schon. Ist ziemlich viel Code für so wenig Spiel. 

Sobald die anderen Grundrechenarten fertig sind, gibt es den heiß ersehnten Download und dann wird sich zeigen, ob die Balance stimmt. Vor allem bei Multiplikation und Division habe ich ein wenig Bauchschmerzen. 


Aktualisiert: 02.06.2018 - 23:51
Hashtags: #kopfnuss
Grund:
Kommentar als Gast hinzufügen