Implementing the actual rules of Reversi took a surprising amount of time—which probably means I really over-engineered things. I also ran into a few hiccups and had to restructure things to make my life easier. For instance, I switched from unsigned integers to signed integers so that I wouldn’t have to do as many conversions when doing arithmetic. I also decided to use my 1D indices explicitly for many of my internal functions rather than calling get_piece, which converts 2D coordinate to a 1D index (so (2, 3) on a 4x4 board would become 11). Another noteworthy change was the decision to map the last bit of the bitmask to the first space on the board, as opposed to reading the bitmasks from left to right as I did previously. Reading the bitmasks from right to left makes more sense in hindsight since the 2^0th place now corresponds with the 0th index, the 2^1st place corresponds with the 1st index, etc.
One clunky detail I had to deal with using 1D indices instead of 2D coordinates was diagonals. Moving one square up and one to the right on an NxN array is generally the same as moving N-1 indices backwards on the flattened 1D array, unless you’re on the last space on a row, in which case you’d jump back to the start of the row rather than moving diagonally. This is definitely not the intended behavior. My fix doesn’t feel particularly elegant: I ended up converting the 1D coordinate into a 2D coordinate to make sure the row and column coordinates wouldn’t change by more than one before stepping the index. I may think of a nicer solution later, but it works for now. :)
Below is a quick demo Asciinema cast, where I’m playing on a 4x4 grid. (All sizes are supported up to 8x8, but a full 8x8 would have taken a while to record.)
Comments 0
No comments yet. Be the first!
Sign in to join the conversation.