Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Prolog > решить задачу на SWI Prolog с пояснением


Автор: Линус 8.12.2014, 18:43
Добрый вечер) помогите решить задачу на SWI Prolog с пояснением. Напишите программу, играющую в «крестики и нулики» на бесконечной плоскости. Заранее спасибо)

Автор: rrrFer 9.12.2014, 05:40
Здравствуйте. Могу помочь, но что именно у вас не получается?

Автор: Линус 10.12.2014, 19:38
Для меня это новый язык программирования, мне в нем ничего не понятно. Помогите пожалуйста решить(((

Автор: rrrFer 11.12.2014, 14:30
Как вы вообще представляете себе игру?
Ясно что юзер должен ставить крестики и нолики, каким образом он укажет в какую клетку нудно ставить?
В шахматах, например, у клеток есть имена типа "e2", но у вас поле бесконечное.

Вы пишите, что программа должна играть, т.е. вам ИИ нужен. Я не видел нигде нормальных алгоритмов для гомоку (бесконечных крестиков-ноликов), вы нашли хотя бы литературу по теме?

Задача более чем нетривиальна, я не думаю что ее вот так просто кто-то будет решать.

Автор: Линус 12.12.2014, 20:21
database
z(integer,integer,symbol) 
predicates
predicates kartinka 
hod(integer,symbol,symbol) 
blok(symbol,symbol) 
chem(integer,symbol)    
naob(symbol,symbol) 
 
goal 
write("Kto hodit pervym? (1 - chelovek, 0 - kompjuter) "), 
readint(Igrok),write("chem? (1 - krestikami, 0 - nolikami) "), 
readint(N),chem(N,I1),naob(I1,I2),hod(Igrok,I1,I2),!, 
nl,nl; write("Pravila narusheny."),nl. 
 
clauses 
z(1,1,"-"). z(1,2,"-"). z(1,3,"-"). z(2,1,"-"). z(2,2,"-"). 
z(2,3,"-"). z(3,1,"-"). z(3,2,"-"). z(3,3,"-"). 
 
chem(1,x). chem(0,o). naob(x,o). naob(o,x). 
 
hod(0,S,_):- blok(S,S),!,kartinka,write("Kompjuter vyigral!"). 
hod(0,S,C):- blok(S,C),!,kartinka,hod(1,C,S). 
hod(0,S,C):- retract(z(2,2,"-")),!,assert(z(2,2,S)), 
  kartinka,hod(1,C,S). 
hod(0,S,C):- z(R,St,"-"), (R+St) mod 2=0,retract(z(R,St,"-")),!, 
  assert(z(R,St,S)),kartinka,hod(1,C,S). 
hod(0,S,C):- retract(z(R,St,"-")),!,assert(z(R,St,S)), 
  kartinka,hod(1,C,S). 
hod(1,C,S):- z(_,_,"-"),write("Hodi:","ctroka (ot 1 do 3) - "), 
  readint®,R>0,R<4,write("ctolbec (ot 1 do 3) - "), 
  readint(St),St>0,St<4,retract(z(R,St,"-")),!, 
  assert(z(R,St,C)),hod(0,S,C). 
hod(_,_,_):- not(z(_,_,"-")),nl,write("Nichja!"). 
 
blok(S,C):- z(N1,St,C),z(N2,St,C),N1<>N2, 
  retract(z(N3,St,"-")),!,assert(z(N3,St,S)); 
  z(R,N1,C),z(R,N2,C),N1<>N2,retract(z(R,N3,"-")),!, 
  assert(z(R,N3,S)); 
  z(I,I1,C),I=I1,z(J,J1,C),J=J1,I<>J,z(K,K1,"-"),K=K1, 
  retract(z(K,K1,"-")),!,assert(z(K,K1,S)); 
  z(I,J,C),I+J=4,z(N,K,C),N<>I,N+K=4,z(M,L,"-"),M+L=4, 
  retract(z(M,L,"-")),!,assert(z(M,L,S)). 
 
kartinka:- z(1,1,S1),z(1,2,S2),z(1,3,S3),z(2,1,S4),z(2,2,S5), 
  z(2,3,S6),z(3,1,S7),z(3,2,S8),z(3,3,S9),!, 
  write("Hod kompjutera."),nl,nl, 
  write(S1,S2,S3),nl,write(S4,S5,S6),nl,write(S7,S8,S9),nl,nl.
Я нашла код....но  он не работает в SWI пролог

Автор: rrrFer 12.12.2014, 21:05
Я могу поправить вам этот код под SWI prolog, но он не имеет отношения к вашей задаче.
У вас сказано
Цитата

   крестики и нулики» на бесконечной плоскости
   

Но в задаче поле 3 на 3 клетки:
Код

z(1,1,"-"). z(1,2,"-"). z(1,3,"-"). z(2,1,"-"). z(2,2,"-").
z(2,3,"-"). z(3,1,"-"). z(3,2,"-"). z(3,3,"-").

Вот тут задаются начальные значения клеток.
Разница огромная
  1.  для поля 3х3 не нужен никакой интеллект, можно перебрать все решения сразу, а на бесконечном поле перебрать все решения невозможно.
  2.  для поля 3х3 нет проблем адресовать ячейки (у них есть номера - типа [1,1], [3,3], как и у клеток шахматной доски, про которую я писал выше), но на бесконечном поле таких номеров нет или их надо вводить как-то очень хитро (т.е. адресовать видимую часть доски).



Этот ответ добавлен с нового Винграда - http://ru.vingrad.com/reshit-zadachu-na-SWI-Prolog-s-poyasneniyem-id5485c77fae201506528b4567#findElement_E7045_548b2e4fae2015d45b33d26a_0

Автор: Линус 12.12.2014, 23:34
я тогда ничего не понимаю....помогите пожалуйста решить эту задачу, а остальные я сделаю по примеру этой задачи

Автор: rrrFer 13.12.2014, 06:11
Ну а что не получается то?
Вы пробовали сами переписать на SWI Prolog?
Хотя бы начните делать это, а лучше начните писать свой собственный код, т.к. то, что вы скинули писал какой-то негодяй (все запутанно специально).

Предикат z тут описывает клетки поля.

Предикат block выполняет ход компьютера, ну например

Код

blok(S,C):- z(N1,St,C),z(N2,St,C),N1<>N2,
  retract(z(N3,St,"-")),!,assert(z(N3,St,S)); 


Он принимает вражеский символ (С) и ищет я клетки (z), в которых стоит заданный символ, такие что расположены на одной линии (St у клеток совпадает). У клеток не должна совпадать еще и вторая координата (это должны быть различные клетки) - об этом говорит N1<>N2.

Если такая клетка найдена, то игрок может выиграть за один ход, т.к. ситуация примерно такая
Цитата

   xx@
   ___
   ___
   

Вот вместо собаки он поставит туда крестик. соответственно в это место надо влепить нолик.

Код

retract(z(N3,St,"-")), % удаляем предыдущее значение из клетки
!,assert(z(N3,St,S)); % запихиваем на его место наш символ (S).


Разберитесь так с остальным кодом и попробуйте хотя бы переписать сами.


Этот ответ добавлен с нового Винграда - http://ru.vingrad.com/reshit-zadachu-na-SWI-Prolog-s-poyasneniyem-id5485c77fae201506528b4567#findElement_E7045_548bae49ae2015743333dfa2_0

Автор: Линус 18.12.2014, 21:42
Очень срочно нужно решить эту задачу....помогите пожалуйста, люди добрые!!!!

Автор: rrrFer 21.12.2014, 10:39
Прочитайте еще раз первый ответ в этой теме ВНИМАТЕЛЬНО:

Код

Как вы вообще представляете себе игру?
Ясно что юзер должен ставить крестики и нолики, каким образом он укажет в какую клетку нудно ставить?
В шахматах, например, у клеток есть имена типа "e2", но у вас поле бесконечное.

Вы пишите, что программа должна играть, т.е. вам ИИ нужен. Я не видел нигде нормальных алгоритмов для гомоку (бесконечных крестиков-ноликов), вы нашли хотя бы литературу по теме?

Задача более чем нетривиальна, я не думаю что ее вот так просто кто-то будет решать. 


Если вы сами не понимаете что от вас требует препод, то как мы можем вам помочь?

Автор: Фантом 21.12.2014, 16:00
Цитата(rrrFer @  21.12.2014,  11:39 Найти цитируемый пост)

Если вы сами не понимаете что от вас требует препод, то как мы можем вам помочь? 

Судя по тому, что это задание в декабре дали человеку, который совершенно не понимает, как его делать, и за полторы недели сам не сделал ничего, то мы имеем дело со студентом, вконец задолбавшим собственных преподавателей либо идиотизмом, либо безделием (или и тем, и другим сразу), которому подсунули такое задание,  чтобы он гарантированно не смог его откуда-нибудь списать, и его можно было спокойно отчислить. Мне кажется, что нам не следует мешать им в этом полезном занятии. smile 

Автор: Линус 22.12.2014, 20:13
database - db %секция для объявления предикатов базы данных
    доска(SLIST)
predicates %секция для объявления предикатов
    nondeterm линия(ilist) %здесь я не уверен, нужен ли nondeterm, но без него программа не запускается и вылазит 590 ошибка
    вынужденный_ход(integer)
    угроза(ilist,integer)
    пусто(integer)
    крестик(integer)
    нолик(integer) % *1
    arg(slist,integer,string)
clauses %секция для описания фактов и правил
    вынужденный_ход(К):-
        линия(Клетки),
        угроза(Клетки,К),!.
    линия([1,2,3]).
    линия([4,5,6]).
    линия([7,8,9]).
    линия([1,4,7]).
    линия([2,5,8]).
    линия([3,6,9]).
    линия([1,5,9]).
    линия([3,5,7]).
    угроза([X,Y,Z],X):-
        пусто(X),
        крестик(Y),
        крестик(Z),!.
    угроза([X,Y,Z],Y):-
        пусто(Y),
        крестик(X),
        крестик(Z),!.
    угроза([X,Y,Z],Z):-
        пусто(Z),
        крестик(X),
        крестик(Y),!.
    пусто(К):-
        retract(доска(SS)),
        arg(SS,К,С),
        assert(доска(SS)),
        С="-",!. % *2
    крестик(К):-
        retract(доска(SS)),
        arg(SS,К,С),
        asserta(доска(SS)),
        С="X",!. % *2
    нолик(К):-
        retract(доска(SS)),
        arg(SS,К,С),
        asserta(доска(SS)),
        С="O",!. % *2
    arg([H|_],1,H):-!.
    arg([_|T],N,Y):-
    M = N-1,
    arg(T,M,Y).

Автор: rrrFer 23.12.2014, 14:09
Линус
Причем тут твоя задача? у тебя крестики-нолики на неограниченном поле. Это совсем другая игра и другим названием. Она насколько нетривиальна, что годах в 80х по ней чемпионаты в совке проводились. А ты все лепишь крестики-нолики 3х3. 

Ты нас читаешь? - там написаны конкретные вопросы.

Код

nondeterm линия(ilist) %здесь я не уверен, нужен ли nondeterm, но без него программа не запускается и вылазит 590 ошибка


nondeterm нужен, т.к. каждая линия - это отдельное "решение".

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)