Ejemplo n.º 1
0
/* Make to an independent copy of from.
 */
void copymovelist(actlist *to, actlist const *from)
{
    to->list = NULL;
    initmovelist(to);
    setmovelist(to, from->count);
    memcpy(to->list, from->list, from->count * sizeof *from->list);
}
Ejemplo n.º 2
0
Archivo: play.c Proyecto: BR903/cgames
/* Initialize the current state to the starting position of the
 * current puzzle, and reset the macro array and the stack.
 */
void initgamestate(void)
{
    memcpy(state.map, state.game->map, sizeof state.map);
    state.currblock = state.game->equivs[KEYID] ? KEYID : FIRSTID;
    state.ycurrpos = state.xcurrpos = 0;
    initmovelist(&state.undo);
    copymovelist(&state.redo, &state.game->answer);
    state.movecount = 0;
    state.stepcount = 0;
}
Ejemplo n.º 3
0
Archivo: play.c Proyecto: BR903/cgames
/* Toggle macro recording on and off.
 */
void setmacro(void)
{
    if (recording) {
	recording = FALSE;
	return;
    }
    macro = &macros[state.player];
    initmovelist(macro);
    recording = TRUE;
}
Ejemplo n.º 4
0
Archivo: play.c Proyecto: BR903/cgames
/* Compare the solution currently sitting in the undo list with the
 * user's best solutions (if any). If this solution beats what's
 * there, replace them. If this solution has the save number of moves
 * as the least-moves solution, but fewer pushes, then the replacement
 * will be done, and likewise for the least-pushes solution. Note that
 * the undo list contains the moves in backwards order, so the list
 * needs to be reversed when it is copied. TRUE is returned if any
 * solution was replaced.
 */
int replaceanswers(int saveinc)
{
    int		i, n;

    if (saveinc && (state.game->movebestcount || state.game->pushbestcount))
	return FALSE;

    n = 0;
    if (!state.game->movebestcount
		|| state.movecount < state.game->movebestcount
		|| (state.movecount == state.game->movebestcount
			&& state.pushcount < state.game->movebestpushcount)) {
	initmovelist(&state.game->moveanswer);
	i = state.undo.count;
	while (i--)
	    addtomovelist(&state.game->moveanswer, state.undo.list[i]);
	if (!saveinc)
	    state.game->movebestcount = state.movecount;
	state.game->movebestpushcount = state.pushcount;
	++n;
    }
    if (!state.game->pushbestcount
		|| state.pushcount < state.game->pushbestcount
		|| (state.pushcount == state.game->pushbestcount
			&& state.movecount < state.game->pushbestmovecount)) {
	initmovelist(&state.game->pushanswer);
	i = state.undo.count;
	while (i--)
	    addtomovelist(&state.game->pushanswer, state.undo.list[i]);
	state.game->pushbestcount = state.pushcount;
	if (!saveinc)
	    state.game->pushbestmovecount = state.movecount;
	++n;
    }

    return n > 0;
}
Ejemplo n.º 5
0
Archivo: play.c Proyecto: BR903/cgames
/* Initialize the current state to the starting position of the
 * current puzzle, and reset the macro array and the stack.
 */
void initgamestate(int usemoves)
{
    int	i;

    memcpy(state.map, state.game->map, sizeof state.map);
    state.player = state.game->start;
    initmovelist(&state.undo);
    if (!state.game->moveanswer.count)
	copymovelist(&state.redo, &state.game->pushanswer);
    else if (!state.game->pushanswer.count || usemoves)
	copymovelist(&state.redo, &state.game->moveanswer);
    else
	copymovelist(&state.redo, &state.game->pushanswer);
    state.movecount = 0;
    state.pushcount = 0;
    state.storecount = state.game->storecount;
    recording = FALSE;
    for (i = 0 ; i < (int)(sizeof macros / sizeof *macros) ; ++i)
	if (macros[i].count)
	    macros[i].count = 0;
}
Ejemplo n.º 6
0
Archivo: play.c Proyecto: BR903/cgames
/* Compare the solution currently sitting in the undo list with the
 * user's best solutions (if any). If this solution beats what's
 * there, replace them. If this solution has the same number of moves
 * as the least-moves solution, but fewer steps, then the replacement
 * will be done, and likewise for the least-steps solution. Note that
 * the undo list contains the moves in backwards order, so the list
 * needs to be reversed when it is copied. TRUE is returned if any
 * solution was replaced.
 */
