在SWI Prolog的刽子手游戏 [英] Hangman Game in SWI Prolog

查看:155
本文介绍了在SWI Prolog的刽子手游戏的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图做一个简单的刽子手游戏SWI序言。
因为我们做这个程序运行你能帮我enchance有以下程序:

1)按跟上已经猜到了,到目前为止的字母。如果用户猜测已经猜到了一封信,该方案应该说你猜对了! ,只是继续比赛。

2)最后,添加一个计数器计数不正确猜测的数目和退出比赛的时候达到一定的数量。该计划应该告诉他们失去用户,显示什么这句话真的是和终止。重复猜测应该不能算作是错误的。

我要感谢大家谁帮我至今。这意味着很多给我。

我为你提供code和意见。

 %这一顶级predicate运行游戏。它打印
%欢迎信息,挑选一个短语,并调用getGuess。

%回答=回答
%AnsList = AnswerList

刽子手: - 
    getPhrase(ANS),
    !,
    写(欢迎来到刽子手。),
    NL,
    名字(ANS,AnsList)
    makeBlanks(AnsList,BlankList)
    getGuess(AnsList,BlankList)。

%随机返回的可能性列表中的短语。

getPhrase(ANS): - 
    短语(L)
    长度(L,X)
    R是随机的(X)
    N为R + 1,
    getNth(L,N,ANS)。

%可能短语猜测。

phrases(['a_picture_is_worth_a_thousand_words','one_for_the_money','dead_or_alive','computer_science']).

%要求一个字母猜测用户。开始于写
%目前显示那句用空格,然后请求猜测和
%的呼叫处理的猜测。

getGuess(AnsList,BlankList): - 
    名字(BlankName,BlankList)
    写(BlankName)
    NL,
    写(请输入你的猜测,随后期和回报。)
    NL,
    阅读(猜),
    !,
    名字(猜,[GuessName]),
    processGuess(AnsList,BlankList,GuessName)。

%工艺猜测利用了codeS重新presenting的回答中,codeS重新presenting当前列表清单
%显示的短语在它的空白,而这仅仅是猜测信的code。如果猜测
%是正确的,叫替身把信在显示短语,并检查了胜利。否则,只
%从用户那里得到另一种猜测。

processGuess(AnsList,BlankList,GuessName): - 
    成员(GuessName,AnsList)
    !,
    写(正确!)
    NL,
    替补(AnsList,BlankList,GuessName,NewBlanks)
    checkWin(AnsList,NewBlanks)。

processGuess(AnsList,BlankList,_): - 
    写(都能跟得上!),
    NL,
    getGuess(AnsList,BlankList)。

%检查,看看是否短语猜测。如果是这样,写上你赢了,如果没有,回去拿另一种猜测。

checkWin(AnsList,BlankList): - 
    名字(ANS,AnsList)
    名字(BlankName,BlankList)
    BlankName =答案,
    !,
    写(你赢了!)。

checkWin(AnsList,BlankList): - 
    !,
    getGuess(AnsList,BlankList)。


%getNth(L,N,E)应该是真实的,当E是列表L n的第N个元素总会
%至少为1。

getNth([H | T],1,H)。

getNth([H | T],N,E): - 
    N1是N-1,
    getNth(T,N1,E1),
    E = E1。

%makeBlanks(AnsList,BlankList)应该采取的答案短语,这是一个列表
%字符codeS的重新present答案词组,并返回一个列表
%,所有codeS,但'_'变成了code为'*'。下划线
%需要保持以显示其中的字的开始和结束。请注意
%这个predicate输入和输出列表是字符codeS名单。
%可以使用这样的查询测试code:
%testMakeBlanks: - 名(csc_is_awesome,列表),makeBlanks(列表,BlankList),名(Towrite,BlankList),写(Towrite)。

makeBlanks(ANS codeS,空白codeS): - 
  MAPLIST(answer_blank,答案codeS,空白codeS)。

answer_blank(ANS,空白): - 
  答== 0'_  - >空白=答;空白= 0'*。

%代用品(AnsList,BlankList,GuessName,NewBlanks)获取字符code列出AnsList和BlankList,
%和GuessName,这是字符code的猜测字母。该NewBlanks应该再是一个
%字符code清单,将所有的猜测到显示字,并保持*的和_的其他方式。
%例如,如果答案是csc_is_awesome'和显示是'C * C _ ** _ *******'和猜测是的,则
%新的显示应该是csc_ * S _ ***县***。
%可以使用这样的查询测试predicate:
%testSubstitute: - 名(csc_is_awesome',AnsList),名('C * C _ ** _ *******,BlankList),名(S,[GuessName]),替代品(AnsList,BlankList ,GuessName,NewBlanks)
%名称(Towrite,NewBlanks),写(Towrite)。

