sokosol-profund.c
author viric@llimona
Fri, 05 May 2006 22:42:30 +0200
changeset 1 edbaeb577eab
parent 0 be33ecaa3619
permissions -rw-r--r--
Adding ignored patterns.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
0
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
     1
#include <stdio.h>
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
     2
#include <string.h>
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
     3
#include <assert.h>
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
     4
#include <stdlib.h>
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
     5
#include <unistd.h>
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
     6
#include <signal.h>
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
     7
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
     8
#define BOX '$'
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
     9
#define WALL '#'
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
    10
#define MAN '@'
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
    11
#define PLATFORM '.'
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
    12
#define BOXINPLATFORM '*'
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
    13
#define MANINPLATFORM 'E'
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
    14
#define BLANK ' '
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
    15
#define CORNER '-'
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
    16
#define MANCANMOVE '+'
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
    17
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
    18
#define NBOX(n) ((n)<<2)
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
    19
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
    20
//#define DEBUG
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
    21
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
    22
enum
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
    23
{
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
    24
	ALARM_SECONDS=1
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
    25
};
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
    26
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
    27
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
    28
enum logic
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
    29
{
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
    30
	TRUE=1,
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
    31
	FALSE=0,
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
    32
};
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
    33
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
    34
#define MAX_X 50
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
    35
#define MAX_Y 50
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
    36
#define MAX_MOVES 50
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
    37
#define MAX_STEPS 50
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
    38
#define MAX_BOXES 15
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
    39
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
    40
#define MOVE_OK		1
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
    41
#define MOVE_BOX	2
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
    42
#define MOVE_ILLEGAL	0
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
    43
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
    44
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
    45
/* SOKOBAN Solution Finder
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
    46
 *
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
    47
 * Input File Format: XSB
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
    48
 *
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
    49
 * XSB Format definition:
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
    50
 * 	Character matrix of:
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
    51
 * 		@	MAN
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
    52
 * 		#	WALL
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
    53
 * 		$	BOX
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
    54
 * 		*	BOX over PLATFORM
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
    55
 * 		+	PLATFORM
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
    56
 * 		-	(optional) Where a BOX should not be put
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
    57
 * 	Everything that cannot be reached by the man or boxes (WALLS) must be
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
    58
 * 	marked as is: WALLS.
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
    59
 * 	All lines must be of the same length.
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
    60
 */
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
    61
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
    62
struct Position
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
    63
{
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
    64
	int x;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
    65
	int y;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
    66
};
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
    67
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
    68
struct Map
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
    69
{
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
    70
	char Cells[MAX_Y][MAX_X];
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
    71
	char cells_boxes[MAX_Y][MAX_X];
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
    72
	char man_moves[MAX_Y][MAX_X];
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
    73
	int SizeX, SizeY;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
    74
	struct Position Man;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
    75
	int NumPlatforms;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
    76
	int NumBoxesInPlatform;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
    77
	struct Position Box[MAX_BOXES];
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
    78
	int NumBoxes;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
    79
};
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
    80
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
    81
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
    82
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
    83
enum e_direction
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
    84
{
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
    85
	DIR_LEFT,
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
    86
	DIR_RIGHT,
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
    87
	DIR_DOWN,
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
    88
	DIR_UP
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
    89
};
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
    90
const struct Position move_vectors[4] = {
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
    91
	{0, 1},
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
    92
	{0, -1},
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
    93
	{1, 0},
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
    94
	{-1, 0}};
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
    95
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
    96
