SWI Prolog中的Hangman游戏

我正在尝试在SWI Prolog中制作一个简单的子手游戏。

既然我们使该程序运行了,那么您可以通过以下方法帮助我增强该程序:

跟上到目前为止已经猜到的字母。如果用户猜到了已经猜到的字母,程序应说“您猜到了!”。然后继续游戏。

最后,添加一个计数器,用于计算错误猜想的数量,并在达到一定数量时退出游戏。该程序应告知用户他们输了,显示该短语的真正含义并终止。重复的猜测不应被认为是错误的。

我为您提供代码和注释。

% 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将其第一个参数(适当Arity的谓词)应用于其他参数列表的所有元素,那么您的makeBlanks可能是:

makeBlanks(AnsCodes, BlankCodes) :-

maplist(answer_blank, AnsCodes, BlankCodes).

answer_blank(Ans, Blank) :-

Ans == 0'_ -> Blank = Ans ; Blank = 0'* .

并替换为:

substitute(AnsCodes, BlankCodes, GuessName, NewBlanks) :-

maplist(place_guess(GuessName), AnsCodes, BlankCodes, NewBlanks).

place_guess(Guess, Ans, Blank, Display) :-

Guess == Ans -> Display = Ans ; Display = Blank.

根据其他要求:1)可以使用其他谓词解决:

alreadyGuessed(Guess, AnsCodes) :-

memberchk(Guess, AnsCodes).

而问候2)getGuessprocessGuess一起构成一个循环,当没有更多呼叫发生时,循环将终止。删除checkWin的最后一条规则,添加一个参数作为计数器来跟踪失败的猜测,并扩展processGuess来指示失败:

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中的Hangman游戏 的全部内容, 来源链接: utcz.com/qa/400103.html

回到顶部