Entwickler-Ecke

Multimedia / Grafik - KI= Problem(Leider)


mimi - Mo 28.04.03 15:37
Titel: KI= Problem(Leider)
Hallo,
ich schreibe gerade einen Pacman Clone und habe probleme mit der KI.
Ich habe es mit folgendem code versucht:

Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
procedure ki_go(Index:Integer);
begin
//  Game.KI[Index].x:=Game.KI[Index].x+1;
//  Game.KI[Index].x:=Game.KI[Index].x-1;

//  Game.KI[Index].y:=Game.KI[Index].y+1;
//  Game.KI[Index].y:=Game.KI[Index].y-1;

  if (Game.Karte[ Game.KI[Index].x+1,Game.KI[Index].y ].typ <> _Wand) then Game.KI[Index].x:=Game.KI[Index].x+1;
  if (Game.Karte[ Game.KI[Index].x-1,Game.KI[Index].y ].typ <> _Wand) then Game.KI[Index].x:=Game.KI[Index].x-1;

  if (Game.Karte[ Game.KI[Index].x,Game.KI[Index].y+1 ].typ <> _Wand) then Game.KI[Index].y:=Game.KI[Index].y+1;
  if (Game.Karte[ Game.KI[Index].x,Game.KI[Index].y-1 ].typ <> _Wand) then Game.KI[Index].y:=Game.KI[Index].y-1;

end;

aber die KI läuft immer nur noch Links.

mein Ziel:
die KI soll sich selbstsändig im Level verteilen...
(also ohne Ziel)
wer könnte mir helfen...
Ein Beispiel währe auch nicht schlecht !!!


maximus - Mo 28.04.03 16:39

Hi.

Ich würds so machen: Deiene KI steht auf einem punkt! Du ermittelst für diesen punkt alle möglichen richtungen, als TPoint ( dirs[i] := point(0,-1) etc)! Dann suchst du dir per random eine aus und filterst vorher am besten noch die richtung, aus der du kommst. Dann game.KI[i].x := game.KI[i].x+dirs[rand].x; etc!

Wär das was?


mimi - Mo 28.04.03 16:59

ja, aber wie sieht das im Code aus ?


mimi - Mo 28.04.03 17:47

ich habe jetzt folgenden code:

Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
procedure ki_go(Index:Integer);
var
  dirs1:String;
  ri:Integer;
begin
  ri:=-1;
  Randomize;
  with Game.KI[Index] do begin
    // Alle freigeben richtungen ermitteln
    if x+1 <= _MapX then
      if Game.Karte[x+1,y].typ <> _Wand then dirs1:=dirs1+IntToStr(_Oben);

    if x-1 >= 0 then
      if Game.Karte[x-1,y].typ <> _Wand then dirs1:=dirs1+IntToStr(_Unten);

    if y-1 >= 0 then
      if Game.Karte[x,y-1].typ <> _Wand then dirs1:=dirs1+IntToStr(_Links);

    if y+1 <= _MapY  then
      if Game.Karte[x,y+1].typ <> _Wand then dirs1:=dirs1+IntToStr(_Rechts);

    ri:=StrToint(Dirs1[Random( StrLen(PChar(dirs1)) )+1] );
    Form1.DXTimer1.Enabled:=False;

//      ShowMessage(IntToStr(Random( StrLen(PChar(dirs1)) )+1 ) );

   Form1.DXTimer1.Enabled:=True;

    Game.karte[x,y].typ:=_None;
    x:=x+dirs[ri].x;
    y:=y+dirs[ri].y;
    Game.karte[x,y].Typ:=_Monster;
  end;
end;

aber leider kommt irgenwan eine fehlermeldeung:
Zugrifsverletzung bei ....
warum ???


Moritz M. - Mo 28.04.03 17:50

Die beste Methode wäre es, perr Array ein Gitternetz aufzubauen, auf dem er sich bewegt, der KI. Und für jeden Pubkt würde ich
1)speichern, ob er gerade belegt ist bzw. ob eine Mauer da ist(das geht mit einem boolean)
2)speichern, wie oft der KI schon dort war, dann nimmt er nämlich immer andere Wege
. Du könntest auch immer einen Zielpunkt setzen, auf den er sich zubewegt.
Das ganze in Code umzusetzen dürfte zwar etwas dauern, aber mit normalem Menschenverstand zu machen sein.


mimi - Mo 28.04.03 18:09

mimi hat folgendes geschrieben:
ich habe jetzt folgenden code:

Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
procedure ki_go(Index:Integer);
var
  dirs1:String;
  ri:Integer;
begin
  ri:=-1;
  Randomize;
  with Game.KI[Index] do begin
    // Alle freigeben richtungen ermitteln
 if y+1 <= _MapY then
      if Game.Karte[x,y+1].typ <> _Wand then dirs1:=dirs1+IntToStr(_Oben);

    if y-1 >= 0 then
      if Game.Karte[x,y-1].typ <> _Wand then dirs1:=dirs1+IntToStr(_Unten);

    if x-1 >= 0 then
      if Game.Karte[x-1,y].typ <> _Wand then dirs1:=dirs1+IntToStr(_Links);

    if x+1 <= _MapX  then
      if Game.Karte[x+1,y].typ <> _Wand then dirs1:=dirs1+IntToStr(_Rechts);
    ri:=StrToint(Dirs1[Random( StrLen(PChar(dirs1)) )+1] );
    Form1.DXTimer1.Enabled:=False;

