Exemple #1
0
/* Undo the last n moves.
 */
int undomoves(int n)
{
    if (!state.undo.count)
	return FALSE;
    while (n-- && undomove()) ;
    return TRUE;
}
Exemple #2
0
void cmd_undo(char *s)
{
    computer[0] = 0;
    computer[1] = 0;
    
    if (ply) undomove();
}
Exemple #3
0
/* Get a keystroke from the user (or from a macro) and perform the
 * indicated command. A non-zero return value indicates a request to
 * change the current puzzle, the actual value being a delta.
 */
static int doturn(void)
{
    switch (input()) {
      case ARROW_N: if (!movecursor(NORTH))		ding();	break;
      case ARROW_E: if (!movecursor(EAST))		ding();	break;
      case ARROW_S: if (!movecursor(SOUTH))		ding();	break;
      case ARROW_W: if (!movecursor(WEST))		ding();	break;
      case 'k':     if (!shiftfromcurrblock(NORTH))	ding();	break;
      case 'l':     if (!shiftfromcurrblock(EAST))	ding();	break;
      case 'j':     if (!shiftfromcurrblock(SOUTH))	ding();	break;
      case 'h':     if (!shiftfromcurrblock(WEST))	ding();	break;
      case 'K':     if (!newmove(NORTH))		ding();	break;
      case 'L':     if (!newmove(EAST))			ding();	break;
      case 'J':     if (!newmove(SOUTH)) 		ding();	break;
      case 'H':     if (!newmove(WEST))			ding();	break;
      case 'x':     if (!undomove())			ding();	break;
      case 'z':     if (!redomove())			ding();	break;
      case 'X':     if (!undostep())			ding();	break;
      case 'Z':     if (!redostep())			ding();	break;
      case 'R':     initgamestate();				break;
      case 's':     savestate();				break;
      case 'r':     if (!restorestate())		ding();	break;
      case 'S':     if (!partialsave())			ding();	break;
      case 'g':	    drawgoalscreen();				break;
      case '?':     drawhelpscreen();				break;
      case '\f':						break;
      case 'P':     return -1;
      case 'N':     return +1;
      case 'q':     exit(0);
      case 'Q':     exit(0);
    }

    return 0;
}
Exemple #4
0
/* Check a move for validity in the current state. If it is valid, it
 * is applied via domove(), otherwise return FALSE. If the move is
 * equivalent to an undo or a redo, then use that instead; otherwise,
 * the redo list is reset.
 */
