Sokoban/C: Difference between revisions
Content added Content deleted
m (replace asserts) |
(added some easy deadlock checks) |
||
Line 11: | Line 11: | ||
int w, h, n_boxes; |
int w, h, n_boxes; |
||
int offset[4] = {0, 0, 1, -1}; |
int offset[4] = {0, 0, 1, -1}; |
||
uint8_t *board, *goals, *live; |
uint8_t *board, *goals, *live, *tmpmap; |
||
int *dist; |
int *dist; |
||
Line 94: | Line 94: | ||
w = x, h = y; |
w = x, h = y; |
||
ensure( board = calloc(w * h, sizeof(uint8_t)) ); |
ensure( board = calloc(w * h, sizeof(uint8_t)) ); |
||
ensure( tmpmap= calloc(w * h, sizeof(uint8_t)) ); |
|||
ensure( goals = calloc(w * h, sizeof(uint8_t)) ); |
ensure( goals = calloc(w * h, sizeof(uint8_t)) ); |
||
ensure( live = calloc(w * h, sizeof(uint8_t)) ); |
ensure( live = calloc(w * h, sizeof(uint8_t)) ); |
||
Line 134: | Line 135: | ||
} |
} |
||
memcpy(tmpmap, board, sizeof(uint8_t) * w * h); |
|||
return state; |
return state; |
||
} |
} |
||
Line 233: | Line 235: | ||
buckets[i] = s; |
buckets[i] = s; |
||
return s; |
return s; |
||
⚫ | |||
inline void sort_state(state_t *n) |
|||
{ |
|||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
} |
|||
} |
} |
||
Line 245: | Line 261: | ||
{ |
{ |
||
for (int i = 1; i <= n_boxes; i++) |
for (int i = 1; i <= n_boxes; i++) |
||
if (!live[s->c[i]]) |
if (!live[s->c[i]]) return 1; |
||
⚫ | |||
sort_state(s); |
|||
return 0; |
|||
int ret = 0; |
|||
for (int i = 1; i <= n_boxes; i++) |
|||
tmpmap[s->c[i]] = box; |
|||
/* check if two boxes are next to each other and sitting along a wall |
|||
or some such */ |
|||
for (int i = 1; i < n_boxes; i++) { |
|||
int x = s->c[i]; |
|||
int y = s->c[i + 1]; |
|||
if (y == x + 1 && !(goals[x] && goals[y])) { |
|||
if ((tmpmap[x - w] >= wall && tmpmap[y - w] >= wall) || |
|||
(tmpmap[x + w] >= wall && tmpmap[y + w] >= wall)) |
|||
{ |
|||
ret = 1; |
|||
goto bail; |
|||
} |
|||
if ((tmpmap[x - w] == wall || tmpmap[x + w] == wall) && |
|||
(tmpmap[y - w] == wall || tmpmap[y + w] == wall)) |
|||
{ |
|||
ret = 1; |
|||
goto bail; |
|||
} |
|||
} |
|||
for (int j = i + 1; j <= n_boxes; j++) { |
|||
y = s->c[j]; |
|||
if (y == x + w) { |
|||
if (goals[x] && goals[y]) continue; |
|||
if ((tmpmap[x - 1] >= wall && tmpmap[y - 1] >= wall) || |
|||
(tmpmap[x + 1] >= wall && tmpmap[y + 1] >= wall)) |
|||
{ |
|||
ret = 1; |
|||
goto bail; |
|||
} |
|||
if ((tmpmap[x - 1] == wall || tmpmap[x + 1] == wall) && |
|||
(tmpmap[y - 1] == wall || tmpmap[y + 1] == wall)) |
|||
{ |
|||
ret = 1; |
|||
goto bail; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
bail: for(int i = 1; i <= n_boxes; i++) |
|||
tmpmap[s->c[i]] = space; |
|||
⚫ | |||
} |
} |
||
Line 315: | Line 379: | ||
n->c[i] = (s->c[i] == c1) ? c2 : s->c[i]; |
n->c[i] = (s->c[i] == c1) ? c2 : s->c[i]; |
||
n->c[0] = c1; |
n->c[0] = c1; |
||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
return n; |
return n; |
||
} |
} |
||
Line 505: | Line 556: | ||
" ##### " |
" ##### " |
||
" # # " |
" # # " |
||
" # |
" #$ # " |
||
" ### $## " |
" ### $## " |
||
" # $ $ # " |
" # $ $ # " |
||
"### # ## # ######" |
"### # ## # ######" |
||
"# # ## ##### ..#" |
"# # ## ##### ..#" |
||
"# $ $ |
"# $ $ ..#" |
||
"##### ### #@## ..#" |
"##### ### #@## ..#" |
||
" # #########" |
" # #########" |
||
Line 537: | Line 588: | ||
for (int d = 1; d < known_moves; d++) { |
for (int d = 1; d < known_moves; d++) { |
||
state_t *s = queue[d]; |
state_t *s = queue[d]; |
||
printf("depth %d (mem: %dM)\r", d, |
printf("depth %d (%d records, mem: %d/%dM)\r", d, filled, |
||
filled * state_size / (1 << 20), |
|||
alloced * state_size / (1 << 20)); |
|||
fflush(stdout); |
fflush(stdout); |
||
Line 553: | Line 606: | ||
free(buckets); |
free(buckets); |
||
free(board); |
free(board); |
||
free(tmpmap); |
|||
free(goals); |
free(goals); |
||
free(live); |
free(live); |