예제 #1
0
int main (int argc, char* argv[]) 
{
  int objs[2*N+1];
  int i;

  objs[0]=N;
  for(i=1; i<=N;i++){
    objs[2*i-1]=N+i;
    objs[2*i]=N-i;
  }
  random_permutation(objs, 2*N+1);

  printf("Test de heap_remove_min\n");

  /********************************/
  heap h=prof_heap_create(f);

  for(i=0; i<=2*N; i++)
    h=prof_heap_insert(h, &objs[i]);

  heap_dump(h);

  for(i=0; i<=2*N; i++){
    h=heap_remove_min(h);
    heap_dump(h);
  }

  prof_heap_destroy(h);

  return 0;  
}
예제 #2
0
gamestate_t take_turn(heap_t *h, cell_t *cell_arr, path_node_t *t_map,
		      path_node_t *n_t_map, character **c_arr, int t_char)
{
  character *c_turn = (character *)heap_remove_min(h);

  return c_turn->take_turn(h, cell_arr, t_map, n_t_map, c_arr, t_char);
}
static void create_corridor(heap_t *h, path_node_c_t *path_arr)
{
  path_node_c_t *curr_p, *curr_n_p;

  while(h->size > 0)
    { 
    curr_p = (path_node_c_t *) heap_remove_min(h);
    curr_p->heap_node = NULL;

    curr_n_p = path_arr + (MAP_WIDTH * (curr_p->y - 1)) + curr_p->x;

    if(curr_n_p->heap_node != NULL)
      {
	if(curr_n_p->distance > curr_p->distance + curr_n_p->weight)
	  {
	    curr_n_p->distance = curr_p->distance + curr_n_p->weight;
	    curr_n_p->previous = curr_p;
	    heap_decrease_key_no_replace(h, curr_n_p->heap_node);
	  }
      }
    curr_n_p = path_arr + (MAP_WIDTH * curr_p->y) + curr_p->x + 1;

    if(curr_n_p->heap_node != NULL)
      {
	if(curr_n_p->distance > curr_p->distance + curr_n_p->weight)
	  {
	    curr_n_p->distance = curr_p->distance + curr_n_p->weight;
	    curr_n_p->previous = curr_p;
	    heap_decrease_key_no_replace(h, curr_n_p->heap_node);
	  }
      }
    curr_n_p = path_arr + (MAP_WIDTH * (curr_p->y + 1)) + curr_p->x;

    if(curr_n_p->heap_node != NULL)
      {
	if(curr_n_p->distance > curr_p->distance + curr_n_p->weight)
	  {
	    curr_n_p->distance = curr_p->distance + curr_n_p->weight;
	    curr_n_p->previous = curr_p;
	    heap_decrease_key_no_replace(h, curr_n_p->heap_node);
	  }
      }
    curr_n_p = path_arr + (MAP_WIDTH * curr_p->y) + curr_p->x - 1;

    if(curr_n_p->heap_node != NULL)
      {
	if(curr_n_p->distance > curr_p->distance + curr_n_p->weight)
	  {
	    curr_n_p->distance = curr_p->distance + curr_n_p->weight;
	    curr_n_p->previous = curr_p;
	    heap_decrease_key_no_replace(h, curr_n_p->heap_node);
	  }
      }
  }
}
예제 #4
0
void turnDo(dungeon_t* dungeonPtr) {
    turn_t *turnPtr;
    do {
        turnPtr = (turn_t *) heap_remove_min(dungeonPtr->turnsHeapPtr);
        if (!monsterIsAlive(turnPtr->monsterPtr)) {
            free(turnPtr);
            turnPtr = NULL;
        }
    } while (!turnPtr);
    moveMonsterLogic(dungeonPtr, turnPtr->monsterPtr);
    turnPtr->nextTurn += 100 / monsterSpeed(turnPtr->monsterPtr);
    heap_insert(dungeonPtr->turnsHeapPtr, (void*) turnPtr);

//    screenClearRow(0);
//    mvprintw(0, 0, "Moved %c", monsterGetChar(*turnPtr->monsterPtr));
//    refresh();
}
예제 #5
0
파일: move.cpp 프로젝트: jkuczek15/rlg327
void do_moves(dungeon_t *d)
{
  pair_t next;
  character *c;

  /* Remove the PC when it is PC turn.  Replace on next call.  This allows *
   * use to completely uninit the heap when generating a new level without *
   * worrying about deleting the PC.                                       */

  if (pc_is_alive(d)) {
    heap_insert(&d->next_turn, d->pc);
  }

  while (pc_is_alive(d) && ((c = ((character *)
                                  heap_remove_min(&d->next_turn))) != d->pc)) {
    if (!character_is_alive(c)) {
      if (d->charmap[character_get_y(c)][character_get_x(c)] == c) {
        d->charmap[character_get_y(c)][character_get_x(c)] = NULL;
      }
      if (c != d->pc) {
        character_delete(c);
      }
      continue;
    }

    character_next_turn(c);

    npc_next_pos(d, c, next);
    move_character(d, c, next);

    heap_insert(&d->next_turn, c);
  }

  if (pc_is_alive(d) && c == d->pc) {
    character_next_turn(c);

    if(d->objmap[character_get_y(c)][character_get_x(c)]){
      if(add_to_inventory(d, d->objmap[character_get_y(c)][character_get_x(c)]) == 0){
        d->objmap[character_get_y(c)][character_get_x(c)] = NULL;
      }
    }

  }
}
예제 #6
0
파일: heap.c 프로젝트: SWhelan/EECS-345
/*--------------------------------------------------------------------------------------*
 * Does an in-place heap sort of the array.                                             *
 * INPUT:  The array to be sorted, the size of the array, and a function to order the   *
 *         elements.  The array stores pointers to the elements that must be sorted.    *
 *--------------------------------------------------------------------------------------*/ 
 void heapSort(void ** data, int size, int (*compare)(void *, void *)) {
  int i;

  normalCompare = compare;
  struct heap heap;
  //this is allowed because the index 0 of the heap is never accessed and this effectively makes the heap the data array 
  heap.data = data - 1;
  heap.capacity = size;
  heap.endptr = size;
  heap.compare = reverseCompare;
  
  /*enforce the heap constraint (each parent is as large or larger than both its children) by
  calling bubble down on all nodes that would have children */
  for(i = heap.capacity / 2; i > 0; i--){
    bubbledown(&heap, i);
  }
  
  /* takes the value at the top of the heap and puts it last in the data */
  while(!heap_empty(&heap)){
   data[heap.endptr] = heap_remove_min(&heap);
  }
}
예제 #7
0
void dijkstra(dungeon_t *d)
{
  /* Currently assumes that monsters only move on floors.  Will *
   * need to be modified for tunneling and pass-wall monsters.  */

  heap_t h;
  uint32_t x, y;
  static path_t p[DUNGEON_Y][DUNGEON_X], *c;
  static uint32_t initialized = 0;

  if (!initialized) {
    initialized = 1;
    dungeon = d;
    for (y = 0; y < DUNGEON_Y; y++) {
      for (x = 0; x < DUNGEON_X; x++) {
        p[y][x].pos[dim_y] = y;
        p[y][x].pos[dim_x] = x;
      }
    }
  }

  for (y = 0; y < DUNGEON_Y; y++) {
    for (x = 0; x < DUNGEON_X; x++) {
      d->pc_distance[y][x] = 255;
    }
  }
  d->pc_distance[d->pc.position[dim_y]][d->pc.position[dim_x]] = 0;

  heap_init(&h, dist_cmp, NULL);

  for (y = 0; y < DUNGEON_Y; y++) {
    for (x = 0; x < DUNGEON_X; x++) {
      if (mapxy(x, y) >= ter_floor) {
        p[y][x].hn = heap_insert(&h, &p[y][x]);
      }
    }
  }

  while ((c = heap_remove_min(&h))) {
    c->hn = NULL;
    if ((p[c->pos[dim_y] - 1][c->pos[dim_x] - 1].hn) &&
        (d->pc_distance[c->pos[dim_y] - 1][c->pos[dim_x] - 1] >
         d->pc_distance[c->pos[dim_y]][c->pos[dim_x]] + 1)) {
      d->pc_distance[c->pos[dim_y] - 1][c->pos[dim_x] - 1] =
        d->pc_distance[c->pos[dim_y]][c->pos[dim_x]] + 1;
      heap_decrease_key_no_replace(&h,
                                   p[c->pos[dim_y] - 1][c->pos[dim_x] - 1].hn);
    }
    if ((p[c->pos[dim_y] - 1][c->pos[dim_x]    ].hn) &&
        (d->pc_distance[c->pos[dim_y] - 1][c->pos[dim_x]    ] >
         d->pc_distance[c->pos[dim_y]][c->pos[dim_x]] + 1)) {
      d->pc_distance[c->pos[dim_y] - 1][c->pos[dim_x]    ] =
        d->pc_distance[c->pos[dim_y]][c->pos[dim_x]] + 1;
      heap_decrease_key_no_replace(&h,
                                   p[c->pos[dim_y] - 1][c->pos[dim_x]    ].hn);
    }
    if ((p[c->pos[dim_y] - 1][c->pos[dim_x] + 1].hn) &&
        (d->pc_distance[c->pos[dim_y] - 1][c->pos[dim_x] + 1] >
         d->pc_distance[c->pos[dim_y]][c->pos[dim_x]] + 1)) {
      d->pc_distance[c->pos[dim_y] - 1][c->pos[dim_x] + 1] =
        d->pc_distance[c->pos[dim_y]][c->pos[dim_x]] + 1;
      heap_decrease_key_no_replace(&h,
                                   p[c->pos[dim_y] - 1][c->pos[dim_x] + 1].hn);
    }
    if ((p[c->pos[dim_y]    ][c->pos[dim_x] - 1].hn) &&
        (d->pc_distance[c->pos[dim_y]    ][c->pos[dim_x] - 1] >
         d->pc_distance[c->pos[dim_y]][c->pos[dim_x]] + 1)) {
      d->pc_distance[c->pos[dim_y]    ][c->pos[dim_x] - 1] =
        d->pc_distance[c->pos[dim_y]][c->pos[dim_x]] + 1;
      heap_decrease_key_no_replace(&h,
                                   p[c->pos[dim_y]    ][c->pos[dim_x] - 1].hn);
    }
    if ((p[c->pos[dim_y]    ][c->pos[dim_x] + 1].hn) &&
        (d->pc_distance[c->pos[dim_y]    ][c->pos[dim_x] + 1] >
         d->pc_distance[c->pos[dim_y]][c->pos[dim_x]] + 1)) {
      d->pc_distance[c->pos[dim_y]    ][c->pos[dim_x] + 1] =
        d->pc_distance[c->pos[dim_y]][c->pos[dim_x]] + 1;
      heap_decrease_key_no_replace(&h,
                                   p[c->pos[dim_y]    ][c->pos[dim_x] + 1].hn);
    }
    if ((p[c->pos[dim_y] + 1][c->pos[dim_x] - 1].hn) &&
        (d->pc_distance[c->pos[dim_y] + 1][c->pos[dim_x] - 1] >
         d->pc_distance[c->pos[dim_y]][c->pos[dim_x]] + 1)) {
      d->pc_distance[c->pos[dim_y] + 1][c->pos[dim_x] - 1] =
        d->pc_distance[c->pos[dim_y]][c->pos[dim_x]] + 1;
      heap_decrease_key_no_replace(&h,
                                   p[c->pos[dim_y] + 1][c->pos[dim_x] - 1].hn);
    }
    if ((p[c->pos[dim_y] + 1][c->pos[dim_x]    ].hn) &&
        (d->pc_distance[c->pos[dim_y] + 1][c->pos[dim_x]    ] >
         d->pc_distance[c->pos[dim_y]][c->pos[dim_x]] + 1)) {
      d->pc_distance[c->pos[dim_y] + 1][c->pos[dim_x]    ] =
        d->pc_distance[c->pos[dim_y]][c->pos[dim_x]] + 1;
      heap_decrease_key_no_replace(&h,
                                   p[c->pos[dim_y] + 1][c->pos[dim_x]    ].hn);
    }
    if ((p[c->pos[dim_y] + 1][c->pos[dim_x] + 1].hn) &&
        (d->pc_distance[c->pos[dim_y] + 1][c->pos[dim_x] + 1] >
         d->pc_distance[c->pos[dim_y]][c->pos[dim_x]] + 1)) {
      d->pc_distance[c->pos[dim_y] + 1][c->pos[dim_x] + 1] =
        d->pc_distance[c->pos[dim_y]][c->pos[dim_x]] + 1;
      heap_decrease_key_no_replace(&h,
                                   p[c->pos[dim_y] + 1][c->pos[dim_x] + 1].hn);
    }
  }
  heap_delete(&h);
}
예제 #8
0
int top_main  (int argc, char ** argv) {

	char c;
	heap h = heap_init(1024, (void *) proc_comparer);
	do {
		int allow_zombies = 0;

		if (argc > 1 && !strcmp(argv[1], "zombies")) {
			allow_zombies = 1;
		}

		int len = 0;
		int i = 0;
		int active_pids[PROCESS_MAX];
		int	active_pids_ticks[PROCESS_MAX];
		int active_pids_n = 0;

		for(; i < PROCESS_MAX; ++i)
		{
			active_pids[i] = -1;
			active_pids_ticks[i] = 0;
		}

		int tick_history[PROCESS_HISTORY_SIZE];
		int * _pticks = pticks();

		i = 0;

		for(; i < PROCESS_HISTORY_SIZE; i++) {
			if(_pticks[i] == -1) {
				break;
			}
			tick_history[i] = _pticks[i];
		}


		len = i;
		i = 0;
		int zombs = 0;
		for(; i < len; ++i)
		{
			int pid = tick_history[i];
			int _pid_index = -1, j = 0;
			for(; j < active_pids_n; j++)	{
				if(active_pids[j] == pid) {
					_pid_index = j;
					break;
				}
			}
			if(_pid_index == -1)	{
				_pid_index = active_pids_n;
				active_pids[_pid_index] = pid;
				active_pids_n++;
			}
			if (pstatus(pid) != PROCESS_ZOMBIE) {
				active_pids_ticks[_pid_index]++;
			} else {
				zombs++;
			}
		}

		if (!allow_zombies) {
			len -= zombs;
		}



		i = 0;
		int printed = 0;
		for(; i < PROCESS_MAX; ++i)	{
			int pid = pgetpid_at(i);

			if (pid != -1){
				int j = -1;
				for(; j < active_pids_n; j++)	{
					if(active_pids[j] == pid) {
						break;
					}
				}
				int ticks = ( j == -1 ) ? 0 : active_pids_ticks[j];
				top_data * data = (top_data *) malloc(sizeof(top_data));
				data->ticks = ticks;
				data->pid = pid;
				heap_insert(data, h);

			}
		} 
		i = 0;
		while(!heap_empty(h)) {
			top_data * data = heap_remove_min(h);
			if(0)	{
				break;
			} else {
				i++;
				int pid = data->pid;
				int ticks = data->ticks;

				char * _pname = pname(pid);
				char * status = NULL;

				int stat = pstatus(pid);
				switch(stat){
					case PROCESS_READY:
					status = "READY";
					break;
					case PROCESS_BLOCKED:
					status = "BLOCKED";
					break;
					case PROCESS_ZOMBIE:
					status = "ZOMBIE ";
					break;
					case PROCESS_RUNNING:
					status = "RUNNING";
					break;
					default:
					status = "UNKNOWN";
				}

				int priority = ppriority(pid);

				len = (!len) ? 1 : len;

				if (stat != PROCESS_ZOMBIE || (stat == PROCESS_ZOMBIE && allow_zombies) ) {
					printed++;

					printf("PID: %d \t NAME: %s \t CPU:%% %d \t STATUS: %s \t PRIORITY: %d\n",
						pid, _pname, 
						(100 * ticks) / len, status, priority);
				}
			}
		}
		
		printf("--------------------------------------------------------------------------------\n");
		sleep(1024);
	}
	while(1);
	
	return 0;
}
예제 #9
0
/* This is the same basic algorithm as in move.c, but *
 * subtle differences make it difficult to reuse.     */