int newmove(yx delta)
{
    dyx	move;
    int	b;
    yx	j;

    j = state.player + delta;
    if (state.map[j] & WALL)
	return FALSE;
    if (state.undo.count) {
	move = state.undo.list[state.undo.count - 1];
	if (!move.box && move.yx == -delta)
	    return undomove();
    }

    b = state.map[j] & BOX ? TRUE : FALSE;
    if (b && state.map[j + delta] & (BOX | WALL))
	return FALSE;
    if (state.redo.count) {
	move = state.redo.list[state.redo.count - 1];
	if (move.box == b && move.yx == delta)
	    return redomove();
    }

    move.yx = delta;
    move.box = b;
    domove(move);
    state.redo.count = 0;
    return TRUE;
}
Exemple #5
0
int
ab(int lvl, int mark, int lb, int d)
{
	int di, pos, ans, dir, s;

	s = score(&hist[hno], mark) - lvl;
	if (lvl <= 0)
		return s;
	if (s <= -WINL || s >= WINL)
		return s;

	ans = lb;
	for (di = 0; di < 4; di++) {
		dir = dirs[di];
		for (pos = 0; pos < bsize; pos++) {
			domove(dir, pos, mark);
			s = -ab(lvl-1, OTHER(mark), -d, -ans);
			if (s > ans)
				ans = s;
			undomove();
			if (ans >= d)
				goto end;
		}
	}
end:
	return ans;
}
Exemple #6
0
void
computemove(char *dirp, int *posp, int mark)
{
	int pos, di, high, lvl, s, i, j, bdir = 0, bpos = 0;
	int dir;
	struct move *mp, *np, *tmp;
	
	mp = moves;
	for (di = 0; di < 4; di++) {
		dir = dirs[di];
		for (pos = 0; pos < bsize; pos++) {
			mp->dir = dir;
			mp->pos = pos;
			mp++;
		}
	}

	mp = moves; np = nmoves;
	for (lvl = 3; lvl < MAXLVL; lvl++) {
		high = -INF;
		for (i = 0; i < bsize4; i++) {
			domove(mp[i].dir, mp[i].pos, mark);
			s = -ab(lvl, OTHER(mark), -INF, -high);
			if (s > high) {
				high = s;
				bdir = mp[i].dir;
				bpos = mp[i].pos;
				if (WINNER(high)) {
					goto done;
				}
			}
			undomove();

			/* sort the move into np */
			for (j = i; j > 0; j--) {
				if (np[j-1].score >= s)
					break;
				np[j] = np[j-1];
			}
			np[j].dir = mp[i].dir;
			np[j].pos = mp[i].pos;
			np[j].score = s;

		}
		*dirp = bdir;
		*posp = bpos;

		DPRINTF(("lvl=%d nscore=%d, high=%d\n", lvl, nscore, high));
		nscore = 0;
		tmp = mp;
		mp = np;
		np = tmp;
	}
done:
	*dirp = bdir;
	*posp = bpos;
	DPRINTF(("high=%d\n", high));
}
Exemple #7
0
void showmoves(c)
{
    move_and_score *restore_sp = move_sp;
    
    genmoves(c);
    
    while (move_sp>restore_sp)
    {
	move m;
	m = popmove();
	domove(m);
	printboard();
	undomove();
    }
}
Exemple #8
0
/* Check a move for validity in the current state. If it is valid, it
 * is applied via domove(), otherwise return FALSE. If the move is
 * equivalent to an undo or a redo, then use that instead; otherwise,
 * the redo list is reset.
 */