%此外,由于predicate不直接与字符codeS处理,这也应该工作:
%替代(['C','S','C'],['C','*','C'],'S',L)。 L时,应['C','S','C']。

替补(ANS codeS,空白codeS,GuessName,NewBlanks): - 
     MAPLIST(place_guess(GuessName),答案codeS,空白codeS,NewBlanks)。

place_guess(猜,答案,空白,显示): - 
    猜猜==答案 - >显示=答;显示=空白。
 

解决方案

<一个href="http://www.swi-prolog.org/pldoc/doc_for?object=section%282,%27A.2%27,swi%28%27/doc/Manual/apply.html%27%29%29"相对=nofollow> MAPLIST / 3及MAPLIST / 4运用他们的第一个参数(适当的元数一predicate)对其他参数列表中的所有元素,那么你的makeBlanks可能是:

  makeBlanks(ANS codeS,空白codeS): - 
  MAPLIST(answer_blank,答案codeS,空白codeS)。

answer_blank(ANS,空白): - 
  答== 0'_  - &GT;空白=答;空白= 0'*。
 

和替代:

 替代(ANS codeS,空白codeS,GuessName,NewBlanks): - 
     MAPLIST(place_guess(GuessName),答案codeS,空白codeS,NewBlanks)。

place_guess(猜,答案,空白,显示): - 
    猜猜==答案 - &GT;显示=答;显示=空白。
 

修改

在其他要求:1)可与附加的predicate来解决:

  alreadyGuessed(猜,答案codeS): - 
   memberchk(猜,答案codeS)。
 

而关于2) getGuess processGuess 共同构成一个循环,这将只是终止的时候没有更多的要求发生。删除checkWin的最后一个规则,添加一个参数作为计数器,以失败猜测的轨道,并延伸processGuess信号故障:

  processGuess(AnsList,BlankList,_,CountFailed): - 
  (CountFailed == 5
   - &GT;格式('对不起,比赛结束了。你没\'吨猜(〜S)〜N',[AnsList])
  ;写(都能跟得上!),
      CountFailed1被CountFailed + 1,
      getGuess(AnsList,BlankList,CountFailed1)
  )。
 

I'm trying to make a simple hangman game in SWI Prolog.
Since we made this program run can you help me enchance the program with the following:

1) By keeping up with the letters that have been guessed so far. If the user guesses a letter that has already been guessed, the program should say 'You guessed that!' and just continue the game.

2) Lastly, add a counter that counts the number of incorrect guesses and quits the game when a certain number is reached. The program should tell the user that they lose, display what the phrase really was, and terminate. Duplicate guesses should not be counted as wrong.

I would like to thank everyone who helped me so far. This means a lot to me.

I provide you with the code and comments.

% This top-level predicate runs the game.  It prints a 
% welcome message, picks a phrase, and calls getGuess.

% Ans = Answer
% AnsList = AnswerList

hangman:- 
    getPhrase(Ans), 
    !, 
    write('Welcome to hangman.'),
    nl,
    name(Ans,AnsList), 
    makeBlanks(AnsList, BlankList), 
    getGuess(AnsList,BlankList).

% Randomly returns a phrase from the list of possibilities.

getPhrase(Ans):-
    phrases(L), 
    length(L, X), 
    R is random(X), 
    N is R+1, 
    getNth(L, N, Ans).

% Possible phrases to guess.

phrases(['a_picture_is_worth_a_thousand_words','one_for_the_money','dead_or_alive','computer_science']).

% Asks the user for a letter guess.  Starts by writing the 
% current "display phrase" with blanks, then asks for a guess and
% calls process on the guess.

getGuess(AnsList, BlankList):- 
    name(BlankName, BlankList), 
    write(BlankName), 
    nl,  
    write('Enter your guess, followed by a period and return.'), 
    nl, 
    read(Guess),
    !, 
    name(Guess, [GuessName]), 
    processGuess(AnsList,BlankList,GuessName).

% Process guess takes a list of codes representing the answer, a list of codes representing the current
% "display phrase" with blanks in it, and the code of the letter that was just guessed.  If the guess
% was right, call substitute to put the letter in the display phrase and check for a win.  Otherwise, just
% get another guess from the user.

