! OXOS (Now in IMP80, with graph mode fixed JGH 4.82) %EXTERNAL %ROUTINE %SPEC TERMINATE %EXTERNAL %ROUTINE %SPEC PROMPT(%STRING(19) S) %SYSTEM %ROUTINE %SPEC CONSOLE(%INTEGER EP, %INTEGER %NAME AD, LEN) %EXTERNAL %STRING(8) %FN %SPEC TIME ! %ROUTINE OXO GUTS(%ROUTINE CLEAR LINE, %routine MOVE (%integer X, Y)) ! %INTEGER I, SEED, AD, MODE %INTEGER %ARRAY SQ(1:9) %OWN %INTEGER WCT, DCT %CONST %INTEGER X = 1, O = 4 %CONST %STRING(5) %ARRAY HT(1:2) = "TAILS", "HEADS" ! %STRING(8) TEMP; TEMP = TIME SEED = (CHARNO(TEMP,7)*10+CHARNO(TEMP,8))&1023 ! %INTEGER %FN RANDOM(%INTEGER MAX) %INTEGER I SEED = (741*SEED+216)&1023 I = SEED>>6 %RESULT = I-I//MAX*MAX+1 %END ! %ROUTINE DRAW(%INTEGER PLAYER, POSN) %CONST %STRING(10) %ARRAY BIG X(1:5) = %C "XXX XXX", " XX XX ", " XXXX ", " XX XX ", "XXX XXX" %CONST %STRING(10) %ARRAY BIG O(1:5) = %C " OOOOOOOO ", "OO OO"(3), " OOOOOOOO " %OWN %STRING(10) %ARRAY BLANK(1:5) = " "(5) %STRING(10) %ARRAY %NAME CHAR %INTEGER I, J, K ! SQ(POSN) = PLAYER %IF PLAYER = 0 %START CHARNO(BLANK(3), 6) = POSN+'0' CHAR == BLANK %FINISH %ELSE %START %IF PLAYER = X %THEN CHAR == BIG X %ELSE CHAR == BIG O %FINISH POSN = POSN-1; K = POSN//3 J = K<<3; K = 21+15*(POSN-3*K) %CYCLE I = 1, 1, 5 MOVE(J+I, K); PRINT STRING(CHAR(I)) %REPEAT TERMINATE %END ! %ROUTINE MESSAGE(%STRING(63) S) MOVE(23, 1); CLEAR LINE MOVE(24, 1); CLEAR LINE PRINT STRING("* ".S) %UNLESS S = "" TERMINATE %END ! %ROUTINE ASK(%STRING(19) Q, %INTEGER %NAME A) MOVE(23, 1) TERMINATE PROMPT(Q) SKIP SYMBOL %WHILE NEXT SYMBOL = ' ' A = NEXT SYMBOL SKIP SYMBOL %WHILE NEXT SYMBOL # NL; SKIP SYMBOL %END ! ! %INTEGER %FN CHECK(%INTEGER LINE, TYPE, FLAG) %CONST %BYTE %INTEGER %ARRAY BASE(1:8) = 1, 4, 7, 1, 2, 3, 1, 3 %CONST %BYTE %INTEGER %ARRAY INC(1:8) = 1, 1, 1, 3, 3, 3, 4, 2 %INTEGER I, TOTAL, M, MOVE ! TOTAL = 0 %CYCLE I = 1, 1, 3 M = BASE(LINE)+(FLAG+FLAG+(FLAG+FLAG-O)*(I//3*3-I))//O*INC(LINE); !!! MOVE = M %IF SQ(M) = 0 TOTAL = TOTAL+SQ(M) %REPEAT %RESULT = 0 %UNLESS TOTAL = TYPE DRAW(X, MOVE) %RESULT = 1 %END ! ! %INTEGER %FN PICK(%INTEGER FIRST, NO, TYPE) %BYTE %INTEGER %ARRAY F(1:NO) %INTEGER I, J %CYCLE J = 1, 1, NO; F(J) = FIRST+J-1; %REPEAT %CYCLE I = NO, -1, 1 J = RANDOM(I) %RESULT = 1 %IF CHECK(F(J), TYPE, 0) = 1 F(J) = F(J+1) %AND J = J+1 %WHILE J < NO %REPEAT %RESULT = 0 %END ! ! %INTEGER %FN MY MOVE %INTEGER I, J %BYTE %INTEGER %ARRAY F(1:9) %RESULT = 1 %IF PICK(1, 8, X+X) = 1 %RESULT = 0 %IF PICK(1, 8, O+O) = 1 %IF SQ(1)+SQ(9) # O+O # SQ(3)+SQ(7) %START %RESULT = 0 %IF CHECK(8, X, (\(SQ(2)!SQ(6)))&O) = 1 %OR %C CHECK(7, X, (\(SQ(2)!SQ(4)))&O) = 1 %OR %C PICK(1, 6, X) = 1 %FINISH %ELSE %START %RESULT = 0 %IF PICK(1, 6, X) = 1 %OR %C CHECK(7, X, (\(SQ(2)!SQ(4)))&O) = 1 %OR %C CHECK(8, X, (\(SQ(2)!SQ(6)))&O) = 1 %FINISH I = 0 %CYCLE J = 1, 1, 9 I = I+1 %AND F(I) = J %IF SQ(J) = 0 %REPEAT DRAW(X, F(RANDOM(I))) %RESULT = 0 %END ! ! %ROUTINE YOUR MOVE %INTEGER POSN %CYCLE ASK("Your turn : ", POSN); POSN = POSN-'0' %IF 1 <= POSN <= 9 %START %IF SQ(POSN) = 0 %START MESSAGE(""); DRAW(O, POSN) %RETURN %FINISH MESSAGE("Occupied") %FINISH %ELSE MESSAGE("No such square") %REPEAT %END ! ! %ROUTINE PICK CORNER %CONST %BYTE %INTEGER %ARRAY C(1:4) = 1, 3, 7, 9 DRAW(X, C(RANDOM(4))) %END ! ! ! AD = ADDR(TEMP); MODE = 1 TEMP = TOSTRING(11).TOSTRING(1) CONSOLE(17, AD, MODE) %CYCLE I = 1, 1, 21 %IF I&7 = 7 %START SPACES(20) PRINT STRING("------------+--------------+------------") %FINISH %ELSE %START SPACES(25) %IF I&7 = 3 %THEN PRINT SYMBOL(I>>3&3*3+'1') %ELSE SPACE PRINT STRING(" | ") %IF I&7 = 3 %THEN PRINT SYMBOL(I>>3&3*3+'2') %ELSE SPACE PRINT STRING(" | ") PRINT SYMBOL(I>>3&3*3+'3') %IF I&7 = 3 PRINT STRING(" # I am X") %IF I = 10 PRINT STRING(" # You are O") %IF I = 12 %FINISH PRINT CH(13); NEWLINE %REPEAT NEWLINES(2) %CYCLE I = 1, 1, 9; SQ(I) = 0; %REPEAT %CYCLE I = RANDOM(2) MESSAGE("I shall toss a coin - heads you start. It's ".HT(I)) %IF I = 1 %THEN PICK CORNER %ELSE %START YOUR MOVE %IF SQ(5) = 0 %THEN DRAW(X, 5) %ELSE PICK CORNER %FINISH %CYCLE YOUR MOVE WCT = WCT+1 %AND MESSAGE("I've won !") %AND %EXIT %IF MY MOVE = 1 DCT = DCT+1 %AND MESSAGE("It's a draw") %AND %EXIT %IF I = 4 I = I+1 %REPEAT PRINT STRING(" Score is : Me"); WRITE(WCT, 0) PRINT STRING(", You 0, Draws"); WRITE(DCT, 0); TERMINATE ASK("Play again ? ", I) %EXIT %UNLESS I = 'Y' %OR I = 'y' %CYCLE I = 1, 1, 9 DRAW(0, I) %IF SQ(I) # 0 %REPEAT %REPEAT TEMP = TOSTRING(11).TOSTRING(0) CONSOLE(17, AD, MODE) ! %END ! ! %EXTERNAL %ROUTINE OXO(%STRING(255) S) ! %ROUTINE CLEAR LINE PRINT CH(27); PRINT CH('I') PRINT CH(0); PRINT CH(0); PRINT CH(0); PRINT CH(0); PRINT CH(0) %END ! %ROUTINE MOVE(%INTEGER X, Y) PRINT CH(27); PRINT CH('X'); PRINT CH(31+X) PRINT CH(27); PRINT CH('Y'); PRINT CH(31+Y) %END ! OXO GUTS(CLEAR LINE, MOVE) %END ! ! %EXTERNAL %ROUTINE VOXO(%STRING(255) S) ! %ROUTINE CLEAR LINE PRINT CH(27); PRINT CH('t') %END ! %ROUTINE MOVE(%INTEGER X, Y) PRINT CH(27); PRINT CH('Y'); PRINT CH(31+X); PRINT CH(31+Y) %END ! OXO GUTS(CLEAR LINE, MOVE) %END ! %END %OF %FILE