[ PeraKojotSuperGenije @ 08.02.2005. 00:43 ] @
function TKlasa.Funkcija(a, b: integer; const c, d, e: byte): integer;

Posle pozivanja navedene funkcije
Code:
Klasa.Funkcija(-10, 10, 3, 2, 1);

u samoj funkciji argumenti c, d i e nemaju vrednosti 3, 2, 1!

Sta se ovde desava???

Unapred hvala!
[ reiser @ 08.02.2005. 01:29 ] @
Postuj celu fju i deo koda gde je pozivas ako nije problem, tako ce nam biti lakse da uocimo problem...
[ PeraKojotSuperGenije @ 08.02.2005. 11:20 ] @
Code:
procedure TAI.RootSearchAB(alpha, beta: integer; const depth: byte; var n, x, y: byte);
label 1;
var f, i, p, la, nowp: integer;
    a: TDynamicArray;
begin
  np:=0;
  form1.Memo1.Lines.Clear;
  form1.Memo2.Lines.Clear;
  nowp:=NumOfWinPawns;
  GenerateAllMoves(self.color, depth, a);
  la:=(length(a) div 5)-1;
  for i:=0 to la do
  begin
    MakeMove(a[i*5], a[i*5+1], a[i*5+2], a[i*5+3], a[i*5+4], 9);
    myGame.gameState:=(1-myGame.gameState);

    f:=-NegaMaxAB(alpha, beta, depth-1, (1-self.color), nowp);
    if f>alpha then
    begin
      alpha:=f;
      p:=i;
    end;
    form1.Memo1.Lines.Append(inttostr(i)+': '+inttostr(a[i*5])+inttostr(a[i*5+1])+ inttostr(a[i*5+2])+ inttostr(a[i*5+3])+ inttostr(a[i*5+4]));
    form1.Memo2.Lines.Append(inttostr(f));
    myGame.gameState:=(1-myGame.gameState);
    MakeMove(a[i*5], a[i*5+3], a[i*5+4], a[i*5+1], a[i*5+2], 9);
    if alpha>=beta then goto 1;
  end;
1:
  n:=jumped;
  n:=steped;
  n:=a[p*5];
  x:=a[p*5+3];
  y:=a[p*5+4];
  form1.Label1.Caption:='Broj procenjenih pozicija je '+IntToStr(np);
end;

function TAI.NegaMaxAB(alpha, beta: integer; const depth, clr, nowp: byte): integer;
label 1, 2;
var f, i, la, sign, a1, b1, c1, d1, f1, g1: integer;
    a: TDynamicArray;
begin
  sign:=ord(self.color=clr)+ord(self.color<>clr)*(-1);
  if (depth<=0) or myGame.players[1-clr].IAmWinner
  then
  begin
    sign:=sign*(depth+1);
    result:=sign*PositionValue(self.a, self.b, self.c, self.d, self.e, self.f, self.g, self.h, self.q, nowp);
    inc(np);
  end
  else
  begin
    GenerateAllMoves(clr, depth, a);
    la:=(length(a) div 5) -1;
    if clr<>self.color then //minimizing
    begin
      for i:=0 to la do
      begin
        myGame.players[clr].MakeMove(a[i*5], a[i*5+1], a[i*5+2], a[i*5+3], a[i*5+4], 9);
        myGame.gameState:=(1-myGame.gameState);

        f:=-NegaMaxAB(alpha, beta, depth-1, 1-clr, nowp);
        if f<beta then beta:=f;

        myGame.gameState:=(1-myGame.gameState);
        myGame.players[clr].MakeMove(a[i*5], a[i*5+3], a[i*5+4], a[i*5+1], a[i*5+2], 9);
        if alpha>=beta then goto 1;
      end;