int newmove(int dir)
{
    action	move;

    if (!state.currblock || !canmove(state.currblock, dir))
	return FALSE;
    if (state.undo.count) {
	move = state.undo.list[state.undo.count - 1];
	if (move.id == state.currblock && move.dir == backwards(dir)
				       && !move.door)
	    return undomove();
    }
    if (state.redo.count) {
	move = state.redo.list[state.redo.count - 1];
	if (move.id == state.currblock && move.dir == dir)
	    return redomove();
    }
    domove(makeaction(state.currblock, dir));
    state.redo.count = 0;
    return TRUE;
}
Exemple #9
0
short play() {

   short c;
   short ret;
   short undolock = 1;		/* locked for undo */

   showscreen();
   tmpsave();
   ret = 0;
   while( ret == 0) {
      	switch( (c = getch())) {
	 	case 'q':    /* quit the game 					*/
	              ret = E_ENDGAME; 
	              break;
	 	case 's':    /* save the games					*/
		      if( (ret = savegame()) == 0)
			 ret = E_SAVED;
		      break;
	 	case '?':    /* show the help file				*/
		      showhelp();
		      showscreen();
		      break;
	 	case CNTL_R: /* refresh the screen 				*/
		      clear();
		      showscreen();
		      break;
	 	case 'c':    /* temporary save					*/
		      tmpsave();
		      break;
	 	case CNTL_U: /* reset to temporary save 			*/
		      tmpreset();
		      undolock = 1;
		      showscreen();
		      break;
	 	case 'U':    /* undo this level 				*/
		      moves = pushes = 0;
		      if( (ret = readscreen()) == 0) {
		         showscreen();
			 undolock = 1;
		      }
		      break;
	 	case 'u':    /* undo last move 				*/
		      if( ! undolock) {
		         undomove();
		         undolock = 1;
		      }
		      break;
	 	case 'k':    /* up 						*/
	 	case 'K':    /* run up 					*/
	 	case CNTL_K: /* run up, stop before object 			*/
	 	case 'j':    /* down 						*/
	 	case 'J':    /* run down 					*/
	 	case CNTL_J: /* run down, stop before object 			*/
	 	case 'l':    /* right 						*/
	 	case 'L':    /* run right 					*/
	 	case CNTL_L: /* run right, stop before object 			*/
	 	case 'h':    /* left 						*/
	 	case 'H':    /* run left 					*/
	 	case CNTL_H: /* run left, stop before object 			*/
		      do {
		         if( (action = testmove( c)) != 0) {
				    lastaction = action;
		            lastppos.x = ppos.x; lastppos.y = ppos.y;
		            lppc = map[ppos.x][ppos.y];
		            lasttpos1.x = tpos1.x; lasttpos1.y = tpos1.y; 
		            ltp1c = map[tpos1.x][tpos1.y];
		            lasttpos2.x = tpos2.x; lasttpos2.y = tpos2.y; 
		            ltp2c = map[tpos2.x][tpos2.y];
		            domove( lastaction); 
		            undolock = 0;
		         }
		      } while( (action != 0) && (! islower( c))
			      && (packets != savepack));
		      break;
	 	default:     helpmessage(); break;
     }
     if( (ret == 0) && (packets == savepack)) {
		 scorelevel = level;
		 scoremoves = moves;
		 scorepushes = pushes;
		 break;
     }
   }
   return( ret);
}
Exemple #10
0
void save_leaf(move *pv, int n, int value, int hashed)
{
#ifndef LEARNING
    return;
#else
    int s_ply = ply;
    int searched_value = -1;
    int stored_board_value = -1;

    
    if (tomove() != WHITE)
	value = -value;

    stored.search_results[stored.index] = value;

    /* first check our stored position */
    if (stored.boards[stored.index]->piececount[0]>0)
    {
	chessboard *temp_board = board;

	board = stored.boards[stored.index];
	countmaterial();
	
	stored_board_value = eval_for_white();

	board = temp_board;
	countmaterial();

	if (((stored_board_value > (value - EVAL_INTERVAL)) &&
	    (stored_board_value < (value + EVAL_INTERVAL))) ||
	    (value > WIN - 50) ||
	    (value < LOSE + 50))
	{
	    stored.usable[stored.index] = 1;
	    stored.actual[stored.index] = stored_board_value;
	    printf("STORING: qsearch board = %d\n", stored_board_value);
	}
    }

    /* then check to see if our value is the same as our last search */
    if (!stored.usable[stored.index])
    {
	if ((stored.search_results[stored.index] ==
	     stored.search_results[stored.index-1]))
	{
	    memcpy(stored.boards[stored.index], stored.boards[stored.index-1],
		   sizeof(chessboard));
	    stored.usable[stored.index] = 1;
	    stored.actual[stored.index] = stored.actual[stored.index]-1;
	    printf("STORING: previous board = %d\n",
		   stored.search_results[stored.index-1]);
	}
    }

    /* lastly check to see if our pv leads to a correct board eval */
    if (!stored.usable[stored.index])
    {
	int i;
	
	printf("pv: ");
	for (i=0;i<n;i++)
	{
	    if (pv[i] == dummymove)
		break;

	    domove(pv[i]);
	    printf("%s ", movestring(pv[i]));
	}
	printf("\n");
    
	searched_value = eval_for_white();
	
	if ((searched_value > value - EVAL_INTERVAL)&&
	    (searched_value < value + EVAL_INTERVAL))
	{
	    memcpy(stored.boards[stored.index], board, sizeof(chessboard));
	    stored.usable[stored.index] = 1;
	    stored.actual[stored.index] = searched_value;
	    printf("STORING: pv board = %d\n", searched_value);
	}
	else
	{
	    printf("!usable: stored_position %d, "
		   "searched %d, previous %d, stored %d\n",
		   stored_board_value, searched_value,
		   stored.search_results[stored.index-1], value);
	}
	
	while (ply>s_ply)
	    undomove();
    }
    
#endif
    
}
Exemple #11
0
int play() {

   short c;
   short ret;
   short testmove();
   short undolock = 1;         /* locked for undo */

#if ATARIST			/* Mess up keyboard to make cursor keys work */
KEY_TABLES *kbt;
KEY_TABLES old_kbt;
int i;

	kbt = Keytbl(-1, -1, -1);
	old_kbt = *kbt;

	for (i = 0; i < 128; i++) {
		unshifted[i] = kbt->unshifted[i];
		shifted[i] = kbt->shifted[i];
	}

	unshifted[0x48] = 'k';	/* Up */
	unshifted[0x50] = 'j';	/* Down */
	unshifted[0x4b] = 'h';	/* Left */
	unshifted[0x4d] = 'l';	/* Right */
	unshifted[0x61] = 'u';	/* Undo */
	unshifted[0x62] = '?';	/* Help */

	shifted[0x48] = '\013';	/* Up ^K */
	shifted[0x50] = '\012';	/* Down ^J */
	shifted[0x4b] = '\010';	/* Left ^H */
	shifted[0x4d] = '\014';	/* Right ^L */
	shifted[0x61] = 'q';	/* Undo */

	Keytbl(unshifted, shifted, -1);
#endif

   showscreen();
   tmpsave();
   ret = 0;
   while( ret == 0) {
      switch( (c = get_char())) {
        case 'q':    /* quit the game                                  */
				ret = E_ENDGAME;
				break;
        case 's':    /* save the games                                 */
                     if( (ret = savegame()) == 0)
                        ret = E_SAVED;
                     break;
        case '?':    /* show the help file                             */
                     showhelp();
                     showscreen();
                     break;
        case CNTL_R: /* refresh the screen                             */
                     clear();
                     showscreen();
                     break;
        case 'c':    /* temporary save                                 */
                     tmpsave();
                     break;
        case CNTL_U: /* reset to temporary save                        */
                     tmpreset();
                     undolock = 1;
                     showscreen();
                     break;
        case 'U':    /* undo this level                                */
                     moves = pushes = 0;
                     if( (ret = readscreen()) == 0) {
                        showscreen();
                        undolock = 1;
                     }
                     break;
        case 'u':    /* undo last move                                 */
                     if(state_num > 0) {
                        undomove();
                        undolock = 0;	/*1*/
                     }
                     break;
        case 'k':    /* up                                             */
        case 'K':    /* run up                                         */
        case CNTL_K: /* run up, stop before object                     */
        case 'j':    /* down                                           */
        case 'J':    /* run down                                       */
        case CNTL_J: /* run down, stop before object                   */
        case 'l':    /* right                                          */
        case 'L':    /* run right                                      */
        case CNTL_L: /* run right, stop before object                  */
        case 'h':    /* left                                           */
        case 'H':    /* run left                                       */
        case CNTL_H: /* run left, stop before object                   */
                     do {
                        if( (action = testmove( c)) != 0) {
						soko_state *s;
							s = &state[state_num];

                        	s->action = action;
							s->ppos = ppos;
                        	s->lppc = map[ppos.x][ppos.y];
							s->tpos1 = tpos1;
                        	s->ltp1c = map[tpos1.x][tpos1.y];
							s->tpos2 = tpos2;
                        	s->ltp2c = map[tpos2.x][tpos2.y];
                           domove( s->action);
                           undolock = 0;
						   state_num++;
                        }
                     } while( (action != 0) && (! islower( c))
                             && (packets != savepack));
                     break;
        default:     helpmessage(); break;
      }
      if( (ret == 0) && (packets == savepack)) {
        scorelevel = level;
        scoremoves = moves;
        scorepushes = pushes;
        break;
      }
   }
#if ATARIST
	kbt = Keytbl(-1, -1, -1);
	kbt->unshifted = old_kbt.unshifted;
	kbt->shifted = old_kbt.shifted;
/*	Keytbl(old_kbt.unshifted, old_kbt.shifted, old_kbt.capslock);*/
#endif
	return ret;
}