Tic-Tac-Toe 02


Das Spielfeld soll sich Kreuz und Kreis merken

Im zweiten Schritt auf dem Weg zu einem funktionierenden Tic-Tac-Toe-Spiel wollen wir programmieren, dass sich das Spiel merkt, welches Symbol in welchem Feld vorhanden ist.

Dazu brauchen wir die Möglichkeit die Belegung des Spielfelds in einer Variablen zu speichern. Eine einzige Variable ist zu wendig, denn darin kann nur eine Zahl oder ein Wort,... gespeichert werden. Wir brauchen eine Variable mit 9 Speicherplätzen. Dazu verwenden wir jetzt ein Array (deutsch: Feld), in dem viele Werte gespeichert werden können.

Jetzt müssen wir uns ausdenken, wie wir die Belegung des Spielfelds speichern können. Also denken wir mal logisch nach: Wir haben neun Felder und jedes Feld kann drei Zustände haben: leer, Kreuz, Kreis. Also genügen drei Werte!

Zum Beispiel: Leer = 0; Kreuz = 1; Kreis = 2;

Wir benutzen ein Array mit 9 Eintragungen und belegen diese bei Spielbeginn mit dem Startwert 0:

1) Ein leeres Array festlegen
  var sFBelegung = [];
2) Das Array mit dem Wert 0 belegen

Ein Array hat Speicherplätze für Werte, die über den sogenannten Index erreicht werden. Der erste Eintrag hat den Index 0, der zweite Eintrag hat den Index 1,... Man schreibt das wie folgt auf:

  sFBelegung[0] = 0;
  sFBelegung[1] = 0;
  sFBelegung[2] = 0;
  sFBelegung[3] = 0;
  sFBelegung[4] = 0;
  sFBelegung[5] = 0;
  sFBelegung[6] = 0;
  sFBelegung[7] = 0;
  sFBelegung[8] = 0;
3) Das geht auch eleganter

Damit man nicht so viele Zeilen schreiben muss, kann man den Wert 0 auch mit Hilfe einer for-Schleife zuordnen.

  for (var i = 0; i < 9; i++) {
    sFBelegung[i] = 0;
  }
3) Den Wert per Mausklick ändern

Jetzt können wir den Wert per Mausklick ändern. In unserer großen if-Abfrage, in der das Programm prüft, in welches Feld du geklickt hast, ergänzen wir das Programm so, dass in der sFBelegung eingetragen wird, welches Feld angeklickt wurde.

Ob ein Kreuz oder ein Kreis eingetragen wird entscheidet die Variable boolKreuzKreis. Wenn boolKreuzKreis wahr ist, dann setze ein Kreuz, sonst einen Kreis. Am Ende wird der Wert von boolKreuzKreis mit Hilfe des Ausrufungszeichens negiert, also aus wahr falsch gemacht oder aus falsch wahr gemacht.

  function mousePressed() {
    xKlick = mouseX;
    yKlick = mouseY;
    if (xKlick > hL1X && xKlick < vL1X && yKlick > vL1Y && yKlick < hL1Y) {
      numKlick = 1;
      if (boolKreuzKreis) { sFBelegung[0] = 1; } else { sFBelegung[0] = 2; }
    }
    if (xKlick > vL1X && xKlick < vL2X && yKlick > vL1Y && yKlick < hL1Y) { 
      numKlick = 2;
      if (boolKreuzKreis) { sFBelegung[1] = 1; } else { sFBelegung[1] = 2; }
    }
    if (xKlick > vL2X && xKlick < hL1X + linienL && yKlick > vL1Y && yKlick < hL1Y) { 
      numKlick = 3; 
      if (boolKreuzKreis) { sFBelegung[2] = 1; } else { sFBelegung[2] = 2; }
    }
    if (xKlick > hL1X && xKlick < vL1X && yKlick > hL1Y && yKlick < hL2Y) { 
      numKlick = 4;
      if (boolKreuzKreis) { sFBelegung[3] = 1; } else { sFBelegung[3] = 2; }
    }
    if (xKlick > vL1X && xKlick < vL2X && yKlick > hL1Y && yKlick < hL2Y) { 
      numKlick = 5;
      if (boolKreuzKreis) { sFBelegung[4] = 1; } else { sFBelegung[4] = 2; }
    }
    if (xKlick > vL2X && xKlick < hL1X + linienL && yKlick > hL1Y && yKlick < hL2Y) { 
      numKlick = 6; 
      if (boolKreuzKreis) { sFBelegung[5] = 1; } else { sFBelegung[5] = 2; }
    }
    if (xKlick > hL1X && xKlick < vL1X && yKlick > hL2Y && yKlick < vL1X + linienL) {
      numKlick = 7; 
      if (boolKreuzKreis) { sFBelegung[6] = 1; } else { sFBelegung[6] = 2; }
    }
    if (xKlick > vL1X && xKlick < vL2X && yKlick > hL2Y && yKlick < vL1X + linienL) { 
      numKlick = 8; 
      if (boolKreuzKreis) { sFBelegung[7] = 1; } else { sFBelegung[7] = 2; }
    }
    if (xKlick > vL2X && xKlick < hL1X + linienL && yKlick > hL2Y && yKlick < vL1X + linienL) { 
      numKlick = 9;
      if (boolKreuzKreis) { sFBelegung[8] = 1; } else { sFBelegung[8] = 2; }
    }  
    boolKreuzKreis = !boolKreuzKreis;
  }