static void dijkstra_corridor(dungeon_t *d, pair_t from, pair_t to)
{
  static corridor_path_t path[DUNGEON_Y][DUNGEON_X], *p;
  static uint32_t initialized = 0;
  heap_t h;
  uint32_t x, y;

  if (!initialized) {
    for (y = 0; y < DUNGEON_Y; y++) {
      for (x = 0; x < DUNGEON_X; x++) {
        path[y][x].pos[dim_y] = y;
        path[y][x].pos[dim_x] = x;
      }
    }
    initialized = 1;
  }
  
  for (y = 0; y < DUNGEON_Y; y++) {
    for (x = 0; x < DUNGEON_X; x++) {
      path[y][x].cost = INT_MAX;
    }
  }

  path[from[dim_y]][from[dim_x]].cost = 0;

  heap_init(&h, corridor_path_cmp, NULL);

  for (y = 0; y < DUNGEON_Y; y++) {
    for (x = 0; x < DUNGEON_X; x++) {
      if (mapxy(x, y) != ter_wall_immutable) {
        path[y][x].hn = heap_insert(&h, &path[y][x]);
      } else {
        path[y][x].hn = NULL;
      }
    }
  }

  while ((p = (corridor_path_t *) heap_remove_min(&h))) {
    p->hn = NULL;

    if ((p->pos[dim_y] == to[dim_y]) && p->pos[dim_x] == to[dim_x]) {
      for (x = to[dim_x], y = to[dim_y];
           (x != from[dim_x]) || (y != from[dim_y]);
           p = &path[y][x], x = p->from[dim_x], y = p->from[dim_y]) {
        if (mapxy(x, y) != ter_floor_room) {
          mapxy(x, y) = ter_floor_hall;
          hardnessxy(x, y) = 0;
        }
      }
      heap_delete(&h);
      return;
    }
    if ((path[p->pos[dim_y] - 1][p->pos[dim_x]    ].hn) &&
        (path[p->pos[dim_y] - 1][p->pos[dim_x]    ].cost >
         p->cost + (hardnesspair(p->pos) ? hardnesspair(p->pos) : 8) +
         ((p->pos[dim_x] != from[dim_x]) ? 48  : 0))) {
      path[p->pos[dim_y] - 1][p->pos[dim_x]    ].cost =
        p->cost + (hardnesspair(p->pos) ? hardnesspair(p->pos) : 8) +
         ((p->pos[dim_x] != from[dim_x]) ? 48  : 0);
      path[p->pos[dim_y] - 1][p->pos[dim_x]    ].from[dim_y] = p->pos[dim_y];
      path[p->pos[dim_y] - 1][p->pos[dim_x]    ].from[dim_x] = p->pos[dim_x];
      heap_decrease_key_no_replace(&h, path[p->pos[dim_y] - 1]
                                           [p->pos[dim_x]    ].hn);
    }
    if ((path[p->pos[dim_y]    ][p->pos[dim_x] - 1].hn) &&
        (path[p->pos[dim_y]    ][p->pos[dim_x] - 1].cost >
         p->cost + (hardnesspair(p->pos) ? hardnesspair(p->pos) : 8) +
         ((p->pos[dim_y] != from[dim_y]) ? 48  : 0))) {
      path[p->pos[dim_y]    ][p->pos[dim_x] - 1].cost =
        p->cost + (hardnesspair(p->pos) ? hardnesspair(p->pos) : 8) +
         ((p->pos[dim_y] != from[dim_y]) ? 48  : 0);
      path[p->pos[dim_y]    ][p->pos[dim_x] - 1].from[dim_y] = p->pos[dim_y];
      path[p->pos[dim_y]    ][p->pos[dim_x] - 1].from[dim_x] = p->pos[dim_x];
      heap_decrease_key_no_replace(&h, path[p->pos[dim_y]    ]
                                           [p->pos[dim_x] - 1].hn);
    }
    if ((path[p->pos[dim_y]    ][p->pos[dim_x] + 1].hn) &&
        (path[p->pos[dim_y]    ][p->pos[dim_x] + 1].cost >
         p->cost + (hardnesspair(p->pos) ? hardnesspair(p->pos) : 8) +
         ((p->pos[dim_y] != from[dim_y]) ? 48  : 0))) {
      path[p->pos[dim_y]    ][p->pos[dim_x] + 1].cost =
        p->cost + (hardnesspair(p->pos) ? hardnesspair(p->pos) : 8) +
         ((p->pos[dim_y] != from[dim_y]) ? 48  : 0);
      path[p->pos[dim_y]    ][p->pos[dim_x] + 1].from[dim_y] = p->pos[dim_y];
      path[p->pos[dim_y]    ][p->pos[dim_x] + 1].from[dim_x] = p->pos[dim_x];
      heap_decrease_key_no_replace(&h, path[p->pos[dim_y]    ]
                                           [p->pos[dim_x] + 1].hn);
    }
    if ((path[p->pos[dim_y] + 1][p->pos[dim_x]    ].hn) &&
        (path[p->pos[dim_y] + 1][p->pos[dim_x]    ].cost >
         p->cost + (hardnesspair(p->pos) ? hardnesspair(p->pos) : 8) +
         ((p->pos[dim_x] != from[dim_x]) ? 48  : 0))) {
      path[p->pos[dim_y] + 1][p->pos[dim_x]    ].cost =
        p->cost + (hardnesspair(p->pos) ? hardnesspair(p->pos) : 8) +
         ((p->pos[dim_x] != from[dim_x]) ? 48  : 0);
      path[p->pos[dim_y] + 1][p->pos[dim_x]    ].from[dim_y] = p->pos[dim_y];
      path[p->pos[dim_y] + 1][p->pos[dim_x]    ].from[dim_x] = p->pos[dim_x];
      heap_decrease_key_no_replace(&h, path[p->pos[dim_y] + 1]
                                           [p->pos[dim_x]    ].hn);
    }
  }
}
예제 #10
0
PC_action turnDoPC(dungeon_t* dungeonPtr) {
    PC_action returnValue = actionMovement;
    int userChar;
    int validChar = 0;
    int dstX;
    int dstY;
    turn_t* turnPtr;
    turnPtr = (turn_t *) heap_remove_min(dungeonPtr->turnsHeapPtr);
    dstX = monsterGetX(turnPtr->monsterPtr);
    dstY = monsterGetY(turnPtr->monsterPtr);

    do {
        userChar = getch();
        screenClearRow(0);
        switch (userChar) {
            case '7': //Num Lock on
            case KEY_HOME: //Num Lock off
            case 'y':
                mvprintw(0, 0, "User entered up-left");
                dstX--;
                dstY--;
                validChar = 1;
                break;
            case '8': //Num Lock on
            case KEY_UP: //Num Lock off
            case 'k':
                mvprintw(0, 0, "User entered up");
                dstY--;
                validChar = 1;
                break;
            case '9': //Num Lock on
            case KEY_PPAGE: //Num Lock off
            case 'u':
                mvprintw(0, 0, "User entered up-right");
                dstX++;
                dstY--;
                validChar = 1;
                break;
            case '4': //Num Lock on
            case KEY_LEFT: //Num Lock off
            case 'h':
            case 'a':
                mvprintw(0, 0, "User entered left");
                dstX--;
                validChar = 1;
                break;
            case '6': //Num Lock on
            case KEY_RIGHT: //Num Lock off
            case 'l':
                mvprintw(0, 0, "User entered right");
                dstX++;
                validChar = 1;
                break;
            case '1': //Num Lock on
            case KEY_END: //Num Lock off
            case 'b':
                mvprintw(0, 0, "User entered down-left");
                dstX--;
                dstY++;
                validChar = 1;
                break;
            case '2': //Num Lock on
            case KEY_DOWN: //Num Lock off
            case 'j':
                mvprintw(0, 0, "User entered down");
                dstY++;
                validChar = 1;
                break;
            case '3': //Num Lock on
            case KEY_NPAGE: //Num Lock off
            case 'n':
                mvprintw(0, 0, "User entered down-right");
                dstX++;
                dstY++;
                validChar = 1;
                break;
            case ' ':
            case '5': //Num Lock on
            case 350: //Num Lock off (from testing, I can't find a #define)
                //do nothing
                validChar = 1;
                break;
            case '>':
                if (dungeonPtr->grid[dstY][dstX].material == stairsDn) {
                    returnValue = actionStairsDn;
                    mvprintw(0, 0, "Going down the stairs.");
                    refresh();
                    validChar = 1;
                } else {
                    mvprintw(0, 0, "I can't dig a hole through the floor. Please find me some stairs to use.");
                }
                break;
            case '<':
                if (dungeonPtr->grid[dstY][dstX].material == stairsUp) {
                    returnValue = actionStairsUp;
                    mvprintw(0, 0, "Going up the stairs.");
                    refresh();
                    validChar = 1;
                } else {
                    mvprintw(0, 0, "I can't reach the ceiling from here. Please find me some stairs to use.");
                }
                break;
            case 'm':
                returnValue = actionListMonsters;
                validChar = 1;
                break;
            case 's':
                returnValue = actionSave;
                validChar = 1;
                break;
            default:
                mvprintw(0, 0, "You can't do that! (%d)", userChar);
        }
    } while (!validChar);

    if (returnValue == actionMovement) {
        moveMonster(dungeonPtr, turnPtr->monsterPtr, dstX, dstY);
        pathTunneling(dungeonPtr);
        pathNontunneling(dungeonPtr);
        turnPtr->nextTurn += 100 / monsterSpeed(turnPtr->monsterPtr);
    }
    heap_insert(dungeonPtr->turnsHeapPtr, (void *) turnPtr);
    return returnValue;
}
예제 #11
0
void dijkstra_tunnel(dungeon_t *d)
{
  /* Currently assumes that monsters only move on floors.  Will *
   * need to be modified for tunneling and pass-wall monsters.  */

  heap_t h;
  uint32_t x, y;
  static path_t p[DUNGEON_Y][DUNGEON_X], *c;
  static uint32_t initialized = 0;

  if (!initialized) {
    initialized = 1;
    dungeon = d;
    for (y = 0; y < DUNGEON_Y; y++) {
      for (x = 0; x < DUNGEON_X; x++) {
        p[y][x].pos[dim_y] = y;
        p[y][x].pos[dim_x] = x;
      }
    }
  }

  for (y = 0; y < DUNGEON_Y; y++) {
    for (x = 0; x < DUNGEON_X; x++) {
      d->pc_tunnel[y][x] = 255;
    }
  }
  d->pc_tunnel[character_get_y(d->pc)][character_get_x(d->pc)] = 0;

  heap_init(&h, tunnel_cmp, NULL);

  for (y = 0; y < DUNGEON_Y; y++) {
    for (x = 0; x < DUNGEON_X; x++) {
      if (mapxy(x, y) != ter_wall_immutable) {
        p[y][x].hn = heap_insert(&h, &p[y][x]);
      }
    }
  }

  while ((c = heap_remove_min(&h))) {
    c->hn = NULL;
    if ((p[c->pos[dim_y] - 1][c->pos[dim_x] - 1].hn) &&
        (d->pc_tunnel[c->pos[dim_y] - 1][c->pos[dim_x] - 1] >
         d->pc_tunnel[c->pos[dim_y]][c->pos[dim_x]] + 1 +
         (d->hardness[c->pos[dim_y]][c->pos[dim_x]] / 60))) {
      d->pc_tunnel[c->pos[dim_y] - 1][c->pos[dim_x] - 1] =
        (d->pc_tunnel[c->pos[dim_y]][c->pos[dim_x]] + 1 +
         (d->hardness[c->pos[dim_y]][c->pos[dim_x]] / 60));
      heap_decrease_key_no_replace(&h,
                                   p[c->pos[dim_y] - 1][c->pos[dim_x] - 1].hn);
    }
    if ((p[c->pos[dim_y] - 1][c->pos[dim_x]    ].hn) &&
        (d->pc_tunnel[c->pos[dim_y] - 1][c->pos[dim_x]    ] >
         d->pc_tunnel[c->pos[dim_y]][c->pos[dim_x]] + 1 +
         (d->hardness[c->pos[dim_y]][c->pos[dim_x]] / 60))) {
      d->pc_tunnel[c->pos[dim_y] - 1][c->pos[dim_x]    ] =
        (d->pc_tunnel[c->pos[dim_y]][c->pos[dim_x]] + 1 +
         (d->hardness[c->pos[dim_y]][c->pos[dim_x]] / 60));
      heap_decrease_key_no_replace(&h,
                                   p[c->pos[dim_y] - 1][c->pos[dim_x]    ].hn);
    }
    if ((p[c->pos[dim_y] - 1][c->pos[dim_x] + 1].hn) &&
        (d->pc_tunnel[c->pos[dim_y] - 1][c->pos[dim_x] + 1] >
         d->pc_tunnel[c->pos[dim_y]][c->pos[dim_x]] + 1 +
         (d->hardness[c->pos[dim_y]][c->pos[dim_x]] / 60))) {
      d->pc_tunnel[c->pos[dim_y] - 1][c->pos[dim_x] + 1] =
        (d->pc_tunnel[c->pos[dim_y]][c->pos[dim_x]] + 1 +
         (d->hardness[c->pos[dim_y]][c->pos[dim_x]] / 60));
      heap_decrease_key_no_replace(&h,
                                   p[c->pos[dim_y] - 1][c->pos[dim_x] + 1].hn);
    }
    if ((p[c->pos[dim_y]    ][c->pos[dim_x] - 1].hn) &&
        (d->pc_tunnel[c->pos[dim_y]    ][c->pos[dim_x] - 1] >
         d->pc_tunnel[c->pos[dim_y]][c->pos[dim_x]] + 1 +
         (d->hardness[c->pos[dim_y]][c->pos[dim_x]] / 60))) {
      d->pc_tunnel[c->pos[dim_y]    ][c->pos[dim_x] - 1] =
        (d->pc_tunnel[c->pos[dim_y]][c->pos[dim_x]] + 1 +
         (d->hardness[c->pos[dim_y]][c->pos[dim_x]] / 60));
      heap_decrease_key_no_replace(&h,
                                   p[c->pos[dim_y]    ][c->pos[dim_x] - 1].hn);
    }
    if ((p[c->pos[dim_y]    ][c->pos[dim_x] + 1].hn) &&
        (d->pc_tunnel[c->pos[dim_y]    ][c->pos[dim_x] + 1] >
         d->pc_tunnel[c->pos[dim_y]][c->pos[dim_x]] + 1 +
         (d->hardness[c->pos[dim_y]][c->pos[dim_x]] / 60))) {
      d->pc_tunnel[c->pos[dim_y]    ][c->pos[dim_x] + 1] =
        (d->pc_tunnel[c->pos[dim_y]][c->pos[dim_x]] + 1 +
         (d->hardness[c->pos[dim_y]][c->pos[dim_x]] / 60));
      heap_decrease_key_no_replace(&h,
                                   p[c->pos[dim_y]    ][c->pos[dim_x] + 1].hn);
    }
    if ((p[c->pos[dim_y] + 1][c->pos[dim_x] - 1].hn) &&
        (d->pc_tunnel[c->pos[dim_y] + 1][c->pos[dim_x] - 1] >
         d->pc_tunnel[c->pos[dim_y]][c->pos[dim_x]] + 1 +
         (d->hardness[c->pos[dim_y]][c->pos[dim_x]] / 60))) {
      d->pc_tunnel[c->pos[dim_y] + 1][c->pos[dim_x] - 1] =
        (d->pc_tunnel[c->pos[dim_y]][c->pos[dim_x]] + 1 +
         (d->hardness[c->pos[dim_y]][c->pos[dim_x]] / 60));
      heap_decrease_key_no_replace(&h,
                                   p[c->pos[dim_y] + 1][c->pos[dim_x] - 1].hn);
    }
    if ((p[c->pos[dim_y] + 1][c->pos[dim_x]    ].hn) &&
        (d->pc_tunnel[c->pos[dim_y] + 1][c->pos[dim_x]    ] >
         d->pc_tunnel[c->pos[dim_y]][c->pos[dim_x]] + 1 +
         (d->hardness[c->pos[dim_y]][c->pos[dim_x]] / 60))) {
      d->pc_tunnel[c->pos[dim_y] + 1][c->pos[dim_x]    ] =
        (d->pc_tunnel[c->pos[dim_y]][c->pos[dim_x]] + 1 +
         (d->hardness[c->pos[dim_y]][c->pos[dim_x]] / 60));
      heap_decrease_key_no_replace(&h,
                                   p[c->pos[dim_y] + 1][c->pos[dim_x]    ].hn);
    }
    if ((p[c->pos[dim_y] + 1][c->pos[dim_x] + 1].hn) &&
        (d->pc_tunnel[c->pos[dim_y] + 1][c->pos[dim_x] + 1] >
         d->pc_tunnel[c->pos[dim_y]][c->pos[dim_x]] + 1 +
         (d->hardness[c->pos[dim_y]][c->pos[dim_x]] / 60))) {
      d->pc_tunnel[c->pos[dim_y] + 1][c->pos[dim_x] + 1] =
        (d->pc_tunnel[c->pos[dim_y]][c->pos[dim_x]] + 1 +
         (d->hardness[c->pos[dim_y]][c->pos[dim_x]] / 60));
      heap_decrease_key_no_replace(&h,
                                   p[c->pos[dim_y] + 1][c->pos[dim_x] + 1].hn);
    }
  }
  heap_delete(&h);
}