Erstellen Sie ein Wort-Ratespiel mit neun Ebenen

11

Die Grundlagen:

Sie müssen ein Wort-Ratespiel mit neun Ebenen in möglichst wenigen Charakteren (in der Sprache Ihrer Wahl) bereitstellen.

Die Metriken:

  • Stellen Sie eine Wortliste bereit (ein Wort pro Zeile, getrennt durch eine neue Zeile) (z. B. /usr/share/dict/wordsoder ähnliches). Es ist in Ordnung, einen Dateinamen oder die Wortliste selbst in Ihre Lösung einzufügen.
  • Stellen Sie 9 Ebenen mit inkrementeller Wortlänge bereit (Wörter mit 4 Zeichen und ->12 Zeichen):
Stufe 1: Ein zufälliges Wort aus der Wortliste mit 4 Zeichen
Stufe 2: Ein zufälliges Wort aus der Wortliste mit 5 Zeichen
... ...
Stufe 8: Ein zufälliges Wort aus der Wortliste mit 11 Zeichen
Stufe 9: Ein zufälliges Wort aus der Wortliste mit 12 Zeichen
  • Verschleiern Sie in jeder Ebene ein zufällig ausgewähltes Wort aus der Liste (natürlich mit einer bestimmten Wortlänge) und ersetzen Sie eine bestimmte Anzahl von Zeichen durch das Sternchen ( *). Die Anzahl der zu ersetzenden Zeichen: current_word_length / 3(abrunden). Randomisieren Sie, welche Zeichen ersetzt werden sollen.
  • Lassen Sie den Spieler das Wort "erraten" (nur eines trypro Level), geben Sie Feedback ( correctoder wrong) und geben Sie entsprechend Punkte. Wenn es richtig ist, gewinnt der Spieler number_of_obfuscated_characters * 10 points.
  • Drucken Sie die aktuelle Punktzahl am Ende jedes Levels aus.

Das Format (& Beispiel-E / A):

Stellen Sie sicher, dass Sie das folgende Formatierungsschema befolgen:

Level 1 # Level Header
======= # 
g * ek # verschleiertes Wort
Geek # Benutzereingabe
korrekte # Vermutung Validierung
Punktzahl: 10 # Druckpunktzahl
            #  
Level 2
=======
l * nux
Linux
richtig
Punktzahl: 20

Stufe 3
=======
lief ** m
zufällig
richtig
Punktzahl: 40

...

Level 9
=======
sem *** act * ve
halbinaktiv
falsch
Punktzahl: 90

Gewinner:

Kürzeste Lösung (nach Anzahl der Codezeichen). Viel Spaß beim Golfen!

ChristopheD
quelle
Was ist die Lösung für sem ** act ve, BTW?
Joe Z.
@ JoeZ. vielleicht sem***act*ve==>semelfactive
dev-masih

Antworten:

5

Perl, 180 Zeichen

@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 schlägt Perl? Das geht nicht! :-)

Wie die Ruby-Lösung von jsvnm, jedoch im Gegensatz zum Perl-Code von Joel Berger, verwendet dieses Skript den Dateinamen einer Wortliste als Befehlszeilenparameter. Das heißt, Sie sollten es so ausführen:

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

Hier ist eine Version ohne 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"; 
}

Die Aussage vec($_, rand $n, 8) = 42 while ($= = $n/3) > y/*//enthält einige interessante Tricks. Erstens ist 42 der ASCII-Code eines Sterns; Es stellt sich heraus, dass die Verwendung veczum Ändern einzelner Zeichen in einer Zeichenfolge kürzer ist als die Verwendung mit substr. Zweitens nimmt die Variable $=nur ganzzahlige Werte an int. Wenn ich sie also zum Speichern der Anzahl versteckter Buchstaben verwende, erspare ich mir eine . Schließlich y/*//ist eine kurze Möglichkeit, die Anzahl der Sternchen in einer Zeichenfolge mithilfe des Transliterationsoperators zu zählen.

Bearbeiten: 7 Zeichen wurden $@gespeichert, indem die Punktzahl geteilt durch 10 gespeichert und während der Ausgabe eine Null angehängt wurde (was, wenn man es sich vorstellt, kürzer gewesen wäre als die vorherige Version, selbst wenn ich eine normale Variable verwendet hätte). .

Bearbeiten 2: Es stellt sich heraus, dass das Einbetten von wörtlichen Zeilenumbrüchen in die Ausgabezeichenfolgen ein Zeichen für das Durcheinander erspart $,.

Ilmari Karonen
quelle
5

Rubin (188)

Nimmt den Dateinamen zum Lesen von Wörtern als Argument.

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
quelle
Schön (Ruby schlägt Perl, das ist kein bekanntes Ereignis in Code Golf ;-)
ChristopheD
Zu meiner Verteidigung habe ich mich nicht so sehr bemüht. Ich bin froh, dass Ilmari Karonen meinen Rücken hatte.
Joel Berger
3

Bash, 350 Zeichen

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
quelle
Kein Schummeln! Laut Notepad ++ sind es 371 Zeichen.
Nyuszika7h
6
@ Nyuszika7H: einschließlich 21 Zeichen, nicht wahr? Dies ist für Unix, wo eine neue Zeile ein einzelnes Zeilenvorschubzeichen ist.
Ninjalj
@ninjalj: Ja, aber denken Sie daran, dass nicht jeder das Unix-Zeilenumbruchformat verwendet. Wir müssen fair sein. meta.codegolf.stackexchange.com/questions/167/…
nyuszika7h
10
@ Nyuszika7H: Wenn du es benutzen kannst, dann solltest du auf jeden Fall in einem Code Golf spielen. Wenn Ihre Sprache zwei gleichwertige Methoden hat und eine kürzer ist, verwenden Sie die längere, weil einige Leute die kürzere möglicherweise nicht kennen? Wenn Sie Zeilenumbrüche haben, für die CRLF erforderlich ist , haben Sie kein Glück, aber mir ist keine solche Sprache bekannt.
Joey
1
Können Sie nicht fast immer Zeilenumbrüche mit Semikolons oder Leerzeichen ersetzen?
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"}

oder mit etwas mehr Leerraum

@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"
}

und ich denke mit ein wenig arbeit könnte es noch besser werden!

Joel Berger
quelle
2

R, 363 Zeichen

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
quelle
2

Python 335

Ich weiß, dass ich ein bisschen zu spät zur Party komme, aber Python ist nicht vertreten, also habe ich mir gedacht, was zum Teufel:

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

Und halb ungolfed:

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
quelle
2

K, 198

Nimmt ein Wörterbuch d im aktuellen Arbeitsverzeichnis an.

{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]}

Ungolfed:

{
        /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
quelle