Пример #1
0
Файл: gif_c.c Проект: cran/gap
void    path_find(vertex *v, int length, int going_up)
{
  edge    *e;
  int     new_length = length+1;
  if (v->proband) path_length[new_length] += 1;
  if (going_up)
  {
    for (e = v->up; e; e = e->next_up)
    {
      e->free = 0;
      path_find(e->top,new_length,1);
      e->free = 1;
    }
  }

  for (e = v->down; e; e = e->next_down) if (e->free)
  {
    e->free = 0;
    path_find(e->bottom,new_length,0);
    e->free = 1;
  }
}
Пример #2
0
void move() {
  // Для алгоритма поиска поути
  if(!path_find()) {
    if(playSound) soundBadMove();
    return;
  }

  if(showPath) {
    // Рисуем шаги на экране
    path_save();
    while(1) {
      switch(path_nextStep()) {
        case 1: drawSpriteStep(path_x, path_y+1, 0); break;
        case 2: drawSpriteStep(path_x, path_y-1, 1); break;
        case 3: drawSpriteStep(path_x+1, path_y, 2); break;
        case 4: drawSpriteStep(path_x-1, path_y, 3); break;
      }
      drawSprite(path_x, path_y, path_c);
      if(path_n==LAST_STEP) break;
      if(playSound) soundJumpSel();
      delay(STEP_SPEED);
    };
 
    // Удаляем нарисованные шаги с экрана
    path_load();
    while(1) {
      drawSprite(path_x, path_y, 0);
      path_nextStep();
      if(path_n==LAST_STEP) break;
    };
  } else {
    drawSprite(selX, selY, 0);
    drawSprite(cursorX, cursorY, path_c);
  }

  // Реально перемещаем шарик. Все выше было лишь анимацией.
  game[cursorX][cursorY] = path_c;

  // Снимаем курсор
  selX = -1;

  // Очищаем игровое поле от временных значений
  path_end();
  
  // Добавляем 3 шарика
  gameStep();
}
Пример #3
0
Файл: gif_c.c Проект: cran/gap
double  total_kinship()
{
  int             i;
  double          half, kin;
  vertex_list     *vl;
  for (i=0; i<max_path_length; i++) path_length[i] = 0;
  for (vl=proband_list; vl; vl = vl->n)
  {
    vl->c->proband = 0;
    path_find(vl->c,0,1);
  }
  for (i=2, half=0.5, kin=0.0; i<max_path_length; i++)
  {
    half *= 0.5;
    kin += path_length[i] * half;
  }
  return(kin);
}
Пример #4
0
static order *make_movement_order(unit * u, const region * target, int moves,
    bool(*allowed) (const region *, const region *))
{
    region *r = u->region;
    region **plan;
    int bytes, position = 0;
    char zOrder[128], *bufp = zOrder;
    size_t size = sizeof(zOrder) - 1;

    if (monster_is_waiting(u))
        return NULL;

    plan = path_find(r, target, DRAGON_RANGE * 5, allowed);
    if (plan == NULL)
        return NULL;

    bytes =
        (int)strlcpy(bufp,
        (const char *)LOC(u->faction->locale, keyword(K_MOVE)), size);
    if (wrptr(&bufp, &size, bytes) != 0)
        WARN_STATIC_BUFFER();

    while (position != moves && plan[position + 1]) {
        region *prev = plan[position];
        region *next = plan[++position];
        direction_t dir = reldirection(prev, next);
        assert(dir != NODIRECTION && dir != D_SPECIAL);
        if (size > 1) {
            *bufp++ = ' ';
            --size;
        }
        bytes =
            (int)strlcpy(bufp,
            (const char *)LOC(u->faction->locale, directions[dir]), size);
        if (wrptr(&bufp, &size, bytes) != 0)
            WARN_STATIC_BUFFER();
    }

    *bufp = 0;
    return parse_order(zOrder, u->faction->locale);
}
Пример #5
0
/** @start 1 */
int
builtin_unknown (Sic *sic, int argc, char *const argv[])
{
  char *path = path_find (argv[0]);
  int status = SIC_ERROR;

  if (!path)
    {
      sic_result_append (sic, "command \"");
      sic_result_append (sic, argv[0]);
      sic_result_append (sic, "\" not found");
    }
  else if (path_execute (sic, path, argv) != SIC_OKAY)
    {
      sic_result_append (sic, "command \"");
      sic_result_append (sic, argv[0]);
      sic_result_append (sic, "\" failed: ");
      sic_result_append (sic, strerror (errno));
    }
  else
    status = SIC_OKAY;

  return status;
}
Пример #6
0
int
move_ground(struct sctstr *start, struct sctstr *end,
	    double weight, char *path,
	    int (*map)(coord, coord, char *, char *),
	    int exploring, int *dam)
{
    struct sctstr sect;
    struct sctstr next;
    coord curx, cury, oldx, oldy;
    coord tmpx, tmpy;
    coord dx, dy;
    char *movstr;
    double sect_mcost;
    double total_mcost;
    double mv_cost;
    size_t len;
    double mobility = start->sct_mobil;
    int dir;
    char scanspace[1024];
    char *argp[128];
    int takedam = *dam;
    int out = 0;
    char prompt[128];
    char buf[1024];

    *end = *start;
    if (mobility <= 0.0)
	return -1;
    *dam = 0;
    if (path && sarg_xy(path, &dx, &dy)) {
	if (dx == start->sct_x && dy == start->sct_y) {
	    pr("Start sector is ending sector!\n");
	    return -1;
	}
	pr("Looking for best path to %s\n", path);
	total_mcost = path_find(start->sct_x, start->sct_y, dx, dy,
				player->cnum, MOB_MOVE);
	path = NULL;
	if (total_mcost < 0)
	    pr("No owned path exists!\n");
	else {
	    len = path_find_route(buf, sizeof(buf),
				  start->sct_x, start->sct_y, dx, dy);
	    if (!exploring) {
		if (len < sizeof(buf))
		    strcpy(buf + len, "h");
		len++;
	    }
	    if (len >= sizeof(buf))
		pr("Can't handle path to %s, it's too long, sorry.\n",
		   xyas(dx, dy, player->cnum));
	    else {
		path = buf;
		pr("Using best path '%s', movement cost %1.3f\n",
		   path, total_mcost);
		if (total_mcost * weight > mobility) {
		    pr("Not enough mobility to go all the way."
		       " Nothing moved.\n");
		    return -1;
		}
	    }
	}
    }
    movstr = path;
    curx = start->sct_x;
    cury = start->sct_y;
    total_mcost = 0.0;
    if (getsect(curx, cury, &sect) < 0) {
	logerror("move_path: getsect %d,%d", curx, cury);
	return -1;
    }
    for (;;) {
	oldx = curx;
	oldy = cury;
	if (!movstr || *movstr == 0) {
	    if (exploring) {
		map(curx, cury, NULL, NULL);
	    } else {
		move_map(curx, cury, NULL);
	    }
	    sprintf(prompt, "<%.1f: %c %s> ", mobility,
		    dchr[sect.sct_type].d_mnem,
		    xyas(sect.sct_x, sect.sct_y, player->cnum));
	    movstr = getstring(prompt, buf);
	}
	if (movstr && sarg_xy(movstr, &dx, &dy)) {
	    mv_cost = path_find(sect.sct_x, sect.sct_y, dx, dy,
				player->cnum, MOB_MOVE);
	    if (mv_cost < 0) {
		pr("Can't get to %s from here!\n",
		   xyas(dx, dy, player->cnum));
		movstr = NULL;
	    } else {
		len = path_find_route(buf, sizeof(buf),
				      sect.sct_x, sect.sct_y, dx, dy);
		if (len < sizeof(buf))
		    strcpy(buf + len, "h");
		len++;
		if (len >= sizeof(buf)) {
		    pr("Can't handle path to %s, it's too long, sorry.\n",
		       xyas(dx, dy, player->cnum));
		    movstr = NULL;
		} else {
		    if ((mv_cost * weight) > mobility) {
			pr("Not enough mobility to go all the way. Nothing moved.\n");
			movstr = NULL;
		    } else {
			movstr = buf;
			pr("Using best path '%s', movement cost %1.3f\n",
			   movstr, mv_cost);
		    }
		}
	    }
	}
	if (!movstr || *movstr == 0) {
	    buf[0] = dirch[DIR_STOP];
	    buf[1] = 0;
	    movstr = buf;
	}
	if ((dir = chkdir(*movstr, DIR_STOP, DIR_MAP)) < 0) {
	    pr("\"%c\" is not legal...", *movstr);
	    direrr("'%c' to stop ", "'%c' to view ", "& '%c' to map\n");
	    *movstr = 0;
	    continue;
	}
	if (dir == DIR_MAP) {
	    parse(movstr, scanspace, argp, NULL, NULL, NULL);
	    if (argp[0][1]) {
		pr("Use of '%c' without a space before its argument is deprecated.\n"
		   "Support for it will go away in a future release\n",
		   *movstr);
		argp[2] = argp[1];
		argp[1] = argp[0] + 1;
	    }
	    if (!exploring)
		map(curx, cury, argp[1], argp[2]);
	    *movstr = 0;
	    continue;
	}
	movstr++;
	if (dir == DIR_STOP)
	    break;
	if (dir == DIR_VIEW) {
	    pr("%d%% %s with %d civilians.\n", sect.sct_effic,
	       dchr[sect.sct_type].d_name, sect.sct_item[I_CIVIL]);
	    continue;
	}
	/*
	 * now see if we can move into the
	 * next sector.  Mobility, terrain,
	 * or ownership may prevent us.
	 */
	tmpx = curx + diroff[dir][0];
	tmpy = cury + diroff[dir][1];
	if (getsect(tmpx, tmpy, &next) < 0) {
	    pr("You can't go there...\n");
	    *movstr = 0;
	    continue;
	}
	if (!player->god) {
	    if ((next.sct_type == SCT_SANCT) &&
		(next.sct_own != player->cnum)) {
		pr("Converts, huh?\n");
		*movstr = 0;
		continue;
	    }
	    sect_mcost = sector_mcost(&next, MOB_MOVE);
	    if ((!player->owner && (!exploring
				    || next.sct_item[I_MILIT]
				    || next.sct_item[I_CIVIL]))
		|| sect_mcost == -1.0) {
		/* already-owned, or prohibited terrain */
		pr("You can't go there...\n");
		*movstr = 0;
		continue;
	    }
	    sect_mcost *= weight;
	    if (sect_mcost > mobility) {
		pr("Not enough mobility.  ");
		pr("You can't go there...\n");
		*movstr = 0;
		continue;
	    }
	    mobility -= sect_mcost;
	    total_mcost += sect_mcost;
	}
	curx = next.sct_x;
	cury = next.sct_y;
	if (cury != start->sct_y)
	    out = 1;
	if (curx != start->sct_x)
	    out = 1;

	sect = next;

	if (takedam)
	    *dam += check_lmines(sect.sct_x, sect.sct_y, weight);
	if (*dam >= 100)
	    break;
	/*
	 * Check and see if anyone will interdict us
	 */
	if (takedam && chance(weight / 100.0) &&
	    ((curx != oldx) || (cury != oldy)))
	    *dam += ground_interdict(curx, cury, player->cnum,
				     "commodities");
	if (*dam >= 100)
	    break;
    }
    *end = sect;
    if ((start->sct_x == end->sct_x) && (start->sct_y == end->sct_y)
	&& !out)
	return -1;

    return roundavg(total_mcost);
}
Пример #7
0
int
sorde(void)
{
    int nships = 0;
    int len, updates;
    double c;
    struct nstr_item nb;
    struct shpstr ship;

    if (!snxtitem(&nb, EF_SHIP, player->argp[1], NULL))
	return RET_SYN;
    while (nxtitem(&nb, (&ship))) {
	if (!player->owner || ship.shp_own == 0)
	    continue;
	if (!(ship.shp_autonav & AN_AUTONAV)
	    && (!opt_SAIL || !ship.shp_path[0]))
	    continue;

	if (!nships) {		/* 1st ship, print banner */
	    if (player->god)
		pr("own ");
	    pr("shp#     ship type       x,y      start      end   "
	       " len  eta\n");
	}
	nships++;
	if (player->god)
	    pr("%3d ", ship.shp_own);
	pr("%4d", nb.cur);
	pr(" %-16.16s", mchr[(int)ship.shp_type].m_name);
	prxy(" %4d,%-4d", ship.shp_x, ship.shp_y);

	if (ship.shp_autonav & AN_AUTONAV) {
	    /* Destination 1 */
	    prxy(" %4d,%-4d", ship.shp_destx[1], ship.shp_desty[1]);

	    /* Destination 2 */
	    if ((ship.shp_destx[1] != ship.shp_destx[0])
		|| (ship.shp_desty[1] != ship.shp_desty[0])) {
		prxy(" %4d,%-4d", ship.shp_destx[0], ship.shp_desty[0]);
	    } else
		pr("          ");

	    if (ship.shp_autonav & AN_STANDBY)
		pr(" suspended");
	    else if (ship.shp_autonav & AN_LOADING)
		pr(" loading");
	    else {
		/* ETA calculation */
		c = path_find(ship.shp_x, ship.shp_y,
			      ship.shp_destx[0], ship.shp_desty[0],
			      ship.shp_own, MOB_SAIL);
		if (c < 0)
		    pr(" no route possible");
		else if (c == 0)
		    pr(" has arrived");
		else {
		    /* distance to destination */
		    len = (int)c;
		    updates = eta_calc(&ship, len);
		    pr(" %3d %4d", len, updates);
		}
	    }
	    if (ship.shp_autonav & AN_SCUTTLE)
		pr(" (scuttling)");
	    pr("\n");
	} else
	    pr(" has a sail path\n");

	if (ship.shp_name[0] != 0) {
	    if (player->god)
		pr("    ");
	    pr("       %s\n", ship.shp_name);
	}
    }
    if (!nships) {
	if (player->argp[1])
	    pr("%s: No ship(s)\n", player->argp[1]);
	else
	    pr("%s: No ship(s)\n", "");
	return RET_FAIL;
    } else
	pr("%d ship%s\n", nships, splur(nships));
    return RET_OK;
}
Пример #8
0
/*
 * Actually get the commod
 *
 * First, try to forage in the sector
 * Second look for a warehouse or headquarters to leech
 * Third, look for a ship we own in a harbor
 * Fourth, look for supplies in a supply unit we own
 *		(one good reason to do this last is that the supply
 *		 unit will then call resupply, taking more time)
 *
 * May want to put code to resupply with SAMs here, later --ts
 */