1:    result:=beta;
    end
    else
    begin
      for i:=0 to la do
      begin
        myGame.players[clr].MakeMove(a[i*5], a[i*5+1], a[i*5+2], a[i*5+3], a[i*5+4], 9);
        myGame.gameState:=(1-myGame.gameState);

        f:=-NegaMaxAB(alpha, beta, depth-1, 1-clr, nowp);
        if f>alpha then alpha:=f;

        myGame.gameState:=(1-myGame.gameState);
        myGame.players[clr].MakeMove(a[i*5], a[i*5+3], a[i*5+4], a[i*5+1], a[i*5+2], 9);
        if alpha>=beta then goto 2;
      end;
2:    result:=alpha;
    end;
  end;
end;


...

Sporna funkcija je Negamax koju poziva Rootsearch, a ovu poziva sledeca...

Code:
procedure TAI.YourTurn;
var n, x, y, depth: byte;
begin
    LoadGens(
    strtoint(form1.memo3.Lines[0]),
    strtoint(form1.memo3.Lines[1]),
    strtoint(form1.memo3.Lines[2]),
    strtoint(form1.memo3.Lines[3]),
    strtoint(form1.memo3.Lines[4]),
    strtoint(form1.memo3.Lines[5]),
    strtoint(form1.memo3.Lines[6]),
    strtoint(form1.memo3.Lines[7]),
    strtoint(form1.memo3.Lines[8]));

  movementStarted:=false;
  jumped:=0;
  steped:=0;
  myTurn:=true;
  timer.Tag:=0;
  timer.Interval:=100;
  myGame.AnounceTime;
  depth:=StrToInt(Form1.Edit1.Text);
  RootSearchAB(-maxint-1, maxint, depth, n, x, y);
  inc(game.numberOfMoves);
  setlength(game.moves, game.numberOfMoves*4);
  game.moves[length(game.moves)-4]:=Pawns[n].x;
  game.moves[length(game.moves)-3]:=Pawns[n].y;
  game.moves[length(game.moves)-2]:=x;
  game.moves[length(game.moves)-1]:=y;

  MakeMove(n, pawns[n].x, pawns[n].y, x, y, 9);

  game.PlayerDone;
end;


[Ovu poruku je menjao PeraKojotSuperGenije dana 09.02.2005. u 01:25 GMT+1]
[ _v!rus_ @ 08.02.2005. 17:16 ] @
Byte tip ima opseg 0..255, a ti gore pozivas sa 1-nesto, ako je 1-nesto < 0 onda se radi wrappovanje bajta tj. 1-nesto = 257 - nesto, ako je nesto>1. Mozda ovo helps, a mozda si tako i hteo, nisam preterano zalazio u kod.
[ PeraKojotSuperGenije @ 08.02.2005. 20:54 ] @
Nije uopste u tome stvar. Onaj argument depth u proceduri YourTurn ima vrednost (konkretan primer) 2. Kada se pozove RootSearch depth tu ima vrednost 220. U prvom pozivu Negamax ima vrednost 120 umesto depth-1 sto je 219! A sto se tice onoga 1-nesto to nesto je color(boja). Ona je uvek 0 ili 1 pa 1-color invertuje boju.
[ morlic @ 08.02.2005. 23:48 ] @
Postavi break point na liniju gde imas:

RootSearchAB(-maxint-1, maxint, depth, n, x, y);

Pa odatle pazljivo posmatraj sta se desava sa vrednoscu promenjivih, narocito pre i posle linija:

GenerateAllMoves(self.color, depth, a);
i
sign:=ord(self.color=clr)+ord(self.color<>clr)*(-1);


Kada ti je program pauziran i nalazis se u Delphi-u samo drzi pokazivac misa nad promenjivom i dobices njenu trenutnu vrednost. Ima i naprednijih tehnika pracenja, ali probaj za sada sa ovom.

Negde gresis, mozda na liniji

GenerateAllMoves(self.color, depth, a);

sta se tu desava? Da li se tu depth prosledjuje po imenu ili vrednosti?

Onda mozemo da vidimo dalje. Kompajler ne gresi na takvim stvarima inace ne bi mogao i najprostiji Delphi program da pokrenes.
[ PeraKojotSuperGenije @ 09.02.2005. 00:23 ] @
Code:
procedure GenerateAllMoves(c: TColor;const  d: byte; var a: TDynamicArray);

