Bangun permainan menebak kata sembilan tingkat

11

Dasar:

Anda harus memberikan permainan tebak kata sembilan tingkat dengan karakter sesedikit mungkin (dalam bahasa pilihan Anda).

Metrik:

  • Berikan daftar kata (satu kata per baris, dipisahkan oleh baris baru) (mis. /usr/share/dict/wordsBisa dilakukan) Tidak masalah untuk mem-pipe nama file atau daftar kata itu sendiri ke dalam solusi Anda.
  • Berikan 9 level dengan penambahan panjang kata (kata dengan 4 karakter ->12 karakter):
Level 1: kata acak dari daftar kata yang berisi 4 karakter
Level 2: kata acak dari daftar kata yang berisi 5 karakter
... ...
Level 8: kata acak dari daftar kata yang berisi 11 karakter
Level 9: kata acak dari daftar kata yang berisi 12 karakter
  • Di setiap level, hapus kata yang dipilih secara acak dari daftar (dengan panjang kata tertentu saja) dan ganti sejumlah karakter dengan asterisk ( *). The jumlah karakter untuk menggantikan: current_word_length / 3(putaran bawah). Acak karakter mana yang akan diganti.
  • Biarkan pemain 'menebak' kata (hanya satu tryper level), memberikan umpan balik ( correctatau wrong) dan memberikan poin yang sesuai. Ketika benar, pemain mendapatkan number_of_obfuscated_characters * 10 points.
  • Cetak skor saat ini di akhir setiap level.

Format (& sampel I / O):

Pastikan Anda mengikuti skema pemformatan berikut:

Level 1 # level header
======= # 
g * ek # kata dikaburkan
masukan pengguna geek #
validasi # tebakan yang benar
skor: skor cetak 10 #
            #  
Level 2
=======
l * nux
linux
benar
skor: 20

Tingkat 3
=======
berlari ** m
acak
benar
skor: 40

...

Level 9
=======
sem *** bertindak * ve
semiinaktif
salah
skor: 90

Pemenang:

Solusi terpendek (berdasarkan jumlah karakter kode). Bersenang-senang bermain golf!

ChristopheD
sumber
Apa solusi untuk sem ** act ve, BTW?
Joe Z.
@ Joz. mungkin sem***act*ve==>semelfactive
dev-masih

Jawaban:

5

Perl, 180 karakter

@w=<>;for$n(4..12){@x=grep/^.{$n}$/,@w;$_=$w=$x[rand@x];vec($_,rand$n,8)=42while($==$n/3)>y/*//;print"Level @{[$n-3]}
=======
$_";say<>eq$w?($@+=$=)&& correct:wrong,"
score: $@0
"}

Ruby mengalahkan Perl? Itu tidak bisa! :-)

Seperti solusi Ruby jsvnm, tetapi tidak seperti kode Perl Joel Berger, skrip ini menggunakan nama file dari daftar kata sebagai parameter baris perintah. Artinya, Anda harus menjalankannya seperti ini:

perl -M5.010 guessword.pl /usr/share/dict/words

Ini versi de-golf:

@w = <>;
for $n (4..12) {
    @x = grep /^.{$n}$/, @w;
    $_ = $w = $x[rand@x];
    vec($_, rand $n, 8) = 42 while ($= = $n/3) > y/\*//;
    print "Level @{[ $n-3 ]}\n=======\n$_";
    say <> eq $w ? ($@ += $=) && correct : wrong, "\nscore: $@0\n"; 
}

Pernyataan itu vec($_, rand $n, 8) = 42 while ($= = $n/3) > y/*//berisi beberapa trik menarik. Pertama, 42 adalah kode ASCII dari tanda bintang; ternyata menggunakan vecuntuk memodifikasi karakter tunggal dalam string lebih pendek daripada melakukannya dengan substr. Kedua, variabel $=hanya mengambil nilai integer, jadi menggunakannya untuk menyimpan jumlah huruf tersembunyi menghemat saya int. Akhirnya, y/*//adalah cara singkat untuk menghitung jumlah tanda bintang dalam string menggunakan operator transliterasi.

Sunting: Disimpan 7 karakter dengan menggunakan $@untuk menyimpan skor dibagi 10 dan menambahkan nol untuk itu selama output (yang, kalau dipikir-pikir, akan lebih pendek dari versi sebelumnya bahkan jika saya menggunakan variabel normal) .

Sunting 2: Menghidupkan baris baru literal dalam string keluaran menghemat lebih dari kekacauan $,.

Ilmari Karonen
sumber
5

Ruby (188)

mengambil nama file untuk membaca kata dari sebagai argumen.

