(************************************************************* * PART OF OTHELLO.PAS see file for details **************************************************************) FUNCTION flipof(*oldcolor: color): color*); BEGIN IF oldcolor = white THEN flipof := black ELSE flipof := white; END; (*flipof*) PROCEDURE updatecrt(*VAR oldstatus,newstatus: gamestatus*); VAR x,y: coordinate; direc: direction; square: squareloc; PROCEDURE showpiece(square: squareloc); PROCEDURE changecrtsq(square: squareloc); CONST bell = 7; VAR s: PACKED ARRAY[1..3] OF CHAR; c: CHAR; crtline,crtcol: INTEGER; h,l: INTEGER; now: REAL; BEGIN WITH square DO BEGIN IF newstatus.boardstatus[row,col].occupier = white THEN c := CHR(whiteascii) ELSE c := CHR(blackascii); FILLCHAR(s,3,c); crtline := (3*row) - 3; crtcol := 26 + (6*col); END; REPEAT TIME(h,l); now := l; IF now < 0.0 THEN now := now + 65536.0; now := (h*65536.0) + now; UNTIL (now - lastchange) > minticks; GOTOXY(crtcol,crtline); WRITE(s); GOTOXY(crtcol,crtline+1); WRITE(s,CHR(bell)); lastchange := now; END; (*changecrtsq*) BEGIN (*showpiece*) WITH square DO IF newstatus.boardstatus[row,col].occupied THEN IF NOT oldstatus.boardstatus[row,col].occupied THEN changecrtsq(square) ELSE IF oldstatus.boardstatus[row,col].occupier <> newstatus.boardstatus[row,col].occupier THEN changecrtsq(square); END; (*showpiece*) BEGIN (*updatecrt*) WITH newstatus DO BEGIN showpiece(lastmoveloc); FOR direc := north to nw DO BEGIN square := lastmoveloc; WHILE boardstatus[square.row,square.col].occupied AND board[square.row,square.col].adjacentsq[direc].onboard DO BEGIN square := board[square.row,square.col].adjacentsq[direc]; showpiece(square); END; (*WHILE...*) END; (*FOR direc...*) GOTOXY(9,2); WRITE(score[white]:2); GOTOXY(9,3); write(score[black]:2); END; (*WITH newstatus...*) GOTOXY(0,0); END; (*updatecrt*) PROCEDURE findlegalmoves(VAR status: gamestatus; VAR legallist: movelist); VAR x,y: coordinate; sq: squareloc; flips,direcflips: INTEGER; borderflips: INTEGER; stopdirec: BOOLEAN; oppcolor: color; direc: direction; trydirs,gooddirs: SET OF direction; possible: BOOLEAN; sqstatus: squarestatus; BEGIN WITH status, legallist DO BEGIN oppcolor := flipof(nextmover); movecount := 0; FOR x := 1 TO 8 DO FOR y := 1 TO 8 DO BEGIN possible := FALSE; WITH boardstatus[x,y] DO IF NOT occupied THEN IF adjacentpieces[oppcolor] <> [] THEN BEGIN possible := TRUE; trydirs := adjacentpieces[oppcolor]; END; IF possible THEN BEGIN gooddirs := []; flips := 0; borderflips := 0; FOR direc := north TO nw DO IF direc IN trydirs THEN BEGIN sq := board[x,y].adjacentsq[direc]; sq := board[sq.row,sq.col].adjacentsq[direc]; IF sq.onboard THEN BEGIN direcflips := 1; stopdirec := FALSE; REPEAT sqstatus := boardstatus[sq.row,sq.col]; IF sqstatus.occupied THEN IF sqstatus.occupier = oppcolor THEN BEGIN direcflips := direcflips + 1; sq := board[sq.row,sq.col].adjacentsq[direc]; END ELSE stopdirec := TRUE ELSE BEGIN direcflips := 0; stopdirec := TRUE; END; UNTIL ( stopdirec OR (NOT sq.onboard) ); IF (stopdirec AND (direcflips>0)) THEN BEGIN flips := flips + direcflips; gooddirs := gooddirs + [direc]; IF board[x,y].border AND board[sq.row,sq.col].border THEN borderflips := borderflips + direcflips; END; END; (*IF sq.onboard...*) END; (*IF direc IN...*) IF flips > 0 THEN BEGIN movecount := movecount + 1; WITH okmove[movecount] DO BEGIN moveloc.onboard := TRUE; moveloc.row := x; moveloc.col := y; points := flips; dirsflipped := gooddirs; bordrsqsflipped := borderflips; END; END; END; (*IF possible...*) END; (*FOR x :=...FOR y :=...*) END; (*WITH status, legallist...*) END; (*findlegalmoves*) PROCEDURE inputmove(mover: color; legallist: movelist; VAR move: movedesc); VAR x,y: coordinate; xch,ych: CHAR; i,listindex: INTEGER; c: CHAR; BEGIN listindex := 0; REPEAT REPEAT GOTOXY(0,23); WRITE('Enter move for ',colorword[mover],': '); GOTOXY(22,23); READ(xch,ych); IF ych IN ['1'..'8'] THEN BEGIN (*Want xy but we'll accept yx*) c := ych; ych := xch; xch := c; END; IF ych IN ['a'..'h'] THEN ych := CHR(ORD(ych)-32); UNTIL ((xch IN ['1'..'8']) AND (ych IN ['A'..'H'])); x := ORD(xch) - ORD('1') + 1; y := ORD(ych) - ORD('A') + 1; i := 1; REPEAT IF legallist.okmove[i].moveloc.row = x THEN IF legallist.okmove[i].moveloc.col = y THEN listindex := i; i := i+1; UNTIL ((i>legallist.movecount) OR (listindex <> 0)); UNTIL listindex <> 0; move := legallist.okmove[listindex]; END; (*inputmove*) PROCEDURE makemove(*VAR status: gamestatus; VAR move: movedesc; updateadjacent: BOOLEAN*); VAR direc,direc2: direction; sq,sq2: squareloc; oppcolor: color; flips: INTEGER; emptyneighbors: SET of direction; BEGIN WITH status, move DO BEGIN lastmoveloc := moveloc; WITH boardstatus[moveloc.row,moveloc.col] DO BEGIN emptyneighbors := [north..nw] - adjacentpieces[white] - adjacentpieces[black]; occupied := TRUE; occupier := nextmover; END; oppcolor := flipof(nextmover); flips := 0; FOR direc := north TO nw DO IF direc IN dirsflipped THEN BEGIN sq := board[moveloc.row,moveloc.col].adjacentsq[direc]; REPEAT IF updateadjacent THEN FOR direc2 := north TO nw DO IF NOT (direc2 IN [direc,opposdir[direc]]) THEN BEGIN sq2 := board[sq.row,sq.col].adjacentsq[direc2]; IF sq2.onboard THEN WITH boardstatus[sq2.row,sq2.col] DO IF NOT occupied THEN BEGIN adjacentpieces[nextmover]:=adjacentpieces[nextmover] + [opposdir[direc2]]; adjacentpieces[oppcolor]:=adjacentpieces[oppcolor] - [opposdir[direc2]]; END; END; boardstatus[sq.row,sq.col].occupier := nextmover; flips := flips + 1; sq := board[sq.row,sq.col].adjacentsq[direc]; UNTIL boardstatus[sq.row,sq.col].occupier = nextmover; END ELSE IF updateadjacent THEN IF direc IN emptyneighbors THEN BEGIN sq := board[moveloc.row,moveloc.col].adjacentsq[direc]; IF sq.onboard THEN WITH boardstatus[sq.row,sq.col] DO adjacentpieces[nextmover] := adjacentpieces[nextmover] + [opposdir[direc]]; END; score[nextmover] := score[nextmover] + flips + 1; score[oppcolor] := score[oppcolor] - flips; nextmover := oppcolor; END; END; (*makemove*) .