Jeu de mots pendu golf

14

Inspiré par reddit .

Écrivez un programme qui joue le pendu .

  • Le programme choisit un mot au hasard dans une liste de N mots, où N> 2.
  • La liste de mots peut être fournie au programme comme vous le souhaitez.
  • À chaque itération

    • Imprimez l'état du jeu en utilisant des traits de soulignement pour les lettres non encore découvertes:

    H _ N _ _ _ N

    • Imprimer le nombre de tentatives restantes

    10

    • Lisez une lettre de stdin et mettez à jour l'état du jeu en soustrayant une tentative s'ils devinent une lettre incorrecte.

    A (contribution)

    H A N _ _ A N

    10

    • Répétez jusqu'à ce que toutes les lettres soient devinées ou que les tentatives atteignent 0
  • Utilisez n'importe quelle langue
  • Le moins de personnages gagne.
  • Il n'est pas nécessaire de tirer la potence, mais cela vous rapportera des votes positifs et des félicitations.
drspod
la source
Puis-je laisser chaque mot de la liste avoir le même nombre de caractères?
Peter Olson
Les lettres dans la sortie doivent-elles être séparées par des espaces?
Lowjacker
@Peter Of The Corn: vous devez supposer que la liste de mots est arbitraire
drspod
@Lowjacker: les espaces améliorent la lisibilité des traits de soulignement consécutifs, sinon il est difficile de compter le nombre de lettres qu'ils représentent.
drspod

Réponses:

6

Ruby 1,9, 134 132 120 117 108 107

Liste de mots fournie dans ARGV. Les mots et les lettres saisies doivent correspondre au cas où.

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
la source
8

Darn, je pensais qu'il disait "le moins de victoires de lignes". Je ne vais pas gagner de concours avec le moins de personnages ici, mais ce programme Common Lisp n'est qu'une ligne.

(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))))
Michael Dickens
la source
1
Je vote pour vous parce que je suis à peu près sûr que vous êtes intentionnellement humoristique :-)
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

Je préfère cependant celui-ci: plus long mais plus agréable.

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
la source
Si je n'avais pas à imprimer aaussi, je pourrais utiliser *deux fois:print(*("_"if x in L else x for x in w))
badp
4

c ++ (-en-têtes)

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

chat / usr / dict / mots | bourreau xargs

user324234sdf
la source
L'invite ">" pour la saisie n'est pas nécessaire pour la solution, je viens de l'ajouter dans la question pour indiquer qu'elle a été saisie, car de nombreuses langues fournissent une invite comme celle-ci.
drspod
@drspod Vous devez alors modifier la question pour refléter cela, alors.
Lowjacker
modifié pour clarifier
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

Je n'ai pas vraiment essayé le moins de personnages, je voulais juste le rendre aussi petit que possible sans rien sacrifier.

Sergey G
la source
@user: Vous pourriez être intéressé par le merveilleux script utilisateur de George Edison pour ce site qui met votre code (tel que copié ici par badp) à 1225 caractères.
dmckee --- chaton ex-modérateur
Je pense que c'est parce que j'utilisais des tabulations et elles ont été converties en espaces ici. wc dit que c'est 1034 avec des onglets.
Sergey G
@user: Oui. Une difficulté bien connue avec les soumissions python.
dmckee --- chaton ex-modérateur
2

Perl, 112 car. Je sens que je peux faire mieux - je vais peut-être réessayer plus tard

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

Les mots sont donnés sur la ligne de commande, les lettres tapées en majuscules


la source
$_=$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
Vous pouvez simplement modifier votre réponse d'origine.
Lowjacker
1
Cela n'affiche pas le nombre de tentatives restantes.
Lowjacker
2

Clojure

C'est 400 octets gzippés, ce qui est encore beaucoup, probablement à cause de la façon dont Clojure gère l'état mutable.

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

liste de mots comme argument

mat
la source
1

VB.NET


Je n'ai pas encore essayé de le rétrécir, mais:
Premier rétrécissement:
Deuxième rétrécissement (3759 caractères):

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
Ry-
la source
Toute l'indentation est-elle vraiment requise?
Lowjacker
ça facilite la lecture, non?
Nate Koppenhaver
Comme en blocs? Non, ce n'est pas obligatoire, mais je ne compte pas comme des caractères.
Ry-
0

Powershell, 125 octets

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

Script de test moins golfé:

$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

Exemple de sortie lorsque le joueur devinant a perdu :

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

Exemple de sortie lorsque le joueur devinant a gagné :

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