Zbog const d:byte mislim da GenerateAllMoves ne moze da pravi probleme.

Code:
procedure TAI.RootSearchAB(alpha, beta: integer; const depth: byte; var n, x, y: byte);

Kada iz YourTurn pozovem RootSearchAB cim (sa F7) udjem u RootSearchAB st(r)anje je sledece:
alpha = -maxint-1 sto je i ocekivano;
beta = maxint sto je takodje ocekivano;
depth = 220 sto nije ocekivano;
n = Inaccessable value sto takodje nije ocekivano;
x = 0 OK;
y = 0 OK;

Sve ove vrednosti se vide u kako hintovima tako i u WatchList-u.
Slicne brlje se desavaju kada se pozove NegaMax.
[ reiser @ 09.02.2005. 01:19 ] @
Ne verujem da je u ovome problem, ali probaj da promenis "konvenciju pozivanja", valjda se tako zove... U produzetku problematicne fje koju pozivas probaj da stavis stdcall; ili cdecl;...
[ PeraKojotSuperGenije @ 09.02.2005. 02:01 ] @
Calling Convection ?!?
Za ovo cujem prvi put u zivotu!, ali je pomoglo (bar za sada tako izgleda)!!! Mnogo HVALA (mada ti od toga nemas nista)! Ja sam se vec izgubio. Cak sam poceo da trazim zakrpe za Delphi 7.

Ima li neko posebno lepo mesto na ovom svetu (web, knjiga, e-knjiga, kurs, ...) gde bih mogao da naucim vise o ovome i slicnom stvarima (a da to nije regularni HELP, jer mi nikad ne bi palo na pamet da gledam sta ima pod calling convention)?

Jos jednom HVALA!
[ morlic @ 09.02.2005. 12:08 ] @
Evo primera koji radi kod mene na D7. Probaj pa javi kako radi:


p.s. Ukljuci "Range checking" u Project->Options->Compiler pa uradi build programa pa javi kako radi.
[ sasas @ 09.02.2005. 12:28 ] @
čekajte ljudi, polako... jel moze neko da objasni u čemu je fazon?
Zašto radi sa jednim a ne radi sa drugim calling conventionom (i sa kojim uopšte radi)? Zašto će mu pomoći range checking, ako je već algoritam ispravan?

Prvi put vidim da u Delphiju neko pomera opcije kompajlera (i generisanja kooda) i da to stvarno ima efekta na 'ispravniji' rad programa. Pa ako ima neko da malo razjasni stvari...

ss.
[ PeraKojotSuperGenije @ 09.02.2005. 13:25 ] @
Ovo sto si ti poslao u sustini radi (smeta samo sto je self.color=10243, ali to nije vazno, jer se kod mene sve to desava u jednoj klasi koja ima polje color i koje uvek ima vrednosti 0 ili 1, bla bla bla...). Nije mi jasno zasto u kombinaciji sa ostalim linijama mog koda pravi problem, ali dodavanje bilo koje od onih "calling convention" direktiva koje cine da se argumenti ucitavaju sa desna na levo popravlja stvar.

Kako da znam kada ovo treba da koristim? Imam dosta metoda pa je malo mucno da proveravam da li na svaku pojedinacno treba da stavljam "nesrecnu" direktivu!

Inace "Range checking" mi je u ovoj fazi uvek ukljucen.

[ Rapaic Rajko @ 09.02.2005. 13:39 ] @
Sta je OVO:
Code:

label 1;


Crni PeraKojote, sta to cinis? i to izmedju deklaracije funkcije i var dela...brrr; nikad to nisam video. U stvari nikad u zivotu nisam upotrebio goto() u Pascalu.

Rajko
[ sasas @ 09.02.2005. 14:23 ] @
Citat:
... i to izmedju deklaracije funkcije i var dela...brrr; ...


