12-7-24
I have added two more items on the outline to the project. The first of these is the ability to step the program as well as have it run at a variety of various time scales. Stepping can be toggled on and off by pressing the P (pause) button, and pressing E to move forward one step. When unpaused, you can adjust the simulator to move between options ranging from one step per frame to one step every five minutes with the Q (shorter delay) and W (longer delay) keys.
The second is saving the state of the board to a file upon program exit. I did this using Zig's standard library and its I/O function. I was originally considering memory mapping the file to make it more comparable to how the state will be stored on a microcontroller, but chose not to ultimately. This was because I saw a post somewhere mentioning how memory mapping small files is bad for performance, even though this performance hit wouldn't have mattered much in this application. I also made use of Zig's error handling to account for the case when no state exists. By catching the error the openFile
function throws, I can check if the error was due to the file not being found and create the file while throwing an error if either the openFile
call failed for another reason or creating a new file fails.
I have also decided against compressing the state, so I have checked it off of the list. I was originally planning to use some form of run-length encoding to save on space. This likely would have worked well after a few steps of the game when the board is mostly dead cells. However, using only RLE would likely have greatly increased the space needed to store the state at the early steps when the board is random with few continuous sequences. I was planning on having extra data to indicate the length of the saved data and whether or not it was run-length encoded. However, this would then require an algorithm to determine when RLE should be employed, which adds extra complexity. This would also require that the persistent storage of the microcontroller be large enough to store the entire uncompressed state anyways.
Now that this is done, I will be working on separating all of the platform independent code away from the platform-dependent functionality. This should not be too hard as all of the usage of the standard library and raylib is inside of the main function. All that will be needed is to abstract the details of the display update and state read in such a way that code can work with the simulator the same as the final product.