Tetronimia is a version of that game we all know and have (or had at some stage in our lives) some kind of love-hate relationship with.
It's written in Nim of course, works in your terminal (including Windows cmd.exe), has colors and a bunch of options, including gameseed for competitive replay, it uses variation of Vim keycodes for controls. The official guidelines for the original game are surprisingly dense, so I didn't try to implement them but I addressed them to choose the default/optional behaviour for the game.
Full announcement is posted in my blog: https://indiscipline.github.io/post/tetronimia/
There I touch upon some mildly interesting specifics about the code. You can jump directly to Nim stuff.
The repo at https://github.com/indiscipline/tetronimia contains a condensed Readme which lacks any specifics about the code. A couple of you already have complemented me on that description, thanks a lot.
I know for a fact that to learn a new programming language requires reading other people's code. But I feel there's often a lack of things to actually dissect when you're past the helloworld and fizzbuzz stage but aren't confident enough with the real world projects with their scope and LOC counters at many thousands. Tetronimia is very basic, has about 500 lines of code total, including empty lines and comments (which I tried to write in as much as seemed reasonable), so my hope is that it could be one of the code snippets to fill the gap mentioned and that programming novices wouldn't be intimidated to read. On the other hand, it's better to read something decent, and I have my doubts about decency of my code :P
I'll be happy to hear any kind of feedback from you all. I still love hearing the specifics of how my code sucks, so feel free to share.
tetronimia user$ nimble build
Verifying dependencies for tetronimia@0.1.0
Tip: 1 messages have been suppressed, use --verbose to show them.
Error: Unsatisfied dependency: nim (>= 1.5.1)
Latest stable version of Nim is 1.4.8, but nimble says your program wants 1.5.1.
Don't see one that runs on my machine.
Really, I can wait.
Now, hopefully builds on stable Nim >= 1.4.6, as we migrated from dropped std/channels to threading/channels.
Tech trivia: As an absolutely unnecessary refactoring, the singlyLinkedList, which was used to hold the state of the "pile" of fallen blocks (see the description in the blog post), was replaced with a custom array-based structure `shufflearray` which maintains a level of index indirection, instead of actually moving array elements.
ps: Special ping for @cantanima, as promised.
Tetronimia is now available to users of Arch and its derivative GNU/Linux distros through aur: https://aur.archlinux.org/packages/tetronimia (you can vote there ;) )
Thanks to our community chat on IRC/Matrix/Discord for figuring out the proper way to make the PKGBUILD for the package.
Please, file a bug report then. Don't forget to mention your OS, your terminal and make a screenshot, if possible.
Does just clearing your terminal (usually, Ctrl+L) not help in your case?
I hope the bug is fixed now, I tagged the new release v0.2.1.
The thread dealing with user input is waiting for it in a blocking call. We currently rely on the OS to clean up after ther program finishes and terminate all the threads. However, when the program quits, the thread gets culled by the OS and the getch procedure doesn't get to restore the state of the stdin, so to fix the bug we have to do it manually now. Thanks to @ElegantBeef for the implementation of the exitproc hook which restores the state of the terminal.
This is an insteresting bug, as it was specific to Bash and slipped trough my main testing rigs both on Linux (Fish shell) and Windows (cmd.exe).
Usage excerpt from the built-in help:
-k=, --kbd= Keyboard controls. Takes a name of a built-in preset or a string with
the custom keybindings. CtrlC always exits, so "Exit" can be omitted.
Built-in presets and their expanded form:
vim = L:h;R:l;Dn:enter,j;Rot:tab,k;Drop:space,d;Hold:f;Ps:escape,p;Exit:q
emacs = L:b;R:f;Dn:enter,n;Rot:tab,r;Drop:space,d;Hold:x;Ps:escape,p;Exit:q
wasd = L:a;R:d;Dn:s;Rot:tab,w;Drop:space,e;Hold:q;Ps:`,p;Exit:escape
casual = L:left;R:right;Dn:down;Rot:up;Drop:space;Hold:tab;Ps:escape;Exit:x
Valid keys for user presets: printable characters, escape, enter, tab, space,
arrow keys, pgup, pgdown, home, end, insert, delete, backspace.
PS: You'll probably need to quote your mapping, depending on your shell syntax.
That was fun. The module for dealing with the keyboard mappings is about 1/3 loc of the main file, but it would be a few times bigger if I were to write/vendor-in handling of keys (including key sequences) for both posix and Windows. Thankfully, we're just up one dependence. My plans of doing without illwill failed :)
This looks great. The key mapping is great.
Have you tried this with any competitive players?
Thanks a lot, @treeform.
I was looking into it but wanted to get at least a few eyes on it before wider advertisement to ensure it actually works. Besides, competitive players are all into weird stuff like wall-kicks and T-spins, which I presently have zero intention to support, so I'm not sure who represent Tetronimia's actual audience.