Ne brini rajko, to je samo deklaracija labele, ne skače na to mesto, nego dole unutar funkcije. Daleko od toga da je lepo koristiti goto, ali verovatno se nije moglo bolje.

ss.
[ PeraKojotSuperGenije @ 09.02.2005. 15:46 ] @
Jasno je i meni koliko je goto ruzna naredba. Moze umesto nje da stoji i break, sto bi u sustini radilo isto: izlazak iz for petlje. Goto isprobavam zbog toga sto mislim da ce biti brze od break.
[ morlic @ 09.02.2005. 18:09 ] @
Problem moze biti ako se zoves neku funkciju iz nekog dll-a. Tu jednostavno mora da se pazi na nacin na koji se nacin prosledjuju parametri. U ostatku programa nema sta da podesavas jer kompajler "zna" svaku funkciju, tj. kako prosledjuje parametre (uglavnom register varijanta zbog brzine). Ako onaj ko poziva neku funkciju promasi tip prosledjivanja argumenata moze doci do korupcije steka i tada obicno dolazi do "access violation" greske, ali kod tebe toga nema.

Dok razmisljam o tvom problemu uradi sledece: u opcijama kompajlera ukljuci "stack frames" i iskljuci "optimization" pa probaj (obrisi posle toga sve dcu fajlove iz projekta i uradi build). Da vidimo :)

p.s. Najlakse bi bilo kada bih mogao da sednem za tu masinu i preko CPU debug prozora prekontrolisao EBP i ESP registre procesora kako bih video sta se tu konkretno desava po pozivu funkcije, kao i sta je i kako prosledjeno od argumenata. Ali sad sta mozemo...

p.s. 2

Onaj primer sto sam ti poslao radi tako da obavezno obrises sve dcu fajlove iz projekta.
[ PeraKojotSuperGenije @ 09.02.2005. 19:18 ] @
Citat:
Dok razmisljam o tvom problemu uradi sledece: u opcijama kompajlera ukljuci "stack frames" i iskljuci "optimization" pa probaj (obrisi posle toga sve dcu fajlove iz projekta i uradi build). Da vidimo

Prob'o. Bez onih direktiva i dalje ne radi. Sa njima, kao i pre, radi.


Citat:
p.s. Najlakse bi bilo kada bih mogao da sednem za tu masinu i preko CPU debug prozora prekontrolisao EBP i ESP registre procesora kako bih video sta se tu konkretno desava po pozivu funkcije, kao i sta je i kako prosledjeno od argumenata. Ali sad sta mozemo...

Da li bi pomoglo ako bih ti poslao ceo projekat?

Citat:
Onaj primer sto sam ti poslao radi tako da obavezno obrises sve dcu fajlove iz projekta.

Kog projekta? Zasto?
[ _v!rus_ @ 09.02.2005. 21:52 ] @
Mozda je glupo, ali sta se desava ako promenis redosled parametara? Jel gresi samo sa byte tipom? Jel si probao druge tipove (iako nema logike da ne radi sa bytom)? Takodje nema logike da cdecl ili stdcall resava stvar.
[ PeraKojotSuperGenije @ 09.02.2005. 22:53 ] @
Promenu redosleda, kao i tipova (stavljao sam da svi argumenti budu integer) ne resava problem. To sam prvo probao...
[ neor @ 10.02.2005. 07:17 ] @
Mislim da ce ovako tesko neko uspeti da ti pomogne. Probaj da izbacis iz tog koda sve sta mozes (narocito pozivi finkcija koje nisi ovde dao) a da se problem i dalje javlja i stavi onda ovde neki kod koji moze da se kompajlira pa da moze da se proba. Ovako je sve samo nagadjanje.
[ PeraKojotSuperGenije @ 11.02.2005. 00:33 ] @
Kod ima oko 1500 linija, pa mi stvarno nije zgodno da eliminisem metodu po metodu...

