(************************************************************** * It was about time I included something for the game freaks * so I looked around for something good. The best I could come * up with was Othello. Unfortunately it is in UCSD but then I * realized that it did not make any difference. It is about time * we devoted some time to learning how to convert from UCSD to * Z. So that is why I included this program. I want someone to * convert it. It also is a good guide to some advanced Pascal * programing. * Othello units: * Othello.pas * Othell1.pas * Othell2.pas * Othellin.pas * * Donated by the now defunct UCSD PASCAL USERS GROUP * (To the best of my knowledge this software is to be used only) * (for us non-commercials. It was originally donated by a ) * (Company who thought kindly of us.) ***************************************************************) (*$S+*) (* UCSD Pascal *) PROGRAM OTHELLO; (* Steve Brecher 16-Jun-79 *) (* The position evaluation weights were derived from a FORTRAN program *) (* headed "from Creative Computing/Klaus E Liebold/4-26-78". *) (* This program provides playing instructions to the user on request. *) CONST (* The game pieces are shown on the screen as 2 rows of 3 characters, e.g. *) (* OOO *) (* OOO *) (* If your crt has a "block" character (like the cursor on some crts), that*) (* is good for the white piece, and capital letter O is good for black, *) (* especially if it has a rectangular shape. Otherwise, choose characters *) (* that are centered within the character dot matrix; try to maximize the *) (* difference in intensity between the black and white pieces while maxi- *) (* mizing the absolute intensity of the black piece. Avoid characters with*) (* semantic content, e.g. "W" and "B" are not so good. *) whiteascii = 96; (*ascii value of char making up piece of first mover*) blackascii = 79; (* " " " " " " " " 2nd " *) minticks = 22.0; (*min # clock ticks between crt square updates *) (*--should be long enough for a distinct, separate *) (*terminal bell sound on each square updated *) spaces = ' '; TYPE coordinate = 1..8; color = (white,black); squareloc = RECORD CASE onboard: BOOLEAN OF TRUE: (row,col: coordinate); END; direction = (north,south,east,west,sw,ne,se,nw); (*pairs of opposites*) squarestatus = RECORD CASE occupied: BOOLEAN OF TRUE: (occupier: color ); FALSE: (adjacentpieces: ARRAY[color] OF SET of direction); END; gamestatus = RECORD boardstatus: ARRAY[coordinate,coordinate] OF squarestatus; nextmover: color; lastmoveloc: squareloc; score: ARRAY[color] OF INTEGER; END; movedesc = RECORD moveloc: squareloc; points: INTEGER; dirsflipped: SET OF direction; 4bordrsqsflipped: INTEGER; bordnoncorn: BOOLEAN; END; movelist = RECORD movecount: INTEGER; okmove: ARRAY[1..30] OF movedesc; END; position = RECORD border: BOOLEAN; corner: BOOLEAN; diagnexttocorner: BOOLEAN; incenter4by4: BOOLEAN; adjacentsq: ARRAY[direction] OF squareloc; (* "special" border squares are those border squares *) (* adjacent to a corner or adjacent to board midline; there *) (* are 2 pairs of such squares on each border. Sample pair: *) (* (1,2) and (1,4); for each we want a pointer to the other *) (* and to the border square between them (1,3). *) CASE specialbordersq: BOOLEAN OF TRUE: (otherofpair,between: squareloc); END; VAR board: ARRAY[coordinate,coordinate] OF position; status,crtstatus: gamestatus; square: squareloc; legallist: movelist; move: movedesc; opposdir: ARRAY[direction] OF direction; legalmoves: ARRAY[color] OF INTEGER; colorword: ARRAY[color] OF STRING[5]; usercolor: color; lastchange: REAL; (*time of last square change on crt*) (*$I OTHELLINIT*) (*$I OTHELL1*) (*$I OTHELL2*) BEGIN (*PROGRAM OTHELLO*) REPEAT initgame; findlegalmoves(status,legallist); legalmoves[white] := legallist.movecount; REPEAT play(white); findlegalmoves(status,legallist); legalmoves[black] := legallist.movecount; play(black); findlegalmoves(status,legallist); legalmoves[white] := legallist.movecount; UNTIL (legalmoves[white]=0) and (legalmoves[black]=0); UNTIL userquits; END. .