This is much more commitment than I was expecting from anyone. I am thoroughly impressed by your high score. Thank you so much!
> I'd say a bag system
This would have been pretty easy to make (a simple array of integers), but I decided against it, as it would allow you to do some stuff like "okay, this game has had 3 "1", so I am much more likely to get a different number on my next draw..." which can lead to situations like "damn, I would have done better had I counted my tiles better". I suppose I could have added counters showing how many remaining tiles there are of each type, but that's exiting the 48h timeframe.
My original design was a bit different. I wanted to have multiple different types of Planes and flavour to match. For example, a "dark" plane that slowly tends towards darkness every turn. Or an "assimilative" plane that causes the rows next to it to slowly converge to match its assigned polarity. However, Sunday, I got caught up for nearly 4-5 hours making the transition between black and white seamless when you press "5" - programming-wise, it is super cursed. I was learning the game engine and the Rust programming language at the same time.
I don't really want to touch this again for a little while. But eventually, the shame of having "unsafe{}" and "static mut" in my codebase for any employer to be horrified by might get the better of me and bring me to improve my game.
Check out the physical card game "Urbion" if you liked this. I took inspiration from it for the "balancing rows" core mechanic, though the whole swap-sides-and-claim thing is by me.