home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
CP/M
/
CPM_CDROM.iso
/
simtel
/
sigm
/
vols000
/
vol024
/
othell2.pas
< prev
next >
Wrap
Pascal/Delphi Source File
|
1984-04-29
|
7KB
|
234 lines
(************************************************************
* PART OF OTHELLO.PAS see file for details
**************************************************************)
PROCEDURE calcmove( mover: color; VAR status: gamestatus;
VAR legallist: movelist; VAR bestmove: movedesc);
TYPE
movearray = ARRAY[1..30] OF movedesc;
VAR
bestsofar,cornmoves,m,respcornmoves: INTEGER;
move,movetemp: movedesc;
aftermove: gamestatus;
responses: movelist;
PROCEDURE checkposition(VAR legallist: movelist; VAR cornmoves: INTEGER);
VAR
m,bestm,bestyet: INTEGER;
BEGIN
bestyet := -MAXINT;
cornmoves := 0;
FOR m := 1 TO legallist.movecount DO WITH legallist.okmove[m],
board[moveloc.row,moveloc.col] DO
BEGIN
bordnoncorn := FALSE;
IF incenter4by4 THEN
points := points + 10
ELSE BEGIN
IF corner THEN BEGIN
points := points + 60;
cornmoves := cornmoves + 1;
END
ELSE IF border THEN BEGIN
bordnoncorn := TRUE;
points := points + 25;
END
ELSE IF diagnexttocorner THEN
points := points - 50;
END;
IF points > bestyet THEN BEGIN
bestyet := points;
bestm := m;
end;
END; (*FOR m := 1 TO legallist.movecount...*)
movetemp := legallist.okmove[1];
legallist.okmove[1] := legallist.okmove[bestm];
legallist.okmove[bestm] := movetemp;
END; (*checkposition*)
PROCEDURE sortmoves(VAR okmove: movearray;
l,r: INTEGER) (*into descending order by points*) ;
VAR
i,j,baseval: INTEGER;
BEGIN
i := l;
j := r;
baseval := okmove[(i+j) DIV 2].points;
REPEAT
WHILE okmove[i].points > baseval DO
i := i+1;
WHILE okmove[j].points < baseval DO
j := j-1;
IF i <= j THEN BEGIN
movetemp := okmove[i];
okmove[i] := okmove[j];
okmove[j] := movetemp;
i := i+1;
j := j-1;
END;
UNTIL i > j;
IF l < j THEN sortmoves(okmove, l, j );
IF i < r THEN sortmoves(okmove, i, r )
END (* sortmoves *) ;
PROCEDURE checkresponses(mover: color; VAR move: movedesc;
VAR responses: movelist; bestsofar: INTEGER);
(*$G+*)
LABEL 0;
VAR
contingent,c,r: INTEGER;
x,y: coordinate;
sq: squareloc;
direc: direction;
oppcolor: color;
afterresp: gamestatus;
cornercounter: BOOLEAN;
respondmove: movedesc;
counterresp: movelist;
BEGIN
oppcolor := flipof(mover);
WITH move DO BEGIN
contingent := 0;
r := 1;
REPEAT
respondmove := responses.okmove[r];
IF NOT board[moveloc.row,moveloc.col].incenter4by4 THEN
FOR direc := north TO nw DO WITH respondmove DO
IF direc IN dirsflipped THEN WITH moveloc DO
IF board[row,col].adjacentsq[direc] = move.moveloc THEN BEGIN
move.points := move.points - 5;
IF move.points <= bestsofar THEN
EXIT(checkresponses);
END;
afterresp := aftermove;
makemove(afterresp,respondmove,FALSE);
IF bordnoncorn THEN WITH moveloc DO
IF afterresp.boardstatus[row,col].occupier = oppcolor THEN BEGIN
bordnoncorn := FALSE;
points := points - 65; (*40, plus the 25 given in checkposition*)
IF points <= bestsofar THEN
EXIT(checkresponses);
END
ELSE
contingent := contingent + 8*respondmove.bordrsqsflipped;
WITH respondmove.moveloc DO
IF board[row,col].corner THEN BEGIN
points := points - 55;
IF cornmoves > 1 THEN
IF board[moveloc.row,moveloc.col].corner THEN
points := points -20;
IF points <= bestsofar THEN
EXIT(checkresponses);
END;
FOR x:=1 TO 8 DO FOR y:=1 TO 8 DO WITH afterresp.boardstatus[x,y] DO
IF occupied THEN
IF occupier = mover THEN
FOR direc := north TO nw DO WITH afterresp DO BEGIN
sq.row := x;
sq.col := y;
REPEAT
sq := board[sq.row,sq.col].adjacentsq[direc];
IF NOT sq.onboard THEN
GOTO 0;
IF NOT boardstatus[sq.row,sq.col].occupied THEN
GOTO 0
UNTIL boardstatus[sq.row,sq.col].occupier = oppcolor;
END;
makemove(afterresp,respondmove,TRUE);
findlegalmoves(afterresp,counterresp);
cornercounter := FALSE;
c := 1;
WITH counterresp DO
WHILE ( (c <= movecount) AND (NOT cornercounter) ) DO BEGIN
WITH okmove[c].moveloc DO
IF board[row,col].corner THEN
cornercounter := TRUE;
c := c + 1;
END;
IF NOT cornercounter THEN BEGIN
points := points -190;
IF points <= bestsofar THEN
EXIT(checkresponses);
END;
0:
IF afterresp.score[mover] = 0 THEN BEGIN
points := -MAXINT+1; (*might be our only choice, so +1*)
EXIT(checkresponses);
END;
r := r + 1;
UNTIL r > responses.movecount;
IF bordnoncorn THEN BEGIN
points := points - contingent;
WITH board[moveloc.row,moveloc.col] DO
IF specialbordersq THEN WITH otherofpair,
status.boardstatus[row,col] DO
IF occupied THEN
IF occupier = mover THEN
WITH status.boardstatus[between.row,between.col] DO
IF NOT occupied THEN
points := points - 90;
END;
END; (*WITH move...*)
END; (*checkresponses*)
BEGIN (*calcmove*)
GOTOXY(0,23);
WRITE('Calculating move for ',colorword[mover],'...');
checkposition(legallist,cornmoves);
IF legallist.movecount > 2 THEN
sortmoves(legallist.okmove,2,legallist.movecount);
bestsofar := -MAXINT;
FOR m := 1 TO legallist.movecount DO BEGIN
move := legallist.okmove[m];
aftermove := status;
makemove(aftermove,move,TRUE);
findlegalmoves(aftermove,responses);
WITH move DO BEGIN
IF responses.movecount = 0 THEN
points := points + 100
ELSE
IF points > bestsofar THEN BEGIN
checkposition(responses,respcornmoves);
checkresponses(mover,move,responses,bestsofar);
END;
IF points > bestsofar THEN BEGIN
bestsofar := points;
bestmove := move;
END;
END; (*WITH move...*)
END; (*FOR m := 1 TO legallist.movecount...*)
END; (*calcmove*)
PROCEDURE play(mover: color);
BEGIN
GOTOXY(0,20+ORD(mover));
IF legalmoves[mover] > 0 THEN BEGIN
WRITE(spaces);
IF mover = usercolor THEN
inputmove(mover,legallist,move)
ELSE
calcmove(mover,status,legallist,move);
makemove(status,move,TRUE);
updatecrt(crtstatus,status);
crtstatus := status;
END
ELSE BEGIN
WRITE('(No legal moves for ',colorword[mover],')');
status.nextmover := flipof(mover);
END;
END; (*play*)
FUNCTION userquits: BOOLEAN;
VAR
playagain: CHAR;
BEGIN
GOTOXY(0,20);
WRITELN(spaces); WRITELN(spaces); WRITELN; WRITE(spaces);
GOTOXY(0,23);
WRITE('Start a new game? (y/n): ');
READ(playagain);
userquits := NOT (playagain IN ['Y','y']);
END; (*userquits*)