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 sourcex
, sourceytop
, sourceybottom
;
46 // 0 = up, 1 = right, 2 = down, 3 = left
53 void add_dir(int *x
, int *y
, int x1
, int y1
, int d
)
59 if (*x
< 0) *x
= boardw
- 1;
60 if (*x
>= boardw
) *x
= 0;
61 if (*y
< 0) *y
= boardh
- 1;
62 if (*y
>= boardh
) *y
= 0;
68 coord_s opentile
[boardmaxw
* boardmaxh
];
75 opentile
[0].x
= sourcex
;
76 opentile
[1].x
= sourcex
;
77 opentile
[0].y
= sourceytop
;
78 opentile
[1].y
= sourceybottom
;
80 for (i
=0; i
<boardw
; i
++) {
81 for (j
=0; j
<boardh
; j
++) {
83 neighbourcount
[i
][j
] = 0;
86 board
[sourcex
][sourceytop
] = 32;
87 board
[sourcex
][sourceybottom
] = 32;
99 //special case for top of server
100 if (x
== sourcex
&& y
== sourceytop
) {
101 if (!board
[x
][y
-1]) {
104 //don't need special case for bottom of server
105 //top is blocked by top server
107 for (j
=0; j
<4; j
++) {
108 add_dir(&x1
, &y1
, x
, y
, j
);
109 if (x1
< 0 || x1
>= boardw
110 || y1
< 0 || y1
>= boardh
) {
114 if (!board
[x1
][y1
]) {
121 //if so, remove from list
124 memmove(&opentile
[i
], &opentile
[i
+1], sizeof(coord_s
) * (n
- i
));
130 //not allowed left or right from top of server
131 if (x
== sourcex
&& y
== sourceytop
) {
135 add_dir(&x1
, &y1
, x
, y
, j
);
137 if (x1
< 0 || x1
>= boardw
138 || y1
< 0 || y1
>= boardh
) continue;
139 if (board
[x1
][y1
]) continue;
140 if (no_fourway
&& neighbourcount
[x
][y
] >= 3) continue;
141 neighbourcount
[x
][y
]++;
142 neighbourcount
[x1
][y1
]++;
144 board
[x
][y
] |= (1 << j
);
145 board
[x1
][y1
] |= (1 << ((j
+ 2) % 4));
153 int rotatecw(int d
, int n
)
159 for (i
=0; i
<n
; i
++) {
161 if (d1
>= 16) d1
-= 15;
175 //handle server by temporarily merging the two blocks into one
177 board
[sourcex
][sourceybottom
] |= board
[sourcex
][sourceytop
] & 1;
179 for (i
=0; i
<boardw
; i
++) {
180 for (j
=0; j
<boardh
; j
++) {
181 if (i
== sourcex
&& j
== sourceytop
) continue;
183 d
= board
[i
][j
] & 15;
184 switch (rand() % 4) {
208 board
[sourcex
][sourceytop
] &= ~1;
209 board
[sourcex
][sourceytop
] |= board
[sourcex
][sourceybottom
] & 1;
210 board
[sourcex
][sourceybottom
] &= ~1;
215 coord_s opentile
[boardmaxw
* boardmaxh
];
224 opentile
[0].x
= sourcex
;
225 opentile
[1].x
= sourcex
;
226 opentile
[0].y
= sourceytop
;
227 opentile
[1].y
= sourceybottom
;
229 for (i
=0; i
<boardw
; i
++) {
230 for (j
=0; j
<boardh
; j
++) {
231 if (board
[i
][j
]) tilecount
++;
235 board
[sourcex
][sourceytop
] |= 16;
236 board
[sourcex
][sourceybottom
] |= 16;
244 for (j
=0; j
<4; j
++) {
245 if (board
[x
][y
] & (1 << j
)) {
246 add_dir(&x1
, &y1
, x
, y
, j
);
247 if (x1
< 0 || x1
>= boardw
248 || y1
< 0 || y1
>= boardh
) {
253 if (i
& (1 << ((j
+ 2) % 4))) {
265 if (livecount
== tilecount
) {