Die Kreuze und Kreise zeichnen

Das Array sFBelegung entscheidet jetzt, wo nichts oder ein Kreuz oder ein Kreis in das Spielfeld gezeichnet werden soll. Dazu schreiben wir die function draw() um.

  function draw() {
    background(250);
    spielfeldBauen();
    textSize(20);
    text(xKlick, 10, 20);
    text(yKlick, 10, 50);
    text(numKlick, 10, 80);

    zeichneSymbol(vL1X-dL/2,hL1Y-dL/2, sFBelegung[0]);
    zeichneSymbol(vL1X+dL/2,hL1Y-dL/2, sFBelegung[1]);
    zeichneSymbol(vL2X+dL/2,hL1Y-dL/2, sFBelegung[2]);
    zeichneSymbol(vL1X-dL/2,hL1Y+dL/2, sFBelegung[3]);
    zeichneSymbol(vL1X+dL/2,hL1Y+dL/2, sFBelegung[4]);
    zeichneSymbol(vL2X+dL/2,hL1Y+dL/2, sFBelegung[5]);
    zeichneSymbol(vL1X-dL/2,hL2Y+dL/2, sFBelegung[6]);
    zeichneSymbol(vL1X+dL/2,hL2Y+dL/2, sFBelegung[7]);
    zeichneSymbol(vL2X+dL/2,hL2Y+dL/2, sFBelegung[8]);
  }
Mal ausprobieren

Starte folgendes Programm und versuche zu verstehen, wie es funktioniert


Fast am Ziel

Unser Spielfeld kann sich die Symbole merken, aber du kannst ein bereits eingetragenes Symbol noch ändern.

Aufgabe

Ändere das folgende Programm so, dass ein Feld, in das bereits ein Kreuz oder ein Kreis eingetragen ist, seine Belegung nicht mehr ändert.

Es folgt eine mögliche Lösung


Sieht schon besser aus, aber irgendwie ändern sich Kreuz und Kreis noch chaotisch. Das liegt daran, dass sich die Variable boolKreuzKreis, die steuert, ob ein Kreuz oder ein Kreis gezeichnet wird, bei jedem Mausklick ändert. Die Variable soll sich aber nur ändern, wenn tatsächlich ein Kreuz oder Kreis gezeichnet wurde, sonst nicht!

Aufgabe

Ändere das folgende Programm so, dass abwechselnd ein Kreuz und ein Kreis gezeichnet wird, bis das Spielfeld voll ist.

Es folgt eine mögliche Lösung, bei welcher boolKreuzKreis nur dann geändert wird, wenn sFBelegung[i] == 0 ist, wenn also noch nie auf das Feld geklickt wurde.


Sieht schon besser aus! Du kannst mit dem kleinen Programm bereits Tic-Tac-Toe gegen jemand anderes spielen, aber ihr müsst selbst entscheiden wer gewonnen hat. Das kann der Computer aber auch.

Im dritten Schritt soll das Programm schlau werden und selbst erkennen, ob ein Spieler gewonnen hat oder ob das Spiel unentschieden ausgeht.