Suppose I have some board game with 2 players. Each player takes turns placing pieces of the board at random locations. A player wins if they have n consecutive pieces in a row (vertically or horizontally). Note that the board can extended indefinitely.
I want to a implement a game such as this, but I'm stuck on how to check the winning condition efficiently. After every move, we can, off coarse, check in all 4 directions to see if we satisfied the winning condition, but that's a O(n) search after every move.
I was thinking of caching the results, although I don't think that helps in this case.
e.g., suppose we have cached results at (i - 1, j) and the next piece is placed at (i, j). we can use the results at the former to compute the results at the latter, so this ends up being a O(1) search, but the problem is, we would have to then update the cached results for all the neighbors up to k squares away, so we have the same issue as before.
Is there a better way to code this problem?
Say each cell stores:
To avoid expensive updates, we only guarantee run length correctness for the cells at the ends of consecutive runs. E.g. if you're the leftmost cell of a run, the correctness of the length of the run to the right is guaranteed.
On a player claiming a cell, check the 4 neighboring cells.
Example 1: X = unclaimed; 0 = player 0, 1 = player 1. Say along some dimension we have ...XXXX000X000000XXXX...
...and then, player 0 claims the cell separating the run of 3 0s from the run of 6 0s. When checking the neighbors, we see that there's a run that extends 3 to the left and 6 to the right. With the new cell, we have a run of 10. In O(1) we update the 2 endpoints to be 10 in the horizontal dimension.
Each time a cell is claimed, we update at most 4 cells in O(1) time. Because we know the length of the runs, we can find the endpoints in O(1).