struct BoxMove
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
    97
{
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
    98
	int box;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
    99
	struct Position dir;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   100
};
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   101
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   102
float percent_to_show = 0;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   103
int depth_to_show = 0;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   104
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   105
int max_depth = 0;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   106
int min_depth_period = 0;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   107
int max_depth_period = 0;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   108
struct Map * actual_map;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   109
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   110
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   111
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   112
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   113
void CopyMap (struct Map *Mdest, const struct Map *Morig)
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   114
{
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   115
	memcpy((void *) Mdest, (void *) Morig, sizeof (struct Map));
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   116
}
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   117
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   118
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   119
void ReadMap(struct Map *M, char *FileName)
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   120
{
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   121
	FILE *Fitxer;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   122
	int i,j;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   123
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   124
	if(!(Fitxer = fopen(FileName, "r")))
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   125
	{
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   126
		printf("Error opening %s!", FileName);
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   127
		exit(1);
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   128
	}
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   129
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   130
	M->SizeX=0;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   131
	M->SizeY=0;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   132
	while (!feof(Fitxer))
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   133
	{
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   134
		fgets(M->Cells[M->SizeY], MAX_X, Fitxer);
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   135
		M->SizeY++;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   136
	}
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   137
	M->SizeY--;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   138
	M->SizeX = strlen(M->Cells[0]) - 1;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   139
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   140
	M->NumPlatforms = 0;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   141
	M->NumBoxesInPlatform = 0;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   142
	M->NumBoxes = 0;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   143
	for (j = 0; j<M->SizeY; j++)
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   144
		for (i=0; i<M->SizeX; i++)
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   145
		{
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   146
			if (M->Cells[j][i] == MAN)
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   147
			{ 
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   148
				M->Man.x = i; M->Man.y = j; 
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   149
				M->Cells[M->Man.y][M->Man.x] = BLANK;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   150
			}
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   151
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   152
			if (M->Cells[j][i] == PLATFORM)
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   153
				M->NumPlatforms++;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   154
			else if (M->Cells[j][i] == BOXINPLATFORM)
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   155
			{
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   156
				M->Cells[j][i] = PLATFORM;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   157
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   158
				M->NumPlatforms++;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   159
				M->NumBoxesInPlatform++;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   160
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   161
				M->Box[M->NumBoxes].x = i;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   162
				M->Box[M->NumBoxes].y = j;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   163
				M->NumBoxes++;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   164
			} else if (M->Cells[j][i] == BOX)
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   165
			{
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   166
				M->Cells[j][i] = BLANK;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   167
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   168
				M->Box[M->NumBoxes].x = i;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   169
				M->Box[M->NumBoxes].y = j;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   170
				M->NumBoxes++;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   171
			} else if (M->Cells[j][i] == CORNER)
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   172
			{
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   173
				M->Cells[j][i] = CORNER;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   174
			} else if (M->Cells[j][i] != WALL)
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   175
			{
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   176
				if (    (M->Cells[j][i-1] == WALL &&
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   177
					 M->Cells[j-1][i] == WALL) ||
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   178
					(M->Cells[j][i-1] == WALL &&
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   179
					 M->Cells[j+1][i] == WALL) ||
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   180
					(M->Cells[j][i+1] == WALL &&
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   181
					 M->Cells[j-1][i] == WALL) ||
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   182
					(M->Cells[j][i+1] == WALL &&
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   183
					 M->Cells[j+1][i] == WALL))
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   184
				M->Cells[j][i] = CORNER;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   185
			}
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   186
				
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   187
		}
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   188
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   189
}
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   190
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   191
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   192
void ShowMap (const struct Map *M)
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   193
{
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   194
	struct Map Temp;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   195
	int i,j;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   196
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   197
	CopyMap(&Temp, M);
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   198
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   199
	Temp.Cells[Temp.Man.y][Temp.Man.x] = MAN;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   200
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   201
	for (i = 0; i < Temp.NumBoxes; i++)
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   202
	{
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   203
		if (Temp.Cells[Temp.Box[i].y][Temp.Box[i].x] == PLATFORM)
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   204
			Temp.Cells[Temp.Box[i].y][Temp.Box[i].x] =BOXINPLATFORM;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   205
		else
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   206
			Temp.Cells[Temp.Box[i].y][Temp.Box[i].x] = BOX;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   207
	}
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   208
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   209
	for (j = 0; j<Temp.SizeY; j++)
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   210
	{
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   211
		for (i=0; i<Temp.SizeX; i++)
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   212
			fprintf(stderr,"%c", Temp.Cells[j][i]);
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   213
		fprintf(stderr,"\n");
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   214
	}
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   215
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   216
#if 0
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   217
	// Print Where the man can move
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   218
	for (j = 0; j<Temp.SizeY; j++)
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   219
	{
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   220
		for (i=0; i<Temp.SizeX; i++)
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   221
			printf("%c", Temp.ManMoves[j][i]);
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   222
		printf("\n");
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   223
	}
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   224
#endif
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   225
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   226
	printf("Man is at (%i,%i)\n", Temp.Man.x, Temp.Man.y);
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   227
	printf("Platforms: %i, BoxesInPlatform: %i\n", Temp.NumPlatforms,
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   228
			Temp.NumBoxesInPlatform);
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   229
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   230
}
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   231
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   232
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   233
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   234
int InverseMove(char Dir1, char Dir2)
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   235
{
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   236
	if ((Dir1 + Dir2 == DIR_LEFT + DIR_RIGHT) ||
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   237
		(Dir1 + Dir2 == DIR_UP + DIR_DOWN))
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   238
		return 1;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   239
	return 0;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   240
}
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   241
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   242
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   243
void PrintCombination(int Moves[], int NumMoves)
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   244
{
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   245
	int i;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   246
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   247
	for (i=0; i < NumMoves; i++)
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   248
	{
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   249
		printf("%i", Moves[i] >> 2);
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   250
		if ((Moves[i] & 0x03) == DIR_LEFT)
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   251
			printf("L");
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   252
		else if ((Moves[i] & 0x03) == DIR_RIGHT)
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   253
			printf("R");
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   254
		else if ((Moves[i] & 0x03) == DIR_UP)
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   255
			printf("U");
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   256
		else
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   257
			printf("D");
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   258
		printf(",");
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   259
	}
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   260
	printf("\n");
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   261
}
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   262
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   263
#if 0 /*** THIS IS AN ERROR!!!  The box_will_be_blocked function doesn't work!*/
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   264
 Situation:
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   265
    
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   266
  ->@$ #
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   267
      $
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   268
*/
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   269
int box_will_be_blocked(const struct Map * m, const struct Position mov,
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   270
	const struct Position box_pos)
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   271
{
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   272
	struct Position next_pos2, tmp, tmp2[2];
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   273
	int i;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   274
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   275
	next_pos2.x = box_pos.x + mov.x;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   276
	next_pos2.y = box_pos.y + mov.y;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   277
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   278
	tmp.x = next_pos2.x + mov.x;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   279
	tmp.y = next_pos2.y + mov.y;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   280
	tmp2[0].x = next_pos2.x + mov.y;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   281
	tmp2[0].y = next_pos2.y + mov.x;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   282
	tmp2[1].x = next_pos2.x - mov.y;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   283
	tmp2[1].y = next_pos2.y - mov.x;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   284
	for (i=0; i < 2; i++)
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   285
	{
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   286
		if (m->man_moves[tmp.y][tmp.x] == WALL &&
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   287
			m->man_moves[tmp2[i].y][tmp2[i].x] == BOX)
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   288
		{
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   289
			return TRUE;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   290
		}
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   291
		else if (m->man_moves[tmp.y][tmp.x] == BOX &&
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   292
			m->man_moves[tmp2[i].y][tmp2[i].x] == WALL)
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   293
		{
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   294
			return TRUE;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   295
		}
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   296
		else if (m->man_moves[tmp.y][tmp.x] == BOX &&
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   297
			m->man_moves[tmp2[i].y][tmp2[i].x] == BOX)
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   298
		{
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   299
			return TRUE;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   300
		}
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   301
	}
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   302
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   303
	return FALSE;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   304
}
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   305
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   306
int is_corner_area(const struct Map * m, const struct Position p,
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   307
	const struct Position box, const struct Position new_box)
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   308
{
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   309
	int NumMoves, NewMoves;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   310
	struct Position pos[MAX_MOVES];
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   311
	struct Position new_pos[MAX_MOVES];
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   312
	char corners[MAX_Y][MAX_X];
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   313
	int i,j;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   314
	struct Position next_pos;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   315
	char *next_cell;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   316
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   317
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   318
	/* Blank the garden */
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   319
	for (j = 0; j<m->SizeY; j++)
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   320
		for (i=0; i<m->SizeX; i++)
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   321
			corners[j][i] = m->Cells[j][i];
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   322
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   323
	/* Let's put the boxes */
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   324
	for (i = 0; i<m->NumBoxes; i++)
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   325
		corners[m->Box[i].y][m->Box[i].x] = BOX;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   326
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   327
	/* Let's put our box - it can be simply added */
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   328
	corners[new_box.y][new_box.x] = BOX;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   329
	/* Let's remove the original box. */
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   330
	corners[box.y][box.x] = BLANK;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   331
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   332
	NewMoves = 1;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   333
	new_pos[0] = p;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   334
	while (NewMoves > 0)
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   335
	{
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   336
		/* The before named "New Moves" become the moves we have
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   337
		   to analyze */
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   338
		NumMoves = NewMoves;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   339
		for (i=0; i<NewMoves; i++)
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   340
		{
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   341
			pos[i] = new_pos[i];
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   342
		}
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   343
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   344
		/* Search new positions for each position */
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   345
		NewMoves = 0;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   346
		for (i=0; i<NumMoves; i++)
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   347
		{
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   348
			/* For each direction */
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   349
			for (j=0; j<4; j++)
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   350
			{
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   351
				next_pos.x = pos[i].x + move_vectors[j].x;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   352
				next_pos.y = pos[i].y + move_vectors[j].y;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   353
				next_cell = &corners[next_pos.y][next_pos.x];
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   354
				if(*next_cell == BLANK ||
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   355
					*next_cell == PLATFORM)
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   356
				{
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   357
					return FALSE;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   358
				}
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   359
				else if(*next_cell == CORNER)
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   360
				{
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   361
					new_pos[NewMoves] = next_pos;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   362
					*next_cell = MANCANMOVE;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   363
					NewMoves++;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   364
				}
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   365
			}
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   366
		}
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   367
	}
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   368
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   369
	return TRUE;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   370
}
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   371
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   372
int does_box_close_corners(const struct Map * m, const struct Position mov,
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   373
	const struct Position box_pos)
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   374
{
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   375
	struct Position p, p2;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   376
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   377
	p.x = box_pos.x + mov.x;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   378
	p.y = box_pos.y + mov.y;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   379
	
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   380
	/* Let's plan the checks */
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   381
	/* The point will be marked with a MANCANMOVE */
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   382
	p2.x = p.x + mov.x;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   383
	p2.y = p.y + mov.y;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   384
	if (m->Cells[p2.y][p2.x] == CORNER)
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   385
	{
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   386
		if (is_corner_area(m, p2, box_pos, p))
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   387
			return TRUE;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   388
	}
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   389
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   390
	p2.x = p.x + mov.y;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   391
	p2.y = p.y + mov.x;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   392
	if (m->Cells[p2.y][p2.x] == CORNER)
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   393
	{
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   394
		if (is_corner_area(m, p2, box_pos, p))
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   395
			return TRUE;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   396
	}
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   397
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   398
	p2.x = p.x - mov.y;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   399
	p2.y = p.y - mov.x;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   400
	if (m->Cells[p2.y][p2.x] == CORNER)
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   401
	{
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   402
		if (is_corner_area(m, p2, box_pos, p))
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   403
			return TRUE;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   404
	}
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   405
	return FALSE;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   406
}
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   407
#endif
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   408
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   409
/*
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   410
Catch the situation where a box is moved next to a corner, where the box
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   411
next to it will not be able to be moved.
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   412
*/
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   413
int is_dead1(const struct Map * m, const struct Position mov,
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   414
	const struct Position new_pos)
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   415
{
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   416
	struct Position opposite1, opposite2;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   417
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   418
	/* The wall corners must exist */
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   419
	opposite1.x = -mov.y;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   420
	opposite1.y = -mov.x;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   421
	opposite2.x = mov.y;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   422
	opposite2.y = mov.x;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   423
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   424
#ifdef DEBUG
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   425
	ShowMap(m);
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   426
#endif
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   427
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   428
	/* Test the first corner */
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   429
	if (m->Cells[new_pos.y+mov.y+opposite1.y][new_pos.x+mov.x+opposite1.x]
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   430
		== WALL)
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   431
	{
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   432
		/* Test wall at opposites 1*/
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   433
		if (m->Cells[new_pos.y+opposite1.y][new_pos.x+opposite1.x]
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   434
			== WALL &&
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   435
			m->man_moves[new_pos.y+mov.y][new_pos.x+mov.x] == BOX)
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   436
		{
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   437
				return TRUE;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   438
		}
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   439
		else
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   440
		if (m->man_moves[new_pos.y+opposite1.y][new_pos.x+opposite1.x]
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   441
			== BOX &&
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   442
			m->Cells[new_pos.y+mov.y][new_pos.x+mov.x] == WALL)
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   443
		{
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   444
				return TRUE;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   445
		}
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   446
		/* Test wall at opposites 2 */
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   447
		if (m->Cells[new_pos.y+opposite2.y][new_pos.x+opposite2.x]
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   448
			== WALL &&
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   449
			m->man_moves[new_pos.y+mov.y][new_pos.x+mov.x] == BOX)
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   450
		{
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   451
				return TRUE;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   452
		}
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   453
		else
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   454
		if (m->man_moves[new_pos.y+opposite2.y][new_pos.x+opposite2.x]
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   455
			== BOX &&
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   456
			m->Cells[new_pos.y+mov.y][new_pos.x+mov.x] == WALL)
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   457
		{
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   458
				return TRUE;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   459
		}
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   460
	}
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   461
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   462
	/* Test the second corner */
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   463
	if (m->Cells[new_pos.y+mov.y+opposite2.y][new_pos.x+mov.x+opposite2.x]
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   464
		== WALL)
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   465
	{
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   466
		/* Test wall at opposites 1*/
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   467
		if (m->Cells[new_pos.y+opposite1.y][new_pos.x+opposite1.x]
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   468
			== WALL &&
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   469
			m->man_moves[new_pos.y+mov.y][new_pos.x+mov.x] == BOX)
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   470
		{
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   471
				return TRUE;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   472
		}
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   473
		else
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   474
		if (m->man_moves[new_pos.y+opposite1.y][new_pos.x+opposite1.x]
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   475
			== BOX &&
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   476
			m->Cells[new_pos.y+mov.y][new_pos.x+mov.x] == WALL)
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   477
		{
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   478
				return TRUE;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   479
		}
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   480
		/* Test wall at opposites 2 */
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   481
		if (m->Cells[new_pos.y+opposite2.y][new_pos.x+opposite2.x]
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   482
			== WALL &&
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   483
			m->man_moves[new_pos.y+mov.y][new_pos.x+mov.x] == BOX)
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   484
		{
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   485
				return TRUE;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   486
		}
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   487
		else
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   488
		if (m->man_moves[new_pos.y+opposite2.y][new_pos.x+opposite2.x]
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   489
			== BOX &&
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   490
			m->Cells[new_pos.y+mov.y][new_pos.x+mov.x] == WALL)
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   491
		{
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   492
				return TRUE;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   493
		}
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   494
	}
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   495
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   496
	return FALSE;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   497
}
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   498
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   499
/*
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   500
Catch the situation where a corner gets surrounded by boxes.
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   501
*/
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   502
int is_dead2(const struct Map * m, const struct Position mov,
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   503
	const struct Position new_pos)
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   504
{
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   505
	struct Position next, next2, opposite1, opposite2;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   506
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   507
	next.x = new_pos.x+mov.x;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   508
	next.y = new_pos.y+mov.y;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   509
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   510
	/* The corner must exist */
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   511
	if (m->Cells[next.y][next.x] != CORNER)
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   512
		return FALSE;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   513
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   514
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   515
	/* The wall corners must exist */
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   516
	opposite1.x = next.x -mov.y;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   517
	opposite1.y = next.y -mov.x;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   518
	opposite2.x = next.x + mov.y;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   519
	opposite2.y = next.y + mov.x;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   520
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   521
	if (m->man_moves[opposite1.y][opposite1.x] == BOX)
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   522
	{
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   523
		if(m->Cells[opposite1.y+mov.y][opposite1.x+mov.x] == WALL
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   524
		   && m->Cells[opposite1.y-mov.y][opposite1.x-mov.x] == WALL)
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   525
		   return TRUE;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   526
	}
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   527
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   528
	if (m->man_moves[opposite2.y][opposite2.x] == BOX)
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   529
	{
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   530
		if(m->Cells[opposite2.y+mov.y][opposite2.x+mov.x] == WALL
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   531
		   && m->Cells[opposite2.y-mov.y][opposite2.x-mov.x] == WALL)
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   532
		   return TRUE;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   533
	}
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   534
	return FALSE;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   535
}
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   536
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   537
int is_box_movable(const struct Map * m, const struct Position mov,
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   538
	const struct Position box_pos)
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   539
{
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   540
	struct Position next_pos2;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   541
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   542
	next_pos2.x = box_pos.x + mov.x;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   543
	next_pos2.y = box_pos.y + mov.y;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   544
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   545
	if((m->Cells[next_pos2.y][next_pos2.x] != BLANK &&
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   546
		m->Cells[next_pos2.y][next_pos2.x] != PLATFORM) ||
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   547
		m->man_moves[next_pos2.y][next_pos2.x] == BOX)
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   548
	{
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   549
		return FALSE;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   550
	}
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   551
	else if (is_dead1(m, mov, next_pos2) == TRUE)
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   552
	{
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   553
		return FALSE;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   554
	}
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   555
	else if (is_dead2(m, mov, next_pos2) == TRUE)
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   556
	{
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   557
		return FALSE;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   558
	}
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   559
	return TRUE;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   560
}
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   561
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   562
/* It modifies m->man_moves */
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   563
int get_box_movements(struct Map * m,
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   564
	struct BoxMove movements[])
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   565
{
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   566
	struct Position pos[MAX_MOVES];
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   567
	struct Position new_pos[MAX_MOVES];
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   568
	int NumMoves, NewMoves;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   569
	int j, i;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   570
	struct Position next_pos;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   571
	char *next_cell;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   572
	int num_box_movements = 0;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   573
	
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   574
	/* Let's  the map with only walls in man_moves - other, blanks */
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   575
	for (j = 0; j<m->SizeY; j++)
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   576
		for (i=0; i<m->SizeX; i++)
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   577
		{
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   578
			if (m->Cells[j][i] == WALL)
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   579
				m->man_moves[j][i] = WALL;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   580
			else
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   581
				m->man_moves[j][i] = BLANK;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   582
		}
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   583
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   584
	/* Let's put the boxes */
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   585
	for (i = 0; i<m->NumBoxes; i++)
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   586
	{
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   587
		m->man_moves[m->Box[i].y][m->Box[i].x] = BOX;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   588
		m->cells_boxes[m->Box[i].y][m->Box[i].x] = i;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   589
	}
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   590
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   591
	NewMoves = 1;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   592
	new_pos[0].x = m->Man.x;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   593
	new_pos[0].y = m->Man.y;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   594
	m->man_moves[m->Man.y][m->Man.x] = MANCANMOVE;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   595
	while (NewMoves > 0)
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   596
	{
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   597
		/* The before named "New Moves" become the moves we have
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   598
		   to analyze */
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   599
		NumMoves = NewMoves;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   600
		for (i=0; i<NewMoves; i++)
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   601
		{
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   602
			pos[i] = new_pos[i];
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   603
		}
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   604
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   605
		/* Search new positions for each position */
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   606
		NewMoves = 0;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   607
		for (i=0; i<NumMoves; i++)
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   608
		{
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   609
			/* For each direction */
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   610
			for (j=0; j<4; j++)
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   611
			{
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   612
				next_pos.x = pos[i].x + move_vectors[j].x;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   613
				next_pos.y = pos[i].y + move_vectors[j].y;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   614
				next_cell = &m->man_moves[next_pos.y][next_pos.x];
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   615
				if(*next_cell == BLANK)
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   616
				{
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   617
					new_pos[NewMoves] = next_pos;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   618
					*next_cell = MANCANMOVE;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   619
					NewMoves++;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   620
				}
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   621
				else if (*next_cell == BOX)
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   622
				{
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   623
						
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   624
					/* Check if the box is movable */
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   625
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   626
					if (is_box_movable(m, move_vectors[j],
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   627
						next_pos ))
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   628
					{
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   629
						{
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   630
					movements[num_box_movements].box =
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   631
					m->cells_boxes[next_pos.y][next_pos.x];
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   632
					movements[num_box_movements].dir =
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   633
					move_vectors[j];
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   634
					num_box_movements++;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   635
						}
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   636
					}
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   637
					
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   638
				}
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   639
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   640
			}
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   641
		}
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   642
	}
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   643
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   644
	return num_box_movements;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   645
}
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   646
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   647
void force_move_box(struct Map *m, struct BoxMove move)
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   648
{
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   649
	struct Position newpos;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   650
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   651
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   652
	/* Add coords */
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   653
	newpos.x = m->Box[move.box].x + move.dir.x;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   654
	newpos.y = m->Box[move.box].y + move.dir.y;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   655
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   656
	/* Be certain the move can be done */
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   657
	assert(m->Cells[newpos.y][newpos.x] != BOX);
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   658
	assert(m->Cells[newpos.y][newpos.x] != WALL);
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   659
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   660
	/* Control if we moved the box to a platform */
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   661
	if(m->Cells[newpos.y][newpos.x] == PLATFORM)
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   662
	{
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   663
		m->NumBoxesInPlatform++;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   664
	}
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   665
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   666
	/* Control if we moved the box from a platform */
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   667
	if (m->Cells[m->Box[move.box].y][m->Box[move.box].x] == PLATFORM)
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   668
	{
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   669
		m->NumBoxesInPlatform--;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   670
	}
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   671
	m->Man = m->Box[move.box];
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   672
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   673
	m->Box[move.box] = newpos;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   674
}
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   675
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   676
int are_boxes_equal(const struct Position b1[], const struct Position b2[],
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   677
	int n)
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   678
{
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   679
	int i;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   680
	char tmp[MAX_Y][MAX_X]; /* !!!argh */
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   681
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   682
	memset(tmp, 0, sizeof(tmp));
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   683
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   684
	for (i=0; i < n; i++)
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   685
	{
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   686
		tmp[b1[i].y][b1[i].x] = 1;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   687
	}
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   688
	for (i=0; i < n; i++)
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   689
	{
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   690
		if (tmp[b2[i].y][b2[i].x] != 1)
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   691
			return FALSE;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   692
	}
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   693
	return TRUE;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   694
}
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   695
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   696
int is_new_map(struct Map maps[], int depth)
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   697
{
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   698
	struct Map *m;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   699
	int i;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   700
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   701
	m = &maps[depth];
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   702
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   703
	for(i=0; i<max_depth; i++)
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   704
	{
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   705
		/* No l'hem de comparar amb ell mateix */
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   706
		if (i == depth)
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   707
			continue;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   708
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   709
		if (m->NumBoxesInPlatform != maps[i].NumBoxesInPlatform)
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   710
			continue;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   711
		else
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   712
		{
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   713
			if (!are_boxes_equal(m->Box, maps[i].Box, m->NumBoxes))
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   714
				continue;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   715
		}
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   716
		return FALSE;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   717
	}
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   718
	return TRUE;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   719
}
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   720
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   721
void PrintMove(struct BoxMove b)
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   722
{
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   723
	printf("Box: %i, Direction: {%i,%i}\n", b.box, b.dir.x, b.dir.y);
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   724
}
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   725
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   726
void show_percent_callback(int parameter)
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   727
{
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   728
	fprintf(stderr, "Percent: %2.12f, depth: %i-%i\n", percent_to_show,
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   729
		min_depth_period, max_depth_period);
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   730
	ShowMap(actual_map);
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   731
	fflush(stderr);
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   732
	min_depth_period = MAX_STEPS;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   733
	max_depth_period = 0;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   734
#ifndef DEBUG
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   735
	alarm(ALARM_SECONDS);
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   736
#endif
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   737
}
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   738
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   739
int search_depth(struct Map maps[], int depth,
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   740
	struct BoxMove movements[],
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   741
	int num_movements, float percent, float total_percent)
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   742
{
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   743
	struct BoxMove new_movements[MAX_MOVES];
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   744
	int num_new_movements;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   745
	struct Map *m; 
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   746
	int i;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   747
	float next_percent;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   748
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   749
	next_percent = percent / num_movements;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   750
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   751
	m = &maps[depth+1];
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   752
	if (depth > max_depth)
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   753
		max_depth = depth;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   754
	if (depth > max_depth_period)
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   755
		max_depth_period = depth;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   756
	if (depth < min_depth_period)
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   757
		min_depth_period = depth;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   758
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   759
	for (i=0; i < num_movements; i++)
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   760
	{
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   761
		CopyMap(m, &maps[depth]);
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   762
		force_move_box(m, movements[i]);
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   763
		if (m->NumPlatforms == m->NumBoxesInPlatform)
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   764
		{
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   765
			printf("\nSolved!\n");
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   766
			PrintMove(movements[i]);
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   767
			return 0;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   768
		}
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   769
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   770
		if (is_new_map(maps, depth+1))
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   771
		{
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   772
			num_new_movements = get_box_movements(m, new_movements);
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   773
			assert(num_new_movements < MAX_MOVES);
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   774
		}
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   775
		else
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   776
			num_new_movements = 0;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   777
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   778
		if (num_new_movements == 0)
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   779
		{
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   780
			percent_to_show = total_percent + next_percent*i;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   781
			depth_to_show = depth;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   782
			actual_map = &maps[depth];
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   783
#ifdef DEBUG		/* to be out */
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   784
			show_percent_callback(0);
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   785
#endif
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   786
	
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   787
		}
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   788
		else
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   789
		{
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   790
			if (depth+1 < MAX_STEPS)
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   791
			{
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   792
				if(search_depth(maps, depth+1, new_movements,
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   793
					num_new_movements, next_percent,
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   794
					total_percent + next_percent*i) == 0)
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   795
				{
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   796
					PrintMove(movements[i]);
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   797
					return 0;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   798
				}
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   799
			}
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   800
		}
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   801
	}
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   802
	return 1;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   803
}
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   804
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   805
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   806
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   807
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   808
void program_alarm()
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   809
{
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   810
        struct sigaction my_action;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   811
        int result;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   812
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   813
        my_action.sa_handler = show_percent_callback;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   814
        my_action.sa_flags = 0;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   815
        memset(&my_action.sa_mask, 0, sizeof(my_action.sa_mask));
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   816
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   817
        result = sigaction(SIGALRM, &my_action, NULL);
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   818
        assert(result == 0);
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   819
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   820
	alarm(1);
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   821
}
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   822
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   823
int main(int argn, char **argv)
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   824
{
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   825
	struct Map Morigin;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   826
	struct Map maps[MAX_STEPS+1];
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   827
	struct BoxMove new_movements[MAX_MOVES];
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   828
	int num_new_movements;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   829
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   830
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   831
	if (argn != 2)
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   832
	{
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   833
		printf("Usage: %s <mapfile>\n", argv[0]);
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   834
		exit(3);
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   835
	}
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   836
	ReadMap(&Morigin, argv[1]);
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   837
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   838
	// Reget the original map
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   839
	CopyMap(&maps[0], &Morigin);
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   840
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   841
	assert(maps[0].NumPlatforms > maps[0].NumBoxesInPlatform);
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   842
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   843
	num_new_movements = get_box_movements(&maps[0], new_movements);
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   844
	assert(num_new_movements < MAX_MOVES);
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   845
	assert(num_new_movements > 0);
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   846
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   847
#ifndef DEBUG
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   848
	program_alarm();
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   849
#endif
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   850
	search_depth(maps, 0, new_movements,
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   851
		num_new_movements, 100. / num_new_movements,
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   852
		0);
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   853
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   854
	return 0;
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   855
be33ecaa3619 Initial commit.
viric@llimona
parents:
diff changeset
   856
}