Autor Beitrag
Abalon
Hält's aus hier
Beiträge: 5



BeitragVerfasst: Do 23.05.13 03:57 
Hallo an alle,

habe zur Übung ein kleines TicTacToe Spiel erstellt. Der Spieler vs. Spieler funktioniert, doch ich möchte nun einen Spieler vs. Computer programmieren.
Ich habe schon was über minimax Algorithmus gelesen, doch ich verstehe es leider nicht…
Kennt sich hier jemand damit aus?


Hier noch ein Abschnitt von meinem Spielfeld:

ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
        public Panel pnlFeld()
        {
            this.btnFeld = new Button[z, s];

            for (int z = 0; z < zeile; zeile++)
            {
                for (int s = 0; s < spalte; spalte++)
                {
                    btnFeld[z, s] = new Square(); //Mein eigener Button
                    btnFeld[z, s].Location = new Point(80 * z + 2080 * s + 20); // Position wird festgelegt
                    this.pnlFeld.Controls.Add(btnFeld[z, s]);

                    btnFeld[z, s].Click += new EventHandler(this.button_Click);
                }
            }
            return pnlFeld;            
        }

Hoffe jemand hat eine Idee wie ich anfangen könnte...

Moderiert von user profile iconTh69: Quote- durch C#-Tags ersetzt
Th69
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Moderator
Beiträge: 4796
Erhaltene Danke: 1059

Win10
C#, C++ (VS 2017/19/22)
BeitragVerfasst: Do 23.05.13 12:24 
Hallo Abalon :welcome:

zuerst einmal müsstest du deinen Code korrigieren:
ausblenden C#-Quelltext
1:
2:
3:
for (int z = 0; z < zeile; z++)
{
    for (int s = 0; s < spalte; s++)

Und dann bin ich verwirrt (d.h. dies kann eigentlich gar nicht kompilieren), daß bei dir die Methode als auch die interne Panel-Variable pnlFeld heißt.

Und dann zu deinem eigentlichen TicTacToe-Spiel.
Hast du denn schon die Methode geschrieben, welche bewertet, ob drei gleiche Symbole in einer Reihe (horizontal, vertikal oder diagonal) sind?
Denn diese ist Voraussetzung für eine KI, denn der MinMax-Algorithmus benötigt eine Bewertungsfunktion.
Abalon Threadstarter
Hält's aus hier
Beiträge: 5



BeitragVerfasst: Do 23.05.13 14:21 
Naja eigentlich funktioniert alles, ich hatte nur mein Code etwas verändert, war ja schon Spät gestern.

Die Bewertungsmethode habe ich auch geschrieben und funktioniert, sieht so aus:

ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
 private void Inhalt() 
        {

            if (btnFeld[00].Text == x)  
            {
                if (btnFeld[01].Text == x)   
                {
                    if (btnFeld[02].Text == x)
                    {
                        //...dann hat Spieler X gewonnen!
                        MessageBox.Show("Spieler X hat gewonnen");

                        return;
                    }
                }
            }


Ich schreibe nur nicht den ganzen Code da es ziemlich viel ist, Ist aber im Endeffekt alles dasselbe, nur die reihe und der Spieler wechseln.
Wenn alle Textinhalte voll sind aber keiner gewonnen hat habe ich am Ende so gelöst…

ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
            if (btnFeld[00].Text != "" && btnFeld[01].Text != "" && 
                btnFeld[02].Text != "" && btnFeld[10].Text != "" && 
                btnFeld[11].Text != "" && btnFeld[12].Text != "" && 
                btnFeld[20].Text != "" && btnFeld[21].Text != "" && 
                btnFeld[22].Text != "")   //...dann hat keiner gewonnen.
            {
                MessageBox.Show("Keiner hat gewonnen!");
                return;
            }


Grüß, Abalon.
Th69
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Moderator
Beiträge: 4796
Erhaltene Danke: 1059

Win10
C#, C++ (VS 2017/19/22)
BeitragVerfasst: Do 23.05.13 19:48 
Hui, da wirst du noch einiges ändern müssen, um die KI zu integrieren.

Du solltest generell GUI und Modell (Logik) strikt trennen, d.h. am besten sogar eine eigene Klasse für das eigentliche TicTacToe schreiben, das nur Berechnungsfunktionen anbietet und von der GUI entsprechend aufgerufen wird.
Konkret heißt das für deine bisherige Methode Inhalt(), daß du daraus eine Methode bool HasPlayerWon(Player player) schreiben solltest, welche nur true oder false als Ergebnis zurückgibt. So kannst du diese Methode für den Spieler und dann für die KI (gegnerischer Spieler) aufrufen.
Und deine GUI ruft diese Methode nach jedem Zug auf und zeigt dann im Erfolgsfall eine MessageBox an.

Und dann kannst du diese Methode noch kürzen (so wie ich das verstehe, hast du jede Möglichkeit bisher einzeln ausprogrammiert :shock:), indem du Schleifen (für die Reihen und Spalten) benutzt!

Und das Spielbrett solltest du auch als internes Array (innerhalb der TicTacToe-Game Klasse) umsetzen und die GUI stellt dann dieses Spielbrett als Buttons dar, so daß du nicht direkt das btnFeld[x, y].Text ausliest, sondern den internen Zustand.

Erst wenn du diese Trennung sauber umgesetzt hast, solltest du dich an der KI versuchen.

Wenn du dir mal ein Beispielprojekt anschauen willst, das nach diesem Prinzip entwickelt worden ist, dann kann ich dir mein Projekt WinForms-Framework für (2-Personen) Karten-/Brettspiele empfehlen: dort sind die Kartenspiele Skat und Schwimmen (bzw. auch "31" genannt) als Download zu finden (in den unteren Beiträgen).
IhopeonlyReader
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 600
Erhaltene Danke: 23


Delphi 7 PE
BeitragVerfasst: Do 23.05.13 20:32 
die procedure sollte so ähnlich aussehen wie deine Abfrage ob wer gewonnen hat prozedure

1. Kontrolliere ob dein Gegner 2 Steine in einer Reihe hat (horizontal, vertikal, diagonal)
wenn: dann setzte du den letzten Stein in reihe
wenn nicht,
2. überprüfen ob dein Gegner ein Stein in einer Ecke hat, wenn ja in die Gegenüberliegende legen (sonst hat er im nächsten Zug Chance auf Doppel-Möglichkeit)
sonst
3. Überprüfen ob dein Gegner 2 Rand-Mittelstücke die aneinanderliegen besetzt hat (Bsp. 2, 1 und (2, 1 oder 2, 3) ) und die Reihen sonst "frei sind" also er dann im nächsten zug eine Doppelmöglichkeit hätte
(Gegern-Win verhinden wäre damit fertig :) )

3. Falls noch kein Stein gesetzt wurde, in eine ecke oder in eine Mitte am Rand setzten
4. wenn in einer Spalte oder Zeile schon 1 Stein ist, dann nicht mehr in diese Spalte/Zeile dein Stein legen...
(sonst kriegt man eh keine 3 steine zusammen :D)
sonst "irgendwo" in ein freies Feld..

P.S: das der "aufbau" programmieren kann ich das in C# leider nicht ;) aber ich denke ddieses hier hilft dir einiges weiter :)

_________________
Sucht "neueres" Delphi :D
Wer nicht brauch was er hat, brauch auch nicht was er nicht hat!
Abalon Threadstarter
Hält's aus hier
Beiträge: 5



BeitragVerfasst: Do 23.05.13 21:36 
Hmm… wie es aussieht habe ich dann wohl noch was zu tun :)
Vielen Dank für eure Antworten, ich versuch dann mal das ganze umzusetzen.

