Палач игры в гольф

14

Вдохновленный Reddit .

Напишите программу, в которую играет Hangman .

  • Программа выбирает случайное слово из списка из N слов, где N> 2.
  • Список слов может быть предоставлен программе любым способом, который вы выберете.
  • На каждой итерации

    • Распечатайте состояние игры, используя подчеркивание для букв, которые еще не обнаружены:

    H _ N _ _ _ N

    • Распечатать количество оставшихся попыток

    10

    • Прочитайте письмо от stdin и обновите состояние игры, вычитая попытку, если они угадывают неправильную букву.

    A (Вход)

    H A N _ _ A N

    10

    • Повторяйте до тех пор, пока все буквы не будут угаданы или попытки не достигнут 0
  • Используйте любой язык
  • Наименьшее количество символов выигрывает.
  • Рисовать виселицу не обязательно, но вы будете зарабатывать голоса и почести.
drspod
источник
Можно ли разрешить каждому слову в списке одинаковое количество символов?
Питер Олсон
Должны ли буквы в выводе быть разделены пробелами?
Лоуджекер,
@Peter Of The Corn: вы должны предположить, что список слов является произвольным
drspod
@Lowjacker: пробелы улучшают четкость последовательных подчеркиваний, в противном случае трудно посчитать, сколько букв они представляют.
drspod

Ответы:

6

Рубин 1.9, 134 132 120 117 108 107

Список слов в ARGV. Слова и введенные буквы должны совпадать в случае.

r=w=$*.sample
t=10
loop{puts [*w.tr(r,?_).chars]*' ',t
t>0&&r>''?w[l=STDIN.gets[0]]?r=r.tr(l,''):t-=1:exit}
Lowjacker
источник
8

Черт возьми, я думал, что сказано "выиграл наименьшее количество линий". Я не собираюсь выигрывать конкурсы с наименьшим количеством персонажей, но эта программа Common Lisp занимает всего одну строчку.

