游戏规则hangman在其Wiki 给出。我假设当绞刑架上的人的所有七个部分(头部、颈部、左臂、身体、右臂、左腿、右腿)都被画出时,试图猜测这个词的玩家会输。
辅助方法
画出被吊死的人
首先创建一个可以用来绘制部分或全部刽子手的散列:
MAN = [" O\n", " |\n", "\\", "|", "/\n", " |\n/", " \\"].
map.each_with_object([""]) { |s,arr| arr << (arr.last + s) }.
each.with_index.with_object({}) { |(s,i),h| h[i] = s }
关键是猜错的次数。例如:
puts MAN[2]
O
|
puts MAN[6]
O
|
\|/
|
/
跟踪单词的字母位置
接下来创建一个散列,其键是秘密单词的唯一字母,其值是单词中键位置的索引数组。
def construct_unknown(word)
word.each_char.with_index.with_object({}) { |(c,i),h| (h[c] ||= []) << i }
end
例如,
unknown = construct_unknown("beetle")
#=> {"b"=>[0], "e"=>[1, 2, 5], "t"=>[3], "l"=>[4]}
我们还将为位置已知的字母创建一个空哈希:
known = {}
将猜测的字母从哈希 unknown 移动到哈希 known
如果猜测的字母是unknown 的键,则该键和值将移动到known。
def move_unknown_to_known(letter, unknown, known)
known.update(letter=>unknown[letter])
unknown.delete(letter)
end
例如(对于上面的unknown 和known),
move_unknown_to_known("e", unknown, known)
unknown #=> {"b"=>[0], "t"=>[3], "l"=>[4]}
known #=> {"e"=>[1, 2, 5]}
看看猜的人是赢了还是输了
我们在猜出一个字母后确定玩家何时赢或输,或继续:
def win?(word_size, known)
known.values.flatten.sum == word_size
end
def lose?(wrong_guess_count)
wrong_guess_count == HANGMAN.size
end
例如,
win?(word.size, known)
#=> false
lose?(6) #=> false
lose?(7) #=> true
显示已知字母
def display_known(word_size, known)
known.each_with_object('_' * word_size) { |(k,a),s| a.each { |i| s[i] = k } }
end
例如(召回word #=> "beetle"),
puts display_known(word.size, known)
_ee__e
主要方法
我们现在可以编写 main 方法了。
def hangman
puts "Player 2, please avert your eyes for a moment."
print "Player 1: enter a secret word with at least two letters: "
word = gets.chomp.downcase
unknown = construct_unknown(word)
known = {}
wrong_guess_count = 0
loop do
puts display_known(word.size, known)
puts MAN[wrong_guess_count] if wrong_guess_count > 0
if win?(word.size, known)
puts "You win! You win! Congratulations!"
break
end
if lose?(wrong_guess_count)
puts "Sorry, but you've run out of guesses"
break
end
print "Player 2: enter a letter or your guess of the word: "
guess = gets.chomp.downcase
if guess.size > 1
if guess == word
puts word
puts "You win! You win! Congratulations!"
break
else
puts "Sorry, that's not the word"
wrong_guess_count += 1
end
elsif unknown.key?(guess)
nbr = unknown[guess].size
puts nbr == 1 ? "There is 1 #{guess}" : "There are #{nbr} #{guess}'s"
move_unknown_to_known(guess, unknown, known)
else
puts "Sorry, the word contains no #{guess}'s"
wrong_guess_count += 1
end
end
end
示例
在向两位选手和观众解释了规则后,嘉宾主持人最后说:“别忘了,在猜一个字母或单词时,必须将其表达为一个问题……片刻。 ..持有那个...有人告诉我没有必要将其作为一个问题提出来”。
假设单词是beetle,字母猜测是't'、'i'、'a'、'l'、'r'、's'、't'、'u'、@986 , 'beetle'.
hangman
Player 2, please avert your eyes for a moment.
Player 1: enter a secret word with at least two letters: beetle
______
Player 2: enter a letter or your guess of the word: t
There is 1 t
___t__
Player 2: enter a letter or your guess of the word: i
Sorry, the word contains no i's
___t__
O
Player 2: enter a letter or your guess of the word: a
Sorry, the word contains no a's
___t__
O
|
Player 2: enter a letter or your guess of the word: l
There is 1 l
___tl_
O
|
Player 2: enter a letter or your guess of the word: r
Sorry, the word contains no r's
___tl_
O
|
\
Player 2: enter a letter or your guess of the word: s
Sorry, the word contains no s's
___tl_
O
|
\|
Player 2: enter a letter or your guess of the word: t
Sorry, the word contains no t's
___tl_
O
|
\|/
Player 2: enter a letter or your guess of the word: u
Sorry, the word contains no u's
___tl_
O
|
\|/
|
/
Player 2: enter a letter or your guess of the word: e
There are 3 e's
_eetle
O
|
\|/
|
/
Player 2: enter a letter or your guess of the word: beetle
beetle
You win! You win! Congratulations!