processGuess(AnsList,BlankList,GuessName):- 
    member(GuessName,AnsList), 
    !,
    write('Correct!'),
    nl, 
    substitute(AnsList, BlankList, GuessName, NewBlanks), 
    checkWin(AnsList,NewBlanks).

processGuess(AnsList, BlankList,_):-
    write('Nope!'),
    nl,
    getGuess(AnsList, BlankList).

% Check to see if the phrase is guessed.  If so, write 'You win' and if not, go back and get another guess.

checkWin(AnsList, BlankList):- 
    name(Ans, AnsList), 
    name(BlankName, BlankList), 
    BlankName = Ans, 
    !, 
    write('You win!').

checkWin(AnsList, BlankList):- 
    !,
    getGuess(AnsList, BlankList).


% getNth(L,N,E) should be true when E is the Nth element of the list L. N will always
% be at least 1.

getNth([H|T],1,H).

getNth([H|T],N,E):-
    N1 is N-1,
    getNth(T,N1,E1),
    E=E1.

% makeBlanks(AnsList, BlankList) should take an answer phrase, which is a list
% of character codes that represent the answer phrase, and return a list
% where all codes but the '_' turn into the code for '*'.  The underscores
% need to remain to show where the words start and end.  Please note that 
% both input and output lists for this predicate are lists of character codes.
% You can test your code with a query like this:
% testMakeBlanks:- name('csc_is_awesome', List), makeBlanks(List, BlankList), name(Towrite, BlankList), write(Towrite). 

makeBlanks(AnsCodes, BlankCodes) :-
  maplist(answer_blank, AnsCodes, BlankCodes).

answer_blank(Ans, Blank) :-
  Ans == 0'_ -> Blank = Ans ; Blank = 0'* .

% substitute(AnsList, BlankList, GuessName, NewBlanks) Takes character code lists AnsList and BlankList, 
% and GuessName, which is the character code for the guessed letter.  The NewBlanks should again be a 
% character code list, which puts all the guesses into the display word and keeps the *'s and _'s otherwise.
% For example, if the answer is 'csc_is_awesome' and the display is 'c*c_**_*******' and the guess is 's', the 
% new display should be 'csc_*s_***s***'.
% You can test your predicate with a query like this:
% testSubstitute:- name('csc_is_awesome', AnsList), name('c*c_**_*******', BlankList), name('s',[GuessName]), substitute(AnsList, BlankList, GuessName, NewBlanks),
%    name(Towrite, NewBlanks), write(Towrite). 

% Also, since the predicate doesn't deal directly with character codes, this should also work:
% substitute(['c','s','c'],['c','*','c'],'s',L).  L should be ['c','s','c'].

substitute(AnsCodes, BlankCodes, GuessName, NewBlanks) :-
     maplist(place_guess(GuessName), AnsCodes, BlankCodes, NewBlanks).

place_guess(Guess, Ans, Blank, Display) :-
    Guess == Ans -> Display = Ans ; Display = Blank.

解决方案

maplist/3 & maplist/4 apply their first argument (a predicate of appropriate arity) against all elements of other arguments lists, then your makeBlanks could be:

makeBlanks(AnsCodes, BlankCodes) :-
  maplist(answer_blank, AnsCodes, BlankCodes).

answer_blank(Ans, Blank) :-
  Ans == 0'_ -> Blank = Ans ; Blank = 0'* .

and substitute:

substitute(AnsCodes, BlankCodes, GuessName, NewBlanks) :-
     maplist(place_guess(GuessName), AnsCodes, BlankCodes, NewBlanks).

place_guess(Guess, Ans, Blank, Display) :-
    Guess == Ans -> Display = Ans ; Display = Blank.

edit:

on additional requests: 1) can be solved with an additional predicate:

alreadyGuessed(Guess, AnsCodes) :-
   memberchk(Guess, AnsCodes).

while regards 2) getGuess and processGuess together make a loop, that will just terminate when no more calls happen. Remove the last rule of checkWin, add an argument as counter to keep track of failed guesses, and extend processGuess to signal failure:

processGuess(AnsList, BlankList, _, CountFailed) :-
  (   CountFailed == 5
  ->  format('Sorry, game over. You didn\'t guess (~s)~n', [AnsList])
  ;   write('Nope!'),
      CountFailed1 is CountFailed + 1,
      getGuess(AnsList, BlankList, CountFailed1)
  ).

这篇关于在SWI Prolog的刽子手游戏的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