(let ((words (list "that" "help" "rent" "chair" "octopus" "monitor" "manual" "speakers" "onomatopoeia" "regardless" "irresponsible" "cornerstone"))) (let ((word (nth (random (length words)) words))) (format t "~a~%" (funcall (defun play (word current remaining-attempts) (progn (if (not (find #\_ current)) (return-from play "You win!")) (if (equalp remaining-attempts 0) (return-from play "You lose!")) (format t "~a~%~d~%" current remaining-attempts) (let ((guess (char (read-line) 0)) (index 0) (found nil)) (loop for letter across word do (if (equalp guess letter) (progn (setf (char current index) letter) (setf found t))) (setf   index (+ index 1))) (if found (play word current remaining-attempts) (play word current (- remaining-attempts 1)))))) word (map 'string #'(lambda (c) #\_) word) 10))))
Майкл Диккенс
источник
1
Я голосую за тебя, потому что я уверен, что ты намеренно шутишь :-)
Доктор Пейн,
8

Python 3

from random,sys import *
w=choice(*argv)
L=set(w)
a=10
while L and a:
 print(" ".join("_"if x in L else x for x in w),a)
 try:L-=set(input()[0])
 except:a-=1

Я предпочитаю этот, хотя: дольше, но приятнее.

import random
w=random.choice(list(open("/usr/dict/words")))[:-1]
L=set(w)
a=10
while L and a:
 print(" ".join("_"if x in L else x for x in w),a)
 try:L.remove(input()[0])
 except:a-=1
print w
badp
источник
Если бы мне не пришлось печатать aтак же, я мог бы использовать *дважды:print(*("_"if x in L else x for x in w))
badp
4

c ++ (-headers)

struct h{h(char a):b(a){}char operator()(char c,char d){return d!='_'?d:c==b?c:'_';}char b;};

int main(int a,char**b){
srand(time(0));string c=*(b+rand()%(a-1)+1),d(c.size(),'_'),e;
char f=10,g;
while(f){
cout<<"> ";cin>>g;e=d;
transform(c.begin(),c.end(),d.begin(),d.begin(),h(g));if(e==d)--f;
cout<<d<<endl<<(int)f<<endl;if(d==c)break;
}return 0;}

кот / usr / dict / words | Xargs Палач

user324234sdf
источник
Запрос «>» для ввода не является обязательным для решения, я просто добавил его в вопрос, чтобы указать, что он был введен, так как многие языки предоставляют запрос, такой как этот.
drspod
@drspod Вы должны отредактировать вопрос, чтобы отразить это.
Лоуджекер,
отредактировано, чтобы уточнить
drspod
2

питон

import random

DEFAULT_ATTEMPTS = 10

def print_word(word, uncovered):
    for c in word:
        if c not in uncovered:
            c = '_'
        print c,
    print ''

def get_letter():
    letter = None
    while letter is None:
        letter = raw_input('> ')
        if len(letter) != 1:
            print 'Letters must be 1 character.  Try again.'
            letter = None
    return letter

if __name__ == '__main__':
    import sys

    if len(sys.argv) != 2: sys.exit(1)
    with open(sys.argv[1], 'r') as f:
        words = [word.strip() for word in f.readlines() if word.strip()]

    word = random.choice(words)
    uncovered = set([' '])
    attempts = DEFAULT_ATTEMPTS

    while attempts > 0 and any(letter not in uncovered for letter in word):
        print_word(word, uncovered)
        print attempts

        letter = get_letter()
        if letter in uncovered:
            print 'You have already tried that letter.'
        elif letter in word:
            print 'You got it!'
        else:
            print 'Wrong!'
            attempts -= 1

        uncovered.add(letter)

    if attempts == 0:
        print 'You lose!',
    else:
        print 'You win!'
    print 'The phrase was "%s".' % word

Я действительно не пытался найти наименьшее количество персонажей, просто хотел сделать его как можно меньше, не жертвуя ничем.

Сергей Г
источник
@user: Вас может заинтересовать замечательный пользовательский скрипт Джорджа Эдисона для этого сайта, который помещает ваш код (скопированный здесь badp) в 1225 символов.
dmckee --- котенок экс-модератора
Я думаю, что это потому, что я использовал вкладки, и они были преобразованы в пробелы здесь. WC говорит, что это 1034 с вкладками.
Сергей Г
@user: Да. Хорошо известная трудность с питона представлений.
dmckee --- котенок экс-модератора
2

Perl 112 симв. Я чувствую, что могу сделать лучше - возможно, я попробую позже

$_=$ARGV[rand@ARGV];$a=10;while($a&&/[a-z]/){print map/[A-Z]/?$_:'_',split'';$x=<STDIN>;chop$x;s/$x/$x/ig||$a--}

Слова даются в командной строке, буквы набираются заглавными буквами


источник
До 107 $_=$ARGV[rand@ARGV];$a=10;while($a&&/[a-z]/){$y=$_;$y=~y/a-z/_/;print$y;$x=<STDIN>;chop$x;s/$x/$x/ig||$a--}
3
Вы можете просто отредактировать свой оригинальный ответ.
Лоуджекер,
1
Это не отображает количество оставшихся попыток.
Лоуджекер,
2

Clojure

Это 400 байтов в сжатом виде, что довольно много, вероятно, из-за того, как Clojure обрабатывает изменяемое состояние.

(def m ["will" "work" "for" "food"])
(def w (nth m (rand-int (count m))))
(def *s* (atom (replicate (count w) "_")))
(def *a* (atom 10))

(defn g [s a]
  (str (apply str (interpose " " s)) "\n" a))

(loop [n (read-line)]
  (if (some (set n) w)
    (swap! *s* (fn [s]
                 (map 
                   (fn [i]
                     (if (= n (str (nth w i)))
                       n
                       (nth s i)))
                   (range 0 (count s)))))
    (swap! *a* dec))

  (println (g (deref *s*) (deref *a*))) 

  (if (and (< 0 (deref *a*)) (some #{"_"} (deref *s*)))
    (recur (read-line))))
jhuni
источник
2

C # 370

using System;namespace h{class P{static void Main(string[]a){int c=10,d,l;char y=' ';string w=a[new Random().Next(a.Length)];l=w.Length;char[]x=new char[l];for(d=-1;++d<l;x[d]='-');while(c>0){for(d=-1;++d<l;x[d]=(y==w[d]||x[d]!='-')?w[d]:x[d]);Console.WriteLine(new string(x)+" "+c);if(w==new string(x))return;y=Console.ReadKey(true).KeyChar;if(!w.Contains(y+""))c--;}}}

список слов в качестве аргумента

матовый
источник
1

VB.NET


Я еще не пытался уменьшить его, но:
Первое сокращение:
Второе сокращение (3759 символов):

Module Hangman
    Sub Main()
        Dim m As Int32, w = "banana|apple|pear|dog|cat|orange|monkey|programming|hangman".Split("|")(New Random().Next(9)), g = "", e = "", x, c As Char, f As Boolean, r = Sub(z) Console.Write(z), p = Sub(y, h) Console.SetCursorPosition(y, h), a = Sub() Console.Clear(), q = Function() Console.ReadKey(1), d = Sub()
                                                                                                                                                                                                                                                                                                                          r("       +--------+S       |        |S                |S                |S                |S                |S                |S                |S                |S                |S                |S                |S                |S                |S                |S                |S                |S                |S                |S                |S                |S                |S                |S   ---------------------".Replace("S", vbCrLf))
                                                                                                                                                                                                                                                                                                                          p(0, 2)
                                                                                                                                                                                                                                                                                                                          r(String.Join(vbCrLf, "    /------\S    | O   O|S    \  ... /S     ------ S        |   S        |   S        |   S        |   S -------+-------S        |   S        |   S        |   S       / \  S      /   \  S     /     \  S    /       \  ".Split("S").Take(m * 4)))
                                                                                                                                                                                                                                                                                                                      End Sub
        Console.CursorVisible = 0
        Do
            a()
            d()
            p(30, 10)
            f = 0
            For Each x In w
                If g.Contains(x) Then
                    r(x)
                Else
                    r(" ")
                    f = 1
                End If
                Console.CursorTop += 1
                Console.CursorLeft -= 1
                r("_")
                Console.CursorTop -= 1
                r(" ")
            Next
            If Not f Then
                a()
                d()
                p(30, 10)
                r("You win! Press any key to close.")
                q()
                End
            End If
            p(30, 13)
            r(e)
            Do
                c = q().KeyChar
            Loop Until Char.IsLetter(c)
            If g.Contains(c) Then
                e = "You have already guessed that letter."
            Else
                g &= c
                If w.Contains(c) Then
                    e = "There is a" & If("aehilmnorsx".Contains(c), "n", "") & " """ & c & """ in the word."
                Else
                    e = "There is no """ & c & """ in the word. Try again."
                    m += 1
                End If
            End If
        Loop Until m = 4
        a()
        d()
        p(30, 10)
        r("You lose! Press any key to close.")
        q()
    End Sub
End Module
Рыбаковым
источник
Все ли отступы действительно необходимы?
Lowjacker
это облегчает чтение, не так ли?
Нейт Коппенхавер
Как в блоках? Нет, это не обязательно, но я не считаю это персонажами.
Ry-
0

Powershell, 125 байт

$w=$h=$args|random|% t*y
for($n=10){$w-replace"[ $h]",'_'-join' ';$n
if(!$h+!$n){break}$n-=($c=Read-Host)-notin$h
$h=$h-ne$c}

Менее гольф тестовый скрипт:

$f = {

$word=$hidden=$args|random|% toCharArray    # let $word and $hidden are a random word chars
#$word                                      # uncomment this to cheating
for($n=10){                                 # forever for with init section
    $word-replace"[ $hidden]",'_'-join' '   # display the word with hidden letters
    $n                                      # display $n
    if(!$hidden+!$n){break}                 # break loop if hidden array is empty or n equal to 0
    $n-=($c=Read-Host)-notin$hidden         # input $c from user, decrease $n if $c does not in $hidden array
    $hidden=$hidden-ne$c                    # recreate $hidden array with removed $c
}

}

$words = gc .\wordlist.txt
&$f $words

Пример вывода, когда угадающий игрок проиграл :

_ _ _ _ _ _ _ _
10
i
_ _ _ _ _ _ _ _
9
e
_ _ e _ _ _ _ e
9
o
o _ e _ _ o _ e
9
a
o _ e _ _ o _ e
8
q
o _ e _ _ o _ e
7
q
o _ e _ _ o _ e
6
q
o _ e _ _ o _ e
5
q
o _ e _ _ o _ e
4
q
o _ e _ _ o _ e
3
q
o _ e _ _ o _ e
2
q
o _ e _ _ o _ e
1
q
o _ e _ _ o _ e
0

Пример вывода, когда угадающий игрок выиграл :

_ _ _ _ _ _ _ _ _ _
10
e
_ _ _ _ e _ _ _ _ _
10
o
_ o _ _ e _ _ _ _ _
10
i
_ o _ _ e _ _ i _ _
10
a
_ o _ _ e _ _ i a _
10
l
_ o _ _ e _ _ i a l
10
c
c o _ _ e _ c i a l
10
m
c o m m e _ c i a l
10
t
c o m m e _ c i a l
9
r
c o m m e r c i a l
9
Mazzy
источник