I think counting liberties might make sense here.
The idea is to keep a count of how many directions your collective pieces can move in. This is equivalent to the number of open squares or enemy pieces (available squares) adjacent to your movable pieces. If an available square is touched by more than one of your pieces, then it is counted multiple times. We'll call each available square/potential move direction a liberty.
You start by counting the number of initial liberties. You only have to count the number of movable pieces in the front row not touching water. No other piece can move and each piece only has one direction they can move in.
After that, the algorithm to update the number of liberties is fairly simple. You count the number of liberties the old position has, subtracting the number of your pieces it blocks and count the number of liberties the new position has, again subtracting the number of pieces it blocks. You add this to the total liberties and you have the new value.
I haven't coded java for a while, so my examples will be in pseudo code/python, but the idea should transfer.
directions = [(0,1),(0,-1),(1,0),(-1,0)]
for d in directions:
if (SpaceIsAvailable(oldPosition + d)):
liberties--
if (SpaceIsMovable(oldPosition + d)):
liberties++
if(SpaceIsAvailable(newPosition + d)):
liberties++
if(SpaceIsMovable(newPosition + d)):
liberties--
SpaceIsAvailable
is true if the spot is empty or the opponent. SpaceIsMovable
is true if the spot is your piece and is movable.
When the opponent moves his piece, your liberties can't change. Neither SpaceIsAvailable
or SpaceIsMovable
will change values.
If your piece is removed, you just run the same algorithm, but drop the newPosition
section.
for d in directions:
if (SpaceIsAvailable(position + d)):
liberties--
if (SpaceIsMovable(position + d)):
liberties++
Now, if liberties > 0
, you have movable pieces. All you need to do is keep track of an integer for both players, and you can skip any calculations determining if any pieces are available.
This doesn't quite work if you enforce the rules preventing move repetition. I'm not sure how you're going to implement that. If you do it by figuring out which pieces aren't allowed to move, you can simply compare the total number of liberties to their liberties instead of to 0
. If it's equal, then there's no moves left. If the total liberties is lower than the liberties of the pieces that can't move, there's either something wrong with my algorithm or your code.
If I read the rules for repetition correctly, there can only be one piece at a time that can't move and thus only one set of liberties that you have to consider.
frozenLiberties = 0
if (frozenPiece):
for d in directions:
if (SpaceIsAvailable(frozenPiece + d)):
frozenLiberties++
if (liberties > frozenLiberties):
// moves available.
else:
// No moves available.