Ahorcado wordgame golf

14

Inspirado en reddit .

Escribe un programa que juegue al Ahorcado .

  • El programa elige una palabra aleatoria de una lista de N palabras, donde N> 2.
  • La lista de palabras se puede proporcionar al programa de cualquier forma que elija.
  • En cada iteración

    • Imprima el estado del juego usando guiones bajos para letras aún no descubiertas:

    H _ N _ _ _ N

    • Imprime el número de intentos restantes

    10

    • Lea una carta de stdin y actualice el estado del juego, restando un intento si adivinan una letra incorrecta.

    A (entrada)

    H A N _ _ A N

    10

    • Repita hasta que todas las letras se adivinen o los intentos lleguen a 0
  • Usa cualquier idioma
  • Poca cantidad de personajes gana.
  • Dibujar la horca no es necesario, pero te dará votos positivos y felicitaciones.
drspod
fuente
¿Puedo dejar que cada palabra en la lista tenga el mismo número de caracteres?
Peter Olson el
¿Las letras en la salida tienen que estar separadas por espacios?
Lowjacker
@Peter Del Maiz: se debe asumir que la lista de palabras es arbitrario
drspod
@Lowjacker: los espacios mejoran la legibilidad de los guiones bajos consecutivos, de lo contrario es difícil contar cuántas letras representan.
drspod

Respuestas:

6

Ruby 1.9, 134 132 120 117 108 107

Lista de palabras proporcionada en ARGV. Las palabras y las letras ingresadas deben coincidir en el caso.

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
fuente
8

Maldición, pensé que decía "gana el menor número de líneas". No voy a ganar ningún concurso de personajes menos aquí, pero este programa Common Lisp es solo una línea.

(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
fuente
1
Te estoy votando porque estoy bastante seguro de que estás siendo intencionalmente humorístico :-)
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

Sin embargo, prefiero este: más largo pero más agradable.

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
fuente
Si no tuviera que imprimir atambién, podría usar *dos veces:print(*("_"if x in L else x for x in w))
badp
4

c ++ (encabezados)

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

gato / usr / dict / palabras | ahorcado de xargs

user324234sdf
fuente
La solicitud de entrada ">" no es necesaria para la solución, simplemente la agregué en la pregunta para indicar que se ingresó, ya que muchos idiomas proporcionan una solicitud como esta.
drspod
@drspod Debería editar la pregunta para reflejar eso, entonces.
Lowjacker
editado para aclarar
drspod
2

Pitón

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

Realmente no intenté con la menor cantidad de personajes, solo quería hacerlo lo más pequeño posible sin sacrificar nada.

Sergey G
fuente
@usuario: Puede que le interese el maravilloso script de usuario de George Edison para este sitio que coloca su código (copiado aquí por badp) en 1225 caracteres.
dmckee --- ex-gatito moderador
Creo que es porque estaba usando pestañas y se convirtieron en espacios aquí. WC dice que es 1034 con pestañas.
Sergey G
@usuario: sí. Una dificultad bien conocida con los envíos de python.
dmckee --- ex-gatito moderador
2

Perl, 112 char. Siento que puedo hacerlo mejor, tal vez lo intente más tarde

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

Las palabras se dan en la línea de comando, las letras se escriben en mayúscula


fuente
Hasta 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
Podrías editar tu respuesta original.
Lowjacker
1
Esto no muestra el número de intentos restantes.
Lowjacker
2

Clojure

Esto es 400 bytes comprimidos, que todavía es bastante, probablemente debido a cómo Clojure maneja el estado 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
fuente
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 de palabras como argumento

mate
fuente
1

VB.NET


No he intentado reducirlo todavía, pero:
Primero contracción:
Segunda contracción (3759 caracteres):

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-
fuente
¿Se requiere realmente toda la sangría?
Lowjacker
hace que sea más fácil de leer, ¿no?
Nate Koppenhaver
¿Como en bloques? No, no es obligatorio, pero no lo cuento como personajes.
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}

Menos guión de prueba de 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

Ejemplo de salida cuando el jugador de adivinanzas ha perdido :

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

Ejemplo de salida cuando el jugador que adivina ha ganado :

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