static int
s_commod(struct empobj *sink, short *vec,
	 i_type type, int wanted, int limit, int actually_doit)
{
    natid own = sink->own;
    coord x = sink->x;
    coord y = sink->y;
    int lookrange;
    struct sctstr sect;
    struct nstr_sect ns;
    struct nstr_item ni;
    struct lchrstr *lcp;
    struct shpstr ship;
    struct lndstr land;
    /* leave at least 1 military in sectors/ships */
    int minimum = 0;
    int can_move;
    double move_cost, weight, mobcost;
    int packing;
    struct dchrstr *dp;
    struct ichrstr *ip;

    if (wanted > limit)
	wanted = limit;
    if (wanted <= vec[type])
	return 1;
    wanted -= vec[type];

    /* try to get it from sector we're in */
    if (sink->ef_type != EF_SECTOR) {
	getsect(x, y, &sect);
	if (sect.sct_own == own) {
	    if (!opt_NOFOOD && type == I_FOOD)
		minimum = 1 + (int)ceil(food_needed(sect.sct_item,
						    etu_per_update));
	    if (sect.sct_item[type] - wanted >= minimum) {
		sect.sct_item[type] -= wanted;
		if (actually_doit) {
		    vec[type] += wanted;
		    putsect(&sect);
		    put_empobj(sink->ef_type, sink->uid, sink);
		}
		return 1;
	    } else if (sect.sct_item[type] - minimum > 0) {
		wanted -= sect.sct_item[type] - minimum;
		sect.sct_item[type] = minimum;
		if (actually_doit) {
		    vec[type] += sect.sct_item[type] - minimum;
		    putsect(&sect);
		}
	    }
	}
    }

    /* look for a headquarters or warehouse */
    lookrange = tfact(own, 10.0);
    snxtsct_dist(&ns, x, y, lookrange);
    while (nxtsct(&ns, &sect) && wanted) {
	if (ns.curdist == 0)
	    continue;
	if (sect.sct_own != own)
	    continue;
	if ((sect.sct_type != SCT_WAREH) &&
	    (sect.sct_type != SCT_HEADQ) && (sect.sct_type != SCT_HARBR))
	    continue;
	if ((sect.sct_type == SCT_HEADQ) &&
	    (sect.sct_dist_x == sect.sct_x) &&
	    (sect.sct_dist_y == sect.sct_y))
	    continue;
	if (sect.sct_effic < 60)
	    continue;
	move_cost = path_find(sect.sct_x, sect.sct_y, x, y, own, MOB_MOVE);
	if (move_cost < 0)
	    continue;
	if (!opt_NOFOOD && type == I_FOOD)
	    minimum = 1 + (int)ceil(food_needed(sect.sct_item,
						etu_per_update));
	if (sect.sct_item[type] <= minimum)
	    continue;
	ip = &ichr[type];
	dp = &dchr[sect.sct_type];
	packing = ip->i_pkg[dp->d_pkg];
	if (packing > 1 && sect.sct_effic < 60)
	    packing = 1;
	weight = (double)ip->i_lbs / packing;
	mobcost = move_cost * weight;
	if (mobcost > 0)
	    can_move = (double)sect.sct_mobil / mobcost;
	else
	    can_move = sect.sct_item[type] - minimum;
	if (can_move > sect.sct_item[type] - minimum)
	    can_move = sect.sct_item[type] - minimum;

	if (can_move >= wanted) {
	    int n;

	    sect.sct_item[type] -= wanted;

	    /* take off mobility for delivering sect */
	    n = roundavg(wanted * weight * move_cost);
	    sect.sct_mobil -= LIMIT_TO(n, 0, sect.sct_mobil);
	    if (actually_doit) {
		vec[type] += wanted;
		putsect(&sect);
		put_empobj(sink->ef_type, sink->uid, sink);
	    }
	    return 1;
	} else if (can_move > 0) {
	    int n;
	    wanted -= can_move;
	    sect.sct_item[type] -= can_move;

	    /* take off mobility for delivering sect */
	    n = roundavg(can_move * weight * move_cost);
	    sect.sct_mobil -= LIMIT_TO(n, 0, sect.sct_mobil);
	    if (actually_doit) {
		vec[type] += can_move;
		putsect(&sect);
	    }
	}
    }

    /* look for an owned ship in a harbor */
    snxtitem_dist(&ni, EF_SHIP, x, y, lookrange);
    while (nxtitem(&ni, &ship) && wanted) {
	if (sink->ef_type == EF_SHIP && sink->uid == ship.shp_uid)
	    continue;
	if (ship.shp_own != own)
	    continue;
	if (!(mchr[(int)ship.shp_type].m_flags & M_SUPPLY))
	    continue;
	getsect(ship.shp_x, ship.shp_y, &sect);
	if (sect.sct_type != SCT_HARBR)
	    continue;
	if (sect.sct_effic < 2)
	    continue;
	move_cost = path_find(sect.sct_x, sect.sct_y, x, y, own, MOB_MOVE);
	if (move_cost < 0)
	    continue;
	if (!opt_NOFOOD && type == I_FOOD)
	    minimum = 1 + (int)ceil(food_needed(ship.shp_item,
						etu_per_update));
	if (ship.shp_item[type] <= minimum)
	    continue;
	ip = &ichr[type];
	dp = &dchr[sect.sct_type];
	packing = ip->i_pkg[dp->d_pkg];
	if (packing > 1 && sect.sct_effic < 60)
	    packing = 1;
	weight = (double)ip->i_lbs / packing;
	mobcost = move_cost * weight;
	if (mobcost > 0)
	    can_move = (double)sect.sct_mobil / mobcost;
	else
	    can_move = ship.shp_item[type] - minimum;
	if (can_move > ship.shp_item[type] - minimum)
	    can_move = ship.shp_item[type] - minimum;
	if (can_move >= wanted) {
	    int n;
	    ship.shp_item[type] -= wanted;

	    n = roundavg(wanted * weight * move_cost);
	    sect.sct_mobil -= LIMIT_TO(n, 0, sect.sct_mobil);
	    if (actually_doit) {
		vec[type] += can_move;
		putship(ship.shp_uid, &ship);
		if (n)
		    putsect(&sect);
		put_empobj(sink->ef_type, sink->uid, sink);
	    }
	    return 1;
	} else if (can_move > 0) {
	    int n;
	    wanted -= can_move;
	    ship.shp_item[type] -= can_move;

	    n = roundavg(can_move * weight * move_cost);
	    sect.sct_mobil -= LIMIT_TO(n, 0, sect.sct_mobil);
	    if (actually_doit) {
		vec[type] += can_move;
		putship(ship.shp_uid, &ship);
		if (n)
		    putsect(&sect);
	    }
	}
    }

    /* look for an owned supply unit */
    snxtitem_dist(&ni, EF_LAND, x, y, lookrange);
    while (nxtitem(&ni, &land) && wanted) {
	int min;

	if (sink->ef_type == EF_LAND && sink->uid == land.lnd_uid)
	    continue;
	if (land.lnd_own != own)
	    continue;

	lcp = &lchr[(int)land.lnd_type];
	if (!(lcp->l_flags & L_SUPPLY))
	    continue;

	if (land.lnd_item[type] <= get_minimum(&land, type))
	    continue;

	if (land.lnd_ship >= 0) {
	    getsect(land.lnd_x, land.lnd_y, &sect);
	    if (sect.sct_type != SCT_HARBR || sect.sct_effic < 2)
		continue;
	}

	move_cost = path_find(land.lnd_x, land.lnd_y, x, y, own, MOB_MOVE);
	if (move_cost < 0)
	    continue;

#if 0
	/*
	 * Recursive supply is disabled for now.  It can introduce
	 * cycles into the "resupplies from" relation.  The code below
	 * attempts to break these cycles by temporarily zapping the
	 * commodity being supplied.  That puts the land file in a
	 * funny state temporarily, risking loss of supplies when
	 * something goes wrong on the way.  Worse, it increases
	 * lnd_seqno even when !actually_doit, which can lead to
	 * spurious seqno mismatch oopses in users of
	 * lnd_could_be_supplied().  I can't be bothered to clean up
	 * this mess right now, because recursive resupply is too dumb
	 * to be really useful anyway: each step uses the first source
	 * it finds, without consideration of mobility cost.  If you
	 * re-enable it, don't forget to uncomment its documentation
	 * in supply.t as well.
	 */
	if (land.lnd_item[type] - wanted < get_minimum(&land, type)) {
	    struct lndstr save;

	    /*
	     * Temporarily zap this unit's store, so the recursion
	     * avoids it.
	     */
	    save = land;
	    land.lnd_item[type] = 0;
	    putland(land.lnd_uid, &land);
	    save.lnd_seqno = land.lnd_seqno;

	    s_commod((struct empobj *)&land, land.lnd_item, type, wanted,
		     lchr[land.lnd_type].l_item[type] - wanted,
		     actually_doit);
	    land.lnd_item[type] += save.lnd_item[type];

	    if (actually_doit)
		putland(land.lnd_uid, &land);
	    else
		putland(save.lnd_uid, &save);
	}
#endif

	min = get_minimum(&land, type);
	ip = &ichr[type];
	weight = ip->i_lbs;
	mobcost = move_cost * weight;
	if (mobcost > 0)
	    can_move = (double)land.lnd_mobil / mobcost;
	else
	    can_move = land.lnd_item[type] - min;
	if (can_move > land.lnd_item[type] - min)
	    can_move = land.lnd_item[type] - min;

	if (can_move >= wanted) {
	    land.lnd_item[type] -= wanted;
	    land.lnd_mobil -= roundavg(wanted * weight * move_cost);
	    if (actually_doit) {
		vec[type] += wanted;
		putland(land.lnd_uid, &land);
		put_empobj(sink->ef_type, sink->uid, sink);
	    }
	    return 1;
	} else if (can_move > 0) {
	    wanted -= can_move;
	    land.lnd_item[type] -= can_move;
	    land.lnd_mobil -= roundavg(can_move * weight * move_cost);
	    if (actually_doit) {
		vec[type] += can_move;
		putland(land.lnd_uid, &land);
	    }
	}
    }

    if (actually_doit)
	put_empobj(sink->ef_type, sink->uid, sink);
    return 0;
}