os.c
author viric@llimona
Sat, 17 Feb 2007 15:14:30 +0100
changeset 28 cd27cb410375
parent 27 545f73869d65
permissions -rw-r--r--
Recursivity changed into a loop. Now the state is loaded on boot, and saved on TERM.

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <assert.h>
#include "general.h"

/* Things related to the showing of the status */
float percent_to_show = 0;
int depth_to_show = 0;

int max_depth = 0;
int min_depth_period = 0;
int max_depth_period = 0;
struct Map * actual_map = NULL;

/* The algorithm data */
extern struct Map *all_maps;
extern struct BoxMove *all_movements; /* DEPTH movements of MAX_MOVES */
extern int *all_mov_tries; /* The actual step in movements for every depth */
extern int *all_mov_max; /* Maximum of movements per all_movement element */
extern float *percent;
extern float *percent_part;
extern int depth;

void ReadMap(struct Map *M, char *FileName)
{
	FILE *Fitxer;
	int i,j;

	if(!(Fitxer = fopen(FileName, "r")))
	{
		printf("Error opening %s!", FileName);
		exit(1);
	}

	M->SizeX=0;
	M->SizeY=0;
	while (!feof(Fitxer))
	{
		fgets(M->Cells[M->SizeY], MAX_X, Fitxer);
		M->SizeY++;
	}
	M->SizeY--;
	M->SizeX = strlen(M->Cells[0]) - 1;

	M->NumPlatforms = 0;
	M->NumBoxesInPlatform = 0;
	M->NumBoxes = 0;
	for (j = 0; j<M->SizeY; j++)
		for (i=0; i<M->SizeX; i++)
		{
			if (M->Cells[j][i] == MAN)
			{ 
				M->Man.x = i; M->Man.y = j; 
				M->Cells[M->Man.y][M->Man.x] = BLANK;
			}

			if (M->Cells[j][i] == PLATFORM)
				M->NumPlatforms++;
			else if (M->Cells[j][i] == BOXINPLATFORM)
			{
				M->Cells[j][i] = PLATFORM;

				M->NumPlatforms++;
				M->NumBoxesInPlatform++;

				M->Box[M->NumBoxes].x = i;
				M->Box[M->NumBoxes].y = j;
				M->NumBoxes++;
			} else if (M->Cells[j][i] == BOX)
			{
				M->Cells[j][i] = BLANK;

				M->Box[M->NumBoxes].x = i;
				M->Box[M->NumBoxes].y = j;
				M->NumBoxes++;
			} else if (M->Cells[j][i] == CORNER)
			{
				M->Cells[j][i] = CORNER;
			} else if (M->Cells[j][i] != WALL)
			{
				if (    (M->Cells[j][i-1] == WALL &&
					 M->Cells[j-1][i] == WALL) ||
					(M->Cells[j][i-1] == WALL &&
					 M->Cells[j+1][i] == WALL) ||
					(M->Cells[j][i+1] == WALL &&
					 M->Cells[j-1][i] == WALL) ||
					(M->Cells[j][i+1] == WALL &&
					 M->Cells[j+1][i] == WALL))
				M->Cells[j][i] = CORNER;
			}
				
		}

}


void ShowMap (const struct Map *M)
{
	struct Map Temp;
	int i,j;

	CopyMap(&Temp, M);

	Temp.Cells[Temp.Man.y][Temp.Man.x] = MAN;

	for (i = 0; i < Temp.NumBoxes; i++)
	{
		if (Temp.Cells[Temp.Box[i].y][Temp.Box[i].x] == PLATFORM)
			Temp.Cells[Temp.Box[i].y][Temp.Box[i].x] =BOXINPLATFORM;
		else
			Temp.Cells[Temp.Box[i].y][Temp.Box[i].x] = BOX;
	}

	for (j = 0; j<Temp.SizeY; j++)
	{
		for (i=0; i<Temp.SizeX; i++)
			fprintf(stdout,"%c", Temp.Cells[j][i]);
		fprintf(stdout,"\n");
	}

#if 0
	/* Print Where the man can move */
	for (j = 0; j<Temp.SizeY; j++)
	{
		for (i=0; i<Temp.SizeX; i++)
			printf("%c", Temp.ManMoves[j][i]);
		printf("\n");
	}
#endif

	fprintf(stdout,"Man is at (%i,%i)\n", Temp.Man.x, Temp.Man.y);
	fprintf(stdout,"Platforms: %i, BoxesInPlatform: %i\n", Temp.NumPlatforms,
			Temp.NumBoxesInPlatform);

}

