#include "function.h"
+typedef struct {
+ int x;
+ int y;
+} point;
+
int strmaxlen (char *str, char ch)
{
int len = 0;
return (x >= 0) && (x < board->width) && (y >= 0) && (y < board->height) ? *getcell (board, x, y) : 0;
}
+int _moveelements (board_t *board, point *pt, int dir)
+{
+ /* define direction */
+ point _move = {0, 0};
+ point *move = &_move;
+ switch (dir) {
+ case 0:
+ move->y--;
+ break;
+ case 1:
+ move->x++;
+ break;
+ case 2:
+ move->y++;
+ break;
+ case 3:
+ move->x--;
+ break;
+ }
+
+ /* check 2 next positions in line */
+ int rc = 1;
+ char next = getvalue (board, pt->x + move->x, pt->y + move->y);
+ char next2 = getvalue (board, pt->x + 2 * move->x, pt->y + 2 * move->y);
+ switch (next) {
+ case '$':
+ case '*':
+ switch (next2) {
+ case ' ':
+ *getcell (board, pt->x + 2 * move->x, pt->y + 2 * move->y) = '$';
+ break;
+ case '.':
+ *getcell (board, pt->x + 2 * move->x, pt->y + 2 * move->y) = '*';
+ break;
+ default:
+ rc = 0;
+ }
+ }
+
+ /* push box */
+ if (rc == 1) {
+ switch (next) {
+ case '$':
+ *getcell (board, pt->x + move->x, pt->y + move->y) = ' ';
+ break;
+ case '*':
+ *getcell (board, pt->x + move->x, pt->y + move->y) = '.';
+ break;
+ }
+ }
+
+ /* move sokoban */
+ switch (next) {
+ case ' ':
+ *getcell (board, pt->x + move->x, pt->y + move->y) = '@';
+ rc = 1;
+ break;
+ case '.':
+ *getcell (board, pt->x + move->x, pt->y + move->y) = '+';
+ rc = 1;
+ break;
+ default:
+ rc = 0;
+ }
+
+ /* clean old sokoban position */
+ if (rc == 1) {
+ char sokoban = getvalue (board, pt->x, pt->y);
+ switch (sokoban) {
+ case '@':
+ *getcell (board, pt->x, pt->y) = ' ';
+ break;
+ case '+':
+ *getcell (board, pt->x, pt->y) = '.';
+ break;
+ }
+ }
+
+ return rc;
+}
+
+void _findsokoban (board_t *board, point *pt)
+{
+ int x, y;
+ for (x = 0; x < board->width; x++) {
+ for (y = 0; y < board->height; y++) {
+ switch (getvalue (board, x, y)) {
+ case '@':
+ case '+':
+ pt->x = x;
+ pt->y = y;
+ break;
+ }
+ }
+ }
+}
+
+void movesokoban (board_t *board, int dir)
+{
+ point sokoban = {-1, -1};
+ _findsokoban (board, &sokoban);
+ if (sokoban.x != -1) {
+ _moveelements (board, &sokoban, dir);
+ }
+}
+
/* vim: set ts=4 sw=4 et: */