233 lines
6.4 KiB
Plaintext
233 lines
6.4 KiB
Plaintext
BEGIN
|
|
|
|
COMMENT scoreWin 6 ;
|
|
COMMENT scoreTie 5 ;
|
|
COMMENT scoreLose 4 ;
|
|
COMMENT scoreMax 9 ;
|
|
COMMENT scoreMin 2 ;
|
|
COMMENT scoreInvalid 0 ;
|
|
COMMENT pieceX 1 ;
|
|
COMMENT pieceY 2 ;
|
|
COMMENT pieceBlank 0 ;
|
|
|
|
INTEGER movecount;
|
|
INTEGER ARRAY board[0:8];
|
|
|
|
INTEGER PROCEDURE winner;
|
|
BEGIN
|
|
INTEGER t, p;
|
|
|
|
p := 0;
|
|
t := board[ 0 ];
|
|
IF 0 # t THEN BEGIN
|
|
IF ( ( ( t = board[1] ) AND ( t = board[2] ) ) OR
|
|
( ( t = board[3] ) AND ( t = board[6] ) ) ) THEN
|
|
p := t;
|
|
END;
|
|
|
|
IF 0 = p THEN BEGIN
|
|
t := board[1];
|
|
IF ( 0 # t ) AND ( t = board[4] ) AND ( t = board[7] ) THEN
|
|
p := t
|
|
ELSE BEGIN
|
|
t := board[2];
|
|
IF ( 0 # t ) AND ( t = board[5] ) AND ( t = board[8] ) THEN
|
|
p := t
|
|
ELSE BEGIN
|
|
t := board[3];
|
|
IF ( 0 # t ) AND ( t = board[4] ) AND ( t = board[5] ) THEN
|
|
p := t
|
|
ELSE BEGIN
|
|
t := board[6];
|
|
IF ( 0 # t ) AND ( t = board[7] ) AND ( t = board[8] ) THEN
|
|
p := t
|
|
ELSE BEGIN
|
|
t := board[4];
|
|
IF ( 0 # t ) THEN BEGIN
|
|
IF ( ( ( t = board[0] ) AND ( t = board[8] ) ) OR
|
|
( ( t = board[2] ) AND ( t = board[6] ) ) ) THEN
|
|
p := t;
|
|
END;
|
|
END;
|
|
END;
|
|
END;
|
|
END;
|
|
END;
|
|
|
|
winner := p;
|
|
END winner;
|
|
|
|
INTEGER PROCEDURE winner2( move );
|
|
VALUE move;
|
|
INTEGER move;
|
|
BEGIN
|
|
INTEGER x;
|
|
x := board[ move ];
|
|
CASE move OF
|
|
0: BEGIN
|
|
IF NOT ( ( ( x = board[1] ) AND ( x = board[2] ) ) OR
|
|
( ( x = board[3] ) AND ( x = board[6] ) ) OR
|
|
( ( x = board[4] ) AND ( x = board[8] ) ) )
|
|
THEN x := 0;
|
|
END;
|
|
1: BEGIN
|
|
IF NOT ( ( ( x = board[0] ) AND ( x = board[2] ) ) OR
|
|
( ( x = board[4] ) AND ( x = board[7] ) ) )
|
|
THEN x := 0;
|
|
END;
|
|
2: BEGIN
|
|
x := board[ 2 ];
|
|
IF NOT ( ( ( x = board[0] ) AND ( x = board[1] ) ) OR
|
|
( ( x = board[5] ) AND ( x = board[8] ) ) OR
|
|
( ( x = board[4] ) AND ( x = board[6] ) ) )
|
|
THEN x := 0;
|
|
END;
|
|
3: BEGIN
|
|
x := board[ 3 ];
|
|
IF NOT ( ( ( x = board[4] ) AND ( x = board[5] ) ) OR
|
|
( ( x = board[0] ) AND ( x = board[6] ) ) )
|
|
THEN x := 0;
|
|
END;
|
|
4: BEGIN
|
|
x := board[ 4 ];
|
|
IF NOT ( ( ( x = board[0] ) AND ( x = board[8] ) ) OR
|
|
( ( x = board[2] ) AND ( x = board[6] ) ) OR
|
|
( ( x = board[1] ) AND ( x = board[7] ) ) OR
|
|
( ( x = board[3] ) AND ( x = board[5] ) ) )
|
|
THEN x := 0;
|
|
END;
|
|
5: BEGIN
|
|
x := board[ 5 ];
|
|
IF NOT ( ( ( x = board[3] ) AND ( x = board[4] ) ) OR
|
|
( ( x = board[2] ) AND ( x = board[8] ) ) )
|
|
THEN x := 0;
|
|
END;
|
|
6: BEGIN
|
|
x := board[ 6 ];
|
|
IF NOT ( ( ( x = board[7] ) AND ( x = board[8] ) ) OR
|
|
( ( x = board[0] ) AND ( x = board[3] ) ) OR
|
|
( ( x = board[4] ) AND ( x = board[2] ) ) )
|
|
THEN x := 0;
|
|
END;
|
|
7: BEGIN
|
|
x := board[ 7 ];
|
|
IF NOT ( ( ( x = board[6] ) AND ( x = board[8] ) ) OR
|
|
( ( x = board[1] ) AND ( x = board[4] ) ) )
|
|
THEN x := 0;
|
|
END;
|
|
8: BEGIN
|
|
x := board[ 8 ];
|
|
IF NOT ( ( ( x = board[6] ) AND ( x = board[7] ) ) OR
|
|
( ( x = board[2] ) AND ( x = board[5] ) ) OR
|
|
( ( x = board[0] ) AND ( x = board[4] ) ) )
|
|
THEN x := 0;
|
|
END
|
|
ELSE text( 1, "unexpected move" );
|
|
|
|
winner2 := x;
|
|
END winner2;
|
|
|
|
INTEGER PROCEDURE minmax( alpha, beta, depth, move );
|
|
VALUE alpha, beta, depth, move;
|
|
INTEGER alpha, beta, depth, move;
|
|
BEGIN
|
|
INTEGER value, p, score, pm;
|
|
value := 0;
|
|
movecount := movecount + 1;
|
|
|
|
IF depth >= 4 THEN BEGIN
|
|
p := winner2( move );
|
|
IF p # 0 THEN BEGIN
|
|
IF p = 1 THEN value := 6
|
|
ELSE value := 4;
|
|
END
|
|
ELSE BEGIN
|
|
IF depth = 8 THEN value := 5;
|
|
END;
|
|
END;
|
|
|
|
IF value = 0 THEN BEGIN
|
|
IF 1 = ( depth MOD 2 ) THEN BEGIN
|
|
value := 2;
|
|
pm := 1;
|
|
END
|
|
ELSE BEGIN
|
|
value := 9;
|
|
pm := 2;
|
|
END;
|
|
|
|
p := 0;
|
|
WHILE p <= 8 DO BEGIN
|
|
IF board[ p ] = 0 THEN BEGIN
|
|
board[ p ] := pm;
|
|
score := minmax( alpha, beta, depth + 1, p );
|
|
board[ p ] := 0;
|
|
|
|
IF pm = 1 THEN BEGIN
|
|
IF score > value THEN BEGIN
|
|
value := score;
|
|
IF ( ( value = 6 ) OR ( value >= beta ) ) THEN
|
|
p := 10
|
|
ELSE BEGIN
|
|
IF ( value > alpha ) THEN alpha := value;
|
|
END;
|
|
END;
|
|
END
|
|
ELSE BEGIN
|
|
IF score < value THEN BEGIN
|
|
value := score;
|
|
IF ( value = 4 ) OR ( value <= alpha ) THEN
|
|
p := 10
|
|
ELSE BEGIN
|
|
IF ( value < beta ) THEN beta := value;
|
|
END;
|
|
END;
|
|
END;
|
|
END;
|
|
|
|
p := p + 1;
|
|
END;
|
|
END;
|
|
|
|
minmax := value;
|
|
END minmax;
|
|
|
|
PROCEDURE findsolution( move );
|
|
VALUE move;
|
|
INTEGER move;
|
|
BEGIN
|
|
INTEGER score;
|
|
|
|
board[ move ] := 1;
|
|
score := minmax( 2, 9, 0, move );
|
|
board[ move ] := 0;
|
|
END findsolution;
|
|
|
|
PROCEDURE main;
|
|
BEGIN
|
|
INTEGER i;
|
|
|
|
FOR i:=0 STEP 1 UNTIL 8 DO BEGIN
|
|
board[ i ] := 0;
|
|
END;
|
|
|
|
FOR i:=0 STEP 1 UNTIL 9 DO BEGIN
|
|
movecount := 0;
|
|
findsolution( 0 );
|
|
findsolution( 1 );
|
|
findsolution( 4 );
|
|
END;
|
|
|
|
text( 1, "moves: " );
|
|
write( 1, movecount );
|
|
text( 1, "*N" );
|
|
|
|
ioc(22);
|
|
END main;
|
|
|
|
main;
|
|
|
|
END
|
|
FINISH
|
|
|