void PrintMoves(const struct BoxMove *b, const int *steps, const int depth)
{
	int i;
	int offset;
	char *dir;

	/* The first isn't a movement. Movements are stored from b[1] and on */
	for (i=0; i < depth; ++i)
	{
		/* the steps are incremented after try. So to find the movement,
		 * we should substract 1. */
		offset = i*MAX_MOVES + steps[i] -1;
		if (b[offset].dir.x == 0 && 
			b[offset].dir.y == 1)
			dir = "down";
		else if (b[offset].dir.x == 0 && 
			b[offset].dir.y == -1)
			dir = "up";
		else if (b[offset].dir.x == -1 && 
			b[offset].dir.y == 0)
			dir = "left";
		else if (b[offset].dir.x == 1 && 
			b[offset].dir.y == 0)
			dir = "right";
		else
			dir = "unknown";

		fprintf(stdout,"Box: %i, Direction: %s\n",
				b[offset].box, dir);
	}
}

void show_tries(const int d)
{
	int i;

	for(i=0; i<=d; ++i)
		printf("%i/%i,", all_mov_tries[i], all_mov_max[i]);
	putchar('\n');
}

void show_percent_and_map()
{
	fprintf(stdout, "Percent: %2.12f, depth: %i-%i\n", percent_to_show,
		min_depth_period, max_depth_period);
	if(actual_map != NULL)
		ShowMap(actual_map);
	show_tries(min_depth_period);
	fflush(stdout);
	min_depth_period = MAX_STEPS;
	max_depth_period = 0;
}

static void show_percent_usr1_callback(const int parameter)
{
	show_percent_and_map();
}

static void show_percent_alarm_callback(const int parameter)
{
	show_percent_and_map();
	alarm(ALARM_SECONDS);
}

static void program_alarm()
{
        struct sigaction my_action;
        int result;

        my_action.sa_handler = show_percent_alarm_callback;
        my_action.sa_flags = 0;
        memset(&my_action.sa_mask, 0, sizeof(my_action.sa_mask));

        result = sigaction(SIGALRM, &my_action, NULL);
        assert(result == 0);

	alarm(1);
}

static void program_usr1()
{
        struct sigaction my_action;
        int result;

        my_action.sa_handler = show_percent_usr1_callback;
        my_action.sa_flags = 0;
        memset(&my_action.sa_mask, 0, sizeof(my_action.sa_mask));

        result = sigaction(SIGUSR1, &my_action, NULL);
        assert(result == 0);
}

void save_state()
{
	FILE *f;

	f = fopen("state.raw", "w");
	fwrite(all_maps, sizeof(*all_maps), MAX_STEPS+1, f);
	fwrite(all_movements, sizeof(*all_movements), MAX_MOVES*(MAX_STEPS+1), f);
	fwrite(all_mov_tries, sizeof(*all_mov_tries), MAX_STEPS+1, f);
	fwrite(all_mov_max, sizeof(*all_mov_max), MAX_STEPS+1, f);
	fwrite(percent, sizeof(*percent), MAX_STEPS+1, f);
	fwrite(percent_part, sizeof(*percent_part), MAX_STEPS+1, f);
	fwrite(&depth, sizeof(depth), 1, f);
	fclose(f);
}

int load_state()
{
	FILE *f;

	f = fopen("state.raw", "r");
	if (f == NULL)
		return 0;
	fread(all_maps, sizeof(*all_maps), MAX_STEPS+1, f);
	fread(all_movements, sizeof(*all_movements), MAX_MOVES*(MAX_STEPS+1), f);
	fread(all_mov_tries, sizeof(*all_mov_tries), MAX_STEPS+1, f);
	fread(all_mov_max, sizeof(*all_mov_max), MAX_STEPS+1, f);
	fread(percent, sizeof(*percent), MAX_STEPS+1, f);
	fread(percent_part, sizeof(*percent_part), MAX_STEPS+1, f);
	fread(&depth, sizeof(depth), 1, f);
	fclose(f);
	return 1;
}

static void save_state_callback(const int parameter)
{
	save_state();
	exit(0);
}

static void program_term_int()
{
        struct sigaction my_action;
        int result;

        my_action.sa_handler = save_state_callback;
        my_action.sa_flags = 0;
        memset(&my_action.sa_mask, 0, sizeof(my_action.sa_mask));

        result = sigaction(SIGTERM, &my_action, NULL);
        assert(result == 0);
        result = sigaction(SIGINT, &my_action, NULL);
        assert(result == 0);
}

void init_os()
{
#ifndef DEBUG
	program_usr1();
	program_term_int();
	/* program_alarm();*/
#endif
}