--- title: TILDE30 subtitle: nine mens morris fennel game author: dozens created: 2024-06-01 updated: 2024-06-14 --- .pl 999i .ce {{title}} .ce {{subtitle}} .IP 01 what is up tilde30 fans it's ya boi dozens back with another up date on my project! today i found a bug that was preventing mills from being recognized as mills. my algorithm for detecting mills is kind of (probably needlessly?) complex. but luckily, i had already written a small module for writing unit tests. so after a small refactor to isolate the individual steps as functions that i can export, i imported them into a test file and was able to more carefully examine each step. turns out the culprit was a small reducer in which i was doing an 'and' when i ought to have been doing an 'or'. literally just changed one word and that fixed it. but i'm still pleased with the process by which i arrived at that realization. i'm now confident that the entirety of the mill detection algorithm does what i want it to do. yay unit tests! . . .IP 02 today's goal was to implement capturing. but instead i discovered a bug in rendering the board, and fixed that. i didn't bother taking the time to really understand why the bug was happening. but after rewriting (and simplifying) the render function, it's working correctly now. so yippee for that. up next: capturing! . . .IP 03 went to go do some remote smol computering. posted up at the library and fixed a small typo that was preventing the game state from advancing from phase 1 to phase 2. and that's about all i could stand doing whilst coding on my phone. later, on my laptop, successfully implemented capturing. next up: prevent a player from capturing a checker that is part of a mill. i think this will lead to a refactoring of the 'mill?' algorithm to generalize it a little more. . . .IP 04 i did not work on tidle30 today. not enough spoons. . . .IP 05 today i did the refactor of the 'mill?' algorithm. i ended up making it much more simple than how i had originally written it. and it works pretty great! the goal of this refactor was to be able check for a mill after a move in order to change the game phase from placing to capture, and also to check for a mill before a move in order to check whether a capture is legal. (a capture cannot break up a mill.) as predicted, my test-driven development workflow made the refactor pretty painless. i just got tripped up for a while because i didn't realize i was passing the wrong type of move to the function. you see, i have two different representations of a move: one is a number 1 - 24 referring to the index of an array of player moves (that is, the game state is a single array with values 0 = vacant, 1 = occupied by player 1, 2 = player 2); and the other is an alphanumeric value (e.g. A1, b4, 7G) referring to a place on the game board. i frequently have to convert e.g. B2 into 4. and what i don't really have right now is a good type system that can tell me if i passed the wrong type to a function. oh well! i guess i'll have to do some manual type checking in each function if i really want that kind of type safety. this completes milestone 3: capture a checker. next up: implement some kind of a play counter so the game can transition from placing to sliding. .nf http://cgit.tilde.town/~dozens/9mm/commit/?id=7776b2011a2585723078b275c838fd7332488d76 .fi . . .IP 06 added transitioning from Placing to Moving, and also implemented Moving logic. this completes milestones 4 and 5. starting to feel like a real game! after getting my ass beat yesterday by unknown function parameter types, i added some type assertions to my new function. and sure enough, later on i passed the wrong value to the function. but this time the assertion failed and gave me a useful error message. wahoooooo! no time wasted tonight haha. up next: fix a bug that prevents captures from happening during the moving phase? watching: maniac (2018) on netflix, starring emma stone and jonah hill. .nf http://cgit.tilde.town/~dozens/9mm/commit/?id=f985dc4e5c9fdec06436c21440c3dc7245369847 .fi . . .IP 07 as i said earlier, there is currently a bug that is preventing the board from updating when a capture happens. instead of working on the bug, i instead focused on how sad it makes me to have to enter 18 - 20 moves every time just to test the capturing ui in the moving phase of the game. this sadness inspired me to write an expect(1) script that will interact with the game ui and make all the moves for me. much faster! then i abstracted and isolated the moves into a data file so that for future ui testing, i can just write down a list of moves and not write a whole expect script. and then i wrote a small awk script that will convert data files into expect files. so now i have some basic ui scripting, which is maybe the first step toward actual ui testing? and i have already used it to confirm the behavior in both the placing phase and the moving phase. so it's not anything unique to phase 2 despite my original suspicions. thanks, tests! up next: fix the dang bug .nf http://cgit.tilde.town/~dozens/9mm/commit/?id=91b1662302c14cf84ca8b90c1f3ec20a585f67a5 .fi . . .IP 08 with fresh eyes, i was able to see the bug that was preventing capturing. it was a single line in the update function. and i deleted it! then i set about trying to allow transitioning moving to flying. but i introduced another bug that i can't find right now.. it prevents capturing in the moving phase. i'll have to look at it more later. right now, i have to finish packing! i'm going on vacation! we'll see whether or not i'm able to continue working on 9mm / tilde30 while away from home. i'm not bringing my laptop. so i'll be limited to coding on my phone with my little folding bluetooth keyboard. . . .IP "WEEK ONE REVIEW" when i look back on week one, i feel like i made more progress than i had expected to. even while spending time on writing unit tests and "ui tests." if i keep up this pace then i expect i'll be done with the game in another week. but i'm on vacation next week, so i'm not confident that i will keep up the pace. whether or not i get around to it as part of tilde30, i do want to build a gui frontend for the game. because i think that would be fun. . . .IP "09-13" i did not do any computering during this five day low-tech beach vacation. . . .IP 14 fixed the bug that prevented capturing during the moving phase. implemented flying! and also handled an edge case where you cannot break up a mill when capturing unless there are no other non-milled checkers. in which case you can break up a mill when capturing. up next: ending the game. . . .IP 15 implemented a game ending! now if a player has fewer than 3 checkers, the other player wins the game. up next: endgame edge case where if a player has 3 or more checkers, but no available legal moves, then they lose. . . .IP "WEEK TWO REVIEW" light week. spent almost all of it on vacation and not working on tilde30 at all. nonetheless, i'm mostly finished with the core of the game. i have one small edge case to iron out and then the game will be all the way complete. i think for my first stretch goal, i want to add some kind of generative story mode based on player moves and decisions, etc. so that by the time you're done with the game, you have a unique little story to take with you. i'm not sure whether i want to do a tracery grammar type of thing.. could be fun to try to write that. well here's to tilde30 being half over! hope everybody is having fun making progress on your projects! . . .IP 16 I wrote the "no-moves?" function to determine whether a player has no legal moves remaining. And a test for it. But integrating it created a bug I need to track down. . . .IP 17 Didn't fix the bug, but rewrote "no-moves?" using the "->" threading macro which is neat. I've never used it before. It's basically the "compose" or "pipe" function that I have enjoyed using before in javascript. up next: fix that bug! . . .IP 18 Finished the game today! (I think!) Working on modularizing the core logic and tidying up some of the libraries. Up next: Story Mode. . . .IP 19 Just did a bunch of tidying up. Consolodated some libs. (All table funs into a 'table' modules, e.g.) Rewrote a couple of functions. Sometimes using the threading macros can replace a 'let' block with a tighter pointfree composition that I sometimes like. My surgery is tomorrow. After that I am going to be in a lot of pain / on a lot of drugs, and will be spending a lot of time on my back. So I'm either going to get a lot on 9mm, or nothing at all. We'll see! . . .IP "20 - 21" I was having back surgery! . . .IP "WEEK THREE REVIEW" Finished the game, and then had a major surgery. Doing some tidying up and housekeeping now. Organzing tests, breaking stuff out into modules. Rewriting and refactoring a couple of functions. Generally getting ready to start thinking about Stretch Goal 1: Story Mode. I have a vague inkling of an idea about doing some kind of generative story / narration based on each move of the game. Assign symbolic meaning to the outer, middle, and inner rings of the board. Add a little twist based on whether the move is a capture, a slide, a placement. That kind of thing. Not sure how I want to do it exactly yet. I'd like to be able to show the story progress as you play. But updating the story every move seems like kind of a lot. Maybe just at every game phase. So three installments. One at the end of Placement, the second at the end of Movement, and the third at the end of the game? Anyway. Up next: big refactor of the validation logic. I don't want it to just print to console if I'm going to eventually support multiple frontends. I need to return an error code or something for the client to interpret. I'm still interested in the Result / Either monad option but I think I'm doing to first try the conventional lua way and throw an error, and then 'pcall' the function and handle the error politely. .pl \n[nl]u