q=*$<
s=0
4.upto(12){|n|o=''+w=q.grep(/^#{?.*n}$/).sample
[*0..n-1].sample(c=n/3).map{|i|o[i]=?*}
puts"Level #{n-3}",?=*7,o
puts STDIN.gets==w ?(s+=c;"correct"):"wrong","score: #{s}0",""}
jsvnm
sumber
Bagus (Ruby mengalahkan Perl, itu bukan acara yang akrab di Code Golf ;-)
ChristopheD
Dalam pembelaan saya, saya tidak berusaha keras. Senang Ilmari Karonen mendukungku.
Joel Berger
3

Bash, 350 karakter

S=0
for L in {4..12}
do
echo -e Level $(($L-3))\\n=======
W=$(grep -E ^.{$L}$ /usr/share/dict/words|shuf|tail -1)
G=$W
while [ `sed 's/[^*]//g'<<<$G|wc -c` -le $(($L/3)) ]
do
P=$(bc<<<$RANDOM*$L/32767)
G=$(sed "s/\(.\{$P\}\)./\1*/"<<<$G)
done
echo $G
read U
if [ x$U == x$W ]
then
echo correct
S=$(($S+$L/3*10))
else
echo wrong
fi
echo score: $S
done
ninjalj
sumber
Jangan curang! Ini 371 karakter menurut Notepad ++.
nyuszika7h
6
@ Nyuszika7H: termasuk 21 karakter, bukan? Ini untuk Unix, di mana baris baru adalah char linefeed tunggal.
ninjalj
@ninjalj: Ya, tetapi perlu diingat bahwa tidak semua orang menggunakan format jeda baris Unix. Kita harus adil. meta.codegolf.stackexchange.com/questions/167/…
nyuszika7h
10
@ Nyuszika7H: Jika Anda bisa menggunakannya, berarti Anda harus bermain golf kode. Jika bahasa Anda memiliki dua cara yang setara untuk melakukan sesuatu dan satu lebih pendek, apakah Anda menggunakan lebih lama karena beberapa orang mungkin tidak tahu yang lebih pendek? Sedangkan untuk jeda baris, jika Anda memiliki bahasa yang membutuhkan CRLF, maka Anda kurang beruntung, tetapi saya tidak mengetahui bahasa tersebut.
Joey
1
Tidak bisakah Anda hampir selalu mengganti baris baru dengan titik koma atau spasi?
barrycarter
2

Perl: 266

@ARGV='/usr/share/dict/words';@w=<>;$"='';while($l<9){$o=1+int++$l/3;@s=grep{$l+4==length}@w;@g=split//,$t=$s[rand$#s+1];my%r;$r{rand$#g}++while keys%r<$o;$g[$_]='*'for keys%r;print"Level $l\n=======\n@g";print<>eq$t?do{$p+=$o*10;"Correct"}:"Wrong","\nScore: $p\n"}

atau dengan sedikit lebih banyak ruang putih

@ARGV='/usr/share/dict/words';
@w=<>;
$"='';
while($l<9){
  $o=1+int++$l/3;
  @s=grep{$l+4==length}@w;
  @g=split//,$t=$s[rand$#s+1];
  my%r;
  $r{rand$#g}++while keys%r<$o;
  $g[$_]='*'for keys%r;
  print"Level $l\n=======\n@g";
  print<>eq$t?do{$p+=$o*10;"Correct"}:"Wrong","\nScore: $p\n"
}

dan saya pikir dengan sedikit kerja itu bisa menjadi lebih baik!

Joel Berger
sumber
2

R, 363 karakter

w=tolower(scan("/usr/share/dict/words",what="c"));l=nchar(w);score=0;for(i in 1:9){mw=sample(w[l==i+3],1);cat("Level",i,"\n=======\n",replace(strsplit(mw,"")[[1]],sample(nchar(mw),floor(nchar(mw)/3)),"*"),"\n");v=scan(what="c",n=1,quiet=T);if(length(v)!=0&&v==mw){score=score+10*floor(nchar(mw)/3);cat("correct\n")} else cat("wrong\n");cat("score:",score,"\n\n")}
Paolo
sumber
2

Python 335

Saya tahu saya agak terlambat ke pesta, tetapi python tidak diwakili, jadi saya pikir apa-apaan:

import sys
import random
D=open(sys.argv[1]).read().split()
random.shuffle(D)
z=0
for L in range(1,10):
 M=L+3;N=M/3;w=[c for c in D if len(c)==M][0];U=list(w)
 for i in[random.randint(0,M-1)for i in range(N)]:U[i]='*'
 print"\nLevel %d\n=======\n"%L+''.join(U);k=raw_input()==w;z+=[0,N*10][k];print["wrong","correct"][k]+"\nscore:",z

Dan semi-tak berkhasiat:

import sys
import random
words = open(sys.argv[1]).read().split()
random.shuffle(words)
score=0
for L in range(1,10):
   M=L+3
   N=M/3
   w=[c for c in words if len(c)==M][0]
   obfus=list(w)
   for i in [random.randint(0,M-1) for i in range(N)]: obfus[i]='*'
   obfus=''.join(obfus)
   print"\nLevel %d\n=======\n"%L+obfus
   correct=raw_input()==w
   score+=[0,N*10][correct]
   print["wrong","correct"][correct]+"\nscore:",score
Gordon Bailey
sumber
2

K, 198

Mengasumsikan kamus d di direktori kerja saat ini.

{O:{@[x;(-_c%3)?c:#x;:;"*"]}',/W:{1?x@&y=#:'x}[_0:`d]'4+!9;i:1+S:0;while[#O;-1"Level ",$i;-1"=======";-1@*O;$[(**W)~0:0;[-1"correct";S+:10*+/"*"=*O];-1"wrong"];-1"score: ",$S;-1"";W:1_W;O:1_O;i+:1]}

Tidak Disatukan:

{
        /W = wordlist; O = obfuscated
        O:{@[x;(-_c%3)?c:#x;:;"*"]}',/W:{1?x@&y=#:'x}[_0:`d]'4+!9;     
        i:1+S:0;                            
        while[#O;
                -1"Level ",$i;
                -1"=======";
                -1@*O;
                $[(**W)~0:0;              /Read user input and compare to the first word
                        [-1"correct";
                        S+:10*+/"*"=*O];  /if correct, increment score
                        -1"wrong"];
                -1"score: ",$S;
                -1"";
                W:1_W;                    /knock one off the top of both word lists
                O:1_O;
                i+:1]
}
tmartin
sumber