Spiele-KI



  • Ich bin mir jetzt nicht sicher ob das hier der richtige Thread ist aber ich poste jetzt hier mal.

    Ich will ein VierGewinnt-Verschnitt proggen.
    Ein Spielbrett mit variabler Anzahl an Feldern (4x4, 8x8, ...) auf dem man abwechselnd einen Stein setzt, bis man 3, 4, 5.. (weiß noch nicht genau) in einer Reihe hat.

    Dafür brauch ich jetzt allerdings eine KI.
    Da ich keine Lust auf so eine elend langes Teil mit zig if-Verzweigungen habe,
    das dann wieder den halben PC zum Absturz bringt, wollt ich mal fragen obs da irgendwas professionelleres gibt, das ich benutzen kann.

    Achja ich benutze C und die WinAPI.

    Ich hoffe man hat mein Problem verstanden.
    Danke 🙂



  • mach es doch so, dass jeder stein, der gesetzt werden kann, "punkte" bekommt... je besser der zug ist, desto mehr "punkte" bekommt er... und dann am ende der berechnungen für jeden zug, wählt man einfach den aus, der die höchste "punktzahl" hat... so oder so ähnlich würde ich das machen.. war gerade so mein erster gedanke.. also nicht hauen, wenn es nicht so gut ist 😉



  • Ocin schrieb:

    Ich will ein VierGewinnt-Verschnitt proggen.

    das ist gut.

    Da ich keine Lust auf so eine elend langes Teil mit zig if-Verzweigungen habe,

    anfangs wird's vermutlich schon ein wenig ifig. aber schmeiß es immer weg, wenn es nix taugt, und bald isses fein.

    hier mal ne KI von mir:

    #include <assert.h>
    #include <stdlib.h>
    
    #include "Spieler.h"
    
    class CompZufall:public Spieler
    {
    public:
       std::string getName()
    	{
    		return "Zufall";
    	}
       std::string getAutor()
       {
          return "Volkard";
       }
       std::string getBeschreibung()
       {
          return "Referenz-Spieler für das elo-Punkte-System. Es wird einfach "
             "definiert, daß dieser Spieler genau 1000 elo-Punkte hat.";
       }
    
       Zug sageZug(const Stellung *stellung)
    	{
          return stellung->sageZufallsZug();
    	}
    };
    
    CompZufall meinSpieler;
    

    und gleich noch ne andere

    #include <assert.h>
    
    #include "Spieler.h"
    
    class Comp4Nachmacher:public Spieler
    {
    public:
       std::string getName()
    	{
    		return "4Nachmacher";
    	}
       std::string getAutor()
       {
          return "Volkard";
       }
       std::string getBeschreibung()
    	{
    		return "Macht einfach alles nach, außer wenn er anfängt, dann wirft er die 4.";
    	}
    	Zug sageZug(const Stellung *stellung)
    	{
          //Falls ich anfange, werfe ich die 4
    		if (stellung->spielAnfang())
       		return 4;
    
          //Sonst mache ich einfach den letzten Zug nach, falls er erlaubt ist
    		Zug z=stellung->sageLetztenZug();
    		if(stellung->istGueltig(z))
    			return z;
    
          //Falls nicht, nehme ich irgend einen
          return stellung->sageZufallsZug();
    	}
    };
    
    Comp4Nachmacher meinSpieler;
    

    und noch eine

    #include <assert.h>
    
    #include "Spieler.h"
    
    class Comp3142:public Spieler
    {
    public:
       std::string getName()
            {
                    return "3142";
            }
       std::string getAutor()
       {
          return "Volkard & Maschine";
       }
       std::string getBeschreibung()
            {
                    return "Versucht, in die 3 zu werfen, falls das nicht geht, dann in die 1, "
             "die 4 und dann die 2. Das hat nur den Zweck, immer gegen den 4Nachmacher "
             "zu gewinnen.";
            }
    
       Zug sageZug(const Stellung *stellung)
            {
                    if(stellung->istGueltig(3))
                            return 3;
                    if(stellung->istGueltig(1))
                            return 1;
                    if(stellung->istGueltig(4))
                            return 4;
                    if(stellung->istGueltig(2))
                            return 2;
                    if(stellung->istGueltig(5))
                            return 5;
                    if(stellung->istGueltig(6))
                            return 6;
                    if(stellung->istGueltig(7))
                            return 7;
                    assert(0);
                    return 0;
            }
    };
    
    Comp3142 meinSpieler;
    

    naja, damit kann man schon ne menge spaß haben, wenn man die KIs in einem tournier gegeneinander spielen läßt.

    mangelde ernsthaftigkeit? sehe ich eigentlich nicht. aber ok, die obigen KIs sind alle sehr scwach. hier der ansatz für stärkeres:

    #include <iostream>
    #include <conio.h>
    
    #include "Spieler.h"
    #include "Stack.h"
    #include "Wert.h"
    #include "BewerteterZug.h"
    
    const int MAX_TIEFE=4;
    
    //#define TRACE
    
    class CompMinMax:public Spieler
    {
       std::string getName()
    	{
    		return "MinMax";
    	}
       std::string getAutor()
       {
          return "Volkard";
       }
       std::string getBeschreibung()
    	{
    		return "Einfacher MinMax ohne jede Optimierung. Er dient nur der Veranschaulichung "
             "des Verfahrens und wird sofort von NegaMax abgelöst. Der Code wurde von "
             "//http://fbi001.informatik.fh-hamburg.de/~owsnicki/search.html genommen und "
             "nach C++ übersetzt.";
    	}
       int heuristik(Stellung *stellung,Farbe farbe)
       {
          //Hier ist anzusetzten. Sie haben in der Vorlesung schön aufgepaßt und wissen, 
          //daß in dieser Methode zunächt die größten Möglichkeiten stecken, eventuelle 
          //Gegner plattzumachen. 
          //Horido!
          return 0;
       }
       BewerteterZug maximiere(Stellung *stellung,Farbe meineFarbe,int suchtiefe)
       {
          Zug besterZug=UNMOEGLICH;
          Wert besterWert=MINUS_UNENDLICH;
          if(stellung->spielEnde())
             besterWert=stellung->bewerte(meineFarbe);
          else if(suchtiefe==0)
             besterWert=heuristik(stellung,meineFarbe);
          else
          {
             Stack<Zug,7> alleZuege;
             stellung->sageAlleZuege(&alleZuege);
             while(!alleZuege.isEmpty())
             {
                stellung->setzeZug(alleZuege.peek());
                BewerteterZug x=minimiere(stellung,meineFarbe,suchtiefe-1);
                stellung->loescheZug(alleZuege.peek());
                if(x.getWert()>besterWert)
                {
                   besterWert=x.getWert();
                   besterZug=alleZuege.peek();
                }
                alleZuege.pop();
             }
          }
    #ifdef TRACE
    stellung->anzeige();std::cout<<besterZug<<": "<<besterWert<<std::endl;getch();
    #endif
          return BewerteterZug(besterZug,besterWert);
       }
       BewerteterZug minimiere(Stellung *stellung,Farbe meineFarbe,int suchtiefe)
       {
          Zug besterZug=UNMOEGLICH;
          Wert besterWert=PLUS_UNENDLICH;
          if(stellung->spielEnde())
             besterWert=stellung->bewerte(meineFarbe);
          else if(suchtiefe==0)
             besterWert=heuristik(stellung,meineFarbe);
          else
          {
             Stack<Zug,7> alleZuege;
             stellung->sageAlleZuege(&alleZuege);
             while(!alleZuege.isEmpty())
             {
                stellung->setzeZug(alleZuege.peek());
                BewerteterZug x=maximiere(stellung,meineFarbe,suchtiefe-1);
                stellung->loescheZug(alleZuege.peek());
                if(x.getWert()<besterWert)
                {
                   besterWert=x.getWert();
                   besterZug=alleZuege.peek();
                }
                alleZuege.pop();
             }
          }
    #ifdef TRACE
    stellung->anzeige();std::cout<<besterZug<<": "<<besterWert<<std::endl;getch();
    #endif
          return BewerteterZug(besterZug,besterWert);
       }
       Zug sageZug(const Stellung *stellung)
       {
          Stellung meineStellung=*stellung;
          Farbe meineFarbe=stellung->werIstDran();
          BewerteterZug besterZug=maximiere(&meineStellung,meineFarbe,MAX_TIEFE);
          return besterZug.getZug();
       }
    };
    
    CompMinMax meinCompMinMax;
    

    ich hab mich nicht in vielen ifs verlaufen und abgestürzt ist auch nix.

    das dann wieder den halben PC zum Absturz bringt, wollt ich mal fragen obs da irgendwas professionelleres gibt, das ich benutzen kann.

    kein grund, den pc abstürzen zu lassen.

    Achja ich benutze C und die WinAPI.

    doch. lern einfach c++. das geht wesentlich schneler, als zu lernen, in c komplexe programme zu schreiben, ohne das was abstürzt.

    Ich hoffe man hat mein Problem verstanden.

    ich denke schon. hoffe, du hast meine antwort verstanden.



  • Ok danke erstmal für eure Antworten.

    Zu dir leech:
    So hab ich mir das auch gedacht! Nur wie lasse ich den Computer die möglichen Züge bewerten ?

    Zu dir Volkard:

    lern einfach c++. das geht wesentlich schneler, als zu lernen, in c komplexe programme zu schreiben, ohne das was abstürzt.

    Ich kann C++ und finde es auch wesentlich besser. Schon allein wegen den Strings^^
    Nur hab ich mir einen Petzold gekauft (den ich gerade durcharbeite) und der ist ja in C geschrieben. Und deshalb hab ich mich jetzt eher wieder auf C runtergelassen, weil ich noch nicht so genau weiß wie ich die ganzen API-Funktionen mit C++ aufrufe 😉



  • Ocin schrieb:

    Ich kann C++ und finde es auch wesentlich besser. Schon allein wegen den Strings^^
    Nur hab ich mir einen Petzold gekauft (den ich gerade durcharbeite) und der ist ja in C geschrieben. Und deshalb hab ich mich jetzt eher wieder auf C runtergelassen, weil ich noch nicht so genau weiß wie ich die ganzen API-Funktionen mit C++ aufrufe 😉

    ok. dann macht das spiel in c++. und die kommunikation mit windows in c.



  • Ocin schrieb:

    Zu dir leech:
    So hab ich mir das auch gedacht! Nur wie lasse ich den Computer die möglichen Züge bewerten ?

    Nennt sich Min/Max-Verfahren, kannst ja'n bissl nachschlagen.

    Bye, TGGC (Wähle deine Helden)


Anmelden zum Antworten