Golf wordgame Hangman


14

Terinspirasi oleh reddit .

Tulis program yang memainkan Hangman .

  • Program memilih kata acak dari daftar kata N, di mana N> 2.
  • Daftar kata dapat disediakan untuk program dengan cara apa pun yang Anda pilih.
  • Di setiap iterasi

    • Cetak status permainan menggunakan garis bawah untuk huruf-huruf yang belum ditemukan:

    H _ N _ _ _ N

    • Cetak jumlah upaya yang tersisa

    10

    • Baca surat dari stdin, dan perbarui status permainan, kurangi upaya jika mereka menebak huruf yang salah.

    A (memasukkan)

    H A N _ _ A N

    10

    • Ulangi sampai semua huruf ditebak atau upaya mencapai 0
  • Gunakan bahasa apa pun
  • Jumlah karakter yang paling sedikit menang.
  • Menggambar tiang gantungan tidak perlu, tetapi akan memberi Anda upvotes dan pujian.

Bisakah saya membiarkan setiap kata dalam daftar menjadi jumlah karakter yang sama?
Peter Olson

Apakah huruf-huruf dalam output harus dipisahkan oleh spasi?
Lowjacker

@ Peter Of The Corn: Anda harus berasumsi bahwa daftar kata arbitrer
drspod

@ Lowjacker: spasi meningkatkan keterbacaan garis bawah berturut-turut, jika tidak, sulit untuk menghitung berapa banyak huruf yang mereka wakili.
drspod

Jawaban:


6

Ruby 1.9, 134 132 120 117 108 107

Daftar kata yang disediakan di ARGV. Kata-kata dan huruf yang dimasukkan harus cocok untuk berjaga-jaga.

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

Sial, saya pikir katanya "paling sedikit baris yang menang." Saya tidak akan memenangkan kontes dengan karakter paling sedikit di sini, tetapi program Common Lisp ini hanya satu baris.

(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
Saya mendukung Anda karena saya cukup yakin Anda sengaja lucu :-)
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

Saya lebih suka yang ini: lebih lama tapi lebih bagus.

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

Jika saya tidak harus mencetak ajuga, saya bisa menggunakan *dua kali: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;}

cat / usr / dikt / kata | xargs hangman


">" Prompt untuk input tidak diperlukan untuk solusi, saya hanya menambahkannya di pertanyaan untuk menunjukkan bahwa itu input, karena banyak bahasa memberikan prompt seperti ini.
drspod

@drspod Anda harus mengedit pertanyaan untuk mencerminkannya, lalu.
Lowjacker

diedit untuk memperjelas
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

Saya tidak benar-benar mencoba untuk karakter paling sedikit, hanya ingin membuatnya sekecil mungkin tanpa mengorbankan apa pun.


@ pengguna: Anda mungkin tertarik pada skrip pengguna yang luar biasa dari George Edison untuk situs ini yang menempatkan kode Anda (seperti disalin di sini oleh badp) pada 1225 karakter.
dmckee --- ex-moderator kitten

Saya pikir itu karena saya menggunakan tab dan mereka dikonversi ke spasi di sini. wc mengatakan ini 1034 dengan tab.
Sergey G

@ pengguna: Ya. Sebuah kesulitan terkenal dengan pengajuan python.
dmckee --- ex-moderator kitten

2

Perl, 112 char. Saya merasa dapat melakukan yang lebih baik - mungkin saya akan mencoba lagi nanti

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

Kata-kata diberikan pada baris perintah, huruf yang diketik huruf besar


Turun ke 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
Anda bisa mengedit jawaban asli Anda.
Lowjacker

1
Ini tidak menampilkan jumlah upaya yang tersisa.
Lowjacker

2

Clojure

Ini adalah 400 byte gzipped, yang masih cukup banyak, mungkin karena cara Clojure menangani keadaan yang bisa berubah.

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

daftar kata sebagai argumen


1

VB.NET


Saya belum mencoba mengecilkannya, tetapi:
Penyusutan pertama:
Penyusutan kedua (3759 karakter):

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

Apakah semua lekukan benar-benar diperlukan?
Lowjacker

itu membuatnya lebih mudah dibaca, bukan?
Nate Koppenhaver

Seperti dalam balok? Tidak, itu tidak wajib, tapi saya tidak menganggapnya sebagai karakter.
Ry-

0

Powershell, 125 byte

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

Skrip uji yang kurang 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

Keluarkan contoh saat pemain yang menebak kalah :

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

Keluarkan contoh saat pemain yang menebak telah menang :

_ _ _ _ _ _ _ _ _ _
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
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.