Изучение базовых стратегий решения задач для программирования игр двух лиц с полной информацией, страница 2

add_beyong_O( [Pos|Used] ).

add_beyong_O( _ ).

member( _, [] ) :- !, fail.

member( X, [X|_] ) :- !.

member( X, [_|Xs] ) :- member( X, Xs ).

draw( ps( X, Y ), Ch ) :X1 = 39+X,

Y1 = 8-Y,

shiftwindow( xowindow ),

cursor( Y1, X1 ),

write( Ch ),

shiftwindow( swindow ).

showpos( user, Pos ) :draw( Pos, 'X' ).

showpos( computer, ps( X, Y ) ) :draw( ps( X, Y ), 'O' ).

best_move( Pos, Weight1, _, Weight2, Pos, Weight1 ) :Weight1 > Weight2.

best_move( _, _, Pos, Weight, Pos, Weight ).

max( X, X, Y ) :- X > Y.

max( X, _, X ).

alpha_beta( Pos, Weight ) :cell( Pos1 ),

retract( cell( Pos1 ), Cells ),

weight( Pos1, Weight1 ),

alpha_beta( Pos2, Weight2 ),

best_move( Pos1, Weight1, Pos2, Weight2, Pos, Weight ).

alpha_beta( ps( 0, 0 ), 0 ).

nsX( ps( X, Y ), N ) :X1 = X+1,

x( ps( X1, Y ) ),

nsX( ps( X1, Y ), N1),

N = N1+1.

nsX( _, 1 ).

snX( ps( X, Y ), N ) :X1 = X-1,

x( ps( X1, Y ) ),

snX( ps( X1, Y ), N1),

N = N1+1.

snX( _, 1 ).

neX( ps( X, Y ), N ) :X1 = X-1,

Y1 = Y+1,

x( ps( X1, Y1 ) ),

neX( ps( X1, Y1 ), N1),

N = N1+1.

neX( _, 1 ).

nwX( ps( X, Y ), N ) :X1 = X-1,

Y1 = Y-1,

x( ps( X1, Y1 ) ),

nwX( ps( X1, Y1 ), N1),

N = N1+1.

nwX( _, 1 ).

seX( ps( X, Y ), N ) :X1 = X+1,

Y1 = Y-1,

x( ps( X1, Y1 ) ),

seX( ps( X1, Y1 ), N1),

N = N1+1.

seX( _, 1 ).

swX( ps( X, Y ), N ) :X1 = X+1,

Y1 = Y+1,

x( ps( X1, Y1 ) ),

swX( ps( X1, Y1 ), N1),

N = N1+1.

swX( _, 1 ).

weX( ps( X, Y ), N ) :Y1 = Y+1,

x( ps( X, Y1 ) ),

weX( ps( X, Y1 ), N1),

N = N1+1.

weX( _, 1 ).

ewX( ps( X, Y ), N ) :Y1 = Y-1,

x( ps( X, Y1 ) ),

ewX( ps( X, Y1 ), N1),

N = N1+1.

ewX( _, 1 ).

nsO( ps( X, Y ), N ) :X1 = X+1,

o( ps( X1, Y ) ),

nsO( ps( X1, Y ), N1),

N = N1+1.

nsO( _, 1 ).

snO( ps( X, Y ), N ) :X1 = X-1,

o( ps( X1, Y ) ),

snO( ps( X1, Y ), N1),

N = N1+1.

snO( _, 1 ).

neO( ps( X, Y ), N ) :X1 = X-1,

Y1 = Y+1,

o( ps( X1, Y1 ) ),

neO( ps( X1, Y1 ), N1),

N = N1+1.

neO( _, 1 ).

nwO( ps( X, Y ), N ) :X1 = X-1,

Y1 = Y-1,

o( ps( X1, Y1 ) ),

nwO( ps( X1, Y1 ), N1),

N = N1+1.

nwO( _, 1 ).

seO( ps( X, Y ), N ) :X1 = X+1,

Y1 = Y+1,

o( ps( X1, Y1 ) ),

seO( ps( X1, Y1 ), N1),

N = N1+1.

seO( _, 1 ).

swO( ps( X, Y ), N ) :X1 = X+1,

Y1 = Y-1,

o( ps( X1, Y1 ) ),

swO( ps( X1, Y1 ), N1),

N = N1+1.

swO( _, 1 ).

weO( ps( X, Y ), N ) :Y1 = Y+1,

o( ps( X, Y1 ) ),

weO( ps( X, Y1 ), N1),

N = N1+1.

weO( _, 1 ).

ewO( ps( X, Y ), N ) :Y1 = Y-1,

