Künstliche Intelligenz in PacMan

Goy

Grünschnabel
Hallo

Ich arbeite momentan an einem Pacman-Clone mit welchem ich schon fast fertig bin. Bis jetzt konnte ich jede Schwierigkeit meistern, doch die KI (Künstliche Intelligenz) für die Geister macht mich fertig.

Ich programmiere das ganze in DelphiX.

Die Abfrage habe ich bis jetzt folgendermaßen gemacht.

Ich ermittelte die Länge zwischen dem Spieler und dem Geist, welches sich ganz leicht mit dem Pythagoräischen Lehrsatz ausrechnen lässt.

O
|\
|y\c
|__\A
x
c² = x² + y²

Man muss nur noch ermitteln in welche Richtung es soll, aber das Problem sieht folgendermaßen aus.

Wenn die Geister in eine Ecke kommen und die Geister sehen mich, dann stecken diese dort fest. Ich schaffe es ihnen nicht zu sagen, dass die versuchen sollen das Hinderniss zu umgehen.

Überhaupt wäre es klasse, wenn mir einer einen Tipp geben könnte, wie man den Geistern eine so gute KI verleihen kann, dass mehrere Schwierigkeitsgrade möglich sind.

Die Hindernisse frage ich mit Hilfe eines Arrays von Nullen und Einsen ab. Die Figuren bewegen sich nicht Kästchenweise, sondern Pixelsmäßig, damit es ein schön flüssig ablauft.

Erhoffe auf baldige Hilfe, bin schon total am verzweifeln.
 

derGugi

