8 ms·
A Wordle clone in 50 lines of Bash
- auraham 5y agoReally cool!
- sinab 5y agoThis is great, thank you for creating it! I just added it to my $PATH.
- shmerl 5y agoReally neat! I wish bash would have a nicer way to address a character in a string though. How hard would it be to use the same syntax as for arrays for it? By the way, this can be expressed simpler: guess_count=$(( $guess_count - 1 )) As ((guess_count--))
- kwhitefoot 5y agoYou need to be careful with that. If guess_count is zero before the post-decrement the statement will have an exit code of 1. If you have set -e in effect this will kill your script. Depending on the circumstances it might be better to use pre-decrement. (( --guess_count ))
- shmerl 5y agoThanks for the hint!
- chubot 5y agoI wish bash would have a nicer way to address a character in a string though. How hard would it be to use the same syntax as for arrays for it? Yes it would be nicer if ${s[i]} worked, instead of needing ${s:i:1}. But there's a pretty fundamental reason for that: bash doesn't have dynamic types of strings and arrays like Python or JavaScript. Instead everything is basically one kind of string-or-array value. Roughly speaking, strings are values with one element, and arrays are values with more than one. And ${array} is equivalent to ${array[0]}, which is very confusing. Conversely, you can do ${s[0]} on anything you declared to be a string, and you'll get the whole value back. Rather than having types attached to values, bash has weird "flags" on the LOCATION for a value. And even that's not the whole story! Evaluation of a variable in bash depends on three things: 1. the contents of the "cell" / location 2. the flag on the cell (-a -A) 3. the operation, e.g. echo $x or echo foo > $x I might make a blog post about this. Oil does it more like Python or JavaScript, which is noted here, but this section could use a lot of elaboration: https://www.oilshell.org/release/0.9.7/doc/known-differences.html#values-are-tagged-with-types-not-cells https://www.oilshell.org/release/0.9.7/doc/known-differences...
- shmerl 5y agoInteresting, thanks! Is there a reason for such awkward design of handling variables and types or it's simply some historic choice that's stuck?
- chubot 5y agoYeah it's definitely a historical thing. Bourne shell / POSIX shell doesn't have arrays, and ksh added arrays and bash adopted the same semantics. ksh did it in the most "backward compatible" way, with the least amount of work, but which leads to very confusing semantics. They just "extended" every string so it can have an array part, and then changed a FEW parts of the evaluator, not ALL parts of it. So arrays "decay" to strings in most contexts. They didn't have to touch that code. It's hard to explain but if you write an interpreter you'll get a feel for this O(M x N) explosion between data types and operations. The amount of work explodes as you add more of either, and shell already has a ton of operations. As mentioned, the evaluation rules for the word $x in 'echo $x' and 'echo foo > $x' are completely different. There are ways to avoid this, like Python has PyObject and a bunch of protocols. Similarly, Clojure has more protocols than Racket, which the Racket authors have noted -- it works on abstractions and not "concretions". As far as I remember, these come directly from Java interfaces. So yes Java actually adds something to Lisp :)
- tyler279 5y ago
- kccqzy 5y agoThis doesn't handle Yellow result correctly. Specifically, if there is a repeated letter in the guess but that letter appears once in the actual word, then the second occurrence will get a Black instead of a Yellow. In other words, a Yellow result doesn't just mean that letter occurs somewhere. A Black also doesn't mean the letter occurs nowhere.
- huydotnet 5y agoYes I just noticed that issue too, still trying to figure out how to fix it :P
- indigodaddy 5y agoPlease let us know when that is fixed and I’ll play this for sure!
- kccqzy 5y agoIf you don't mind a shameless plug, I made this same mistake before and here's how I fixed it: https://github.com/kccqzy/Wordle-Assistant/blob/27d208248b7a1cc63de2773b072bcfa42266e7bc/src/main.rs#L220-L257 https://github.com/kccqzy/Wordle-Assistant/blob/27d208248b7a...
- hddqsb 5y agoHere is one way to fix it (but it will push you over 50 lines!) remaining="" output="" for ((i = 0; i < ${#actual}; i++)); do if [[ "${actual:$i:1}" != "${guess:$i:1}" ]]; then remaining+=${actual:$i:1} fi done for ((i = 0; i < ${#actual}; i++)); do if [[ "${actual:$i:1}" != "${guess:$i:1}" ]]; then if [[ "$remaining" == *"${guess:$i:1}"* ]]; then output+="\033[30;103m ${guess:$i:1} \033[0m" remaining=${remaining/"${guess:$i:1}"/} else output+="\033[30;107m ${guess:$i:1} \033[0m" fi else output+="\033[30;102m ${guess:$i:1} \033[0m" fi done printf "$output\n" Explanation: The variable `remaining` tracks the letters of `actual` that can contribute toward yellows.
- 5y ago
- seanp2k2 5y agoDoesn't work for me on linux using 5.1.8(1)-release (x86_64-pc-linux-gnu). Output with `set -vx` at top (I guessed "fooba"): ++ [[ false != true ]] ++ guess_count=1 ++ [[ 1 -le 6 ]] ++ echo 'Enter your guess (1 / 6):' Enter your guess (1 / 6): ++ read guess fooba +++ echo fooba +++ tr '[a-z]' '[A-Z]' ++ guess=FOOBA [... ÉTUDE =~ FOOBA ]] ++ echo 'Please enter a valid word with 5 letters!' Please enter a valid word with 5 letters! ++ guess_count=0 ++ [[ false != true ]] ++ guess_count=1 ++ [[ 1 -le 6 ]] ++ echo 'Enter your guess (1 / 6):' Enter your guess (1 / 6): ++ read guess
- huydotnet 5y agoI think it's something with the `/usr/share/dict/words` file, I made a comment in the gist to update the code to the actual english dictionary words, could you try that?
- berkes 5y agoI've replied to your comment on GH, The problem is likely due to how your symlinks are set-up. Which is an artifact of your systems' locales. Easiest is to check /usr/share/dict with `ls -hal`. Do read the README there, before manually flipping symlinks around, though.
- ragingrobot 5y agoPerhaps allowing the user to specify a word list, and defaulting to some value would be better than suggesting symlinks. On Tumbleweed, I have no /usr/share/dict/words, but /use/share/dict/american. Allowing the user to set would also be useful if multiple languages are installed, and doesn't change the number of lines of code. I changed the first line to: words=$(grep -Ex '\w{5}' "/usr/share/dict/${wordlist:=words}" | tr '[a-z]' '[A-Z]') so I can invoke it wordlist=american wordle.sh You can also replace it with $1 (or any other positional parameter): words=$(grep -Ex '\w{5}' "/usr/share/dict/${1:=words}" | tr '[a-z]' '[A-Z]') And invoke it with wordle.sh american In either case, it defaults to /usr/share/dict/words if no list is given. Personally I'd go with the first as you use $1 for guesses, and higher numbered parameters get messy.
- tomcat27 5y agoMillion dollah 50 lines
- alana314 5y agoThis is awesome. My word was cleam though. That was hard.
- BMorearty 5y agoYou know, like "cleam the bathroon"
- dgivney 5y agoAlways cleam your inputs!
- ragingrobot 5y agoThis article made me check out my dict out of curiosity (american). It has words like "zorch". No. Clue.
- surrTurr 5y agoAnd here’s a quick one-liner to solve Wordle puzzles: https://twitter.com/AlexWeichart/status/1488223629867462664 https://twitter.com/AlexWeichart/status/1488223629867462664
- berkes 5y agoI do use some grep-fu and sed, awk, and sort to assist though. It may be cheating (I think it is) but its a great moment to hone some of your gnutools skills. Some tricks (shameless self-promotion, sorry) https://twitter.com/berkes/status/1481222011980550146 https://twitter.com/berkes/status/1481222011980550146 and https://twitter.com/berkes/status/1486296116899504131 https://twitter.com/berkes/status/1486296116899504131
- huydotnet 5y agoThank you so much everyone! The issue with the yellow letters is fixed. Please give it a try again!
- jsiaajdsdaa 5y agoSomeone needs to make the obligatory "Wordle clone in 50,000 lines of react/java/nosql/docker/terraform/documentation/7GB of unused dependencies" :)
- jmfldn 5y agoHa yes! Worldle enterprise edition. Needs to be microservice-based, obv. A word finder service, a word checker service and a few others for good measure. Reactive architecture, probably Kafka based, for resilience. Also GDPR compliant, CI/CD pipeline, distributed tracing, all major languages covered, dev, staging and production environments. Bonus points for Java spring, React and Redux.
- rmonvfer 5y agoIt may sound hilarious at first but also serve as a good (and extremely simple) learning model.
- cute_boi 5y agoIt may sound logical, but learning many things without going in deep is dangerous. One reason I can think on top of my head is people will abuse and try to use same techniques in every upcoming projects. One of my friend start Kubernetes in digital ocean for simple website is one anecdote i can remember atm. A little knowledge is a dangerous thing.
- yepthatsreality 5y agoWordle Desktop, a small modern handcrafted Wordle clone built on Electron that uses 3GB of RAM.
- jsiaajdsdaa 5y agoA bespoke Wordle clone where each pixel is an image!
- deleted 5y ago[deleted]
- libele 5y agofinally the words file has a purpose again
- indigodaddy 5y agoSweet, I even got it to work on my iPhone with iSH terminal!
- indigodaddy 5y agoGotta be something wrong here no? https://ibb.co/2dFhwN4 https://ibb.co/2dFhwN4
- apengwin 5y agoshuck
- indigodaddy 5y agoLooks like you’re right, but that’s not how Wordle yellow letters are supposed to work.. OP this needs another fix I believe
- laumars 5y agoAre you sure about that? I thought yellow letters were matches but in the wrong placement. Which is what’s happening in your screenshot
- indigodaddy 5y agoI don’t believe it should show yellow like that when you already have the other letters placed/guessed correctly. Should show black again (or white in this version’s case)..
- omnicognate 5y agoThe repeated letters handling is subtle. If your guess contains repeats of a letter it will highlight as many of them as there are repeats in the actual word. Any that can be green will be green and other repeats will be marked yellow to make up the numbers (going from left to right). Repeats left over after that are black. So for example if the target word is QUEEN and you guess EELER (not an accepted guess but let's pretend it is), it would be yellow, black, black, green, black.
- laumars 5y agoAhhh that makes sense. Thanks for the explanation.
- mkdirp 5y agoSlightly off-topic - I've seen wordle become very popular out of nowhere, and haven't been following it. I'm trying to understand how it would be played. Is this basically Lingo (a gameshow on Dutch TV) but for individuals and as an app?
- boomboomsubban 5y agoNot that it matters, but the Dutch Lingo is a local version of an originally US/Canadian game show, filmed in Vancouver but aired in the US, hosted by Ronald Reagan's adopted son. I watched far too many game shows as a child.
- mkdirp 5y agoI did not know this. I had a look, and I'm surprised that the Dutch version is still running where the British version was only just revived, and the rest aren't running at all.
- osrec 5y agoYes, pretty much!
- dTal 5y agoWhy not try it and see for yourself? It's not an app, it's a website: https://www.powerlanguage.co.uk/wordle/ https://www.powerlanguage.co.uk/wordle/
- skrebbel 5y agoFellow Dutchman here, who initially wondered the same. Yes, it's Lingo, but: - One word every day, same word for the whole world. - You don't get a start letter - No ballenbak :-( :-( - No purpose Note that as a fellow comment suggested, Lingo itself isn't an original show either. I don't know where the idea originated but certainly not on Dutch TV, so Wordle is simply a new iteration of an old idea. The innovation is in the accessibility and the low-key virality, not the game dynamics.
- commandlinefan 5y ago
- 0xedd 5y agoNice work! With enough determination, anything can be a one liner in bash. /joke
- aronhegedus 5y agovery cool!
- climech 5y agoPro tip: if you're using Solarized, change to another color scheme before running it.