(********************************************************** * PART OF OTHELLO.PAS so see that file for details. ************************************************************) (* included file for OTHELLO *) PROCEDURE updatecrt(VAR oldstatus,newstatus: gamestatus); FORWARD; FUNCTION flipof(oldcolor: color): color; FORWARD; PROCEDURE makemove(VAR status: gamestatus; VAR move: movedesc; updateadjacent: BOOLEAN); FORWARD; SEGMENT PROCEDURE initgame; CONST backspace = 8; VAR x,y: coordinate; direc: direction; answer: CHAR; h,l,h0,l0: INTEGER; (*for testing whether clock is on*) PROCEDURE defineboard; BEGIN FOR x := 1 TO 8 DO FOR y := 1 TO 8 DO WITH board[x,y] DO BEGIN border := (x IN [1,8]) OR (y IN [1,8]); corner := (x IN [1,8]) AND (y IN [1,8]); incenter4by4 := (x IN [3..6]) AND (y IN [3..6]); diagnexttocorner := (x IN [2,7]) AND (y IN [2,7]); FOR direc := north TO nw DO WITH adjacentsq[direc] DO BEGIN CASE direc OF north: onboard := x>1; ne: onboard := (x>1) AND (y<8); east: onboard := y<8; se: onboard := (x<8) AND (y<8); south: onboard := x<8; sw: onboard := (x<8) AND (y>1); west: onboard := y>1; nw: onboard := (x>1) AND (y>1); END; (*CASE*) IF onboard THEN BEGIN CASE direc OF north,ne,nw: row := x-1; east,west: row := x; south,se,sw: row := x+1; END; CASE direc OF nw,west,sw: col := y-1; north,south: col := y; ne,east,se: col := y+1; END; END; END; (*FOR direc...WITH adjacentsq...*) specialbordersq := border AND (NOT corner) AND ( (x IN [2,4,5,7]) OR (y IN [2,4,5,7]) ); IF specialbordersq THEN BEGIN otherofpair.onboard := TRUE; between.onboard := TRUE; IF x IN [1,8] THEN BEGIN otherofpair.row := x; between.row := x; IF y IN [2,5] THEN BEGIN otherofpair.col := y+2; between.col := y+1; END ELSE BEGIN otherofpair.col := y-2; between.col := y-1; END; END ELSE BEGIN otherofpair.col := y; between.col := y; IF x IN [2,5] THEN BEGIN otherofpair.row := x+2; between.row := x+1; END ELSE BEGIN otherofpair.row := x-2; between.row := x-1; END; END; END; (*IF specialbordersq...*) END; (*FOR x:= ... FOR y:= ... WITH board[x,y]...*) END; (*defineboard*) PROCEDURE showemptyboard; CONST vertdivs = '| | | | | | | | |'; horzdivs = '|-----|-----|-----|-----|-----|-----|-----|-----|'; colnames = ' A B C D E F G H '; blanks = ' '; VAR gamerow : coordinate; BEGIN GOTOXY(0,0); FOR gamerow := 1 TO 8 DO BEGIN IF gamerow>1 THEN (* "IF" because no room for topmost border line *) writeln(blanks,horzdivs); writeln(blanks:29,gamerow,vertdivs); writeln(blanks,vertdivs); END; write(blanks,colnames); GOTOXY(4,0); WRITELN('Score'); WRITELN('-----------'); WRITELN(CHR(whiteascii),'/White:'); WRITELN(CHR(blackascii),'/Black:'); END; (*showemptyboard*) PROCEDURE instructions; VAR i: INTEGER; PROCEDURE page1; BEGIN WRITELN('A move consists of placing '); WRITELN('one of your pieces on an '); WRITELN('unoccupied square which is '); WRITELN('adjacent (vertically, hori- '); WRITELN('zontally, or diagonally) to '); WRITELN('a square occupied by your '); WRITELN('opponent so that a straight '); WRITELN('line starting at your piece '); WRITELN('and continuing in the direc-'); WRITELN('tion of the adjacent oppon- '); WRITELN('ent hits one of your other '); WRITELN('pieces before hitting an un-'); WRITELN('occupied square. All of the'); WRITELN('opponent''s pieces which that'); WRITELN('line crosses are converted '); WRITELN('to become your pieces. Thus'); WRITELN('each move "flips" at least '); WRITELN('one opposing piece. '); WRITE (' (Tap space bar for more...)'); END; (*page1*) PROCEDURE page2; BEGIN WRITELN('Example: a legal move for '); WRITELN('white on the first play '); WRITELN('would be 3E, 4F, 6D, or 5C. '); WRITELN('To make a move at, e.g., 3E '); WRITELN('you may type any of: 3E, 3e,'); WRITELN('E3, or e3. '); WRITELN('If you have no legal move, '); WRITELN('you must pass. The object '); WRITELN('of the game is to end up '); WRITELN('occupying more squares than '); WRITELN('does your opponent. '); WRITELN('Hints on strategy: Usually '); WRITELN('the board position of a move'); WRITELN('is more important than the '); WRITELN('number of pieces it "flips".'); WRITELN('Try to occupy the borders '); WRITELN('(especially corners!) and '); WRITELN('avoid giving them to your '); WRITE ('opponent. (Tap space bar...)'); END; (*page2*) BEGIN (*instructions*) GOTOXY(0,5); WRITE('Want instructions? (y/n): '); READ(answer); IF NOT (answer IN ['N','n']) THEN BEGIN GOTOXY(0,5); page1; READ(answer); GOTOXY(0,5); page2; READ(answer); GOTOXY(0,5); FOR i := 5 TO 22 DO WRITELN(spaces); WRITE(spaces); END ELSE BEGIN GOTOXY(0,5); WRITE(spaces); END; END; (*instructions*) BEGIN (*initgame*) lastchange := 0; TIME(h0,l0); defineboard; FOR direc := north TO NW DO IF odd(ORD(direc)) THEN opposdir[direc] := pred(direc) ELSE opposdir[direc] := succ(direc); TIME(h,l); IF (h=h0) AND (l=l0) THEN BEGIN GOTOXY(20,11); WRITE('Please turn on the clock.'); WHILE l=l0 DO TIME(h,l); END; showemptyboard; WITH status DO BEGIN score[white] := 0; score[black] := 0; FOR x := 1 TO 8 DO FOR y := 1 TO 8 DO WITH boardstatus[x,y] DO BEGIN occupied := FALSE; adjacentpieces[white] := []; adjacentpieces[black] := []; END; END; crtstatus := status; move.dirsflipped := []; move.points := 0; WITH status DO BEGIN FOR x := 4 TO 5 DO FOR y := 4 TO 5 DO BEGIN move.moveloc.row := x; move.moveloc.col := y; IF x=y THEN nextmover := white ELSE nextmover := black; makemove(status,move,TRUE); updatecrt(crtstatus,status); crtstatus := status; END; (*FOR...FOR...*) nextmover := white; END; (*WITH status...*) instructions; GOTOXY(0,6); WRITELN('White goes first -- Which'); WRITELN('color do you want to play:'); REPEAT GOTOXY(3,8); WRITE('W)hite or B)lack? ',CHR(backspace)); READ(answer); UNTIL answer IN ['W','w','B','b']; IF answer IN ['W','w'] THEN usercolor := white ELSE usercolor := black; GOTOXY (0,6); WRITELN(spaces); WRITELN(spaces); WRITELN(spaces); colorword[white] := 'white'; colorword[black] := 'black'; END; (*initgame*) .