unit Unit2; { DavData software 3D boter - kaas - eieren data & search unit 2 players red - blue - red - blue............... analyse button predicts game 7 - 02 - 2014 version 1.1 9 - 02 - 2014 1.2 no win test if node < 5 } interface uses sysutils; type TWintriple = record p1,p2,p3 : byte; end; TNode = record pos : byte; rating : byte; treshold : byte; end; const maxmove = 27; var game : array[0..maxmove] of byte; //1=O 2=X node : array[1..maxmove] of TNode; moveNr : byte; procedure makewinlist; procedure initgame; procedure analyse; function checkwin(var tr : Twintriple; player : byte) : boolean; implementation uses unit1; var winlist : array[1..50] of TWinTriple; wincount : byte; testNode : byte; baseNode :byte; procedure initgame; var i : byte; begin for i := 0 to maxmove do game[i] := 0; for i := 1 to maxmove do with node[i] do begin pos := 0; rating := 0; treshold :=0; end; moveNr := 0; end; function checkwin(var tr : TwinTriple; player : byte) : boolean; //check for win somewhere, return wintriple# tr var i : byte; begin i := 0; result := false; repeat inc(i); with winlist[i] do result := (game[p1] = player) and (game[p2] = player) and (game[p3] = player); until result or (i = wincount); if result then tr := winlist[i]; end; procedure makewinlist; const concode : array[1..maxmove] of byte = (1,2,1,3,4,3,1,2,1,5,6,5,7,0,7,5,6,5,1,2,1,3,4,3,1,2,1); var i,j : byte; //start..end field begin wincount := 0; for i:= 1 to 25 do for j := i+2 to 27 do if concode[i] = concode[j] then begin inc(wincount); with winlist[wincount] do begin p1 := i; p2 := (i + j) shr 1; p3 := j; end; end; end; //-- analyze helpers function firstmove : boolean; //make first move of new node //false if no move (node = 27) //true if move done var i,m : byte; begin with node[testnode] do begin if treshold = 100 then treshold := 98; //no win result := rating < treshold; if result then begin m := 2 - (testNode and 1); i := 1; while game[i] > 0 do inc(i); game[i] := m; pos := i; end;//if end; end; procedure testwin; //test for any win in new node //set rating = 100 if win //report basenode wins var i,m,p : byte; win : boolean; begin if testNode < 5 then exit; m := 2 - (testNode and 1); if testnode = basenode then //basenode begin for p := 1 to maxmove do if game[p] = 0 then begin game[p] := m; for i := 1 to wincount do begin win := (game[winlist[i].p1] = m) and (game[winlist[i].p2] = m) and (game[winlist[i].p3] = m); if win then begin analysereport(p,100); node[testNode].rating := 100; end; end; game[p] := 0; end; end //basenode else //not basenode begin p := 1; win := false; repeat if game[p] = 0 then begin game[p] := m; i := 0; repeat inc(i); win := (game[winlist[i].p1] = m) and (game[winlist[i].p2] = m) and (game[winlist[i].p3] = m); until win or (i = wincount); game[p] := 0; end;//if game[p] inc(p); until win or (p = maxmove+1); if win then node[testnode].rating := 100; end;//else end; function nextNode : boolean; //open node testnr+1 //set 1st move var x : byte; begin result := testNode < 27; if result then begin inc(testNode); with node[testNode] do begin pos := 0; if testNode = baseNode then begin treshold := 100; rating := 1; end else begin x := 100 - node[testNode-1].rating; if x < 50 then dec(x); if (x > 50) then inc(x); if testNode >= maxmove-1 then treshold := 50 else treshold := x; x := 100 - node[testNode-1].treshold; if x < 50 then dec(x); if x > 50 then inc(x); rating := x; end; end;//with end; end; function previousnode : boolean; //close node nr //if baseNode set score //else set rating var x,p : byte; prf : boolean; begin result := false; prf := true; while prf do begin prf := false; p := node[testnode].pos; game[p] := 0; //remove O,X if testNode > baseNode then begin result := true; x := 100 - node[testnode].rating; dec(testNode); with node[testnode] do begin if x > 50 then dec(x); if x < 50 then inc(x); if testnode = basenode then analysereport(pos,x) else if x > rating then begin rating := x; prf := rating >= treshold; end; end; end else result := false; //testNode = baseNode end;//while end; function nextmove : boolean; var x : byte; begin result := false; x := node[testNode].pos; game[x] := 0;//none while (x < maxmove) and (result = false) do begin inc(x); result := game[x] = 0; end; if result then begin game[x] := 2 - (testNode and 1); node[testnode].pos := x; end; end; //-- main call procedure analyse; //analyse game var Ffirst,Fnext,Fprev : boolean; begin if movenr = 27 then exit; testNode := moveNr; baseNode := moveNr + 1; Ffirst := true; while Ffirst do begin Fnext := true; while Fnext do begin Fnext := false; if nextNode then begin testwin; Fnext := firstMove; end; end; Fprev := true; while Fprev do if previousNode then begin if nextmove then Fprev := false; end else begin Ffirst := false; Fprev := false; end; end;//Ffirst end; end.