int replaceanswer(int saveinc)
{
    int	i;

    if (state.game->beststepcount) {
	if (saveinc)
	    return FALSE;
	if (state.stepcount > state.game->beststepcount
		|| (state.stepcount == state.game->beststepcount
			&& state.movecount >= state.game->answer.count))
	    return FALSE;
	state.game->beststepcount = state.stepcount;
    } else {
	if (!saveinc)
	    state.game->beststepcount = state.stepcount;
    }

    initmovelist(&state.game->answer);
    i = state.undo.count;
    while (i--)
	addtomovelist(&state.game->answer, state.undo.list[i]);

    return TRUE;
}
Ejemplo n.º 7
0
/* Expand a level's solution data into an actual list of moves.
 */
int expandsolution(solutioninfo *solution, gamesetup const *game)
{
    unsigned char const	       *dataend;
    unsigned char const	       *p;
    action			act;
    int				n;

    if (game->solutionsize <= 16)
	return FALSE;

    solution->flags = game->solutiondata[6];
    solution->rndslidedir = indextodir(game->solutiondata[7] & 7);
    solution->stepping = (game->solutiondata[7] >> 3) & 7;
    solution->rndseed = game->solutiondata[8] | (game->solutiondata[9] << 8)
					      | (game->solutiondata[10] << 16)
					      | (game->solutiondata[11] << 24);

    initmovelist(&solution->moves);
    act.when = -1;
    p = game->solutiondata + 16;
    dataend = game->solutiondata + game->solutionsize;
    while (p < dataend) {
	switch (*p & 0x03) {
	  case 0:
	    act.dir = indextodir((*p >> 2) & 0x03);
	    act.when += 4;
	    addtomovelist(&solution->moves, act);
	    act.dir = indextodir((*p >> 4) & 0x03);
	    act.when += 4;
	    addtomovelist(&solution->moves, act);
	    act.dir = indextodir((*p >> 6) & 0x03);
	    act.when += 4;
	    addtomovelist(&solution->moves, act);
	    ++p;
	    break;
	  case 1:
	    act.dir = indextodir((*p >> 2) & 0x07);
	    act.when += ((*p >> 5) & 0x07) + 1;
	    addtomovelist(&solution->moves, act);
	    ++p;
	    break;
	  case 2:
	    if (p + 2 > dataend)
		goto truncated;
	    act.dir = indextodir((*p >> 2) & 0x07);
	    act.when += ((p[0] >> 5) & 0x07) + ((unsigned long)p[1] << 3) + 1;
	    addtomovelist(&solution->moves, act);
	    p += 2;
	    break;
	  case 3:
	    if (*p & 0x10) {
		n = (*p >> 2) & 0x03;
		if (p + 2 + n > dataend)
		    goto truncated;
		act.dir = ((p[0] >> 5) & 0x07) | ((p[1] & 0x3F) << 3);
		act.when += (p[1] >> 6) & 0x03;
		while (n--)
		    act.when += (unsigned long)p[2 + n] << (2 + n * 8);
		++act.when;
		p += 2 + ((*p >> 2) & 0x03);
	    } else {
		if (p + 4 > dataend)
		    goto truncated;
		act.dir = indextodir((*p >> 2) & 0x03);
		act.when += ((p[0] >> 5) & 0x07) | ((unsigned long)p[1] << 3)
						 | ((unsigned long)p[2] << 11)
						 | ((unsigned long)p[3] << 19);
		++act.when;
		p += 4;
	    }
	    addtomovelist(&solution->moves, act);
	    break;
	}