Разработка программы с использованием языка логического программирования Prolog
МИНИСТЕРСТВО
ОБРАЗОВАНИЯ И НАУКИ РОССИЙСКОЙ ФЕДЕРАЦИИ
ФЕДЕРАЛЬНОЕ
АГЕНТСТВО ПО ОБРАЗОВАНИЮ
ГОСУДАРСТВЕННОЕ
ОБРАЗОВАТЕЛЬНОЕ УЧРЕЖДЕНИЕ
ВЫСШЕГО
ПРОФЕССИОНАЛЬНОГО ОБРАЗОВАНИЯ
НОВОСИБИРСКИЙ
ГОСУДАРСТВЕННЫЙ ТЕХНИЧЕСКИЙ УНИВЕРСИТЕТ
Кафедра
вычислительной техники
ПОЯСНИТЕЛЬНАЯ
ЗАПИСКА
к
курсовому проекту по дисциплине: «Функциональное и логическое программирование»
Тема:
Разработка программы с использованием языка логического программирования Prolog
Новосибирск
2010 г.
1. ОПИСАНИЕ НАЗНАЧЕНИЯ ПРОГРАММНОГО
ПРОДУКТА
Настоящий программный продукт предназначен для
игры «Крестики - нолики». «Крестики - нолики» - игра для двух участников, в
которой игроки по очереди вписывают “x” или “o” в таблицу 3 x 3. Цель игрока -
первым заполнить строку, столбец или диагональ таблицы.
2. ОПИСАНИЕ ДАННЫХ
Данными в программе являются 3 динамических
факта для базы данных. Факты состоят из ряда полей:
первый факт содержит 9 полей, обозначающих
текущую ситуацию на поле (рис. 1),
второй факт содержит 2 поля, обозначающих текущий
счет игры,
третий факт содержит 1 поле и обозначает конец
игры.
Путём редактирования данных осуществляется
игровой процесс. Используется целочисленный тип данных.
Рисунок 1 - Пример игрового поля
3. ОПИСАНИЕ МЕТОДОВ РЕШЕНИЯ
В программе реализовано 2 режима:
Ход пользователя - в этом режиме обрабатывается
ход пользователя;
Ход компьютера - в этом режиме обрабатывается
ход компьютера.
Оба хода реализованы с помощью предиката game.
Ход пользователя.
Ход пользователя начинается с предиката game с
параметром 1.
Предикат global_game_end(Endgame) выполняет
проверку на случай окончания игры.
Далее выводится подсказка для пользователя, что
его очередь ходить, и он должен ввести значение ячейки с номером ячейки для
хода (нумерация по порядку слева на право).
Предикат make_move(1, Xod, XodEst) отвечает за
выполнение хода.
Вспомогательный предикат scan_move проверяет
возможность выполнения заданного хода.
scan_move(1,1):-
global_field(X1,_,_,_,_,_,_,_,_), X1>0 ,!._move(2,1):-
global_field(_,X2,_,_,_,_,_,_,_), X2>0 ,!._move(3,1):-
global_field(_,_,X3,_,_,_,_,_,_), X3>0 ,!._move(4,1):-
global_field(_,_,_,X4,_,_,_,_,_), X4>0 ,!._move(5,1):-
global_field(_,_,_,_,X5,_,_,_,_), X5>0 ,!._move(6,1):- global_field(_,_,_,_,_,X6,_,_,_),
X6>0 ,!._move(7,1):- global_field(_,_,_,_,_,_,X7,_,_), X7>0
,!._move(8,1):- global_field(_,_,_,_,_,_,_,X8,_), X8>0 ,!._move(9,1):-
global_field(_,_,_,_,_,_,_,_,X9), X9>0 ,!.
scan_move(_,0).
Если заданный ход можно выполнить то, предикат
edit_global_field изменяет ситуацию на игровом поле (в выбранную позицию
заносится символ игрока “x”), меняя содержимое фактов базы данных, а предикат
draw_field выводит текущее состояние игрового поля на экран.
Предикат draw_field имеет вспомогательный
предикат scan_x_o.
При помощи предиката scan_x_o осуществляется
выбор символа для вывода на экран (“x”, “o”, “ ” в зависимости от текущего
состояния проверяемой ячейки).
Предикат find_win проверяет наличие победителя
на текущем ходе игры.
find_win(1):-
global_field(X1,X2,X3,X4,X5,X6,X7,X8,X9), X1<>0, X1=X2,X1=X3,
who_won(X1),!._win(1):- global_field(X1,X2,X3,X4,X5,X6,X7,X8,X9), X4<>0,
X4=X5,X4=X6, who_won(X4),!._win(1):- global_field(X1,X2,X3,X4,X5,X6,X7,X8,X9),
X7<>0, X7=X8,X7=X9, who_won(X7),!._win(1):- global_field(X1,X2,X3,X4,X5,X6,X7,X8,X9),
X1<>0, X1=X4,X1=X7, who_won(X1),!._win(1):-
global_field(X1,X2,X3,X4,X5,X6,X7,X8,X9), X2<>0, X2=X5,X2=X8,
who_won(X2),!._win(1):- global_field(X1,X2,X3,X4,X5,X6,X7,X8,X9), X3<>0,
X3=X6,X3=X9, who_won(X3),!._win(1):- global_field(X1,X2,X3,X4,X5,X6,X7,X8,X9),
X1<>0, X1=X5,X1=X9, who_won(X1),!._win(1):-
global_field(X1,X2,X3,X4,X5,X6,X7,X8,X9), X3<>0, X3=X5,X3=X7,
who_won(X3),!.
find_win(0).
Если победитель найден вызывается предикат
who_won.
Предикат who_won добавляет победителю очко, с помощью
предиката edit_global_score, «сбрасывает» состояние игрового поля до исходного
edit_global_field(0,0,0,0,0,0,0,0,0), изменяет состояние игрового процесса
(окончание игры) edit_global_game_end(1) и выводит сообщение о победителе.
Если победитель не найден, то вызывается
предикат count_field, который проверяет наличие свободных ячеек на поле.
count_field(End):-
global_field(X1,X2,X3,X4,X5,X6,X7,X8,X9),_empty(X1,A),_empty(X2,B),_empty(X3,C),_empty(X4,D),_empty(X5,E),_empty(X6,F),_empty(X7,G),_empty(X8,H),_empty(X9,I),=A+B+C+D+E+F+G+H+I.
Предикат scan_end_game проверяет ситуацию
окончания игры (все ячейки заполнены) и с помощью предиката
edit_global_game_end изменяет состояние факта окончания игры в базе данных.
scan_end_game(9):-edit_global_game_end(1).
scan_end_game(_).
Если игра не закончена, вызывается предикат game
и следует ход компьютера.
Ход компьютера.
Ход пользователя начинается с предиката game с
параметром 2.
Предикат global_game_end(Endgame) выполняет
проверку на случай окончания игры.
Далее выполнятся предикат select_move, который
анализирует ситуацию игрового поля и принимает решение, какой ход наиболее
правильный (если нет ситуации гарантированного выигрыша или гарантированного
проигрыша ход осуществляется случайным образом).
select_move(Xod):-
random(8,TempXod), Xod=TempXod+1,!.
Далее выполняется предикат make_move(1, Xod,
XodEst).
Вспомогательный предикат scan_move проверяет
возможность выполнения заданного хода.
scan_move(1,1):-
global_field(X1,_,_,_,_,_,_,_,_), X1>0 ,!._move(2,1):-
global_field(_,X2,_,_,_,_,_,_,_), X2>0 ,!._move(3,1):-
global_field(_,_,X3,_,_,_,_,_,_), X3>0 ,!._move(4,1):-
global_field(_,_,_,X4,_,_,_,_,_), X4>0 ,!._move(5,1):-
global_field(_,_,_,_,X5,_,_,_,_), X5>0 ,!._move(6,1):- global_field(_,_,_,_,_,X6,_,_,_),
X6>0 ,!._move(7,1):- global_field(_,_,_,_,_,_,X7,_,_), X7>0
,!._move(8,1):- global_field(_,_,_,_,_,_,_,X8,_), X8>0 ,!._move(9,1):-
global_field(_,_,_,_,_,_,_,_,X9), X9>0 ,!.
scan_move(_,0).
Если заданный ход можно выполнить то, предикат
edit_global_field изменяет ситуацию на игровом поле (в выбранную позицию
заносится символ игрока “x”), меняя содержимое фактов базы данных, а предикат
draw_field выводит текущее состояние игрового поля на экран.
Предикат draw_field имеет вспомогательный
предикат scan_x_o.
При помощи предиката scan_x_o осуществляется
выбор символа для вывода на экран (“x”, “o”, “ ” в зависимости от текущего
состояния проверяемой ячейки).
Предикат find_win проверяет наличие победителя
на текущем ходе игры.
find_win(1):- global_field(X1,X2,X3,X4,X5,X6,X7,X8,X9),
X1<>0, X1=X2,X1=X3, who_won(X1),!._win(1):-
global_field(X1,X2,X3,X4,X5,X6,X7,X8,X9), X4<>0, X4=X5,X4=X6,
who_won(X4),!.
_win(1):- global_field(X1,X2,X3,X4,X5,X6,X7,X8,X9), X7<>0, X7=X8,X7=X9,
who_won(X7),!._win(1):- global_field(X1,X2,X3,X4,X5,X6,X7,X8,X9), X1<>0,
X1=X4,X1=X7, who_won(X1),!._win(1):- global_field(X1,X2,X3,X4,X5,X6,X7,X8,X9),
X2<>0, X2=X5,X2=X8, who_won(X2),!._win(1):-
global_field(X1,X2,X3,X4,X5,X6,X7,X8,X9), X3<>0, X3=X6,X3=X9, who_won(X3),!._win(1):-
global_field(X1,X2,X3,X4,X5,X6,X7,X8,X9), X1<>0, X1=X5,X1=X9,
who_won(X1),!._win(1):- global_field(X1,X2,X3,X4,X5,X6,X7,X8,X9), X3<>0,
X3=X5,X3=X7, who_won(X3),!.
find_win(0).
Если победитель найден вызывается предикат
who_won.
Предикат who_won добавляет победителю очко, с
помощью предиката edit_global_score, «сбрасывает» состояние игрового поля до
исходного edit_global_field(0,0,0,0,0,0,0,0,0), изменяет состояние игрового
процесса (окончание игры) edit_global_game_end(1) и выводит сообщение о
победителе.
Если победитель не найден, то вызывается
предикат count_field, который проверяет наличие свободных ячеек на поле.
программа игра
крестики нолики
count_field(End):-
global_field(X1,X2,X3,X4,X5,X6,X7,X8,X9),_empty(X1,A),_empty(X2,B),_empty(X3,C),_empty(X4,D),_empty(X5,E),_empty(X6,F),_empty(X7,G),_empty(X8,H),_empty(X9,I),=A+B+C+D+E+F+G+H+I.
Предикат scan_end_game проверяет ситуацию
окончания игры (все ячейки заполнены) и с помощью предиката
edit_global_game_end изменяет состояние факта окончания игры в базе данных.
scan_end_game(9):-edit_global_game_end(1).
scan_end_game(_).
4. ОПИСАНИЕ ПРОГРАММЫ
global_field
(integer, integer,
integer, integer,
integer, integer,
integer, integer,
integer) Факт базы данных,
определяющий состояние игрового поля._score (integer, integer) Факт базы
данных, определяющий состояние счёта._game_end (integer) Факт базы данных
определяющий конец игры.Предикат реализующий цикличный вывод главного меню.С
данного предиката начинается программа. Предикат выводит на экран пункты меню и
предлагает пользователю выбрать один из них.(integer) Предикат реализует выбор
одного из пунктов меню._score () Предикат выводит на экран текущее состояние
счёта._first () Предикат опрашивает пользователя о праве первого хода.(integer)
Предикат выводит сообщение о том, кому принадлежит первый ход и запускает
игру.(integer) Предикат, осуществляющий непосредственный игровой процесс в двух
вариациях, в зависимости от ходящего.
make_move (integer, integer,
integer) Предикат выполняющий
ход
игрока._field
(integer, integer, integer, integer, integer, integer, integer, integer,
integer) Предикат выполняющий
прорисовку
игрового
поля.
scan_x_o (integer) Вспомогательный предикат
выбирающий символ необходимый для вывода в ячейку поля.
edit_global_field (integer, integer,
integer, integer, integer, integer, integer, integer, integer) Предикат
изменяющий
состояние
игрового
поля
в
базе
данных.
edit_global_score (integer) Предикат изменяющий
состояние счёта в базе данных._global_game_end (integer) Предикат, изменяющий
текущее состояние игрового процесса (конец игры)._field (integer) Предикат
подсчитывающий количество занятых ячеек поля._empty (integer, integer)
Вспомогательный предикат проверяющий ячейку поля на пустоту._win (integer)
Предикат проверяющий наличие выигрышной комбинации на поле._won (integer)
Предикат определяющий победителя раунда._move (integer, integer)
Вспомогательный предикат, проверяющий возможность заданного хода._move
(integer) Предикат определяющий ход компьютера._end_game (integer) Предикат
проверяющий ситуацию окончания игры.
5. ОПИСАНИЕ ПОЛЬЗОВАТЕЛЬСКОГО
ИНТЕРФЕЙСА
Программа имеет простой пользовательский
интерфейс:
При запуске программы на экран выводиться
главное меню (рис. 2):
Рисунок 2 - Главное меню
В соответствии с каждым пунктом меню
пользователь получает возможность:
начать новую игру,
просмотреть текущий счёт,
закончить игру.
При выборе первого пункта пользователь видит
опрос о праве первого хода (рис. 3):
Рисунок 3 - Право первого хода
Выбрав, кому будет принадлежать первый ход,
пользователь начинает игровой процесс. На экран выводится игровое поле и
сообщение о первом ходе (рис. 4).
Рисунок 4 - Игровое поле
Пользователю предлагается сделать ход (ввести
порядковый номер ячейки, нумерация слева на право, куда пользователь хочет
походить, если номер введён неправильно, выводится предложение о повторном
вводе).
По окончанию игры на экран выводится игровое
поле и главное меню (рис. 5).
Рисунок 5 - Окончание игры
СПИСОК ИСПОЛЬЗОВАННЫХ ИСТОЧНИКОВ
1. Стерлинг
Л., Шапиро Э. Искусство программирования на языке Пролог. - М.: Мир, 1990. -
333 с.
. Братко
И. Программирование на языке Пролог для искусственного интеллекта: Пер. с англ.
- М.: Мир, 1990.- 560 с., ил.
. Материал
из Википедии - свободной энциклопедии. - 2010. [Электронный ресурс]. URL:
http://ru.wikipedia.org/wiki/ Крестики-нолики.
ПРИЛОЖЕНИЕ
Исходный код программы
%===================================================%
DATABASE
- mydb
global_field (integer, integer,
integer, integer, integer, integer, integer, integer, integer)_score (integer,
integer)_game_end (integer)
%===================================================%(integer)_score
()_first ()(integer)(integer)_move (integer, integer, integer)_field (integer,
integer, integer, integer, integer, integer, integer, integer, integer)_x_o
(integer)_global_field (integer, integer, integer, integer, integer, integer,
integer, integer, integer)_global_score (integer)_global_game_end
(integer)_field (integer)_empty (integer, integer)_win (integer)_won
(integer)_move (integer, integer)_move (integer)_end_game (integer)
%===================================================%_empty(0,NX):-
NX=0._empty(_,NX):- NX=1._field(End):-
global_field(X1,X2,X3,X4,X5,X6,X7,X8,X9),_empty(X1,A),_empty(X2,B),_empty(X3,C),_empty(X4,D),_empty(X5,E),_empty(X6,F),_empty(X7,G),_empty(X8,H),_empty(X9,I),=A+B+C+D+E+F+G+H+I._global_score(1):-_score(You,Comp),(global_score(_,_),
mydb),=You+1,(global_score(NewYou,Comp),
mydb)._global_score(2):-_score(You,Comp),(global_score(_,_),
mydb),=Comp+1,(global_score(You,NewComp), mydb)._global_score(_)._global_game_end(X):-(global_game_end(_),
mydb),(global_game_end(X), mydb),!._won(1):- edit_global_score(1),
edit_global_field(0,0,0,0,0,0,0,0,0), edit_global_game_end(1), write(">
You won! =)"), nl, nl,!._won(2):- edit_global_score(2), edit_global_field(0,0,0,0,0,0,0,0,0),
edit_global_game_end(1), write("> You lose.:("), nl,
nl,!._won(_)._win(1):- global_field(X1,X2,X3,X4,X5,X6,X7,X8,X9), X1<>0,
X1=X2,X1=X3, who_won(X1),!._win(1):- global_field(X1,X2,X3,X4,X5,X6,X7,X8,X9),
X4<>0, X4=X5,X4=X6, who_won(X4),!._win(1):-
global_field(X1,X2,X3,X4,X5,X6,X7,X8,X9), X7<>0, X7=X8,X7=X9,
who_won(X7),!._win(1):- global_field(X1,X2,X3,X4,X5,X6,X7,X8,X9), X1<>0,
X1=X4,X1=X7, who_won(X1),!._win(1):- global_field(X1,X2,X3,X4,X5,X6,X7,X8,X9),
X2<>0, X2=X5,X2=X8, who_won(X2),!._win(1):-
global_field(X1,X2,X3,X4,X5,X6,X7,X8,X9), X3<>0, X3=X6,X3=X9,
who_won(X3),!._win(1):- global_field(X1,X2,X3,X4,X5,X6,X7,X8,X9), X1<>0,
X1=X5,X1=X9, who_won(X1),!._win(1):- global_field(X1,X2,X3,X4,X5,X6,X7,X8,X9),
X3<>0, X3=X5,X3=X7, who_won(X3),!._win(0)._move(1,1):-
global_field(X1,_,_,_,_,_,_,_,_), X1>0 ,!._move(2,1):-
global_field(_,X2,_,_,_,_,_,_,_), X2>0 ,!._move(3,1):-
global_field(_,_,X3,_,_,_,_,_,_), X3>0 ,!._move(4,1):-
global_field(_,_,_,X4,_,_,_,_,_), X4>0 ,!._move(5,1):- global_field(_,_,_,_,X5,_,_,_,_),
X5>0 ,!._move(6,1):- global_field(_,_,_,_,_,X6,_,_,_), X6>0
,!._move(7,1):- global_field(_,_,_,_,_,_,X7,_,_), X7>0 ,!._move(8,1):-
global_field(_,_,_,_,_,_,_,X8,_), X8>0 ,!._move(9,1):-
global_field(_,_,_,_,_,_,_,_,X9), X9>0 ,!._move(_,0)._global_field(NewX1,NewX2,NewX3,NewX4,NewX5,NewX6,NewX7,NewX8,NewX9):-_field(X1,X2,X3,X4,X5,X6,X7,X8,X9),(global_field(X1,X2,X3,X4,X5,X6,X7,X8,X9),
mydb),(global_field(NewX1,NewX2,NewX3,NewX4,NewX5,NewX6,NewX7,NewX8,NewX9),
mydb)._x_o(1):- !, write("x")._x_o(2):- !,
write("o")._x_o(0):- !, write("
")._field(X1,X2,X3,X4,X5,X6,X7,X8,X9):- clearwindow,("
-------------"), nl,(" | "), scan_x_o(X1), write(" |
"), scan_x_o(X2), write(" | "), scan_x_o(X3), write("
|"), nl,(" -------------"), nl,(" | "), scan_x_o(X4),
write(" | "), scan_x_o(X5), write(" | "), scan_x_o(X6),
write(" |"), nl,(" -------------"), nl,(" | "),
scan_x_o(X7), write(" | "), scan_x_o(X8), write(" | "),
scan_x_o(X9), write(" |"), nl,(" -------------"), nl,
nl._move(First, 1, 1):- scan_move(1,Pusto),
Pusto<1,!,global_field(X1,X2,X3,X4,X5,X6,X7,X8,X9),
edit_global_field(First,X2,X3,X4,X5,X6,X7,X8,X9),
draw_field(First,X2,X3,X4,X5,X6,X7,X8,X9),!._move(First, 2, 1):-
scan_move(2,Pusto), Pusto<1,!,global_field(X1,X2,X3,X4,X5,X6,X7,X8,X9), edit_global_field(X1,First,X3,X4,X5,X6,X7,X8,X9),
draw_field(X1,First,X3,X4,X5,X6,X7,X8,X9),!._move(First, 3, 1):-
scan_move(3,Pusto), Pusto<1,!,global_field(X1,X2,X3,X4,X5,X6,X7,X8,X9),
edit_global_field(X1,X2,First,X4,X5,X6,X7,X8,X9), draw_field(X1,X2,First,X4,X5,X6,X7,X8,X9),!._move(First,
4, 1):- scan_move(4,Pusto),
Pusto<1,!,global_field(X1,X2,X3,X4,X5,X6,X7,X8,X9),
edit_global_field(X1,X2,X3,First,X5,X6,X7,X8,X9),
draw_field(X1,X2,X3,First,X5,X6,X7,X8,X9),!._move(First, 5, 1):-
scan_move(5,Pusto), Pusto<1,!,global_field(X1,X2,X3,X4,X5,X6,X7,X8,X9),
edit_global_field(X1,X2,X3,X4,First,X6,X7,X8,X9),
draw_field(X1,X2,X3,X4,First,X6,X7,X8,X9),!._move(First, 6, 1):-
scan_move(6,Pusto), Pusto<1,!,global_field(X1,X2,X3,X4,X5,X6,X7,X8,X9),
edit_global_field(X1,X2,X3,X4,X5,First,X7,X8,X9),
draw_field(X1,X2,X3,X4,X5,First,X7,X8,X9),!._move(First, 7, 1):-
scan_move(7,Pusto), Pusto<1,!,global_field(X1,X2,X3,X4,X5,X6,X7,X8,X9),
edit_global_field(X1,X2,X3,X4,X5,X6,First,X8,X9),
draw_field(X1,X2,X3,X4,X5,X6,First,X8,X9),!._move(First, 8, 1):-
scan_move(8,Pusto), Pusto<1,!,global_field(X1,X2,X3,X4,X5,X6,X7,X8,X9),
edit_global_field(X1,X2,X3,X4,X5,X6,X7,First,X9),
draw_field(X1,X2,X3,X4,X5,X6,X7,First,X9),!._move(First, 9, 1):-
scan_move(9,Pusto), Pusto<1,!,global_field(X1,X2,X3,X4,X5,X6,X7,X8,X9),
edit_global_field(X1,X2,X3,X4,X5,X6,X7,X8,First),
draw_field(X1,X2,X3,X4,X5,X6,X7,X8,First),!._move(_,_,0):-
!._end_game(9):-edit_global_game_end(1)._end_game(_).(1):-_game_end(Endgame),
Endgame=0,!,("Your step (1-9): "), readint(Xod),_move(1, Xod,
XodEst), XodEst>0,_win(Find_win), Find_win<1 ,!,_field(End),
scan_end_game(End),(2).(1):- global_game_end(End), End=0,!,
game(1).(2):-_game_end(Endgame), Endgame=0,!,_move(Xod),
%write("Computer's lead:
",Xod), nl, readchar(QWERTY),_move(2, Xod, XodEst),
XodEst>0,_win(Find_win), Find_win<1 ,!,_field(End),
scan_end_game(End),(1).(2):- global_game_end(End), End=0,!,
game(2).(_):-!.(1):- draw_field(0,0,0,0,0,0,0,0,0),("> Your step is the
first!"), nl, nl,(1),menu.(2):- draw_field(0,0,0,0,0,0,0,0,0),(">
Your step is the second"), readchar(JKHBVJD), nl, nl,(2),menu.(_):-
clearwindow, write(">! Incorrect input ! Please try again."), nl,
nl, who_first()._first():-("The first step?"), nl,nl,("1. You's"),
nl,("2. Computer's"), nl,("=>"), readint(Select),
nl,(Select)._score():-_score(You,Comp),(" You: "), write(You),
nl,(" Computer: "), write(Comp)._move(1):-
global_field(X1,X2,X3,X4,X5,X6,X7,X8,X9),
X2<>0,X3<>0,X4<>0,X5<>0,X6<>0,X7<>0,X8<>0,X9<>0,!._move(2):-
global_field(X1,X2,X3,X4,X5,X6,X7,X8,X9),
X1<>0,X3<>0,X4<>0,X5<>0,X6<>0,X7<>0,X8<>0,X9<>0,!._move(3):-
global_field(X1,X2,X3,X4,X5,X6,X7,X8,X9),
X1<>0,X2<>0,X4<>0,X5<>0,X6<>0,X7<>0,X8<>0,X9<>0,!._move(4):-
global_field(X1,X2,X3,X4,X5,X6,X7,X8,X9),
X1<>0,X2<>0,X3<>0,X5<>0,X6<>0,X7<>0,X8<>0,X9<>0,!._move(5):-
global_field(X1,X2,X3,X4,X5,X6,X7,X8,X9),
X1<>0,X2<>0,X3<>0,X4<>0,X6<>0,X7<>0,X8<>0,X9<>0,!._move(6):-
global_field(X1,X2,X3,X4,X5,X6,X7,X8,X9), X1<>0,X2<>0,X3<>0,X4<>0,X5<>0,X7<>0,X8<>0,X9<>0,!._move(7):-
global_field(X1,X2,X3,X4,X5,X6,X7,X8,X9),
X1<>0,X2<>0,X3<>0,X4<>0,X5<>0,X6<>0,X8<>0,X9<>0,!._move(8):-
global_field(X1,X2,X3,X4,X5,X6,X7,X8,X9),
X1<>0,X2<>0,X3<>0,X4<>0,X5<>0,X6<>0,X7<>0,X9<>0,!._move(9):-
global_field(X1,X2,X3,X4,X5,X6,X7,X8,X9),
X1<>0,X2<>0,X3<>0,X4<>0,X5<>0,X6<>0,X7<>0,X8<>0,!.
%_move(3):-
global_field(X1,X2,X3,X4,X5,X6,X7,X8,X9), X1<>0,X1=X2,X3=0,!._move(6):-
global_field(X1,X2,X3,X4,X5,X6,X7,X8,X9), X4<>0,X4=X5,X6=0,!._move(9):-
global_field(X1,X2,X3,X4,X5,X6,X7,X8,X9), X7<>0,X7=X8,X9=0,!._move(1):-
global_field(X1,X2,X3,X4,X5,X6,X7,X8,X9), X2<>0,X2=X3,X1=0,!._move(4):-
global_field(X1,X2,X3,X4,X5,X6,X7,X8,X9), X5<>0,X5=X6,X4=0,!._move(7):-
global_field(X1,X2,X3,X4,X5,X6,X7,X8,X9), X8<>0,X8=X9,X7=0,!._move(7):-
global_field(X1,X2,X3,X4,X5,X6,X7,X8,X9), X1<>0,X1=X4,X7=0,!._move(8):-
global_field(X1,X2,X3,X4,X5,X6,X7,X8,X9), X2<>0,X2=X5,X8=0,!._move(9):-
global_field(X1,X2,X3,X4,X5,X6,X7,X8,X9), X3<>0,X3=X6,X9=0,!._move(1):-
global_field(X1,X2,X3,X4,X5,X6,X7,X8,X9), X4<>0,X4=X7,X1=0,!._move(2):-
global_field(X1,X2,X3,X4,X5,X6,X7,X8,X9), X5<>0,X5=X8,X2=0,!._move(3):-
global_field(X1,X2,X3,X4,X5,X6,X7,X8,X9), X6<>0,X6=X9,X3=0,!._move(9):-
global_field(X1,X2,X3,X4,X5,X6,X7,X8,X9), X1<>0,X1=X5,X9=0,!._move(1):-
global_field(X1,X2,X3,X4,X5,X6,X7,X8,X9), X5<>0,X5=X9,X1=0,!._move(7):-
global_field(X1,X2,X3,X4,X5,X6,X7,X8,X9), X5<>0,X5=X3,X7=0,!._move(3):-
global_field(X1,X2,X3,X4,X5,X6,X7,X8,X9), X5<>0,X5=X7,X3=0,!._move(2):-
global_field(X1,X2,X3,X4,X5,X6,X7,X8,X9), X1<>0,X1=X3,X2=0,!._move(5):-
global_field(X1,X2,X3,X4,X5,X6,X7,X8,X9), X4<>0,X4=X6,X5=0,!._move(8):-
global_field(X1,X2,X3,X4,X5,X6,X7,X8,X9), X7<>0,X7=X9,X8=0,!._move(4):-
global_field(X1,X2,X3,X4,X5,X6,X7,X8,X9), X1<>0,X1=X7,X4=0,!._move(5):-
global_field(X1,X2,X3,X4,X5,X6,X7,X8,X9), X2<>0,X2=X8,X5=0,!._move(6):- global_field(X1,X2,X3,X4,X5,X6,X7,X8,X9),
X3<>0,X3=X9,X6=0,!._move(5):- global_field(X1,X2,X3,X4,X5,X6,X7,X8,X9),
X1<>0,X1=X9,X5=0,!._move(5):- global_field(X1,X2,X3,X4,X5,X6,X7,X8,X9),
X3<>0,X3=X7,X5=0,!._move(Xod):- random(8,TempXod), Xod=TempXod+1,!.(1):-
clearwindow, write("New
Game"),nl,_global_game_end(0),edit_global_field(0,0,0,0,0,0,0,0,0),,
who_first(), nl, nl.(2):- clearwindow, write("Score"), nl,
show_score(), nl, nl,fail.(0):-!.(_).:-nl,repeat,("Crosses and
zeroes"), nl, nl,("1. New Game"), nl,("2. Score"),
nl,("0. Exit"), nl,("=>"), readint(Choice),(Choice),
Choice=0..:-repeat.
%=============================================================================%(off),,(global_game_end(0),
mydb),(global_field(0,0,0,0,0,0,0,0,0), mydb),(global_score(0,0), mydb),
menu