o( ps( X, Y1 ) ),

ewO( ps( X, Y1 ), N1),

N = N1+1.

ewO( _, 1 ).

fiveX :-        % Направление север-юг

x( Pos ),

nsX( Pos, 5 ).

fiveX :-        % Направление запад-восток

x( Pos ),

weX( Pos, 5 ).

fiveX :-        % Направление северо-восток

x( Pos ),

neX( Pos, 5 ).

fiveX :-        % Направление юго-восток

x( Pos ),

seX( Pos, 5 ).

fiveO :-          % Направление север-юг

o( Pos ),

nsO( Pos, 5 ).

fiveO :-        % Направление запад-восток

o( Pos ),

weO( Pos, 5 ).

fiveO :-        % Направление северо-восток

o( Pos ),

neO( Pos, 5 ).

fiveO :-        % Направление юго-восток

o( Pos ),

seO( Pos, 5 ).

weight( Pos, 10 ) :snO( Pos, N1 ),

nsO( Pos, N2 ),

N1+N2 = 6.

weight( Pos, 10 ) :neO( Pos, N1 ),

swO( Pos, N2 ),

N1+N2 = 6.

weight( Pos, 10 ) :weO( Pos, N1 ),

ewO( Pos, N2 ),

N1+N2 = 6.

weight( Pos, 10 ) :seO( Pos, N1 ),

nwO( Pos, N2 ),

N1+N2 = 6.

weight( Pos, 9 ) :snX( Pos, N1 ),

nsX( Pos, N2 ),

N1+N2 = 6.

weight( Pos, 9 ) :neX( Pos, N1 ),

swX( Pos, N2 ),

N1+N2 = 6.

weight( Pos, 9 ) :weX( Pos, N1 ),

ewX( Pos, N2 ),

N1+N2 = 6.

weight( Pos, 9 ) :seX( Pos, N1 ),

nwX( Pos, N2 ),

N1+N2 = 6.

weight( Pos, 8 ) :snO( Pos, N1 ),

nsO( Pos, N2 ),

N1+N2 = 5.

weight( Pos, 8 ) :neO( Pos, N1 ),

swO( Pos, N2 ),

N1+N2 = 5.

weight( Pos, 8 ) :weO( Pos, N1 ),

ewO( Pos, N2 ),

N1+N2 = 5.

weight( Pos, 8 ) :seO( Pos, N1 ),

nwO( Pos, N2 ),

N1+N2 = 5.

weight( Pos, 8 ) :snX( Pos, N1 ),

nsX( Pos, N2 ),

N1+N2 = 5.

weight( Pos, 8 ) :neX( Pos, N1 ),

swX( Pos, N2 ),

N1+N2 = 5.

weight( Pos, 8 ) :weX( Pos, N1 ),

ewX( Pos, N2 ),

N1+N2 = 5.

weight( Pos, 8 ) :seX( Pos, N1 ),

nwX( Pos, N2 ),

N1+N2 = 5.

weight( Pos, 7 ) :snO( Pos, N1 ),

nsO( Pos, N2 ),

N1+N2 = 4.

weight( Pos, 7 ) :neO( Pos, N1 ),

swO( Pos, N2 ),

N1+N2 = 4.

weight( Pos, 7 ) :weO( Pos, N1 ),

ewO( Pos, N2 ),

N1+N2 = 4.

weight( Pos, 7 ) :seO( Pos, N1 ),

nwO( Pos, N2 ),

N1+N2 = 4.

weight( Pos, 6 ) :snO( Pos, N1 ),

nsO( Pos, N2 ),

N1+N2 = 3.

weight( Pos, 6 ) :neO( Pos, N1 ),

swO( Pos, N2 ),

N1+N2 = 3.

weight( Pos, 6 ) :weO( Pos, N1 ),

ewO( Pos, N2 ),

N1+N2 = 3.

weight( Pos, 6 ) :seO( Pos, N1 ),

nwO( Pos, N2 ),

N1+N2 = 3.

weight( _, 5 ).

5.  Тестирование

·  Реализованный алгоритм при установке глубины анализа равной 0 может играть в крестики-нолики на не очень высоком уровне. Алгоритм отслеживает попытки противника построить 5 крестиков в ряд и пресекает их. Однако «склонность к обороне» алгоритма иногда мешает ему находить правильный ход из выигрышных позиций. Кроме того, алгоритм пресекает только явные попытки нападений и обмануть его не составляет особой сложности.

·  Если параметр глубин анализа увеличить, то программа играет несколько лучше, однако провести тестирование до конца не удалось, вследствие постоянно возникающих ошибок нехватки памяти.