!***************************************************************************! ! ! ! OTHELO ! ! Othello for the Alpha Micro ! ! ! ! Author: David F. Pallmann ! ! ! !***************************************************************************! STORAGE: MAP1 BOARD(8,8), F, 6 !board array MAP1 VALUE(8,8), F, 6 !positional value array MAP1 I, F, 6 !temporary MAP1 J, F, 6 !temporary MAP1 ROW, F, 6 !current row MAP1 COL, F, 6 !current column MAP1 FLAG, F, 6 !flag used internally by subroutines MAP1 WARN, F, 6 !flag used to warn of corner give-a-way MAP1 ROWDIR, F, 6 !vertical direction of travel MAP1 COLDIR, F, 6 !horizontal direction of travel MAP1 TESTROW, F, 6 !sample row MAP1 TESTCOL, F, 6 !sample column MAP1 NEWROW, F, 6 !new row MAP1 NEWCOL, F, 6 !new column MAP1 COLOR, F, 6 !current color (1=human, 2=alpha) MAP1 FLIPS, F, 6 !number of flips from move MAP1 TESTFLIPS, F, 6 !number of flips in one direction MAP1 MOVE, S, 10 !move text MAP1 HIGHFLIPS, F, 6 !highest #flips MAP1 BESTROW, F, 6 !row of best move encountered MAP1 BESTCOL, F, 6 !column of best move encountered MAP1 HDISCS, F, 6 !number of discs - human MAP1 ADISCS, F, 6 !number of discs - alpha MAP1 SCORE, F, 6 !score of move (flips + pos value) MAP1 HIGHSCORE, F, 6 !score of best move encountered CONSTANTS: MAP1 EMPTY, F, 6, 0 !empty square MAP1 HUMAN, F, 6, 1 !human disc (O) MAP1 ALPHA, F, 6, 2 !alpha disc (@) REM****************** REM* INITIALIZE * REM****************** REM LOAD POSITIONAL VALUE ARRAY INITIALIZE: FOR I = 1 TO 8 FOR J = 1 TO 8 READ VALUE(I,J) NEXT J NEXT I DATA 99,00,80,80,80,80,00,99 DATA 00,00,00,00,00,00,00,00 DATA 80,00,40,30,30,40,00,80 DATA 80,00,30,00,00,30,00,80 DATA 80,00,30,00,00,30,00,80 DATA 80,00,40,30,30,40,00,80 DATA 00,00,00,00,00,00,00,00 DATA 99,00,80,80,80,80,00,99 REM************** REM* SCREEN * REM************** REM SET UP SCREEN SCREEN: PRINT TAB(-1,0); PRINT TAB(-1,12); PRINT TAB(1,12); "* OTHELLO *"; PRINT TAB(-1,11); FOR I = 1 TO 8 PRINT TAB(I*2+1,1); CHR(I+64); PRINT TAB(19,I*4); STR(I); NEXT I PRINT TAB(7,50); "HUMAN MOVE"; PRINT TAB(10,50); "HUMAN DISCS"; PRINT TAB(13,50); "ALPHA MOVE"; PRINT TAB(16,50); "ALPHA DISCS"; REM************** REM* NEW'GAME * REM************** REM SET UP SCREEN FOR NEW GAME NEW'GAME: FOR I = 1 TO 8 FOR J = 1 TO 8 PRINT TAB(I*2+1,J*4); "."; BOARD(I,J) = EMPTY NEXT J NEXT I PRINT TAB(-1,12); PRINT TAB(9,16); "O @" BOARD(4,4) = HUMAN : BOARD(4,5) = ALPHA PRINT TAB(11,16); "@ O"; BOARD(5,4) = ALPHA : BOARD(5,5) = HUMAN HDISCS = 2 ADISCS = 2 PRINT TAB(11,55); SPACE(2); PRINT TAB(17,55); SPACE(2); REM****************** REM* HUMAN'MOVE * REM****************** REM GET, VERIFY, AND MAKE HUMAN MOVE HUMAN'MOVE: IF HDISCS+ADISCS=64 THEN GOTO END'GAME PRINT TAB(8,55); INPUT LINE MOVE PRINT TAB(23,1); TAB(-1,9); IF UCS(MOVE)="PASS" THEN GOTO ALPHA'MOVE IF LEN(MOVE)<>2 THEN GOTO INVALID NEWROW = ASC(MOVE[1;1])-64 IF NEWROW<1 OR NEWROW>8 THEN GOTO INVALID NEWCOL = MOVE[2;1] IF NEWCOL<1 OR NEWCOL>8 THEN GOTO INVALID IF BOARD(NEWROW,NEWCOL)<>EMPTY THEN GOTO INVALID COLOR = HUMAN ROW = NEWROW : COL = NEWCOL CALL CHECK'MOVE IF FLIPS=0 THEN GOTO INVALID PRINT TAB(NEWROW*2+1,NEWCOL*4); "O"; BOARD(NEWROW,NEWCOL) = COLOR CALL MAKE'MOVE IF WARN=1 THEN PRINT TAB(23,1); "NOT YOUR BEST MOVE"; HDISCS = HDISCS+FLIPS+1 ADISCS = ADISCS-FLIPS PRINT TAB(11,55); STR(HDISCS); " "; PRINT TAB(17,55); STR(ADISCS); " "; GOTO ALPHA'MOVE INVALID: PRINT TAB(23,1); "INVALID"; GOTO HUMAN'MOVE REM****************** REM* ALPHA'MOVE * REM****************** REM MAKE COMPUTER'S MOVE ALPHA'MOVE: PRINT TAB(23,1); "THINKING"; HIGHFLIPS = 0 HIGHSCORE = 0 BESTROW = 0 : BESTCOL = 0 COLOR = ALPHA FOR ROW = 1 TO 8 FOR COL = 1 TO 8 IF BOARD(ROW,COL)<>EMPTY THEN GOTO ALPHA'NEXT CALL CHECK'MOVE IF FLIPS=0 THEN SCORE = 0 : GOTO COMPARE REASON: SCORE = FLIPS+VALUE(ROW,COL) IF WARN=1 THEN SCORE = 1 IF ROW=1 THEN CALL ROW'ADJUST IF ROW=8 THEN CALL ROW'ADJUST IF COL=1 THEN CALL COL'ADJUST IF COL=8 THEN CALL COL'ADJUST COMPARE: IF SCORE>HIGHSCORE THEN & HIGHFLIPS = FLIPS : HIGHSCORE = SCORE :& BESTROW = ROW : BESTCOL = COL ALPHA'NEXT: NEXT COL NEXT ROW PRINT TAB(23,1); TAB(-1,9); IF HIGHSCORE=0 THEN PRINT TAB(23,1); "ALPHA CAN'T MOVE"; : GOTO HUMAN'MOVE ROW = BESTROW : COL = BESTCOL PRINT TAB(ROW*2+1,COL*4); "@"; BOARD(ROW,COL) = COLOR PRINT TAB(14,55); CHR(ROW+64); STR(COL); CALL MAKE'MOVE ADISCS = ADISCS+FLIPS+1 HDISCS = HDISCS-FLIPS PRINT TAB(11,55); STR(HDISCS); " "; PRINT TAB(17,55); STR(ADISCS); " "; PRINT TAB(23,1); "YOUR MOVE"; GOTO HUMAN'MOVE REM**************** REM* END'GAME * REM**************** REM END OF GAME END'GAME: PRINT TAB(23,1); TAB(-1,9); IF HDISCSADISCS THEN PRINT "WON"; PRINT " GAME"; PRINT TAB(23,50); "CARE FOR ANOTHER? "; INPUT LINE MOVE PRINT TAB(23,1); TAB(-1,9); IF UCS(LEFT(MOVE,1))="Y" THEN GOTO NEW'GAME END REM****************** REM* CHECK'MOVE * REM****************** REM ON ENTRY: ROW = ROW TO TEST; COL = COL TO TEST; COLOR = MOVER'S COLOR REM ON EXIT: FLIPS = #FLIPS MOVE WILL RETURN CHECK'MOVE: FLAG = 0 GOTO MOVE REM***************** REM* MAKE'MOVE * REM***************** REM ON ENTRY: ROW = ROW TO TEST; COL = COL TO TEST; COLOR = MOVER'S COLOR REM ON EXIT: FLIPS = #FLIPS MADE MAKE'MOVE: FLAG = 1 MOVE: FLIPS = 0 WARN = 0 FOR ROWDIR = -1 TO 1 FOR COLDIR = -1 TO 1 IF ROWDIR<>0 OR COLDIR<>0 THEN & CALL LINEAR :& FLIPS = FLIPS+TESTFLIPS NEXT COLDIR NEXT ROWDIR RETURN REM************* REM* LINEAR * REM************* REM SUBROUTINE USED BY CHECK'MOVE: AND MAKE'MOVE: REM REM ON ENTRY: ROW/COL = ROW/COL TO TEST; ROWDIR/COLDIR = MOVE DIRECTION; REM COLOR = MOVER COLOR REM ON EXIT: TESTFLIPS = #FLIPS GENERATED LINEAR: TESTROW = ROW TESTCOL = COL TESTFLIPS = 0 LINEAR'1: TESTROW = TESTROW + ROWDIR TESTCOL = TESTCOL + COLDIR IF TESTROW<1 THEN GOTO LINEAR'FAIL IF TESTROW>8 THEN GOTO LINEAR'FAIL IF TESTCOL<1 THEN GOTO LINEAR'FAIL IF TESTCOL>8 THEN GOTO LINEAR'FAIL IF BOARD(TESTROW,TESTCOL)=EMPTY THEN GOTO LINEAR'FAIL IF BOARD(TESTROW,TESTCOL)=COLOR THEN GOTO LINEAR'COLOR LINEAR'OTHER: TESTFLIPS = TESTFLIPS+1 IF ROW=2 AND COL=2 AND BOARD(1,1)=EMPTY THEN WARN = 1 IF ROW=2 AND COL=7 AND BOARD(1,8)=EMPTY THEN WARN = 1 IF ROW=7 AND COL=2 AND BOARD(8,1)=EMPTY THEN WARN = 1 IF ROW=7 AND COL=7 AND BOARD(8,8)=EMPTY THEN WARN = 1 GOTO LINEAR'1 LINEAR'FAIL: TESTFLIPS = 0 RETURN LINEAR'COLOR: IF FLAG=0 THEN RETURN IF TESTFLIPS=0 THEN RETURN ROWDIR = -ROWDIR COLDIR = -COLDIR FOR I = 1 TO TESTFLIPS TESTROW = TESTROW+ROWDIR TESTCOL = TESTCOL+COLDIR BOARD(TESTROW,TESTCOL) = COLOR PRINT TAB(TESTROW*2+1,TESTCOL*4); MID("O@",COLOR,1); NEXT I ROWDIR = -ROWDIR COLDIR = -COLDIR RETURN ROW'ADJUST: IF COL<2 OR COL>7 THEN RETURN IF (BOARD(ROW,COL-1)=(3-COLOR) AND BOARD(ROW,COL+1)=EMPTY) OR & (BOARD(ROW,COL-1)=EMPTY AND BOARD(ROW,COL+1)=(3-COLOR)) THEN & SCORE = 1 RETURN COL'ADJUST: IF ROW<2 OR ROW>7 THEN RETURN IF (BOARD(ROW-1,COL)=(3-COLOR) AND BOARD(ROW+1,COL)=EMPTY) OR & (BOARD(ROW-1,COL)=EMPTY AND BOARD(ROW+1,COL)=(3-COLOR)) THEN & SCORE = 1 RETURN END