コード例 #1
0
ファイル: pathfind.c プロジェクト: artes-liberales/FAangband
bool findpath(int y, int x)
{
    int i, j, k, dir, starty = 0, startx = 0, startdir, start_index;
    bool try_again;
    int cur_distance;
    int findir[] = { 1, 4, 7, 8, 9, 6, 3, 2 };

    fill_terrain_info();

    terrain[p_ptr->py - oy][p_ptr->px - ox] = 1;

    if ((x >= ox) && (x < ex) && (y >= oy) && (y < ey)) {
	if ((cave_m_idx[y][x] > 0) && (m_list[cave_m_idx[y][x]].ml)) {
	    terrain[y - oy][x - ox] = MAX_PF_LENGTH;
	}
	/* else if (terrain[y - oy][x - ox] != MAX_PF_LENGTH) { bell("Target
	 * blocked"); return (FALSE); } */
	terrain[y - oy][x - ox] = MAX_PF_LENGTH;
    } else {
	bell("Target out of range.");
	return (FALSE);
    }

    if (terrain[y - oy][x - ox] == -1) {
	bell("Target space forbidden");
	return (FALSE);
    }


    /* 
     * And now starts the very naive and very 
     * inefficient pathfinding algorithm
     */
    do {
	try_again = (FALSE);
	for (j = oy + 1; j < ey - 1; j++)
	    for (i = ox + 1; i < ex - 1; i++) {
		cur_distance = terrain[j - oy][i - ox] + 1;
		if ((cur_distance > 0) && (cur_distance < MAX_PF_LENGTH)) {
		    for (dir = 1; dir < 10; dir++) {
			if (dir == 5)
			    continue;
			MARK_DISTANCE(terrain[j - oy + ddy[dir]]
				      [i - ox + ddx[dir]], cur_distance);
		    }
		}
	    }
	if (terrain[y - oy][x - ox] < MAX_PF_LENGTH)
	    try_again = (FALSE);
    } while (try_again);

    /* Failure */
    if (terrain[y - oy][x - ox] == MAX_PF_LENGTH) {
	bell("Target space unreachable.");
	return (FALSE);
    }

    /* Success */
    i = x;
    j = y;

    pf_result_index = 0;

    while ((i != p_ptr->px) || (j != p_ptr->py)) {
	int xdiff = i - p_ptr->px, ydiff = j - p_ptr->py;

	cur_distance = terrain[j - oy][i - ox] - 1;

	/* Starting direction */
	if (xdiff < 0)
	    startx = 1;
	else if (xdiff > 0)
	    startx = -1;
	else
	    startx = 0;

	if (ydiff < 0)
	    starty = 1;
	else if (ydiff > 0)
	    starty = -1;
	else
	    starty = 0;

	for (dir = 1; dir < 10; dir++)
	    if ((ddx[dir] == startx) && (ddy[dir] == starty))
		break;

	/* Should never happend */
	if ((dir % 5) == 0) {
	    bell("Wtf ?");
	    return (FALSE);
	}

	for (start_index = 0; findir[start_index % 8] != dir; start_index++);

	for (k = 0; k < 5; k++) {
	    dir = findir[(start_index + k) % 8];
	    if (terrain[j - oy + ddy[dir]][i - ox + ddx[dir]]
		== cur_distance)
		break;
	    dir = findir[(8 + start_index - k) % 8];
	    if (terrain[j - oy + ddy[dir]][i - ox + ddx[dir]]
		== cur_distance)
		break;
	}

	/* Should never happend */
	if (k == 5) {
	    bell("Heyyy !");
	    return (FALSE);
	}

	pf_result[pf_result_index++] = '0' + (char) (10 - dir);
	i += ddx[dir];
	j += ddy[dir];
	starty = 0;
	startx = 0;
	startdir = 0;
    }
    pf_result_index--;
    return (TRUE);
}
コード例 #2
0
ファイル: pathfind.c プロジェクト: EpicMan/angband
bool findpath(int y, int x)
{
	int i, j, dir;
	bool try_again;
	int cur_distance;

	fill_terrain_info();

	terrain[p_ptr->py - oy][p_ptr->px - ox] = 1;

	if ((x >= ox) && (x < ex) && (y >= oy) && (y < ey))
	{
		if ((cave_m_idx[y][x] > 0) && (mon_list[cave_m_idx[y][x]].ml))
		{
			terrain[y - oy][x - ox] = MAX_PF_LENGTH;
		}

#if 0
		else if (terrain[y-oy][x-ox] != MAX_PF_LENGTH)
		{
		   bell("Target blocked");
		   return (FALSE);
		}
#endif

		terrain[y - oy][x - ox] = MAX_PF_LENGTH;
	}
	else
	{
		bell("Target out of range.");
		return (FALSE);
	}

	/* 
	 * And now starts the very naive and very 
	 * inefficient pathfinding algorithm
	 */
	do
	{
		try_again = FALSE;

		for (j = oy + 1; j < ey - 1; j++)
		{
			for (i = ox + 1; i < ex - 1; i++)
			{
				cur_distance = terrain[j - oy][i - ox] + 1;

				if ((cur_distance > 0) && (cur_distance < MAX_PF_LENGTH))
				{
					for (dir = 1; dir < 10; dir++)
					{
						if (dir == 5)
							dir++;

						MARK_DISTANCE(terrain[j - oy + ddy[dir]][i - ox + ddx[dir]], cur_distance);
					}
				}
			}
		}

		if (terrain[y - oy][x - ox] < MAX_PF_LENGTH)
			try_again = (FALSE);

	}
	while (try_again);

	/* Failure */
	if (terrain[y - oy][x - ox] == MAX_PF_LENGTH)
	{
		bell("Target space unreachable.");
		return (FALSE);
	}

	/* Success */
	i = x;
	j = y;

	pf_result_index = 0;

	while ((i != p_ptr->px) || (j != p_ptr->py))
	{
		cur_distance = terrain[j - oy][i - ox] - 1;
		for (dir = 1; dir < 10; dir++)
		{
			if (terrain[j - oy + ddy[dir]][i - ox + ddx[dir]] == cur_distance)
				break;
		}

		/* Should never happend */
		if (dir == 10)
		{
			bell("Wtf ?");
			return (FALSE);
		}

		else if (dir == 5)
		{
			bell("Heyyy !");
			return (FALSE);
		}

		pf_result[pf_result_index++] = '0' + (char)(10 - dir);
		i += ddx[dir];
		j += ddy[dir];
	}

	pf_result_index--;

	return (TRUE);
}
コード例 #3
0
ファイル: player-path.c プロジェクト: myshkin/angband
bool findpath(int y, int x)
{
	int i, j, k;
	int dir = 10;
	bool try_again;
	int cur_distance;

	fill_terrain_info();

	terrain[player->py - oy][player->px - ox] = 1;

	if ((x >= ox) && (x < ex) && (y >= oy) && (y < ey)) {
		if ((cave->squares[y][x].mon > 0) &&
			mflag_has(square_monster(cave, y, x)->mflag, MFLAG_VISIBLE))
			terrain[y - oy][x - ox] = MAX_PF_LENGTH;

		terrain[y - oy][x - ox] = MAX_PF_LENGTH;
	} else {
		bell("Target out of range.");
		return (FALSE);
	}

	/* 
	 * And now starts the very naive and very 
	 * inefficient pathfinding algorithm
	 */
	do {
		try_again = FALSE;

		for (j = oy + 1; j < ey - 1; j++) {
			for (i = ox + 1; i < ex - 1; i++) {
				cur_distance = terrain[j - oy][i - ox] + 1;

				if ((cur_distance > 0) && (cur_distance < MAX_PF_LENGTH)) {
					for (dir = 1; dir < 10; dir++) {
						int next_y, next_x;
						if (dir == 5)
							dir++;
						next_y = j - oy + ddy[dir];
						next_x = i - ox + ddx[dir];

						MARK_DISTANCE(terrain[next_y][next_x], cur_distance);
					}
				}
			}
		}

		if (terrain[y - oy][x - ox] < MAX_PF_LENGTH)
			try_again = FALSE;

	}
	while (try_again) ;

	/* Failure */
	if (terrain[y - oy][x - ox] == MAX_PF_LENGTH) {
		bell("Target space unreachable.");
		return (FALSE);
	}

	/* Success */
	i = x;
	j = y;

	pf_result_index = 0;

	while ((i != player->px) || (j != player->py)) {
		cur_distance = terrain[j - oy][i - ox] - 1;
		for (k = 0; k < 8; k++) {
			dir = dir_search[k];
			if (terrain[j - oy + ddy[dir]][i - ox + ddx[dir]] == cur_distance)
				break;
		}

		/* Should never happen */
		assert ((dir != 10) && (dir != 5));

		pf_result[pf_result_index++] = '0' + (char)(10 - dir);
		i += ddx[dir];
		j += ddy[dir];
	}

	pf_result_index--;

	return (TRUE);
}
コード例 #4
0
ファイル: pathfind.c プロジェクト: mangband/mangband
bool findpath(player_type *p_ptr, int y, int x)
{
	int i, j, k;
	int dir = 10;
	bool try_again;
	int cur_distance;

	fill_terrain_info(p_ptr);

	terrain[p_ptr->py - oy][p_ptr->px - ox] = 1;

	if ((x >= ox) && (x < ex) && (y >= oy) && (y < ey))
	{
		if ((cave[p_ptr->dun_depth][y][x].m_idx > 0) && (p_ptr->mon_los[cave[p_ptr->dun_depth][y][x].m_idx ]))
		{
			terrain[y - oy][x - ox] = MAX_PF_LENGTH;
		}

#if 0
		else if (terrain[y-oy][x-ox] != MAX_PF_LENGTH)
		{
		   bell();
		   return (FALSE);
		}
#endif

		terrain[y - oy][x - ox] = MAX_PF_LENGTH;
	}
	else
	{
		bell();
		return (FALSE);
	}

	if (terrain[y - oy][x - ox] == -1)
	{
		bell();
		return (FALSE);
	}


	/* 
	 * And now starts the very naive and very 
	 * inefficient pathfinding algorithm
	 */
	do
	{
		try_again = FALSE;

		for (j = oy + 1; j < ey - 1; j++)
		{
			for (i = ox + 1; i < ex - 1; i++)
			{
				cur_distance = terrain[j - oy][i - ox] + 1;

				if ((cur_distance > 0) && (cur_distance < MAX_PF_LENGTH))
				{
					for (dir = 1; dir < 10; dir++)
					{
						if (dir == 5)
							dir++;

						MARK_DISTANCE(terrain[j - oy + ddy[dir]][i - ox + ddx[dir]], cur_distance);
					}
				}
			}
		}

		if (terrain[y - oy][x - ox] < MAX_PF_LENGTH)
			try_again = (FALSE);

	}
	while (try_again);

	/* Failure */
	if (terrain[y - oy][x - ox] == MAX_PF_LENGTH)
	{
		bell();
		return (FALSE);
	}

	/* Success */
	i = x;
	j = y;

	p_ptr->pf_result_index = 0;

	while ((i != p_ptr->px) || (j != p_ptr->py))
	{
		cur_distance = terrain[j - oy][i - ox] - 1;
		for (k = 0; k < 8; k++)
		{
			dir = dir_search[k];
			if (terrain[j - oy + ddy[dir]][i - ox + ddx[dir]] == cur_distance)
				break;
		}

		/* Should never happend */
		if (dir == 10)
		{
			bell();
			return (FALSE);
		}

		else if (dir == 5)
		{
			bell();
			return (FALSE);
		}

		p_ptr->pf_result[p_ptr->pf_result_index++] = '0' + (char)(10 - dir);
		i += ddx[dir];
		j += ddy[dir];
	}

	p_ptr->pf_result_index--;

	return (TRUE);
}