Estive olhando o aplicativo Wordle e me parece muito fácil de duplicar. Estou aprendendo sozinho a programar shell script, então estou me perguntando se há uma maneira de criar um wordle para a linha de comando no Linux?
Há muito sobre o Wordle que foi realmente inteligente desde o primeiro lançamento, não menos importante do que é que é simples de entender e difícil de dominar. Como tem apenas um quebra-cabeça de palavras por dia, também é um jogo casual perfeito para um dispositivo móvel a caminho da escola, do trabalho, mesmo deitado na cama, acordando lentamente. Seis palpites. Cinco letras. Ele mostra se você adivinhar uma letra no slot correto, uma letra que está na palavra, mas não no primeiro slot, e quaisquer letras em seu palpite que estejam faltando na palavra.
A outra faceta que funcionou realmente bem é que é muito fácil compartilhar seus resultados com amigos nas redes sociais. Claro, amigos que não jogam Wordle não vão se interessar, mas ei, aqueles que jogam podem facilmente comparar o número de palpites com o seu, e doces são os dias em que você consegue a palavra com apenas alguns palpites! Como não há pistas, é definitivamente difícil porque existem milhares e milhares de palavras de 5 letras no dicionário de inglês.
Ainda assim, se você pode codificá-lo, também pode codificá-lo como um shell script, embora possa não ser o mais eficiente ou elegante (particularmente em comparação com o simples e eficaz design do aplicativo móvel). Vamos nos aprofundar e ver como recriar o Wordle como um shell script Linux e MacOS.
ETAPA 1: ESCOLHA UMA PALAVRA DO DICIONÁRIO
Várias distros do Linux incluem dicionários, mas geralmente incluem centenas de palavras bastante obscuras que nem aparecem nos dicionários padrão da língua inglesa. O jogo não é divertido se estiver solicitando palavras das quais você nunca ouviu falar, certo? Felizmente, a Web aparece e há um bom arquivo de texto com cerca de 5.000 palavras em inglês de 5 letras que você pode pegar diretamente da rede em
https://www-cs-faculty.stanford.edu/~knuth/sgb-words.txt
Pegue-o e salve-o como “5 letras-palavras.txt”. Em seguida, defina uma variável para que possamos nos referir a ela como “dict” no futuro:
dict=”5-letter-words.txt”.
Agora vamos entrar na primeira parte interessante da codificação: Escolher um palavra aleatória de um arquivo de texto. Isso pode ser feito calculando o número de linhas no arquivo e, em seguida, usando a variável interna $RANDOM no shell para gerar um número inteiro aleatório de 2**32, modificado para ficar entre 0 e o número de linhas – 1:
# 1. Escolha uma palavra da lista lines=”$(wc-l <$dict)"randomchoice="$(( $RANDOM % $lines ))"word="$(head-n $randomchoice $dict | tail-1)"
Espero que esteja tudo claro para você, usando $randomchoice para lembrar qual linha queremos, então head|tail para extrair apenas aquela linha do dicionário. O resultado é que $palavra é a palavra a ser adivinhada.
Agora, enquanto a temos, vamos dividi-la em cinco variáveis de uma letra. Existem várias maneiras de fazer isso, mas usarei um corte simples em uma abordagem de subshell:
w1=”$(echo $word | cut-c1)”; w2=”$(echo $palavra | cortar-c2)”w3=”$(echo $palavra | cortar-c3)”; w4=”$(echo $word | cut-c4)”w5=”$(echo $word | cut-c5)”
A primeira etapa está concluída. $palavra contém a palavra a ser adivinhada e $w1 a $w5 contém as cinco letras que compõem essa palavra.
ETAPA 2: SOLICITAR AO USUÁRIO SUA DIVISÃO
A segunda etapa é criar um loop e, dentro dele, solicitar o palpite do usuário. Feito facilmente:
até [ 0-eq 1 ] ; do echo”\nGuess: \c”read answer more code will go here done
O restante do nosso código (com exceção de uma função que aparecerá daqui a pouco) será dobrado depois de’read answer’, mas antes’feito’. Enquanto processamos a suposição, vamos dividi-la em cinco variáveis sequenciais também:
a1=”$(echo $answer | cut-c1)”; a2=”$(echo $resposta | cortar-c2)”a3=”$(echo $resposta | cortar-c3)”; a4=”$(echo $answer | cut-c4)”a5=”$(echo $answer | cut-c5)”
Você sempre pode dividir uma variável com uma notação ${varname:x:y}, mas Prefiro variáveis separadas para maior clareza.
ETAPA 3: VERIFIQUE A CONDIÇÃO NO DICIONÁRIO
Como uma das regras do Wordle é que sua suposição deve ser uma palavra em inglês adequada, precisaremos para verificar isso também. Acontece que é muito fácil…
if [“$(grep-E”^$answer\$”$dict)”=””] ; então # A resposta está no dicionário? Se não, não avalia? echo”Seu palpite não está no meu dicionário.”else
Formatei isso como uma condicional porque é um dos vários testes que aplicaremos…
PASSO 4: COMPARE CADA LETRA COM O ALVO
O próximo passo , e de longe o mais complicado, é testar cada letra da suposição do usuário não apenas com o mesmo slot de letra na palavra de destino, mas com todas as letras da palavra. Para fazer isso, vou criar uma função shell:
lettercheck() { # answer-letter lettercount # todas as letras de resposta já estão em w1 w2 etc # retorna o valor em”$returnchar”if [“$1″=”$(eval echo \$w$2)”] ; então # letra adivinhada no local correto! returnchar=”$(echo $1 | tr”[:lower:]””[:upper:]”)”elif [“$(echo $palavra | grep”$1″)”!=””] ; then # letra presente, ponto errado (precisa de refinamento) returnchar=”$1″else # letra não presente na palavra returnchar=”-“fi }
Como você pode passar variáveis para funções no shell, ela será invocada com o primeiro parâmetro a letra adivinhada e o segundo parâmetro o slot ordinal (em outras palavras, se eu adivinhasse “carom” então a letra 3 seria “r” e seria a letra nº 3 em meu palpite.
Como não posso alterar a cor das letras adivinhadas, estou usando a notação de que repetir o palpite com uma letra transliterada para maiúscula significa que é a letra certa no lugar certo; se for minúscula, é a letra certa no lugar errado, e se for apenas um”-“, é uma letra que não está presente. Você pode ver como tudo isso aparece no código acima?
ETAPA 5: AVALIE A ADUVIADA COM LETTERCHECK
Com a função escrita, é hora de utilizá-la, e aqui está como eu faço isso:
echo”Resultado do seu palpite: \c”lettercheck”$a1″1 ; echo”$retur nchar \c”lettercheck”$a2″2 ; echo”$returnchar \c”lettercheck”$a3″3 ; echo”$returnchar \c”lettercheck”$a4″4 ; echo”$returnchar \c”lettercheck”$a5″5 ; echo”$returnchar”
Estou aproveitando a notação \c em echo para que não inclua um retorno de linha, permitindo que o script construa uma linha de saída letra por letra. Útil!
JUNTO TUDO
Antes de mostrar todo o código com loops, vamos dar uma olhada na saída, um jogo rápido de SHWORDLE:
$ sh shwordle.sh Adivinha: pássaros Resultado do seu palpite:—-S Adivinha: carpas Resultado do seu palpite:-a–S Adivinhe: bobinas Resultado do seu palpite:-E e L S Adivinhe: zelos Você adivinhou: ZELOS! Muito bem.
Eu trapaceei porque já conhecia a palavra de antemão, mas você pode ver que é difícil, mas quando você lembra que maiúscula significa letra correta, slot correto e minúscula significa letra correta, slot errado, funciona perfeitamente. Bem, não exatamente, mas voltarei a isso.
Por enquanto, aqui está o script completo, linha por linha, incluindo comentários:
#!/bin/sh # SHWORDLE-duplica a funcionalidade do jogo de adivinhação de palavras Wordle # escrito por Dave Taylor. Ainda tem alguns bugs para resolver. dict=”/Users/taylor/bin/5-letter-words.txt”lettercheck() { # answer-letter lettercount # todas as letras de resposta já estão em w1 w2 etc # retorna o valor em”$returnchar”if [“$1″=”$(eval echo \$w$2)”] ; então # letra adivinhada no local correto! returnchar=”$(echo $1 | tr”[:lower:]””[:upper:]”)”elif [“$(echo $palavra | grep”$1″)”!=””] ; then # letra presente, ponto errado (precisa de refinamento) returnchar=”$1″else # letra não presente na palavra returnchar=”-“fi } # 1. Escolha uma palavra da lista lines=”$(wc-l <$dict )"randomchoice="$(( $RANDOM % $lines ))"word="$(head-n $randomchoice $dict | tail-1)"w1="$(echo $word | cut-c1)"; w2="$(echo $palavra | cortar-c2)"w3="$(echo $palavra | cortar-c3)"; w4="$(echo $palavra | corte-c4)"w5="$(echo $palavra | corte-c5)"# aqui está um cheat: echo"--$palavra--$w1 $w2 $w3 $w4 $ w5"# 2. Loop para solicitar ao usuário um palpite. até [ 0-eq 1 ] ; faça echo"\nAdivinhe: \c"leia a resposta # 3. divida a palavra adivinhada em letras a1="$(echo $resposta | cut-c1)"; a2="$(echo $resposta | cortar-c2)"a3="$(echo $resposta | cortar-c3)"; a4="$(echo $resposta | cortar-c4)"a5="$(echo $resposta | cortar-c5)"if ["$resposta"="$palavra"] ; então # entendi! bem feito echo"Você adivinhou: $(echo $palavra | tr'[:inferior:]''[:superior:]')! Muito bem."exit 0 elif ["$resposta"="sair"-o"$resposta"=""]; then # escape do loop infinito echo"A palavra era $(echo $palavra | tr'[:inferior:]''[:superior:]'). Até a próxima."exit 0 else # avalia o palpite if ["$(grep-E"^$answer\$"$dict)"=""] ; então # 4. A resposta está no dicionário? Se não, não avalia? echo"Seu palpite não está no meu dicionário."else # 5. avaliar e gerar o resultado: echo"Resultado do seu palpite: \c"lettercheck"$a1"1 ; echo"$returnchar \c"lettercheck"$a2"2 ; echo"$returnchar \c"lettercheck"$a3"3 ; echo"$returnchar \c"lettercheck"$a4"4 ; echo"$returnchar \c"lettercheck"$a5"5 ; echo"$returnchar"fi fi done exit 0
Então, o que não está certo? O principal problema de funcionalidade aparece quando você tem letras duplicadas em uma palavra. Se você observar o código lettercheck de perto, perceberá que se a palavra for, digamos, zeals e eu acho mandona, ambas as letras’s’serão mostradas como correspondendo a uma letra na palavra final , embora apenas o primeiro deva ser uma correspondência. Esse bug, porém, vou deixar para você resolver, e lembre-se que pode acontecer com letra duplicada no palpite ou na palavra alvo. Caso contrário, isso deve lhe dar uma grande vantagem na criação do Wordle para a linha de comando do Linux. Divirta-se!
Dica profissional: escrevo sobre o Linux desde o surgimento do sistema operacional, e o Unix antes disso. Confira minha extensa área de ajuda do Linux e área de programação de script de shell do Linux para obter muitos conteúdos adicionais de tutoriais enquanto estiver visitando. Obrigado!
wordle para linux, programa wordle