algorithm.c
author viric@llimona
Sat, 06 May 2006 10:08:11 +0200
changeset 7 834620831e7a
parent 6 bfbca2c0fc70
child 8 b41a580b3abe
permissions -rw-r--r--
Added pedantic into compilation flags.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
6
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
     1
#include <assert.h>
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
     2
#include <string.h>
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
     3
#include "general.h"
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
     4
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
     5
/* Variables related to the showing of information by os */
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
     6
extern float percent_to_show;
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
     7
extern int depth_to_show;
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
     8
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
     9
extern int max_depth;
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
    10
extern int min_depth_period;
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
    11
extern int max_depth_period;
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
    12
extern struct Map * actual_map;
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
    13
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
    14
#if 0 /*** THIS IS AN ERROR!!!  The box_will_be_blocked function doesn't work!*/
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
    15
 Situation:
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
    16
    
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
    17
  ->@$ #
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
    18
      $
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
    19
*/
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
    20
int box_will_be_blocked(const struct Map * m, const struct Position mov,
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
    21
	const struct Position box_pos)
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
    22
{
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
    23
	struct Position next_pos2, tmp, tmp2[2];
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
    24
	int i;
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
    25
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
    26
	next_pos2.x = box_pos.x + mov.x;
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
    27
	next_pos2.y = box_pos.y + mov.y;
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
    28
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
    29
	tmp.x = next_pos2.x + mov.x;
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
    30
	tmp.y = next_pos2.y + mov.y;
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
    31
	tmp2[0].x = next_pos2.x + mov.y;
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
    32
	tmp2[0].y = next_pos2.y + mov.x;
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
    33
	tmp2[1].x = next_pos2.x - mov.y;
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
    34
	tmp2[1].y = next_pos2.y - mov.x;
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
    35
	for (i=0; i < 2; i++)
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
    36
	{
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
    37
		if (m->man_moves[tmp.y][tmp.x] == WALL &&
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
    38
			m->man_moves[tmp2[i].y][tmp2[i].x] == BOX)
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
    39
		{
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
    40
			return TRUE;
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
    41
		}
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
    42
		else if (m->man_moves[tmp.y][tmp.x] == BOX &&
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
    43
			m->man_moves[tmp2[i].y][tmp2[i].x] == WALL)
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
    44
		{
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
    45
			return TRUE;
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
    46
		}
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
    47
		else if (m->man_moves[tmp.y][tmp.x] == BOX &&
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
    48
			m->man_moves[tmp2[i].y][tmp2[i].x] == BOX)
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
    49
		{
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
    50
			return TRUE;
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
    51
		}
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
    52
	}
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
    53
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
    54
	return FALSE;
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
    55
}
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
    56
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
    57
