Créez un jeu de devinettes à neuf niveaux


11

Les bases:

Vous devrez fournir un jeu de devinettes à neuf niveaux avec le moins de caractères possible (dans la langue de votre choix).

Les métriques:

  • Fournissez une liste de mots (un mot par ligne, séparé par une nouvelle ligne) (par exemple, /usr/share/dict/wordsou similaire pourrait faire). C'est bien de canaliser un nom de fichier ou la liste de mots dans votre solution.
  • Fournir 9 niveaux avec incrémentation de la longueur des mots (mots avec 4 caractères ->12 caractères):
Niveau 1: un mot aléatoire de la liste de mots contenant 4 caractères
Niveau 2: un mot aléatoire de la liste de mots contenant 5 caractères
... ...
Niveau 8: un mot aléatoire de la liste de mots contenant 11 caractères
Niveau 9: un mot aléatoire de la liste de mots contenant 12 caractères
  • À chaque niveau, obscurcissez un mot choisi au hasard dans la liste (avec une longueur de mot bien sûr) et remplacez un certain nombre de caractères par l'astérisque ( *). Le nombre de caractères à remplacer: current_word_length / 3(arrondir vers le bas). Randomisez qui caractères à remplacer.
  • Laissez le joueur «deviner» le mot (un seul trypar niveau), donnez votre avis ( correctou wrong) et donnez des points en conséquence. Quand c'est correct, le joueur gagne number_of_obfuscated_characters * 10 points.
  • Imprime le score actuel à la fin de chaque niveau.

Le format (& exemple d'E / S):

Assurez-vous de suivre le schéma de mise en forme suivant:

En-tête de niveau 1 # niveau
======= # 
g * ek # mot obscurci
geek # user input
# validation de supposition correcte
score: 10 # partition imprimée
            #  
Niveau 2
=======
l * nux
linux
correct
score: 20

Niveau 3
=======
couru ** m
Aléatoire
correct
score: 40

...

Niveau 9
=======
sem *** act * ve
semi-inactif
faux
score: 90

Gagnant:

Solution la plus courte (par nombre de caractères de code). Amusez-vous au golf!


Quelle est la solution pour sem ** act ve, BTW?
Joe Z.

@JoeZ. peut-être sem***act*ve==>semelfactive
dev-masih

Réponses:


5

Perl, 180 caractères

@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 bat Perl? Ça n'ira pas! :-)

Comme la solution Ruby de jsvnm, mais contrairement au code Perl de Joel Berger, ce script prend le nom de fichier d'une liste de mots comme paramètre de ligne de commande. Autrement dit, vous devez l'exécuter comme ceci:

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

Voici une version dé-golfée:

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

La déclaration vec($_, rand $n, 8) = 42 while ($= = $n/3) > y/*//contient quelques astuces intéressantes. Premièrement, 42 est le code ASCII d'un astérisque; il s'avère que l'utilisation vecde modifier des caractères uniques dans une chaîne est plus courte que de le faire avec substr. Deuxièmement, la variable $=ne prend que des valeurs entières, donc l'utiliser pour stocker le nombre de lettres cachées me fait gagner un an int. Enfin, y/*//est un moyen rapide de compter le nombre d'astérisques dans une chaîne à l'aide de l'opérateur de translittération.

Edit: 7 caractères enregistrés en utilisant $@pour stocker le score divisé par 10 et en y ajoutant un zéro pendant la sortie (ce qui, à bien y penser, aurait été plus court que la version précédente même si j'avais utilisé une variable normale) .

Edit 2: Il s'avère que l'intégration de nouvelles lignes littérales dans les chaînes de sortie permet d'économiser un caractère au lieu de jouer avec $,.


5

Rubis (188)

prend le nom de fichier pour lire les mots comme 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",""}

Sympa (Ruby bat Perl, ce n'est pas un événement familier dans Code Golf ;-)
ChristopheD

Pour ma défense, je n'ai pas essayé si fort. Content qu'Ilmari Karonen m'ait soutenu.
Joel Berger

3

Bash, 350 caractères

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

Pas de tricherie! Il s'agit de 371 caractères selon Notepad ++.
nyuszika7h

6
@ Nyuszika7H: y compris les caractères 21 \ r, n'est-ce pas? C'est pour Unix, où une nouvelle ligne est un caractère de saut de ligne unique.
ninjalj

@ninjalj: Oui, mais gardez à l'esprit que tout le monde n'utilise pas le format de saut de ligne Unix. Nous devons être justes. meta.codegolf.stackexchange.com/questions/167/…
nyuszika7h

10
@ Nyuszika7H: Si vous pouvez l'utiliser, alors certainement vous devriez dans un golf de code. Si votre langue a deux façons équivalentes de faire quelque chose et que l'une est plus courte, utilisez-vous la plus longue parce que certaines personnes pourraient ne pas connaître la plus courte? En ce qui concerne les sauts de ligne, si vous avez une langue qui nécessite CRLF, alors vous n'avez pas de chance, mais je ne connais pas une telle langue.
Joey

1
Ne pouvez-vous pas presque toujours remplacer les retours à la ligne par des points-virgules ou des espaces?
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"}

ou avec un peu plus d'espace blanc

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

et je pense qu'avec un peu de travail ça pourrait être encore mieux!


2

R, 363 caractères

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

2

Python 335

Je sais que je suis un peu en retard à la fête, mais le python n'est pas représenté, alors j'ai compris ce que le diable:

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

Et semi-non golfé:

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

2

K, 198

Suppose un dictionnaire d dans le répertoire de travail actuel.

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

Non golfé:

{
        /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]
}
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.