A simple brute-force optimization that came to mind when reading the title was:
1,2,3, 4,5,6, 7,8,9
For each cell, you can perform 3 checks: Horizontal (H), Vertical (V) and Diagonal (D(D1, D2))
But not all checks are needed for each cell, so lets see:
Cell 1: H, V, D1 Cell 2: V Cell 3: V, D2 Cell 4: H Cell 5: - Cell 6: - Cell 7: H Cell 8: - Cell 9: -
In case its not clear:
Cell 2: H is not needed because its covered by Cell1-H and D is simply not possible
Cell 5: H is covered by Cell4-H, Diagonals are covered by Cell1-D1 and Cell3-D2 and V is covered by Cell2-V
So this leaves you with 3x H, 3x V and 2x D checks ~ 8x Checks in total, which is much less then 36x Checks
Ofc the other solutions are much more elegant (referring to the one suggested at #5)
Edit: Oh and ofc, the traversal itself could look like this:
// Horizontal for (int i = 0; i < 3; i++) ... field[(pos.x + i) % 3, pos.y] ... // Vertical for (int i = 0; i < 3; i++) ... field[pos.x, (pos.y + i) % 3] ... // Diag 1 for (int i = 0; i < 3; i++) ... field[(pos.x + i) % 3, (pos.y + i) % 3] ... // Diag 2 for (int i = 0; i < 3; i++) ... field[(pos.x - i) % 3, (pos.y + i) % 3] ...
Im not sure about whether C++ % (mod) handles negative numbers mathematically correctly..