Kao sto vec rekoh, dodavanje neke od gore navedenih direktiva mi resava stvar! Sta je bilo uzrok pocetnog problema i dalje ne znam. Ako je neko zainteresovan da dobije kod, da se sa njim "poigra" ne bi li nasao uzrok problema neka mi pise na mail.

[ neor @ 11.02.2005. 07:01 ] @
Citat:
PeraKojotSuperGenije:
Kao sto vec rekoh, dodavanje neke od gore navedenih direktiva mi resava stvar! Sta je bilo uzrok pocetnog problema i dalje ne znam.


To je opasno resenje.
Promena konvencije u ispravnom programu koji ne poziva spoljne funkcije ne sme da pravi razliku. Problem mora biti u necem drugom i samo ceka da se ponovo pojavi na drugom mestu.
Posto je to koliko vidim rekurzija, da nisi mozda ostao bez steka? Da ga povecas malo?
[ PeraKojotSuperGenije @ 11.02.2005. 13:43 ] @
Citat:
Posto je to koliko vidim rekurzija, da nisi mozda ostao bez steka?

Zar u ovom slucaju ne bi "pukao" program sa porukom "Stack overflow error..."(ili tako nesto)?
[ neor @ 11.02.2005. 15:02 ] @
Trebalo bi ali mozda negde imas try...except koji uhvati taj exception i ne obradi ga
[ PeraKojotSuperGenije @ 11.02.2005. 17:02 ] @
Neor mislim da me nisi razumeo. Meni se u toku izvrsavanja programa nikad ne javlja "Stack overflow error...", a na tvoje pitanje
Citat:
Posto je to koliko vidim rekurzija, da nisi mozda ostao bez steka?
, ja pitam: " Da li se u situaciji kada program ostaje bez steka uvek javlja "Stack overflow error"? Ja mislim da da.
[ morlic @ 12.02.2005. 00:57 ] @
Posto vidim da nema rezultata nasih saveta ne preostaje nista drugo nego da
upotrebimo tesku artiljeriju, u ovom slucaju CPU prozor koji omogucava da
se vidi sta se tacno desava u memoriji i u registrima procesora. Napravio sam
primer koji se sastoji od jedne forme i dugmenceta na njoj, na koji kada se
klikne poziva se procedura YourTurn koja dalje poziva sledecu proceduru i tako
dalje. Cilj je da pokazem nacin na koji se prosledjuju argumenti do procedure
i kako mozemo proveriti ispravnost prenetih podataka. Postoje jos nekoliko metoda
kako se sve ovo moze uraditi, ali sam izabrao ovaj jer je malo zanimljiviji.

Potrebno znanje:

Stek, postavljanje prekida (breakpoint) i jos po nesto :)

U opcijama projekta na stranici compiler treba postaviti:

Optimization=iskljuceno
Stack frames=iskljuceno
Range checking=iskljuceno
Overflow checking=iskljuceno

Debug information=ukljuceno

i uraditi Build projekta.

Kod primera:

Code:

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    procedure RootSearchAB(alpha, beta: integer; const depth: byte; var n,
      x, y: byte);
    procedure YourTurn;
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}
procedure TForm1.RootSearchAB(alpha, beta: integer; const depth: byte; var n, x, y: byte);
begin
  n:= depth;
end;

procedure TForm1.YourTurn;
Var
  n, x, y, depth: byte;
begin
   depth:= $63; // Decimalno 99
   n:= $11;     // Decimalno 17
   x:= $22;     // Decimalno 34
   y:= $33;     // Decimalno 51
   RootSearchAB(-maxint-1, maxint, depth, n, x, y);
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  YourTurn;
end;

end.



Postavljamo breakpoint na liniju:

depth:= $63;

i pokrenemo program. Kliknemo na button1 i program prekida izvrsavanje
i prikazuje se Delphi editor sa obelezenom linijom prekida.

Sada pritiskamo ctrl+alt+c i dobijamo CPU window kao na slici 1 koju
sam poslao. Od crvene tacke na dole mozemo videti kako promenjive
depth, n, x i y dobijaju vrednosti:

Code:

mov byte ptr [ebp-$08], $63


Ovo nije nista drugo do naredba da se vrednost $63 (decimalno 99) stavi na
lokaciju u memoriji na adresi [ebp-$08] (u pitanju je stek memorija u
kojoj se nalaze izmedju ostalog i lokalne promenjive. Ovo pravilo ne vazi
uvek ali da sada ne ulazim u detalje). Isto se desava i sa
ostalim promenjivama.

Slika1:



Od linije Unit1.pas.43 u CPU prozoru pocinju da se desavaju zanimljive
stvari. Krece pakovanje podataka za poziv procedure
RootSearchAB(). Prevodilac (compiler) pakuje argumente za
poziv procedure tako sto prva dva argumenta (alpha i beta)
stavlja u registre, dok ostale parametre pakuje na stek sa
leva na desno. Prvo pakuje na stek:

Code:

mov al,[ebp-$08]   // Vrednost promenjive depth se kopira u
                   // registar procesora al (1 byte register)
push eax           // Vrednost registra eax se smesta na stek
                   // al registar je deo eax registra


ovo je zbog toga sto je depth prosledjen kao const i procedura
koju pozivamo zapravo dobija kopiju vrednosti depth promenjive
i na taj nacin nece moci da izmeni originalnu depth promenjivu
koja se nalazi na lokaciji [ebp-$08].

Treba sa F7 ici kroz naredbe dok se ne stigne do linije

Code:

push eax


(kao na slici 2) koja je pomenuta gore.

Slika2:



Ako pogledamo u gornjem desnom delu
CPU prozora vrednosti registra procesora u tom trenutku videcemo da je u
eax registru vrednost $008C1E63. Posto je depth smesten u al
registar treba gledati samo zadnje dve cifre a to iznosi $63 sto i jeste
vrednost promenjive depth. Za sada je sve kako treba.

Ostale promenjive se prosledjuju kao var sto znaci da treba
omoguciti proceduri koju pozivamo da promeni njihove vrednosti.
Kompajler ovo radi tako sto prosledjuje adrese promenjivih u
memoriji proceduri koju zovemo kako bi ona eventualno mogla da
trajno upise nove vrednosti:

Code:

lea eax,[ebp-$05]   // Izracunaj efektivnu adresu promenjive n
                    // i izracunatu adresu stavi u eax registar
push eax            // stavi vrednost eax registra na stek


i isto tako i za x i y promenjive.


Sada dolazimo i do alpha i beta argumenata. Kompajler ce
staviti ove vrednosti da se prenose do procedure RootSearchAB() u
registrima ecx i edx kako i treba po konvenciji register.
Sledeci interesantan korak je i pozivanje procedure RootSearchAB().
Potrebno je pritiskati F7 (korak po korak) dok ne dodjemo do tacke kao na
slici 3:

Slika3:



To je trenutak kada se u promenjivu n stavlja vrednost promenjive
depth. Linija:

Code:

mov dl,[ebp+$14]


prebacuje vrednost promenjive depth u registar dl koji je deo edx
registra. To je trenutak kada mozemo u gornjem desnom uglu CPU prozora pogledati
edx registar i videti da sadrzi vrednost $63 (zadnje dve cifre) sto znaci da
promenjiva ima ispravnu vrednost. I tako dalje.

Ovaj koliko toliko prost primer pokazuje kako funkcionisu pozivi procedura i kako
se prosledju parametri. Ako stavimo da procedura RootSearchAB() koristi
stdcall prosledjivanje onda bi i alpha, beta promenjive isle preko steka
a ne preko registara. Imali bi smo umesto:

Code:

mov ecx,$7fffffff
mov edx,$80000000


sledeci kod:

Code:

push $7fffffff
push $80000000


sto na oko i nije neka velika razlika dokle god se ne koriste dll-ovi. Sa njima ova
razlika postaje velika jer ako procedura u dll-u ocekuje sve argumente na steku a dobije
prva dva u registrima onda imamo veliki problem, koji se najcesce rezultuje korupcijom steka.

