A simple to understand solution without excessive loops (only pseudocode provided, let me know if you need more explanation):
I assume your 2-d array runs like this:
board = [
[...],
[...],
[...],
...
];
I.e. the inner arrays represent the horizontal rows of the board.
I also assume that the array is populated by "b", "w", and "x", representing black pieces, white pieces, and empty squares, respectively.
My solution is somewhat divide-and-conquer, so I've divided it into the 3 cases below. Bear with me, it may seem more complex than simply running multiple nested loops at first, but the concept is easy to understand, read, and with the right approach, quite simple to code.
Horizontal lines
Let's first consider the case of detecting a win situation ONLY if the line is horizontal - this is the easiest. First, join a row into a single string, using something like board[0].join("")
. Do this for each row. You end up with an array like this:
rows = [
"bxwwwbx...",
"xxxwbxx...",
"wwbbbbx...",
...
]
Now join THIS array, but inserting an "x" between elements to separate each row: rows.join("x")
.
Now you have one long string representing your board, and it's simply a matter of applying a regexp to find consecutive "w" or "b" of exactly 5 length: superString.test(/(b{5,5})|(w{5,5})/)
. If the test returns true
you have a win situation. If not, let's move on to vertical lines.
Vertical lines
You want to reuse the above code, so create a function testRows
for it. Testing for vertical lines is exactly the same process, but you want to transpose the board, so that rows become columns and columns become rows. Then you apply the same testRows
function. Transposing can be done by copying values into a new 2-d array, or by writing a simple getCol
function and using that within testRows
.
Diagonal lines
Again, we want to reuse the `testRows' function. A diagonal such as this:
b x x x x
x b x x x
x x b x x
x x x b x
x x x x b
Can be converted to a vertical such as this:
b x x x x
b x x x
b x x
b x
b
By shifting row i
by i
positions. Now it's a matter of transposing and we are back at testing for horizontals. You'll need to do the same for diagonals that go the other way, but this time shift row i
by length - 1 - i
positions, or in your case, 18 - i
positions.
Functional javascript
As a side note, my solution fits nicely with functional programming, which means that it can be quite easily coded if you have functional programming tools with you, though it's not necessary. I recommend using underscore.js as it's quite likely you'll need basic tools like map
, reduce
and filter
in many different game algorithms. For example, my section on testing horizontal lines can be written in one line of javascript with the use of map
:
_(board).map(function (row) {return row.join("")}).join("x").test(/(b{5,5})|(w{5,5})/);