int is_corner_area(const struct Map * m, const struct Position p,
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
    58
	const struct Position box, const struct Position new_box)
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
    59
{
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
    60
	int NumMoves, NewMoves;
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
    61
	struct Position pos[MAX_MOVES];
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
    62
	struct Position new_pos[MAX_MOVES];
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
    63
	char corners[MAX_Y][MAX_X];
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
    64
	int i,j;
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
    65
	struct Position next_pos;
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
    66
	char *next_cell;
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
    67
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
    68
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
    69
	/* Blank the garden */
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
    70
	for (j = 0; j<m->SizeY; j++)
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
    71
		for (i=0; i<m->SizeX; i++)
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
    72
			corners[j][i] = m->Cells[j][i];
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
    73
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
    74
	/* Let's put the boxes */
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
    75
	for (i = 0; i<m->NumBoxes; i++)
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
    76
		corners[m->Box[i].y][m->Box[i].x] = BOX;
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
    77
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
    78
	/* Let's put our box - it can be simply added */
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
    79
	corners[new_box.y][new_box.x] = BOX;
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
    80
	/* Let's remove the original box. */
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
    81
	corners[box.y][box.x] = BLANK;
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
    82
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
    83
	NewMoves = 1;
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
    84
	new_pos[0] = p;
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
    85
	while (NewMoves > 0)
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
    86
	{
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
    87
		/* The before named "New Moves" become the moves we have
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
    88
		   to analyze */
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
    89
		NumMoves = NewMoves;
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
    90
		for (i=0; i<NewMoves; i++)
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
    91
		{
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
    92
			pos[i] = new_pos[i];
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
    93
		}
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
    94
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
    95
		/* Search new positions for each position */
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
    96
		NewMoves = 0;
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
    97
		for (i=0; i<NumMoves; i++)
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
    98
		{
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
    99
			/* For each direction */
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   100
			for (j=0; j<4; j++)
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   101
			{
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   102
				next_pos.x = pos[i].x + move_vectors[j].x;
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   103
				next_pos.y = pos[i].y + move_vectors[j].y;
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   104
				next_cell = &corners[next_pos.y][next_pos.x];
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   105
				if(*next_cell == BLANK ||
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   106
					*next_cell == PLATFORM)
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   107
				{
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   108
					return FALSE;
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   109
				}
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   110
				else if(*next_cell == CORNER)
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   111
				{
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   112
					new_pos[NewMoves] = next_pos;
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   113
					*next_cell = MANCANMOVE;
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   114
					NewMoves++;
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   115
				}
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   116
			}
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   117
		}
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   118
	}
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   119
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   120
	return TRUE;
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   121
}
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   122
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   123
int does_box_close_corners(const struct Map * m, const struct Position mov,
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   124
	const struct Position box_pos)
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   125
{
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   126
	struct Position p, p2;
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   127
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   128
	p.x = box_pos.x + mov.x;
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   129
	p.y = box_pos.y + mov.y;
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   130
	
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   131
	/* Let's plan the checks */
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   132
	/* The point will be marked with a MANCANMOVE */
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   133
	p2.x = p.x + mov.x;
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   134
	p2.y = p.y + mov.y;
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   135
	if (m->Cells[p2.y][p2.x] == CORNER)
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   136
	{
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   137
		if (is_corner_area(m, p2, box_pos, p))
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   138
			return TRUE;
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   139
	}
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   140
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   141
	p2.x = p.x + mov.y;
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   142
	p2.y = p.y + mov.x;
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   143
	if (m->Cells[p2.y][p2.x] == CORNER)
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   144
	{
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   145
		if (is_corner_area(m, p2, box_pos, p))
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   146
			return TRUE;
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   147
	}
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   148
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   149
	p2.x = p.x - mov.y;
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   150
	p2.y = p.y - mov.x;
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   151
	if (m->Cells[p2.y][p2.x] == CORNER)
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   152
	{
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   153
		if (is_corner_area(m, p2, box_pos, p))
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   154
			return TRUE;
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   155
	}
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   156
	return FALSE;
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   157
}
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   158
#endif
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   159
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   160
/*
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   161
Catch the situation where a box is moved next to a corner, where the box
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   162
next to it will not be able to be moved.
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   163
*/
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   164
static int is_dead1(const struct Map * m, const struct Position mov,
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   165
	const struct Position new_pos)
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   166
{
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   167
	struct Position opposite1, opposite2;
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   168
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   169
	/* The wall corners must exist */
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   170
	opposite1.x = -mov.y;
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   171
	opposite1.y = -mov.x;
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   172
	opposite2.x = mov.y;
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   173
	opposite2.y = mov.x;
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   174
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   175
#ifdef DEBUG
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   176
	ShowMap(m);
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   177
#endif
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   178
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   179
	/* Test the first corner */
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   180
	if (m->Cells[new_pos.y+mov.y+opposite1.y][new_pos.x+mov.x+opposite1.x]
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   181
		== WALL)
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   182
	{
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   183
		/* Test wall at opposites 1*/
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   184
		if (m->Cells[new_pos.y+opposite1.y][new_pos.x+opposite1.x]
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   185
			== WALL &&
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   186
			m->man_moves[new_pos.y+mov.y][new_pos.x+mov.x] == BOX)
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   187
		{
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   188
				return TRUE;
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   189
		}
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   190
		else
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   191
		if (m->man_moves[new_pos.y+opposite1.y][new_pos.x+opposite1.x]
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   192
			== BOX &&
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   193
			m->Cells[new_pos.y+mov.y][new_pos.x+mov.x] == WALL)
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   194
		{
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   195
				return TRUE;
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   196
		}
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   197
		/* Test wall at opposites 2 */
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   198
		if (m->Cells[new_pos.y+opposite2.y][new_pos.x+opposite2.x]
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   199
			== WALL &&
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   200
			m->man_moves[new_pos.y+mov.y][new_pos.x+mov.x] == BOX)
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   201
		{
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   202
				return TRUE;
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   203
		}
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   204
		else
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   205
		if (m->man_moves[new_pos.y+opposite2.y][new_pos.x+opposite2.x]
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   206
			== BOX &&
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   207
			m->Cells[new_pos.y+mov.y][new_pos.x+mov.x] == WALL)
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   208
		{
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   209
				return TRUE;
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   210
		}
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   211
	}
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   212
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   213
	/* Test the second corner */
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   214
	if (m->Cells[new_pos.y+mov.y+opposite2.y][new_pos.x+mov.x+opposite2.x]
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   215
		== WALL)
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   216
	{
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   217
		/* Test wall at opposites 1*/
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   218
		if (m->Cells[new_pos.y+opposite1.y][new_pos.x+opposite1.x]
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   219
			== WALL &&
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   220
			m->man_moves[new_pos.y+mov.y][new_pos.x+mov.x] == BOX)
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   221
		{
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   222
				return TRUE;
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   223
		}
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   224
		else
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   225
		if (m->man_moves[new_pos.y+opposite1.y][new_pos.x+opposite1.x]
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   226
			== BOX &&
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   227
			m->Cells[new_pos.y+mov.y][new_pos.x+mov.x] == WALL)
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   228
		{
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   229
				return TRUE;
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   230
		}
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   231
		/* Test wall at opposites 2 */
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   232
		if (m->Cells[new_pos.y+opposite2.y][new_pos.x+opposite2.x]
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   233
			== WALL &&
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   234
			m->man_moves[new_pos.y+mov.y][new_pos.x+mov.x] == BOX)
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   235
		{
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   236
				return TRUE;
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   237
		}
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   238
		else
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   239
		if (m->man_moves[new_pos.y+opposite2.y][new_pos.x+opposite2.x]
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   240
			== BOX &&
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   241
			m->Cells[new_pos.y+mov.y][new_pos.x+mov.x] == WALL)
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   242
		{
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   243
				return TRUE;
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   244
		}
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   245
	}
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   246
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   247
	return FALSE;
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   248
}
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   249
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   250
/*
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   251
Catch the situation where a corner gets surrounded by boxes.
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   252
*/
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   253
static int is_dead2(const struct Map * m, const struct Position mov,
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   254
	const struct Position new_pos)
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   255
{
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   256
	struct Position next, opposite1, opposite2;
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   257
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   258
	next.x = new_pos.x+mov.x;
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   259
	next.y = new_pos.y+mov.y;
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   260
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   261
	/* The corner must exist */
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   262
	if (m->Cells[next.y][next.x] != CORNER)
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   263
		return FALSE;
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   264
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   265
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   266
	/* The wall corners must exist */
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   267
	opposite1.x = next.x -mov.y;
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   268
	opposite1.y = next.y -mov.x;
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   269
	opposite2.x = next.x + mov.y;
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   270
	opposite2.y = next.y + mov.x;
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   271
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   272
	if (m->man_moves[opposite1.y][opposite1.x] == BOX)
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   273
	{
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   274
		if(m->Cells[opposite1.y+mov.y][opposite1.x+mov.x] == WALL
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   275
		   && m->Cells[opposite1.y-mov.y][opposite1.x-mov.x] == WALL)
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   276
		   return TRUE;
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   277
	}
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   278
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   279
	if (m->man_moves[opposite2.y][opposite2.x] == BOX)
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   280
	{
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   281
		if(m->Cells[opposite2.y+mov.y][opposite2.x+mov.x] == WALL
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   282
		   && m->Cells[opposite2.y-mov.y][opposite2.x-mov.x] == WALL)
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   283
		   return TRUE;
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   284
	}
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   285
	return FALSE;
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   286
}
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   287
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   288
static int is_box_movable(const struct Map * m, const struct Position mov,
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   289
	const struct Position box_pos)
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   290
{
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   291
	struct Position next_pos2;
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   292
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   293
	next_pos2.x = box_pos.x + mov.x;
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   294
	next_pos2.y = box_pos.y + mov.y;
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   295
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   296
	if((m->Cells[next_pos2.y][next_pos2.x] != BLANK &&
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   297
		m->Cells[next_pos2.y][next_pos2.x] != PLATFORM) ||
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   298
		m->man_moves[next_pos2.y][next_pos2.x] == BOX)
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   299
	{
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   300
		return FALSE;
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   301
	}
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   302
	else if (is_dead1(m, mov, next_pos2) == TRUE)
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   303
	{
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   304
		return FALSE;
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   305
	}
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   306
	else if (is_dead2(m, mov, next_pos2) == TRUE)
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   307
	{
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   308
		return FALSE;
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   309
	}
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   310
	return TRUE;
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   311
}
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   312
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   313
/* It modifies m->man_moves */
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   314
static int get_box_movements(struct Map * m,
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   315
	struct BoxMove movements[])
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   316
{
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   317
	struct Position pos[MAX_MOVES];
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   318
	struct Position new_pos[MAX_MOVES];
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   319
	int NumMoves, NewMoves;
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   320
	int j, i;
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   321
	struct Position next_pos;
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   322
	char *next_cell;
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   323
	int num_box_movements = 0;
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   324
	
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   325
	/* Let's  the map with only walls in man_moves - other, blanks */
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   326
	for (j = 0; j<m->SizeY; j++)
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   327
		for (i=0; i<m->SizeX; i++)
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   328
		{
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   329
			if (m->Cells[j][i] == WALL)
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   330
				m->man_moves[j][i] = WALL;
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   331
			else
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   332
				m->man_moves[j][i] = BLANK;
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   333
		}
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   334
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   335
	/* Let's put the boxes */
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   336
	for (i = 0; i<m->NumBoxes; i++)
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   337
	{
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   338
		m->man_moves[m->Box[i].y][m->Box[i].x] = BOX;
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   339
		m->cells_boxes[m->Box[i].y][m->Box[i].x] = i;
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   340
	}
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   341
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   342
	NewMoves = 1;
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   343
	new_pos[0].x = m->Man.x;
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   344
	new_pos[0].y = m->Man.y;
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   345
	m->man_moves[m->Man.y][m->Man.x] = MANCANMOVE;
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   346
	while (NewMoves > 0)
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   347
	{
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   348
		/* The before named "New Moves" become the moves we have
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   349
		   to analyze */
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   350
		NumMoves = NewMoves;
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   351
		for (i=0; i<NewMoves; i++)
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   352
		{
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   353
			pos[i] = new_pos[i];
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   354
		}
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   355
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   356
		/* Search new positions for each position */
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   357
		NewMoves = 0;
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   358
		for (i=0; i<NumMoves; i++)
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   359
		{
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   360
			/* For each direction */
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   361
			for (j=0; j<4; j++)
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   362
			{
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   363
				next_pos.x = pos[i].x + move_vectors[j].x;
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   364
				next_pos.y = pos[i].y + move_vectors[j].y;
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   365
				next_cell = &m->man_moves[next_pos.y][next_pos.x];
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   366
				if(*next_cell == BLANK)
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   367
				{
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   368
					new_pos[NewMoves] = next_pos;
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   369
					*next_cell = MANCANMOVE;
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   370
					NewMoves++;
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   371
				}
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   372
				else if (*next_cell == BOX)
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   373
				{
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   374
						
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   375
					/* Check if the box is movable */
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   376
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   377
					if (is_box_movable(m, move_vectors[j],
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   378
						next_pos ))
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   379
					{
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   380
						{
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   381
					movements[num_box_movements].box =
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   382
					m->cells_boxes[next_pos.y][next_pos.x];
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   383
					movements[num_box_movements].dir =
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   384
					move_vectors[j];
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   385
					num_box_movements++;
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   386
						}
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   387
					}
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   388
					
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   389
				}
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   390
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   391
			}
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   392
		}
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   393
	}
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   394
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   395
	return num_box_movements;
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   396
}
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   397
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   398
static void force_move_box(struct Map *m, struct BoxMove move)
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   399
{
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   400
	struct Position newpos;
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   401
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   402
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   403
	/* Add coords */
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   404
	newpos.x = m->Box[move.box].x + move.dir.x;
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   405
	newpos.y = m->Box[move.box].y + move.dir.y;
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   406
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   407
	/* Be certain the move can be done */
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   408
	assert(m->Cells[newpos.y][newpos.x] != BOX);
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   409
	assert(m->Cells[newpos.y][newpos.x] != WALL);
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   410
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   411
	/* Control if we moved the box to a platform */
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   412
	if(m->Cells[newpos.y][newpos.x] == PLATFORM)
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   413
	{
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   414
		m->NumBoxesInPlatform++;
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   415
	}
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   416
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   417
	/* Control if we moved the box from a platform */
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   418
	if (m->Cells[m->Box[move.box].y][m->Box[move.box].x] == PLATFORM)
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   419
	{
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   420
		m->NumBoxesInPlatform--;
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   421
	}
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   422
	m->Man = m->Box[move.box];
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   423
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   424
	m->Box[move.box] = newpos;
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   425
}
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   426
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   427
static int is_new_map(struct Map maps[], int depth)
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   428
{
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   429
	struct Map *m;
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   430
	int i;
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   431
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   432
	m = &maps[depth];
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   433
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   434
	for(i=0; i<max_depth; i++)
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   435
	{
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   436
		/* No l'hem de comparar amb ell mateix */
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   437
		if (i == depth)
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   438
			continue;
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   439
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   440
		if (m->NumBoxesInPlatform != maps[i].NumBoxesInPlatform)
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   441
			continue;
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   442
		else
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   443
		{
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   444
			if (!are_boxes_equal(m->Box, maps[i].Box, m->NumBoxes))
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   445
				continue;
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   446
		}
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   447
		return FALSE;
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   448
	}
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   449
	return TRUE;
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   450
}
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   451
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   452
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   453
static int search_depth(struct Map maps[], int depth,
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   454
	struct BoxMove movements[],
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   455
	int num_movements, float percent, float total_percent)
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   456
{
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   457
	struct BoxMove new_movements[MAX_MOVES];
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   458
	int num_new_movements;
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   459
	struct Map *m; 
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   460
	int i;
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   461
	float next_percent;
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   462
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   463
	next_percent = percent / num_movements;
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   464
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   465
	m = &maps[depth+1];
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   466
	if (depth > max_depth)
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   467
		max_depth = depth;
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   468
	if (depth > max_depth_period)
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   469
		max_depth_period = depth;
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   470
	if (depth < min_depth_period)
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   471
		min_depth_period = depth;
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   472
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   473
	for (i=0; i < num_movements; i++)
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   474
	{
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   475
		CopyMap(m, &maps[depth]);
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   476
		force_move_box(m, movements[i]);
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   477
		if (m->NumPlatforms == m->NumBoxesInPlatform)
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   478
		{
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   479
			PrintMove(movements[i]);
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   480
			return 0;
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   481
		}
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   482
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   483
		if (is_new_map(maps, depth+1))
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   484
		{
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   485
			num_new_movements = get_box_movements(m, new_movements);
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   486
			assert(num_new_movements < MAX_MOVES);
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   487
		}
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   488
		else
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   489
			num_new_movements = 0;
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   490
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   491
		if (num_new_movements == 0)
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   492
		{
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   493
			percent_to_show = total_percent + next_percent*i;
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   494
			depth_to_show = depth;
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   495
			actual_map = &maps[depth];
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   496
#ifdef DEBUG		/* to be out */
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   497
			show_percent_callback(0);
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   498
#endif
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   499
	
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   500
		}
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   501
		else
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   502
		{
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   503
			if (depth+1 < MAX_STEPS)
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   504
			{
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   505
				if(search_depth(maps, depth+1, new_movements,
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   506
					num_new_movements, next_percent,
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   507
					total_percent + next_percent*i) == 0)
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   508
				{
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   509
					PrintMove(movements[i]);
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   510
					return 0;
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   511
				}
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   512
			}
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   513
		}
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   514
	}
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   515
	return 1;
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   516
}
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   517
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   518
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   519
int solve_map(const struct Map origin)
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   520
{
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   521
	struct Map maps[MAX_STEPS+1];
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   522
	struct BoxMove new_movements[MAX_MOVES];
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   523
	int num_new_movements;
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   524
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   525
	CopyMap(&maps[0], &origin);
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   526
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   527
	num_new_movements = get_box_movements(&maps[0], new_movements);
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   528
	assert(num_new_movements < MAX_MOVES);
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   529
	assert(num_new_movements > 0);
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   530
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   531
	init_os();
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   532
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   533
	return search_depth(maps, 0, new_movements,
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   534
		num_new_movements, 100. / num_new_movements,
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   535
		0);
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   536
bfbca2c0fc70 More file separation.
viric@llimona
parents:
diff changeset
   537
}