Erfahrenes Mitglied
ich würde dein Programm gerne testen, jedoch läuft das unter NT nicht :( gibts eigentlich ein DirectX für NT? Nicht, oder? Wollte nämlich auch mal mit DelphiX was machen, ging dann aber halt wegen dem NT nicht :(

Zu deinem Problem: Was bringt dir eigentlich die Länge zwischen der Figur und dem Gegner? Funktioniert PacMan nicht so, dass die Gegner einfach rumlaufen und falls sie ein Spieler entdecken, ihm hinterher jagen? Sie steuern ja nicht von einer Ecke direkt auf den Spieler zu. Verschiedene Schwierigkeitsstufen waren beim PacMan unterschiedliche Geschwindigkeiten.
 

Goy

Grünschnabel
Es gibt ein DirectX für NT, weiß nicht mehr wo das zu finden ist.

Ich hätte die KI schon so machen können, wie du es geschrieben hast.
Aber das wäre dann viel zu simpel und keine richtige KI.

Ich habe es so gemacht, dass jeder Geist einen bestimmten Sichtradius hat, und wenn der Spieler in dem Sichtradius ist, soll es die Verfolgung aufnehmen, sollte der Spieler einen großen Punkt gefressen haben so flieht der Geist.

Die Geister sind alle langsamer als der Spieler, der Spieler kann dank der KI schnell aufgehalten werden.

Es gibt bereits ein Spiel das WinPac 2 heißt.
Wenn man genau hinschaut, merkt man, dass die Geister sofort um die Ecke gehen und dich nur für eine bestimmte Zeit jagen.

Wenn du willst werde ich ein Screenshot von meinem Spiel schicken, wenn du das DirectX für NT nicht finden solltest.
 

Goy

Grünschnabel
Ich habe es jetzt so gemacht, dass die KI nur noch Rauf, Runter, Links, Rechts verfolgen kann, hier der Code

Code:
function TGegner.WatchOut4Player: TDirection;
   function IfDo(Expression : boolean; const TruePart, FalsePart : TDirection):TDirection;
   begin
     if Expression then
       result := TruePart
     else
       result := FalsePart;
   end;

var i, lookx, looky, PacX, PacY:integer;
    laenge : array [1..2] of integer;
    VerfolgeSpieler : TSpieler;
begin
  result := fsStehen;
  VerfolgeSpieler := nil;

  for i:= 1 to 2 do
    if Game.Spieler[i]<>nil then  //Errechnet den Radius eines "existierenden" Spielers
      laenge[i] := round(sqrt(sqr(Game.Spieler[i].X - X) + sqr(Game.Spieler[i].Y - Y)))
    else laenge[i] := -1;   //Dient zur folgenden Abfrage
                            // - 1 bedeutet, das es den Spieler nicht mehr gibt

  //Verfolgt den Spieler, der dem Geist am nächsten ist
  if (laenge[2]=-1) or (laenge[1]<laenge[2]) and (laenge[1]<>-1) then
    VerfolgeSpieler := Game.Spieler[1]
  else
    if (laenge[1]=-1) or (laenge[1]<>laenge[2]) and (laenge[2]<>-1) then
      VerfolgeSpieler := game.Spieler[2]
    else
      if (laenge[1]<>-1) and (laenge[2]<>-1) then
        VerfolgeSpieler := Game.Spieler[Random(2)+1];  //Sollten beide Radien gleich sein
                                                       //so wird per Zufall entschieden

  if (VerfolgeSpieler<>nil) then
  begin
    PacX := (round(VerfolgeSpieler.X) div gr)+1;
    PacY := (round(VerfolgeSpieler.Y) div gr)+1;

    lookx := (round(x) div gr)+1;
    looky := (round(y) div gr)+1;
    // Rechts
      repeat
        inc (lookx);
        if (PacX = lookx) and (looky = PacY) then
        begin
          result := IfDo(VerfolgeSpieler.DoEatingAll,fsLinks,fsRechts);
          Exit;
        end;
      until (Game.Level.ArrayofBilder[lookx,looky] = 1) or (lookx >= zeile);

    lookx := (round(x) div gr)+1;
    looky := (round(y) div gr)+1;
    //Runter
      repeat
        inc(looky);
        if (PacX = lookx) and (looky = PacY) then
        begin
          result := IfDo(VerfolgeSpieler.DoEatingAll,fsRauf,fsRunter);
          Exit;
        end;
      until (Game.Level.ArrayofBilder[lookx,looky] = 1) or (looky >= spalte);

    // Links
    lookx := (round(x) div gr)+1;
    looky := (round(y) div gr)+1;
      repeat
        dec(lookx);
        if (PacX = lookx) and (looky = PacY) then
        begin
          result := IfDo(VerfolgeSpieler.DoEatingAll,fsRechts,fsLinks);
          Exit;
        end;
      until (Game.Level.ArrayofBilder[lookx,looky] = 1) or (lookx <= 1);

    lookx := (round(x) div gr)+1;
    looky := (round(y) div gr)+1;
    //Rauf
      repeat
        dec(looky);
        if (PacX = lookx) and (looky = PacY)  then
        begin
          result := IfDo(VerfolgeSpieler.DoEatingAll,fsRunter,fsRauf);
          Exit;
        end;
      until (Game.Level.ArrayofBilder[lookx,looky] = 1) or (looky <= 1);
  end;
end;
 

Andreas Gaisbauer

Erfahrenes Mitglied
Original geschrieben von derGugi
ich würde dein Programm gerne testen, jedoch läuft das unter NT nicht :( gibts eigentlich ein DirectX für NT? Nicht, oder? Wollte nämlich auch mal mit DelphiX was machen, ging dann aber halt wegen dem NT nicht

Q. Is DirectX compatible with Windows NT 4.0?

A. Yes. However, the only version supported on Microsoft Windows NT® 4.0 is DirectX 3.0a. You must also install Windows NT 4.0 Service Pack 6.

-> http://www.microsoft.com/windows/di...=/windows/directx/productinfo/faq/default.htm

also wenn es irgendwo rumliegt dann wahrscheinlich auf -> http://www.microsoft.com/windows/directx/default.aspx

ciao
 

derGugi

Erfahrenes Mitglied
danke aber habs ned gefunden... entweder haben sie es nicht mehr auf dem Server oder es ist einfach nur gut versteckt :)
 

olo

Grünschnabel
ich weiss nicht.
ich finde die lösung relativ umständlich. du könntest doch auch vektor-mathematik für dein problem benutzen, soll aber nur ein vorschlag sein :).