Tic-Tac-Toe 01


In dieser mehrteiligen Übung sollst du das Spiels "Tic-Tac-Toe" entwerfen. Im ersten Teil entwerfen wir eine Funktionsstudie, also kleine Programme, mit denen wir alles ausprobieren, was das Programm können soll. Es wird noch nicht gut aussehen und auch noch nicht spielbar sein, aber du kannst Ideen entwickeln, wie das Spiel in Schritt 2 gebaut werden könnte.

Schritt 1: Spielfeld entwerfen

Zuerst wird die Größe des Zeichenbereichs in Abhängigkeit von der Bildschirmgröße festgelegt. Die Variable windowWidth liefert die Breite des Browserfensters und die Variable windowHeight liefert die Höhe des Browserfensters. Mit dem Befehl

createCanvas(windowWidth, windowHeight);

wird ein Zeichenbereich angelegt, der das ganze Fenster ausfüllt.


Schritt 2: Spielfeld zeichnen

Das Tic Tac Toe-Spielfeld soll jetzt in die Mitte des Zeichenbereichs gesetzt werden. Auch die Größe des Spielfelds soll sich dem Zeichenbereich anpassen. Natürlich wäre es einfacher, wenn man die Größe des Zeichenbereichs mit unveränderlichen Zahlenwerten festlegt, aber dann müsstest du weniger nachdenken und Nachdenken sollst du jetzt hier trainieren!

Aufgabe:

Nimm ein Blatt Papier und einen Bleistift und denke darüber nach, wie du den Computer ein Tic-Tac-Toe Spielfeld zeichnen lassen kannst, das sich der Größe des Zeichenbereichs anpasst und in der Mitte des Zeichenbereichs platziert ist.

Hier folgt ein Lösungsvorschlag:

Mit relativeLinienLaenge = 0.7; wird festgelegt, dass eine Linie im Spielfeld ein Länge von 70% der Breite oder Höhe haben soll. Da nicht klar ist, ob die Höhe oder Breite kleiner ist, wird mit folgender Abfrage genau das herausgefunden:

if (windowHeight >= windowWidth) {
  linienLaenge = windowWidth*relativeLinienLaenge;  
}
else {
  linienLaenge = windowHeight*relativeLinienLaenge;  
}

Nachdem die Linienlänge berechnet ist, soll der Abstand zwischen 2 Linien 1/3 der Linienlänge sein, da es ja 3 gleich große Spalten oder Zeilen geben soll.

abstandLinien = linienLaenge/3;

Mit den Anweisungen:

push();
translate(windowWidth/2-abstandLinien/2,windowHeight/2-3*abstandLinien/2);
line(0,0,0,linienLaenge);
pop();

wird eine Linie an die gewünschte Position gezeichnet. Wie du aus den p5.js-Grundlagen weisst, wirken sich Anweisungen zwischen push() und pop() nicht auf den Rest des Programms aus. Mit translate() wird die Linie an die gewünschte Position verschoben. Über die angegebenen Koordinaten kannst du in Ruhe nachdenken.

In den drei folgenden Beispielen kannst du beobachten, wie sich das Spielfeld an die Größe des Zeichenbereichs anpasst.


Schritt 3: Kreise und Kreuze per Mausklick plazieren

Um Tic Tac Toe zu spielen, musst du ins Spielfeld Kreise und Kreuze per Mausklick platzieren. Damit der Computer weiss, wohin du geklickt hast, müssen die x- und y-Koordinaten des Mausklicks bekannt sein.

Dazu gibt es die Funktion mousePressed(), die immer aufgerufen wird, sobald du eine Maustaste gedrückt hast:

  var xAngeklickt = 0;
  var yAngeklickt = 0;

  function mousePressed() {
    xAngeklickt = mouseX;
    yAngeklickt = mouseY;
  }

Damit weisst du wohin du geklickt hast.

Wie aber weisst du, in welches Feld der neun Tic-Tac-Toe-Felder du geklickt hast?

Das kannst du mit der folgenden if-Abfrage herausfinden (&& bedeutet logisch und. Die Abfrage in der Klammer ist wahr, wenn alle Bedingungen erfüllt sind, sonst ist die Abfrage in der Klammer falsch):

if (xAngeklickt > horizontaleLinie1X && xAngeklickt < vertikaleLinie1X && yAngeklickt > vertikaleLinie1Y && yAngeklickt < horizontaleLinie1Y) {
  nummerAngeklickt = 1;
}

Wobei in den Variablen die Grenzen der Felder gespeichert sind. Wie man diese aus der Größe des Zeichenbereichs berechnet kannst du dir mit Hilfe von Papier und Bleistift überlegen.

vertikaleLinie1X = windowWidth/2-abstandLinien/2;
vertikaleLinie1Y = windowHeight/2-3*abstandLinien/2;
vertikaleLinie2X = windowWidth/2+abstandLinien/2;
vertikaleLinie2Y = vertikaleLinie1Y;
horizontaleLinie1X = windowWidth/2-3*abstandLinien/2;
horizontaleLinie1Y = windowHeight/2-abstandLinien/2;
horizontaleLinie2X = horizontaleLinie1X;
horizontaleLinie2Y = windowHeight/2+abstandLinien/2;

Im folgenden Beispiel kannst du nachvollziehen wie der Computer herausfindet, in welches Feld des Tic-Tac-Toe-Spielfelds du geklickt hast:

Jetzt soll ein Kreis in das angeklickte Feld gezeichnet werden. Dazu gibt es folgende Bedingung in der Zeichenfunktion draw():

if (nummerAngeklickt === 1) {
  ellipse(vertikaleLinie1X-abstandLinien/2,horizontaleLinie1Y-abstandLinien/2,kreisdurchmesser,kreisdurchmesser);  
}

Als nächstes soll ein Kreuz in das angeklickte Feld gezeichnet werden. Das wird mit Hilfe der folgenden Funktion gemacht:

function zeichneKreuz(xKoord, yKoord) {
  push();
  translate(xKoord,yKoord);
  line(-kreisdurchmesser/2,-kreisdurchmesser/2,kreisdurchmesser/2,kreisdurchmesser/2);
  line(-kreisdurchmesser/2,kreisdurchmesser/2,kreisdurchmesser/2,-kreisdurchmesser/2);
  pop();
}

Jetzt soll abwechselnd ein Kreuz und ein Kreis gezeichnet werden. Das steuert man mit Hilfe der Variablen

var boolKreuzKreis = false;

die bei jedem Mausklickt geändert wird.

Unsere Funktionsstudie kann schon ganz schön viel. Wenn du aber Tic Tac Toe spielen möchtest, muss das Programm sich merken, wohin ein Spieler bereits geklickt hat und wenn in einem Feld schon ein Symbol ist, darf es nicht mehr geändert werden. Das alles soll im zweiten Schritt programmiert werden.