5 Copyright (C) 2004 Benjamin Lynn (blynn@cs.stanford.edu)
7 This program is free software; you can redistribute it and/or
8 modify it under the terms of the GNU General Public License
9 as published by the Free Software Foundation; either version 2
10 of the License, or (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
26 //bits 0...3 specify which directions lead out
29 int boardw
= 10, boardh
= 9;
30 int board
[boardmaxw
][boardmaxh
];
31 int neighbourcount
[boardmaxw
][boardmaxh
];
32 int flags
[boardmaxw
][boardmaxh
];
33 int sourcex
, sourceytop
, sourceybottom
;
47 // 0 = up, 1 = right, 2 = down, 3 = left
54 void add_dir(int *x
, int *y
, int x1
, int y1
, int d
)
60 if (*x
< 0) *x
= boardw
- 1;
61 if (*x
>= boardw
) *x
= 0;
62 if (*y
< 0) *y
= boardh
- 1;
63 if (*y
>= boardh
) *y
= 0;
70 for(i
= 0;i
< boardw
;i
++)
73 for(j
= 0;j
< boardh
;j
++)
80 coord_s opentile
[boardmaxw
* boardmaxh
];
87 opentile
[0].x
= sourcex
;
88 opentile
[1].x
= sourcex
;
89 opentile
[0].y
= sourceytop
;
90 opentile
[1].y
= sourceybottom
;
92 for (i
=0; i
<boardw
; i
++) {
93 for (j
=0; j
<boardh
; j
++) {
95 neighbourcount
[i
][j
] = 0;
98 board
[sourcex
][sourceytop
] = 32;
99 board
[sourcex
][sourceybottom
] = 32;
108 //check if surrounded
111 //special case for top of server
112 if (x
== sourcex
&& y
== sourceytop
) {
113 if (!board
[x
][y
-1]) {
116 //don't need special case for bottom of server
117 //top is blocked by top server
119 for (j
=0; j
<4; j
++) {
120 add_dir(&x1
, &y1
, x
, y
, j
);
121 if (x1
< 0 || x1
>= boardw
122 || y1
< 0 || y1
>= boardh
) {
126 if (!board
[x1
][y1
]) {
133 //if so, remove from list
136 memmove(&opentile
[i
], &opentile
[i
+1], sizeof(coord_s
) * (n
- i
));
142 //not allowed left or right from top of server
143 if (x
== sourcex
&& y
== sourceytop
) {
147 add_dir(&x1
, &y1
, x
, y
, j
);
149 if (x1
< 0 || x1
>= boardw
150 || y1
< 0 || y1
>= boardh
) continue;
151 if (board
[x1
][y1
]) continue;
152 if (no_fourway
&& neighbourcount
[x
][y
] >= 3) continue;
153 neighbourcount
[x
][y
]++;
154 neighbourcount
[x1
][y1
]++;
156 board
[x
][y
] |= (1 << j
);
157 board
[x1
][y1
] |= (1 << ((j
+ 2) % 4));
165 int rotatecw(int d
, int n
)
171 for (i
=0; i
<n
; i
++) {
173 if (d1
>= 16) d1
-= 15;
187 //handle server by temporarily merging the two blocks into one
189 board
[sourcex
][sourceybottom
] |= board
[sourcex
][sourceytop
] & 1;
191 for (i
=0; i
<boardw
; i
++) {
192 for (j
=0; j
<boardh
; j
++) {
193 if (i
== sourcex
&& j
== sourceytop
) continue;
195 d
= board
[i
][j
] & 15;
196 switch (rand() % 4) {
220 board
[sourcex
][sourceytop
] &= ~1;
221 board
[sourcex
][sourceytop
] |= board
[sourcex
][sourceybottom
] & 1;
222 board
[sourcex
][sourceybottom
] &= ~1;
227 coord_s opentile
[boardmaxw
* boardmaxh
];
236 opentile
[0].x
= sourcex
;
237 opentile
[1].x
= sourcex
;
238 opentile
[0].y
= sourceytop
;
239 opentile
[1].y
= sourceybottom
;
241 for (i
=0; i
<boardw
; i
++) {
242 for (j
=0; j
<boardh
; j
++) {
243 if (board
[i
][j
]) tilecount
++;
247 board
[sourcex
][sourceytop
] |= 16;
248 board
[sourcex
][sourceybottom
] |= 16;
256 for (j
=0; j
<4; j
++) {
257 if (board
[x
][y
] & (1 << j
)) {
258 add_dir(&x1
, &y1
, x
, y
, j
);
259 if (x1
< 0 || x1
>= boardw
260 || y1
< 0 || y1
>= boardh
) {
265 if (i
& (1 << ((j
+ 2) % 4))) {
277 if (livecount
== tilecount
) {