algorithm.c
changeset 21 e73048967870
parent 17 7c1e68c17c0e
equal deleted inserted replaced
20:7d212921dad4 21:e73048967870
   242 				/* Maybe we could update the percent here... */
   242 				/* Maybe we could update the percent here... */
   243 				continue;
   243 				continue;
   244 			}
   244 			}
   245 			actual_map = &maps[depth+1];
   245 			actual_map = &maps[depth+1];
   246 #ifdef DEBUG		/* to be out */
   246 #ifdef DEBUG		/* to be out */
       
   247 			actual_map = &maps[depth+1];
   247 			show_percent_and_map();
   248 			show_percent_and_map();
   248 #endif
   249 #endif
   249 			/* the assert should be IN the function before,
   250 			/* the assert should be IN the function before,
   250 			   before OVERfilling new_movements */
   251 			   before OVERfilling new_movements */
   251 			assert(num_new_movements < MAX_MOVES);
   252 			assert(num_new_movements < MAX_MOVES);
   355 	} dep;
   356 	} dep;
   356 
   357 
   357 	/* Free boxes' arrays */
   358 	/* Free boxes' arrays */
   358 	struct
   359 	struct
   359 	{
   360 	{
   360 		Bool box_is_free[MAX_BOXES]; /* This is only used in 'free' */
   361 		Bool tag[MAX_BOXES]; /*This is only used in 'free' & 'blocked'*/
   361 		int box[MAX_BOXES];
   362 		int box[MAX_BOXES];
   362 		int n;
   363 		int n;
   363 	} free,			/* List of all boxes free-to-move */
   364 	} free,			/* List of all boxes free-to-move */
   364 		new_free,	/* List of boxes for the next loop (code) */
   365 		new_free,	/* List of boxes for the next loop (code) */
   365 		tfree;	/* List of boxes of the loop (code) */
   366 		tfree,	/* List of boxes of the loop (code) */
       
   367 		new_blocked,
       
   368 		tblocked,
       
   369 		blocked;
   366 
   370 
   367 	struct Position tpos;
   371 	struct Position tpos;
   368 
   372 
   369 	Bool is_not_set_free;
   373 	Bool is_not_set_free;
   370 
   374 
   371 	/* Initialize to 0 the dependency structures */
   375 	/* Initialize to 0 the dependency structures */
   372 	memset((void *) &dep, 0, sizeof(dep));
   376 	memset((void *) &dep, 0, sizeof(dep));
   373 	new_free.n=0;
   377 	new_free.n=0;
       
   378 	blocked.n=0;
       
   379 	new_blocked.n=0;
   374 	for(i=0; i<m->NumBoxes; i++)
   380 	for(i=0; i<m->NumBoxes; i++)
   375 	{
   381 	{
   376 		new_free.box[i] = FALSE;
   382 		new_free.box[i] = FALSE;
       
   383 		blocked.tag[i] = FALSE;
       
   384 		new_blocked.tag[i] = FALSE;
   377 	}
   385 	}
   378 
   386 
   379 	/* Let's fill the structure */
   387 	/* Let's fill the structure */
   380 	for(i=0; i<m->NumBoxes; i++)
   388 	for(i=0; i<m->NumBoxes; i++)
   381 	{
   389 	{
   387 			m->box_deps[i].dep_dir[3] == BLOCKED )
   395 			m->box_deps[i].dep_dir[3] == BLOCKED )
   388 		{
   396 		{
   389 			if (m->Cells[m->Box[i].y][m->Box[i].x] !=
   397 			if (m->Cells[m->Box[i].y][m->Box[i].x] !=
   390 				PLATFORM)
   398 				PLATFORM)
   391 				return TRUE;
   399 				return TRUE;
   392 			/* This is not used actually 
       
   393 			else
   400 			else
       
   401 			{
       
   402 				blocked.tag[i] = TRUE;
       
   403 				blocked.box[blocked.n++] = i;
       
   404 				new_blocked.box[new_blocked.n++] = i;
       
   405 
       
   406 				/* This is not used actually 
   394 				m->boxes[m->Box[i].y][m->Box[i].x] =
   407 				m->boxes[m->Box[i].y][m->Box[i].x] =
   395 					WALL;
   408 					WALL;
   396 			*/
   409 				*/
       
   410 				/* The dependencies are checked. All blocked.*/
       
   411 				continue;
       
   412 			}
   397 		}
   413 		}
   398 		/* Let's take note of the dependencies */
   414 		/* Let's take note of the dependencies */
   399 		is_not_set_free = TRUE;
   415 		is_not_set_free = TRUE;
   400 		for(d=0; d<4; d++)
   416 		for(d=0; d<4; d++)
   401 		{
   417 		{
   456 
   472 
   457 	/* ---------------- The next possible movements have been calculated --
   473 	/* ---------------- The next possible movements have been calculated --
   458 	We can still find that this map is illegal. We need to find
   474 	We can still find that this map is illegal. We need to find
   459 	further more if there are boxes unmovable (due to dependencies) */
   475 	further more if there are boxes unmovable (due to dependencies) */
   460 
   476 
       
   477 	/* Let's block those boxes dependant on blocked boxes.
       
   478 	   If some of those is not in a platform, the function exits TRUE. */
       
   479 	/* The new_blocked and blocked structures are filled fine */
       
   480 	while (new_blocked.n > 0)
       
   481 	{
       
   482 		/* Copy new_blocked into tblocked */
       
   483 		tblocked.n = new_blocked.n;
       
   484 		for(i=0; i<new_blocked.n; i++)
       
   485 			tblocked.box[i] = new_blocked.box[i];
       
   486 		new_blocked.n = 0;
       
   487 
       
   488 		for(i=0; i<tblocked.n; i++)
       
   489 		{
       
   490 			for(j=0; j<m->NumBoxes; j++)
       
   491 			{
       
   492 				if(dep.box[j][tblocked.box[i]])
       
   493 				{
       
   494 				/* The next line depends on the multiple-
       
   495 				   dependency improvement, still not done. */
       
   496 				   	/* Look for the dep direction */
       
   497 					for(d=0;d<4;d++)
       
   498 					{
       
   499 						if(m->box_deps[j].dep_dir[d]==
       
   500 						tblocked.box[i])
       
   501 							break;
       
   502 					}
       
   503 					/* d owns the dependency dir. */
       
   504 					/* Look if the other directions are
       
   505 					blocked */
       
   506 					if(m->box_deps[j].dep_dir[(d+1)%4] !=
       
   507 						BLOCKED ||
       
   508 					m->box_deps[j].dep_dir[(d+3)%4] !=
       
   509 						BLOCKED)
       
   510 						continue;
       
   511 
       
   512 					/* A dependancy on a blocked box found*/
       
   513 					if (!blocked.tag[j])
       
   514 					{
       
   515 						/* If the box is not already
       
   516 						known as blocked...*/
       
   517 						if (m->Cells[m->Box[j].y][m->Box[j].x] != PLATFORM)
       
   518 						{
       
   519 							return TRUE;
       
   520 						}
       
   521 						else
       
   522 						{
       
   523 							new_blocked.box[new_blocked.n++]=j;
       
   524 							/* The next line is not
       
   525 							really used 
       
   526 							blocked.box[blocked.n++]=j;
       
   527 							*/
       
   528 							blocked.tag[j]=TRUE;
       
   529 						}
       
   530 					}
       
   531 				}
       
   532 			}
       
   533 		}
       
   534 	}
       
   535 
   461 	/* Let's take out all dependencies from 'free' boxes */
   536 	/* Let's take out all dependencies from 'free' boxes */
   462 	/* Prepare the 'free' list */
   537 	/* Prepare the 'free' list */
   463 	for(i=0; i<m->NumBoxes;i++)
   538 	for(i=0; i<m->NumBoxes;i++)
   464 		free.box_is_free[i] = FALSE;
   539 		free.tag[i] = FALSE;
   465 	free.n = new_free.n;
   540 	free.n = new_free.n;
   466 	for(i=0; i<new_free.n; i++)
   541 	for(i=0; i<new_free.n; i++)
   467 	{
   542 	{
   468 		free.box[i] = new_free.box[i];
   543 		free.box[i] = new_free.box[i];
   469 		free.box_is_free[new_free.box[i]] = TRUE;
   544 		free.tag[new_free.box[i]] = TRUE;
   470 	}
   545 	}
   471 
   546 
   472 	/* KACXO-loop  */
   547 	/* KACXO-loop  */
   473 	while (new_free.n > 0)
   548 	while (new_free.n > 0)
   474 	{
   549 	{
   484 			{
   559 			{
   485 				/* The box j no more depends on
   560 				/* The box j no more depends on
   486 				   the box tfree[i] */
   561 				   the box tfree[i] */
   487 				if(dep.box[j][tfree.box[i]])
   562 				if(dep.box[j][tfree.box[i]])
   488 				{
   563 				{
       
   564 					/* Remove the dependency */
   489 					dep.box[j][tfree.box[i]] = FALSE;
   565 					dep.box[j][tfree.box[i]] = FALSE;
   490 					dep.ndeps[j]--;
   566 					dep.ndeps[j]--;
   491 					assert(dep.ndeps[j] >= 0);
   567 					assert(dep.ndeps[j] >= 0);
   492 					if (dep.ndeps[j] == 0 &&
   568 					if (dep.ndeps[j] == 0 &&
   493 						!free.box_is_free[tfree.box[i]])
   569 						!free.tag[j])
   494 					{
   570 					{
   495 						new_free.box[new_free.n++]=j;
   571 						new_free.box[new_free.n++]=j;
   496 						free.box[free.n++]=j;
   572 						free.box[free.n++]=j;
       
   573 						free.tag[j]=TRUE;
   497 					}
   574 					}
   498 				}
   575 				}
   499 			}
   576 			}
   500 		}
   577 		}
   501 	}
   578 	}
       
   579 
   502 
   580 
   503 	/* Now are left only boxes which depend on others-non-free */
   581 	/* Now are left only boxes which depend on others-non-free */
   504 	for(i=0; i<m->NumBoxes; i++)
   582 	for(i=0; i<m->NumBoxes; i++)
   505 	{
   583 	{
   506 		for(j=0; j<m->NumBoxes; j++)
   584 		for(j=0; j<m->NumBoxes; j++)
   572 				continue;
   650 				continue;
   573 			}
   651 			}
   574 
   652 
   575 			/* if there is Wall limit, we don't want to set box
   653 			/* if there is Wall limit, we don't want to set box
   576 			   dependency */
   654 			   dependency */
   577 			if(m->box_deps[i].dep_dir[dir] == WALL)
   655 			if(m->box_deps[i].dep_dir[dir] == BLOCKED)
   578 				continue;
   656 				continue;
   579 
   657 
   580 			/* Put the box dependency in the list */
   658 			/* Put the box dependency in the list */
   581 			if(m->cells_boxes[n.y][n.x] >= 0)
   659 			if(m->cells_boxes[n.y][n.x] >= 0)
   582 			{
   660 			{