## Play Connect-Five

Did you come here via search engine? Sorry, this webpage won't play Connect-Five with you directly. This is from a discussion in a free on-line programming course.

I don't have a Connect-Five Solver I'm ready to show to the world. In fact, the game is Unsolved, so perhaps the reader would like to write a program to solve it, and be the first in the solar system to know the winning moves!

If you're familiar with Connect-Four on the 6-x-7 board, Connect-Five can be explained easily. It's just the same as Connect-Four except:

• Drop two stones instead of one on moves 2 - 21. (Drop a single stone on the first move and, perforce, on the 22nd move if the game lasts that long.)
• It takes five in a row to win, not four.

In the ``inner loop'' of any Connect-Five solver, a critical task will be to see if a given stone completes five-in-a-row, horizontally, vertically or diagonally. Here is the high-speed subroutine to do that, with the macros and typedefs it needs to compile. No comments -- but a clever programmer should be able to ``reverse engineer'' the data assumptions from this fragment.

```

typedef long long       Bigint;

typedef enum {
Red, White, Draw, Illegal, Unknown,
} Code;

#define xy2k(x, y)      ((x) | ((y) << 3))
#define Bit(k)          ((Bigint)1 << (k))
#define But(k)          ((k) < 0 || (k) > 60 ? 0 : Bit(k))

#define ISM(k1, k2, k3, k4, k5) {                                        \
if ((myocc | ~(But(k1) | But(k2) | But(k3) | But(k4) | But(k5))) \
== (Bigint)(-1)) goto ret1;                              \
}

#define Esub(z, d)                                                      \
ISM((z), (z)+(d), (z)+(d)+(d), (z)+(d)+(d)+(d), (z)+(d)+(d)+(d)+(d))

#define E(y, x)                                                         \
case xy2k(x, y):                                                \
if (y > 3) Esub(xy2k(x, y)-32, 8);                              \
if (x > 3         ) Esub(xy2k(x, y)-4, 1);                      \
if (x > 2 && x < 6) Esub(xy2k(x, y)-3, 1);                      \
if (x > 1 && x < 5) Esub(xy2k(x, y)-2, 1);                      \
if (x > 0 && x < 4) Esub(xy2k(x, y)-1, 1);                      \
if (         x < 3) Esub(xy2k(x, y), 1);                        \
if (x > 3          && y > 3         ) Esub(xy2k(x, y)-36, 9);   \
if (x > 2 && x < 6 && y > 2 && y < 5) Esub(xy2k(x, y)-27, 9);   \
if (x > 1 && x < 5 && y > 1 && y < 4) Esub(xy2k(x, y)-18, 9);   \
if (x > 0 && x < 4 && y > 0 && y < 3) Esub(xy2k(x, y)-9, 9);    \
if (         x < 3 &&          y < 2) Esub(xy2k(x, y), 9);      \
if (x < 3          && y > 3         ) Esub(xy2k(x, y)-28, 7);   \
if (x < 4 && x > 0 && y > 2 && y < 5) Esub(xy2k(x, y)-21, 7);   \
if (x < 5 && x > 1 && y > 1 && y < 4) Esub(xy2k(x, y)-14, 7);   \
if (x < 6 && x > 2 && y > 0 && y < 3) Esub(xy2k(x, y)-7, 7);    \
if (         x > 3 &&          y < 2) Esub(xy2k(x, y), 7);      \
break;

/* In the board with stones located per the ioccup bitmask
* (red stones per ired bitmask)
* does a stone by mover at xy win at once?
*/
Code ismate(xy, mover, ioccup, ired)
Code    mover;
Bigint ioccup, ired;
{
register Bigint myocc;

myocc = ioccup & (mover == Red ? ired : ~ired) | Bit(xy);

switch (xy) {
E(0, 0) E(0, 1) E(0, 2) E(0, 3) E(0, 4) E(0, 5) E(0, 6)
E(1, 0) E(1, 1) E(1, 2) E(1, 3) E(1, 4) E(1, 5) E(1, 6)
E(2, 0) E(2, 1) E(2, 2) E(2, 3) E(2, 4) E(2, 5) E(2, 6)
E(3, 0) E(3, 1) E(3, 2) E(3, 3) E(3, 4) E(3, 5) E(3, 6)
E(4, 0) E(4, 1) E(4, 2) E(4, 3) E(4, 4) E(4, 5) E(4, 6)
E(5, 0) E(5, 1) E(5, 2) E(5, 3) E(5, 4) E(5, 5) E(5, 6)
}
return Unknown;
ret1:
return mover;
}

```