Sada bi PeraKojotSuperGenije trebao da primeni ovu tehniku na svom programu uz neke sitne izmene
(kao sto je n:=depth na pocetku procedure kako bi vec tu mogao lakse iz CPU prozora da proveri
vrednost koja je prosledjena).

Eto materijala za pocetak pa da vidimo, posalji slike CPU prozora u ove tru faze koje sam
pomenuo :) pa da analiziramo.

Izvinjavam se ako sam nesto izostavio, ali materija je obimna a ja sam probao da sve to sabijem
u par recenica, tako da je mnogo toga ostalo bez objasnjenja.

Ako ima pitanja u vezi sa ovim postom, slobodno...
[ sasas @ 12.02.2005. 07:33 ] @
off-topic:
morlicu, svaka cast na ovako detaljnom objasnjenju. samo bih ti predlozio da svoj post prebacis u novu temu i da je topujes, jer je univerzalna i bogami vrlo korisna.

on-topic:
imam utisak da svi razmisljate u pogresnom smeru. delphi garantovano 100% dobro generise kood. to nije kompajler koji je u nekoj alpha/beta fazi, pa da se nekom analizom generisanog kooda uoce bugovi u kompajleru.

Citat:
neor: Probaj da izbacis iz tog koda sve sta mozes (narocito pozivi finkcija koje nisi ovde dao) a da se problem i dalje javlja i stavi onda ovde neki kod koji moze da se kompajlira pa da moze da se proba.


ovo je najkorisniji savet u celoj diskusiji. Znam da je tesko i dosadno, ali moras svesti program na razumnu velicinu (a da i dalje imas bug), pa tek onda traziti pomoc. u stvari, kad to uradis, siguran sam da ti saveti nece ni trebati, jer ces sam videti eventualne greske u algoritmu.

just my 0.02$

ss.
[ morlic @ 15.02.2005. 16:53 ] @
Dzabe ja pisem kad PKSG nema nameru da proba ovo, a mi se trudimo da resimo...
[ PeraKojotSuperGenije @ 15.02.2005. 17:19 ] @
Stvarno se izvinjavam. Imam nameru, ali trenutno nemam vremena. Cim odradim javicu se.
[ morlic @ 15.02.2005. 21:15 ] @
Ok :) strpljivi smo, nije da nismo... :)
[ PeraKojotSuperGenije @ 20.02.2005. 15:22 ] @
Napravio sam screenshotove u kriticnim momentima(u spajalici su). Na mojih 15 incha je bilo malo guzva pa ne znam da li se svi potrebni delovi cpu i source prozora vide.

1) Vidi se kako depth (depth je polje klase) dobija vrednost.
2) Neposredno pre poziva RootSearchAB.
3) Neposredno po ulasku u RootSearchAB.
4) Neposredno pre ulaska u NegaMaxAB.
5) Neposredno po ulsaku u NegaMax.

Sada se nenormalne vrednosti (za depth) javljaju tek u NegaMax Funkciji!?!
[ PeraKojotSuperGenije @ 20.02.2005. 15:26 ] @
Ovde su preostale 3 slike. Morao sam ovako zbog ogranicenja od 200k!
[ morlic @ 21.02.2005. 00:17 ] @
Kako se sada menjaju vrednosti? :)

Na pogresnim si mestima "slikao" ekran:

Slika 1) Pritisni jos dva puta F7 dok si na CPU prozoru, pa tek onda slikaj kako bi u prozoru za pregled registara videli vrednost al registra koji drzi vrednost depth.

Slika 3) jednom F7 pa slikaj

Slika 4) jednom F7 pa slikaj

Slika 5) jednom F7 pa slikaj

Ajde prvo probaj sliku br1 da vidimo da li je ok, pa ces onda i ostale.
[ morlic @ 02.03.2005. 21:36 ] @
Ajde kada stignes posalji barem sliku br1!