Galgenmännchen-Wortspielgolf


14

Inspiriert von reddit .

Schreiben Sie ein Programm, das Hangman spielt .

  • Das Programm wählt ein zufälliges Wort aus einer Liste von N Wörtern aus, wobei N> 2 ist.
  • Die Wortliste kann dem Programm auf beliebige Weise zur Verfügung gestellt werden.
  • Bei jeder Iteration

    • Drucken Sie den Status des Spiels mit Unterstrichen für noch nicht entdeckte Buchstaben aus:

    H _ N _ _ _ N

    • Gibt die Anzahl der verbleibenden Versuche aus

    10

    • Lies einen Brief von stdin und aktualisiere den Status des Spiels. Subtrahiere einen Versuch, wenn sie einen falschen Buchstaben erraten.

    A (Eingang)

    H A N _ _ A N

    10

    • Wiederholen Sie diesen Vorgang, bis alle Buchstaben erraten wurden oder die Anzahl der Versuche 0 erreicht hat
  • Verwenden Sie eine beliebige Sprache
  • Die wenigste Anzahl von Charakteren gewinnt.
  • Es ist nicht notwendig, den Galgen zu ziehen, aber Sie verdienen sich positive Stimmen und Anerkennung.

Darf jedes Wort in der Liste die gleiche Anzahl von Zeichen haben?
Peter Olson

Müssen die Buchstaben in der Ausgabe durch Leerzeichen getrennt werden?
Lowjacker

@ Peter Of The Corn: Sie sollten annehmen, dass die Wortliste willkürlich ist
drspod

@Lowjacker: Die Leerzeichen verbessern die Lesbarkeit aufeinanderfolgender Unterstriche. Andernfalls ist es schwierig zu zählen, wie viele Buchstaben sie darstellen.
DRSPOD

Antworten:


6

Ruby 1,9, 134 132 120 117 108 107

Wortliste in ARGV. Die Wörter und die eingegebenen Buchstaben müssen in Groß- und Kleinschreibung übereinstimmen.

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

Verdammt, ich dachte, es steht "die geringste Anzahl an Gewinnlinien". Ich werde hier keine Wettbewerbe mit den wenigsten Charakteren gewinnen, aber dieses Common-Lisp-Programm ist nur eine Zeile.

(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
Ich stimme dir zu, weil ich mir ziemlich sicher bin, dass du absichtlich humorvoll bist :-)
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

Ich bevorzuge dieses allerdings: länger, aber schöner.

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

Wenn ich nicht auch drucken a*print(*("_"if x in L else x for x in w))
müsste

4

c ++ (-Header)

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

katze / usr / dikt / wörter | Xargs Henker


Die Eingabeaufforderung ">" ist für die Lösung nicht erforderlich. Ich habe sie nur in der Frage hinzugefügt, um anzuzeigen, dass sie eingegeben wurde, da viele Sprachen eine solche Eingabeaufforderung bereitstellen.
DRSPOD

@drspod Dann sollten Sie die Frage bearbeiten, um dies widerzuspiegeln.
Lowjacker

bearbeitet, um zu klären
drspod

2

Python

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

Ich habe es nicht wirklich mit den wenigsten Charakteren versucht, wollte es nur so klein wie möglich machen, ohne etwas zu opfern.


@user: Möglicherweise interessiert Sie George Edisons wundervolles Benutzerskript für diese Site, das Ihren Code (wie hier von badp kopiert) auf 1225 Zeichen setzt.
dmckee

Ich denke, das liegt daran, dass ich Tabulatoren verwendet habe und diese hier in Leerzeichen umgewandelt wurden. wc sagt, es ist 1034 mit Registerkarten.
Sergey G

@user: Ja. Eine bekannte Schwierigkeit bei Python-Einsendungen.
dmckee

2

Perl, 112 char. Ich habe das Gefühl, dass ich es besser machen kann - vielleicht versuche ich es später noch einmal

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

Wörter werden in der Befehlszeile angegeben, Buchstaben in Großbuchstaben


Runter auf 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
Sie können einfach Ihre ursprüngliche Antwort bearbeiten.
Lowjacker

1
Dies zeigt nicht die Anzahl der verbleibenden Versuche an.
Lowjacker

2

Clojure

Das sind 400 Bytes gzipped, was immer noch ziemlich viel ist, wahrscheinlich weil Clojure mit dem veränderlichen Zustand umgeht.

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

Wortliste als Argument


1

VB.NET


Ich habe es noch nicht ausprobiert, aber:
Erstes Verkleinern:
Zweites Verkleinern (3759 Zeichen):

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

Ist die gesamte Einrückung wirklich erforderlich?
Lowjacker

es macht es leichter zu lesen, nicht wahr?
Nate Koppenhaver

Wie in Blöcken? Nein, es ist nicht erforderlich, aber ich zähle es nicht als Zeichen.
Ry

0

Powershell, 125 Bytes

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

Weniger Golf-Testskript:

$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

Ausgabebeispiel, wenn der erratende Spieler verloren hat :

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

Ausgabebeispiel , wenn das Erraten Spieler gewinnen :

_ _ _ _ _ _ _ _ _ _
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
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.