Gra słowna golfa


14

Zainspirowany przez reddit .

Napisz program, który gra Hangman .

  • Program wybiera losowe słowo z listy N słów, gdzie N> 2.
  • Lista słów może być dostarczona do programu w dowolny sposób.
  • Przy każdej iteracji

    • Wydrukuj stan gry, używając znaków podkreślenia dla liter, które nie zostały jeszcze odkryte:

    H _ N _ _ _ N

    • Wydrukuj liczbę pozostałych prób

    10

    • Przeczytaj list od standardowego wejścia i zaktualizuj stan gry, odejmując próbę, jeśli zgadną niepoprawną literę.

    A (Wejście)

    H A N _ _ A N

    10

    • Powtarzaj, aż wszystkie litery zostaną odgadnięte lub próby osiągną 0
  • Użyj dowolnego języka
  • Wygrywa najmniejsza liczba postaci.
  • Narysowanie szubienicy nie jest konieczne, ale zapewni ci pochwały i uznanie.

Czy mogę pozwolić, aby każde słowo na liście miało taką samą liczbę znaków?
Peter Olson,

Czy litery na wydruku muszą być oddzielone spacjami?
Lowjacker 23.04.11

@Peter Of The Corn: należy założyć, że lista słowo jest dowolna
drspod

@ Lowowacker: spacje poprawiają czytelność kolejnych znaków podkreślenia, w przeciwnym razie trudno policzyć, ile liter reprezentują.
drspod

Odpowiedzi:


6

Ruby 1.9, 134 132 120 117 108 107

Lista słów podana w ARGV. Słowa i wprowadzone litery muszą pasować do wielkości liter.

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}

8

Cholera, myślałem, że jest napisane „wygrywa najmniej linii”. Nie zamierzam tutaj wygrywać konkursów na najmniej znaków, ale ten program Common Lisp to tylko jedna linia.

(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
Głosuję za tobą, ponieważ jestem całkiem pewien, że celowo masz poczucie humoru :-)
Dr. Pain

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

Wolę jednak ten: dłuższy, ale ładniejszy.

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

Gdybym również nie musiał drukować a, mógłbym użyć *dwa razy:print(*("_"if x in L else x for x in w))
badp

4

c ++ (nagłówki)

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;}

cat / usr / dict / words | xargs kata


Pytanie „>” o podanie danych wejściowych nie jest konieczne dla rozwiązania, właśnie dodałem je w pytaniu, aby wskazać, że dane wejściowe zostały wprowadzone, ponieważ wiele języków udostępnia takie pytania, jak ten.
drspod

@drspod W takim razie należy edytować pytanie, aby to odzwierciedlić.
Lowjacker 23.04.11

edytowane w celu wyjaśnienia
drspod

2

Pyton

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

Tak naprawdę nie starałem się znaleźć najmniejszej liczby postaci, chciałem tylko, aby była jak najmniejsza bez poświęcania czegokolwiek.


@ użytkownik: Możesz być zainteresowany wspaniałym skryptem użytkownika George'a Edisona dla tej witryny, który umieszcza Twój kod (skopiowany tutaj przez badp) na 1225 znaków.
dmckee --- były moderator kociak

Myślę, że to dlatego, że używałem tabulatorów i zostały one tutaj zamienione na spacje. wc mówi, że to 1034 z zakładkami.
Siergiej G

@ użytkownik: Tak. Dobrze znane trudności ze zgłoszeń Pythonie.
dmckee --- były moderator kociak

2

Perl, 112 znaków Czuję, że dam sobie radę - może spróbuję później

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

Słowa są podawane w wierszu poleceń, litery są pisane wielkimi literami


Do 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
Możesz po prostu edytować swoją oryginalną odpowiedź.
Lowjacker 23.04.11

1
Nie wyświetla liczby pozostałych prób.
Lowjacker 23.04.11

2

Clojure

Jest to 400 bajtów zgzipowanych, co wciąż jest całkiem sporo, prawdopodobnie ze względu na to, jak Clojure obsługuje stan zmiennych.

(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))))

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--;}}}

lista słów jako argument


1

VB.NET


Nie próbowałem go jeszcze zmniejszać, ale:
Pierwsze zmniejszanie:
Drugie zmniejszanie (3759 znaków):

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

Czy wszystkie wcięcia są naprawdę wymagane?
Lowjacker 24.04.11

ułatwia czytanie, prawda?
Nate Koppenhaver

Jak w blokach? Nie, nie jest to wymagane, ale nie liczę go jako postaci.
Ry-

0

PowerShell, 125 bajtów

$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}

Skrypt testu mniej golfowego:

$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

Przykład wyjścia, gdy zgadywający gracz przegrał :

_ _ _ _ _ _ _ _
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

Przykład wyjścia, gdy zgadywający gracz wygrał :

_ _ _ _ _ _ _ _ _ _
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
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.