Zitat:
Und dann kannst du diese Methode noch kürzen (so wie ich das verstehe, hast du jede Möglichkeit bisher einzeln ausprogrammiert :shock:), indem du Schleifen (für die Reihen und Spalten) benutzt!


Was genau meinst du mit kürzer halten? Ich hab mir schon Gedanken gemacht wie ich das ganze „kleiner “ bekomme aber eine kürzere Möglichkeit habe ich nicht wirklich gefunden…

Grüß, Abalon

Moderiert von user profile iconTh69: Beitragsformatierung überarbeitet.
IhopeonlyReader
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 600
Erhaltene Danke: 23


Delphi 7 PE
BeitragVerfasst: Do 23.05.13 21:59 
Für dein Beispiel anstatt
Wenn folgende zellen
0,0 0,1 0,2
1.0 1,1 1,2
2,0 2,1 2,2
!= '' sind dann unentschieden

Kannst du auch
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
Unentschieden := true;
For Int i=0 to 2 do
  For Int z=0 to 2 Do
  {
    If  i,z = ''  Then unentschieden := false;
  }

If unentschieden then 
{
  //unentschieden
}


Moderiert von user profile iconTh69: Delphi-Tags hinzugefügt
Nachtrag: Danke @Th96 für die Delphi-Tags, aber das ist kein direkter Quellcode, sondern ein Misch aus Delphi und C, deshalb hatte ich keine Tags gesetzt..

_________________
Sucht "neueres" Delphi :D
Wer nicht brauch was er hat, brauch auch nicht was er nicht hat!


Zuletzt bearbeitet von IhopeonlyReader am Fr 24.05.13 15:23, insgesamt 1-mal bearbeitet

Für diesen Beitrag haben gedankt: Abalon
Th69
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Moderator
Beiträge: 4796
Erhaltene Danke: 1059

Win10
C#, C++ (VS 2017/19/22)
BeitragVerfasst: Fr 24.05.13 11:31 
Hallo,

schau dir z.B. mal die Methode HatSpielerGewonnen unter tuts4you.de/87-progr...l-tutorial-tictactoe an (und versuche sie zu verstehen ;-)).

Für diesen Beitrag haben gedankt: Abalon
Abalon Threadstarter
Hält's aus hier
Beiträge: 5



BeitragVerfasst: Sa 25.05.13 02:15 
Hallo und vielen Dank für eure Hilfe,

Ich hätte nicht gedacht das es so kompliziert sein würde… ich habe es zwar mehr oder weniger geschafft das ganze kürzer zu machen aber es in eine separate Klasse zu machen will mir einfach nicht gelingen…

Ich hänge mein ganzes Projekt mal an, wäre nett wenn ihr ihn euch anschauen würdet denn das ganze hier zu posten wäre etwas zu viel

Ich hoffe ihr kommt mit den ganze Mischmasch Code zurecht :D

Grüß, Abalon.


Zuletzt bearbeitet von Abalon am So 26.05.13 17:57, insgesamt 1-mal bearbeitet
Abalon Threadstarter
Hält's aus hier
Beiträge: 5



BeitragVerfasst: So 26.05.13 17:56 
Vielen Dank nochmal, ich habe ein Weg gefunden… musste zwar ziemlich viel dran Schrauben aber jetzt ist meine KI funktionsfähig.

Noch ein schöner Start in der Woche! :D