//      ShowMessage(IntToStr(Random( StrLen(PChar(dirs1)) )+1 ) );

   Form1.DXTimer1.Enabled:=True;

    Game.karte[x,y].typ:=_None;
    x:=x+dirs[ri].x;
    y:=y+dirs[ri].y;
    Game.karte[x,y].Typ:=_Monster;
  end;
end;

aber leider kommt irgenwan eine fehlermeldeung:
Zugrifsverletzung bei ....
warum ???


mimi - Mo 28.04.03 18:16

ich habe es jetzt so weit, das sich die KI beweg, aber es dauert zu lange bis die aus dem Kasten raußgekommen ist :(


Moritz M. - Mo 28.04.03 18:19

Schick mir mal das Prog mit Source. Ich schaus mir mal an.
Email:
Mo@onz24.de


mimi - Mo 28.04.03 18:26

Mein Mail Client(Pegasus Mail) Spinnt mal wieder...ich kann dir es leider nicht sende.... soll ich hier mal den qullcode von den wichtigesten sachen posten ?


Moritz M. - Mo 28.04.03 18:30

Sowas bringt mir leider wenig.


mimi - Mo 28.04.03 18:38

ja.. ich verzuche es gleich nochmal....
aber ich glaube kaum das du dich mein qullcode steigts(unübersichtlich)

EDIT:
prima, ich habe es hinbekommen, die mail wird gerade versendet ;) *FREU*


Moritz M. - Mo 28.04.03 18:53

Ok, werds mir mal anschaun.


mimi - Mo 28.04.03 19:58

ich hoffe du hast nicht zuviele mail bekommen(von mir) ;)


Moritz M. - Mo 28.04.03 20:00

Nein nein, aber wir sollen di Diskussion nicht privatisieren.


mimi - Mo 28.04.03 20:19

ist mir klar.... und kannst du mir bei mein Problem weiter helfen ?


maximus - Mo 28.04.03 22:31

Könnte es sein, dass du die array-grenzen verletzt?


mimi - Mo 28.04.03 22:42

Lautzeitfehler treten nicht auf, dafür habe ich gesorgt, es ist ein denk fehle irgenwie.... zwischen durch habe ich soga ein Stack überlauf erzeugt ;)


maximus - Di 29.04.03 10:02

Nur so aus interesse: Warum ist bei dir oben - unten?

Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
if y+1 <= _MapY then 
      if Game.Karte[x,y+1].typ <> _Wand then dirs1:=dirs1+IntToStr(_Oben); // y+1 ist doch unten! 

    if y-1 >= 0 then 
      if Game.Karte[x,y-1].typ <> _Wand then dirs1:=dirs1+IntToStr(_Unten); // y-1 ist normalerweise oben!

    if x-1 >= 0 then 
      if Game.Karte[x-1,y].typ <> _Wand then dirs1:=dirs1+IntToStr(_Links); 

    if x+1 <= _MapX  then 
      if Game.Karte[x+1,y].typ <> _Wand then dirs1:=dirs1+IntToStr(_Rechts);

?Oder hast du das koordinaten system gedreht?


mimi - Di 29.04.03 17:25

Oh, jetzt wo du es sagts, fählt es mir auch auf.... werde ich mal ändern ;)


mimi - Di 29.04.03 17:48

ich habe es jetzt geändert:
aber immer noch so wie führer, die KI verbreitet sich zu langsamm auf dem bildschirm, in der zeit, hätte der spieler schon alles futter was da ist aufgessen :(
die KI muss sich rasend schnell verbreiten....


maximus - Di 29.04.03 18:26

Zum verständniss: Die KI (geister) befinden sich in einem geschlossenen bereich (ghosthome) aus dem sie erstmal raus müssen. Es gibt einen ausgang an dem sie immer vorbei laufen und sich somit nicht schnell genug verteilen?


Wenn dem so ist, dann plaziere doch am ausgang ein item, das sie immer durch den ausgang laufen lässt.


mimi - Di 29.04.03 19:12

ja genau das meine ich:
ich habe Pacman KIS(unter dos) gesehen wo sich die ki recht schnell über den bildschrim verteilt haben....


Moritz M. - Di 29.04.03 19:18

Schickst du mir dann bitte den neuen Code?


mimi - Di 29.04.03 23:47

habe da nicht viel geändert aber mache ich;)
sende mir mal ne mail(mimi_171@gmx.de) weil ich habe deine nicht mehr :(


Moritz M. - Mi 30.04.03 16:57

Hähe. Die steht
1)weiter oben
2)im Profil
Aber hier 3) nochmal:
Mo@onz24.de


mimi - Mi 30.04.03 20:05

OK sende ich gleich