Tic tak toe, wie kann man so ein Spiel umsetzen?

    Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

    Aufgrund technischer Veränderungen ist der Mailverkehr innerhalb des Forums (Private Nachrichten) nur noch eingeschränkt möglich. Die Einschränkung ist notwendig, um zusätzliche Betriebskosten für das Forum zu vermeiden. Näheres zu den Hintergründen im Thread "Aktuelles zum Forum".Wir bitten um Verständnis.

    Hinweis kann nach Kenntnisnahme deaktiviert werden!

    • Tic tak toe, wie kann man so ein Spiel umsetzen?

      Ihr kennt sicher alle das Spiel tic tac toe (die älteren vielleicht aus dem Film 'Wargames')
      Wikipedia schreibt dazu de.wikipedia.org/wiki/Tic-Tac-Toe
      Ich möchte jetzt dieses Spiel auf meinem Modellbauservoplotter spielen können, dazu wird es eine 3x3 Tastatur geben und halt einen Startknopf und so Kleinzeugs.
      Meine Frage ist es jetzt, wie programmiert man den Spielverlauf. Der ist ja zum Glück überschaubar von der Anzahl der Spielzugvarianten und man könnte sich mit if..then durch hangeln. Oder gibt es geschicktere Möglichkeiten? a_27_b277ca12
      Raum für Notizen

      -----------------------------------------------------------------------------------------------------

      -----------------------------------------------------------------------------------------------------
    • Also gut, hab' das Buch bestellt und bin jetzt gespannt, wer beim hoffentlich baldigen Spiel gewinnt. (Muss ja meine Kinematikberechnungen noch fertig machen...)
      Raum für Notizen

      -----------------------------------------------------------------------------------------------------

      -----------------------------------------------------------------------------------------------------
    • Ich bin jetzt im Urlaub (Lötkolben- und Pcfrei) und beschäftige mich bisschen mit theoretischen Dingen. Eben mit tic tac toe und dessen Umsetzung. Ziel ist es, dass mein Programm mindestens ein Unentschieden hin kriegt, verlieren ist nur eine Option, wenn man das explizit zulässt, über Rnd(), damit das Gegenüber nicht die Lust verliert. Ein Setzen an Stellen, die noch frei sind, ist somit nicht zu brauchen. Das Buch von Stefan hab' ich auch nicht dabei, ich will aber auch nicht dessen Programm verwenden, schon allein deshalb, weil ich später mein Gesamtprojekt veröffentlichen will. Ich hab' jetzt unter wikipedia diese Seite gefunden xkcd.com/832_large/ (das ist schon eine Vergrößerung), die den Spielverlauf darstellt. Jetzt grüble ich, wie ich das in ein Programm bekomme. Ich bin soweit, dass ich 2 words anlege, eins für Kreuz, eins für Bollern. 9 bits jeweils davon entsprechen den Plätzen des Spiels, ein 1 bedeutet Platz besetzt, eine 0 Platz frei. Ein or-Vergleich ergibt die freien Stellen, wo man platzieren kann, wenn man dran ist. Könnte man jetzt diese Graphik einfach in data-Zeilen übertragen, mit dem nächsten Zug als Nachbarn und mit lookdown den aktuellen Stand suchen, um den daneben liegenden Zug zu finden? Ne klappt ja nicht, weil es meist verschiedene Varianten gibt.
      Hat vielleicht jemand schon einen Ansatz, der nicht copyrightgeschützt ist?
      Raum für Notizen

      -----------------------------------------------------------------------------------------------------

      -----------------------------------------------------------------------------------------------------
    • Mach doch folgendes:
      Leg drei Word Variablen an. Eine für die Spielfläche und die beiden anderen für je einen Spieler. Die Variable für die Spielfläche nimmst du nur um ein freies Feld fest zustellen und die für die Spieler nimmst du wer als erstes drei in einer reihe hat. Es gibt ja nur acht Varianten um zu gewinnen. Diese Varianten kannst du in einer Datentabelle ablegen und mit den beiden Spielervariablen vergleichen. Wer also zuerst eine der Varianten erreicht hat, hat gewonnen.

      Wenn Spieler 1 das Feld 1:1 belegt hat kann Spieler 2 nur noch eins von den restlichen acht Feldern belegen.

      Spielfeld = &B1000000000000000% 'Feld 1:1 ist belegt
      Spieler1 = &B1000000000000000% 'Spieler 1 hat Feld 1:1 belegt
      Spieler2 = &B0100000000000000% 'Spieler 2 kann Feld 1:1 nicht mehr belegen

      Nach dem Zug von Spieler 2 sieht die Variable vom Spielfeld so aus

      Spielfeld = &B1100000000000000%

      Bedeutet also das du auch pro Spielzug einen Zähler mit zählen lassen musst, um die Position der Spielfeld-Variablen zu bestimmen.
      Eine Lösung habe ich nicht, aber mir gefällt Ihr Problem.
    • ceperiga schrieb:

      Hallo tschoeatsch,
      was ist denn mit zweidimonensionalen Array´s? Die kann man doch inzwischen auch unter BASCOM nutzen. So ein Spielfeld ist doch eigentlich auch nur ein solches Array.

      Gruß Christian
      Eigentlich reicht eine Dimension, bei einem byte hab' ich ja genügend Info pro Spielfeldplatz. Je ein bit für das gesetzte Spielerzeichen, bleiben noch 6 bits für irgendwas.
      @djmsc mit den 8 Möglichkeiten für einen Gewinn hast du schon recht, aber man kommt auch mal in die Situation, dass man verteidigen muss, dann muss man sich auf andere Möglichkeiten konzentrieren.

      Wenn man sich die verlinkte Graphik betrachtet, die ja die Züge zum Sieg bzw Unentschieden beschreibt, könnte die ersten 4 Züge in einer Tabelle ablegen und die restlichen Züge evtl. 'einfach' mit einem Algorithmus errechnen. Man sucht mit lookdown die derzeitige Stellung, findet als nächsten Eintrag in der Tabelle die Anzahl der möglichen Antworten und sucht sich eine per Rnd() davon aus.
      Raum für Notizen

      -----------------------------------------------------------------------------------------------------

      -----------------------------------------------------------------------------------------------------
    • Das mag sein, aber es gibt auch ungünstige Züge.
      Aus wikipedia:
      Meist setzt der erste Spieler (X) in die Mitte. Der zweite Spieler muss, um ein Unentschieden zu erzwingen, in die Ecke setzen, sonst kann Spieler 1 mühelos einen Sieg erringen:

      Die in jeder Situation möglichen Züge könnte man bewerten und dann nimmt man nur den besten, so macht man das als Mensch automatisch. Aber wie macht man das mit bascom?
      Raum für Notizen

      -----------------------------------------------------------------------------------------------------

      -----------------------------------------------------------------------------------------------------
    • Im Grunde musst du diese Konstellationen abfragen. Also wenn der Spieler z.B. schon in zwei Ecken ein X hat muss der "Computer" dazwischen ein O setzen. Solche Konstellationen sollten Vorrang haben.

      X|O|X
      O|X|O
      O|o|o <- hier müsste dann das O folgen.

      Ok bei der Konstellation gewinnt natürlich der Spieler :)
      Eine Lösung habe ich nicht, aber mir gefällt Ihr Problem.
    • Ich glaube ich komme meinem Ziel näher.
      Diese Graphik ist mein Ausgangspunkt
      tic_tac_toe_large.png
      Wenn man den x-Teil betrachtet, kann man hier im schlechtesten Fall ein Unentschieden erleiden (wenn das Gegenüber bei seinem ersten Zug in der Mitte setzt. Diese Graphik beinhaltet optimale Züge. Wenn man optimal spielt, gewinnt man, oder wenn der Gegner auch optimal spielt, kommt es zum Unentschieden. Wenn man, so wie ich, lange genug auf das Bildchen glotzt, erkennt man auch, dass man innerhalb der Graphik nur den letzten Spielstand des Gegners (die Anordnung seiner Zeichen auf dem Spielfeld) suchen muss, um den nächsten, eigenen, optimalen Zug zu finden. Man braucht also 'nur' die möglichen Spielstände des Gegners in einer Tabelle auflisten und daneben den nächsten eigenen Zug. Dieses 'nur' kann man seiner Bedeutung nähern, wenn man erkennt (auch durch Starren auf das Bild), dass viele Spielstände auf Drehung und Spiegelung eines Standes beruhen. Was ich also brauche ist diese Tabelle für X und O und einen Dreh- und Spiegelmechanismus eines Spielstandes. Der Ablauf wäre dann:
      Spielstand des Gegners in der Tabelle suchen, wenn gefunden, eigenen, neuen Spielstand aus der Tabelle entnehmen. Wenn nicht in der Tabelle gefunden, dann solange drehen und spiegeln, bis was gefunden wird, den eigenen, neuen Spielstand entnehmen und auf gleiche Art zurück drehen und spiegeln und ausgeben. Ganz einfach. Dadurch spielt das Programm immer optimal und kann somit nicht verlieren, das ist mein Ziel.
      Raum für Notizen

      -----------------------------------------------------------------------------------------------------

      -----------------------------------------------------------------------------------------------------
    • Dann mus man halt noch, wie beim Geldspielautomaten auch, einen Prozentsatz ungünstige Züge zulassen. Das ist dann vielleicht sogar das Schwierigere an dem Ganzen. Oder man betrachtet das Programm als Trainingspartner, um dann bei Spielen mit anderen Gegnern optimal zu spielen.
      Raum für Notizen

      -----------------------------------------------------------------------------------------------------

      -----------------------------------------------------------------------------------------------------
    • Hallo tschoeatsch,
      wie du schon geschrieben hast, endet das Spiel immer mit einem Unentschieden, wenn beide Spieler optimal spielen. Daher ist es meiner Meinung nach nicht so richtig interessant.
      Ich denke, dass deine Graphik viel zu kompliziert ist. Ganz viele, wenn nicht sogar die meisten Züge sind Zwangszüge, weil ein Spieler schon 2 Felder in einer Reihe belegt hat. Da soll dein Programm doch sicherlich den Zug setzen, der den direkten Sieg verhindert. Also gar keine Wahl, es muss dieses Feld belegt werden.
      Die einzige Gewinnmöglichkeit ist, wenn ein Spieler es schafft, zwei solcher Situationen gleichzeitig zu erreichen. Aufgrund der wenigen Felder ist dies allerdings nur möglich, wenn 5,6 oder 7 Felder belegt sind. Die Vorraussetzung dafür wird allerdings schon direkt am Anfang geschaffen.
      Spieler1 hat zu Anfang nur 3 Möglichkeiten: In die Mitte, in ein Eckfeld, in eines der anderen vier Felder. Welches Eckfeld oder welches der anderen Felder ist egal (gedreht, gespiegelt).
      Setzt er in die Mitte, hat Spieler2 nur zwei Möglichkeiten; Eckfeld oder nicht Eckfeld. Eckfeld bleibt er auf Unentschieden Kurs, anderes Feld führt mit einer Ausnahme zum Sieg von Spieler1.
      Und so ähnlich sieht das mit den anderen Möglichkeiten des Starts auch aus.

      Interessant fände ich jetzt höchstens, wie man das Spielfeld so im Speicher abbildet, dass das Erkennen von zwei Feldern in Reihe möglichst einfach geht, also ohne 100 Vergleiche durchzuführen.
    • Hm, komplizierte Graphik - sie bildet in der x-map einen möglichen, optimalen Spielverlauf ab, in der o-map den kompletten Spielverlauf für den 2. Spieler, natürlich auch optimal. Es sind halt darin die Entscheidungen schon eingezeichnet, die man sonst irgenwie mit Abfragen erledigen müsste. Um jetzt den 100ten Abfragen zu entgehen, hänge ich jetzt noch an der Vorstellung, diese Graphik in eine Tabelle zu quetschen. Ich hab' schon nach meiner obigen Beschreibung versucht, bin aber schon an einem Problem hängen geblieben, ist also nicht so einfach wie gedacht.
      Das Spielfeld im Speicher abbilden, da bin ich derzeit bei 2 words hängen geblieben, für jeden Spieler eins.

      Ich finde es erstaunlich, wie schwer man sich tut, um so ein einfaches Spiel umzusetzen, wenn man nicht nur einen möglichen Zug sucht und setzt, sondern auf die bisher gesetzten Rücksicht nehmen will. Von vorausschauend ja noch gar keine Spur.
      Raum für Notizen

      -----------------------------------------------------------------------------------------------------

      -----------------------------------------------------------------------------------------------------
    • hero schrieb:

      Ich denke, dass deine Graphik viel zu kompliziert ist. Ganz viele, wenn nicht sogar die meisten Züge sind Zwangszüge, weil ein Spieler schon 2 Felder in einer Reihe belegt hat. Da soll dein Programm doch sicherlich den Zug setzen, der den direkten Sieg verhindert.
      ja, der Grafik-, bzw. der Tabellenansatz ist hier sicher nicht nötig.
      Der Controller hat genug Zeit und ist zum Rechnen geboren, da braucht er keine Tabelle

      hero schrieb:

      Spieler1 hat zu Anfang nur 3 Möglichkeiten: In die Mitte, in ein Eckfeld, in eines der anderen vier Felder. Welches Eckfeld oder welches der anderen Felder ist egal (gedreht, gespiegelt).
      Setzt er in die Mitte, hat Spieler2 nur zwei Möglichkeiten; Eckfeld oder nicht Eckfeld.
      genau ;)


      tschoeatsch schrieb:

      Ich finde es erstaunlich, wie schwer man sich tut, um so ein einfaches Spiel umzusetzen, wenn man nicht nur einen möglichen Zug sucht und setzt, sondern auf die bisher gesetzten Rücksicht nehmen will. Von vorausschauend ja noch gar keine Spur.
      Bei einfachen Schachprogrammen wird auch nur ein paar Züge probiert und der mit dem meisten Erfolg nach dem x-ten Zug genommen.
    • Und das Ergebnis aus diesen Tipps? Mögliche Züge suchen und bewerten? Was gibt aber eine hohe Bewertung. Diese Formulierung in einem Algorithmus überfordert mich total.
      Und wenn man das von @hero betrachtet, ist das Geschriebene eigentlich nix anderes, wie eine Tabelle (ist jetzt nicht abwertend gemeint!) Klar, die Graphik wirkt kompliziert, aber warum? Es gibt viele Möglichkeiten, die aber durch Spiegelung und Drehung zu reduzieren sind.
      Raum für Notizen

      -----------------------------------------------------------------------------------------------------

      -----------------------------------------------------------------------------------------------------