void PSPKeyboard::getCursorMovement(SceCtrlData &pad) { DEBUG_ENTER_FUNC(); CursorDirections cursor; // Find where the cursor is pointing cursor = kCenter; _state = kDefault; if (DOWN(PSP_DPAD)) { _state = kCornersSelected; if (DOWN(PSP_CTRL_UP)) cursor = kUp; else if (DOWN(PSP_CTRL_RIGHT)) cursor = kRight; else if (DOWN(PSP_CTRL_DOWN)) cursor = kDown; else if (DOWN(PSP_CTRL_LEFT)) cursor = kLeft; } if (cursor != _oldCursor) { //If we've moved, update dirty and return _dirty = true; _oldCursor = cursor; } }
bool PSPKeyboard::handleMoveState(SceCtrlData &pad) { DEBUG_ENTER_FUNC(); if (UP(PSP_CTRL_SELECT)) { // Toggle between visible and invisible _state = (_lastState == kInvisible) ? kDefault : kInvisible; _dirty = true; if (_moved) { // We moved the keyboard. Keep the keyboard onscreen anyway _state = kDefault; _moved = false; // reset moved flag } if (_state == kInvisible) { return true; // we become invisible } } else if (DOWN(PSP_DPAD)) { // How we move the KB onscreen _moved = true; _dirty = true; if (DOWN(PSP_CTRL_DOWN)) increaseKeyboardLocationY(5); else if (DOWN(PSP_CTRL_UP)) increaseKeyboardLocationY(-5); else if (DOWN(PSP_CTRL_LEFT)) increaseKeyboardLocationX(-5); else /* DOWN(PSP_CTRL_RIGHT) */ increaseKeyboardLocationX(5); } return false; }
void YukonSolver::undo_move(MOVE *m) { #if PRINT if ( m->totype == O_Type ) fprintf( stderr, "\nundo move %d from %d out (at %d)\n\n", m->card_index, m->from, m->turn_index ); else fprintf( stderr, "\nundo move %d from %d to %d (%d)\n\n", m->card_index, m->from, m->to, m->turn_index ); print_layout(); #endif int from, to; card_t card; from = m->from; to = m->to; /* Add to 'from' pile. */ if ( m->turn_index > 0 ) { card_t card2 = *Wp[from]; if ( !DOWN( card2 ) ) card2 = ( SUIT( card2 ) << 4 ) + RANK( card2 ) + ( 1 << 7 ); *Wp[from] = card2; } if (m->totype == O_Type) { card = O[to] + Osuit[to]; O[to]--; Wp[from]++; *Wp[from] = card; Wlen[from]++; } else { for ( int l = m->card_index; l >= 0; l-- ) { card = W[to][Wlen[to]-l-1]; Wp[from]++; *Wp[from] = card; Wlen[from]++; *Wp[to]--; } Wlen[to] -= m->card_index + 1; hashpile(to); } if ( m->turn_index == 0 ) { card_t card = *Wp[from]; if ( DOWN( card ) ) card = ( SUIT( card ) << 4 ) + RANK( card ); else card += ( 1 << 7 ); *Wp[from] = card; } hashpile(from); #if PRINT print_layout(); #endif }
void YukonSolver::make_move(MOVE *m) { #if PRINT if ( m->totype == O_Type ) fprintf( stderr, "\nmake move %d from %d out (at %d)\n\n", m->card_index, m->from, m->turn_index ); else fprintf( stderr, "\nmake move %d from %d to %d (%d)\n\n", m->card_index, m->from, m->to, m->turn_index ); print_layout(); #else //print_layout(); #endif int from, to; card_t card = NONE; from = m->from; to = m->to; for ( int l = m->card_index; l >= 0; l-- ) { card = W[from][Wlen[from]-l-1]; Wp[from]--; if ( m->totype != O_Type ) { Wp[to]++; *Wp[to] = card; Wlen[to]++; } } Wlen[from] -= m->card_index + 1; if ( m->turn_index == 0 ) { if ( DOWN( card ) ) card = ( SUIT( card ) << 4 ) + RANK( card ); else card += ( 1 << 7 ); W[to][Wlen[to]-m->card_index-1] = card; } else if ( m->turn_index != -1 ) { card_t card2 = *Wp[from]; if ( DOWN( card2 ) ) card2 = ( SUIT( card2 ) << 4 ) + RANK( card2 ); *Wp[from] = card2; } hashpile(from); /* Add to pile. */ if (m->totype == O_Type) { O[to]++; Q_ASSERT( m->card_index == 0 ); } else { hashpile(to); } #if PRINT print_layout(); #endif }
const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt) { // MACRODOWN only works in this function switch(id) { case 0 ... END_UC: if (record->event.pressed) { send_unicode(unicode_chars[id]); } break; case M_CSA_SFT: // BÉPO over CSA: toggle shift layer layer_invert(LR_CSA_SFT); if (record->event.pressed) { hold_shift(); } else { release_shift(); } break; case M_CSA_SFT_AGR: // BÉPO over CSA: from shift layer, momentary altgr+shift layer layer_invert(LR_CSA_AGR); layer_invert(LR_CSA_AGR_SFT); if (record->event.pressed) { // shift not needed for LR_CSA_AGR_SFT release_shift(); } else { // back to shift layer hold_shift(); } break; case M_CSA_AGR_SFT: // BÉPO over CSA: from altgr layer, momentary altgr+shift layer layer_invert(LR_CSA_SFT); layer_invert(LR_CSA_AGR_SFT); break; case M_1 ... M_0: case M_DEGR: case M_SCLN: case M_GRV: case M_NBSP: // macros of the shift layer that require to release shift if (record->event.pressed) { release_shift(); switch (id) { case M_1 ... M_0: register_code(KC_1 + (id - M_1)); break; case M_DEGR: return MACRO(DOWN(CSA_ALTGR), D(SCLN), END); case M_SCLN: return MACRO(D(SCLN), END); case M_GRV: return MACRO(I(75), DOWN(CSA_ALTGR), TYPE(CSA_DCRC), UP(CSA_ALTGR), T(SPACE), END); case M_NBSP: // use weak mod such that pressing another key will not be affected add_weak_mods(MOD_BIT(CSA_ALTGR)); return MACRO(D(SPACE), END); } } else {
IMG_VOID HostAquireMutex(IMG_VOID * pvMutex) { BUG_ON(in_interrupt()); #if defined(PVR_DEBUG_DBGDRV_DETECT_HOST_MUTEX_COLLISIONS) if (DOWN_TRYLOCK((MUTEX *)pvMutex)) { printk(KERN_INFO "HostAquireMutex: Waiting for mutex\n"); DOWN((MUTEX *)pvMutex); } #else DOWN((MUTEX *)pvMutex); #endif }
int do_rmdir (struct inode *inode, const char *name, int len) { #if POST_20_KERNEL_F struct dentry *tmp_dent; #endif int ret_code; DOWN(&(inode->i_sem)); #if POST_20_KERNEL_F /* Grab a dentry for the directory being removed. */ ret_code = ovlfs_inode_get_child_dentry(inode, name, len, &tmp_dent, OVLFS_DENT_GET_POSITIVE); if ( ret_code == 0 ) { /* Use the vfs_rmdir function to do the dirty work. */ ret_code = vfs_rmdir(inode, tmp_dent); dput(tmp_dent); } #else IMARK(inode); ret = inode->i_op->rmdir(inode, name, len); #endif UP(&(inode->i_sem)); return ret_code; }
int do_mkdir (struct inode *inode, const char *name, int len, int mode) { #if USE_DENTRY_F struct dentry *tmp_dent; #endif int ret_code; DOWN(&(inode->i_sem)); #if USE_DENTRY_F /* Create a temporary negative dentry for the target. */ ret_code = ovlfs_inode_get_child_dentry(inode, name, len, &tmp_dent, OVLFS_DENT_GET_NEGATIVE); if ( ret_code == 0 ) { /* Use the vfs_mkdir function to do the dirty work. */ ret_code = vfs_mkdir(inode, tmp_dent, mode); dput(tmp_dent); } #else IMARK(inode); ret_code = inode->i_op->mkdir(inode, name, len, mode); #endif UP(&(inode->i_sem)); return ret_code; }
int do_create (struct inode *dir_i, const char *name, int len, int mode, struct dentry **r_dent) { struct dentry *dent; int ret; ret = 0; DOWN(&(dir_i->i_sem)); ret = ovlfs_inode_get_child_dentry(dir_i, name, len, &dent, OVLFS_DENT_GET_NEGATIVE); if ( ret == 0 ) { /* Create the entry using vfs_create to do all the */ /* "dirty work". */ ret = vfs_create(dir_i, dent, mode); if ( ret == 0 ) { if ( dent->d_inode == NULL ) ret = -ENOENT; else r_dent[0] = dent; } } UP(&(dir_i->i_sem)); return ret; }
int main(int argc, char const *argv[]) { init(); creat_POSIX(); DIR1 = DIR; //if the player change the direction of snake,change the DIR and Pirnt the new snake while(1){ if (DIR != DIR1) { DIR = DIR1; } switch(DIR){ case up: UP(); break; case down: DOWN(); break; case left: LEFT(); break; case right: RIGHT(); break; default: break; }; Print(); usleep(speed); } return 0; }
void GolfSolver::translate_layout() { /* Read the workspace. */ int total = 0; for ( int w = 0; w < 7; ++w ) { int i = translate_pile(deal->stack[w], W[w], 52); Wp[w] = &W[w][i - 1]; Wlen[w] = i; total += i; } int i = translate_pile( deal->waste, W[7], 52 ); Wp[7] = &W[7][i-1]; Wlen[7] = i; total += i; i = translate_pile( deal->talon, W[8], 52 ); Wp[8] = &W[8][i-1]; Wlen[8] = i; total += i; for ( int i = 0; i < 9; i++ ) { for ( int l = 0; l < Wlen[i]; l++ ) { card_t card = W[i][l]; if ( DOWN( card ) ) card = RANK( card ) + PS_SPADE + ( 1 << 7 ); else card = RANK( card ) + PS_SPADE; W[i][l] = card; } } }
void SimonSolver::undo_move(MOVE *m) { #if PRINT //qDebug() << "\n\nundo_move\n"; if ( m->totype == O_Type ) fprintf( stderr, "move %d from %d out (at %d)\n\n", m->card_index, m->from, m->turn_index ); else fprintf( stderr, "move %d from %d to %d (%d)\n\n", m->card_index, m->from, m->to, m->turn_index ); print_layout(); #endif int from, to; card_t card; from = m->from; to = m->to; if (m->totype == O_Type) { for ( int j = PS_KING; j >= PS_ACE; --j ) { Wp[from]++; *Wp[from] = O[to] + j; Wlen[from]++; } O[to] = -1; hashpile( from ); #if PRINT print_layout(); #endif return; } /* Add to 'from' pile. */ if ( m->turn_index > 0 ) { card_t card2 = *Wp[from]; if ( !DOWN( card2 ) ) card2 = ( SUIT( card2 ) << 4 ) + RANK( card2 ) + ( 1 << 7 ); *Wp[from] = card2; } for ( int l = m->card_index; l >= 0; --l ) { card = W[to][Wlen[to]-l-1]; Wp[from]++; *Wp[from] = card; Wlen[from]++; Wp[to]--; } Wlen[to] -= m->card_index + 1; hashpile(to); hashpile(from); #if PRINT print_layout(); #endif }
int do_lookup2 (struct inode *inode, const char *name, int len, struct dentry **result, int lock_f) { struct dentry *tmp_dent; struct dentry *r_dent; int ret_code; if ( lock_f ) DOWN(&(inode->i_sem)); /* Grab a dentry for the directory. */ tmp_dent = ovlfs_inode2dentry(inode); if ( tmp_dent == NULL ) { WARN("failed to obtain dentry for dir inode %lu", inode->i_ino); return -ENOENT; } /* Perform the lookup; this will call the filesystem's */ /* lookup entry-point, if needed. */ r_dent = lookup_one_len(name, tmp_dent, len); if ( IS_ERR(r_dent) ) { ret_code = PTR_ERR(r_dent); } else if ( r_dent == NULL ) { ret_code = -ENOENT; } else if ( r_dent->d_inode == NULL ) { dput(r_dent); ret_code = -ENOENT; } else { ret_code = 0; result[0] = r_dent; } dput(tmp_dent); if ( lock_f ) UP(&(inode->i_sem)); return ret_code; }
void SimonSolver::make_move(MOVE *m) { #if PRINT //qDebug() << "\n\nmake_move\n"; if ( m->totype == O_Type ) fprintf( stderr, "move %d from %d out (at %d) Prio: %d\n\n", m->card_index, m->from, m->turn_index, m->pri ); else fprintf( stderr, "move %d from %d to %d (%d) Prio: %d\n\n", m->card_index, m->from, m->to, m->turn_index, m->pri ); print_layout(); #else //print_layout(); #endif int from, to; card_t card = NONE; from = m->from; to = m->to; if (m->totype == O_Type) { O[to] = SUIT( *Wp[from] ); Wlen[from] -= 13; Wp[from] -= 13; hashpile( from ); if ( Wlen[from] && DOWN( *Wp[from] ) ) { *Wp[from] = ( SUIT( *Wp[from] ) << 4 ) + RANK( *Wp[from] ); } #if PRINT print_layout(); #endif return; } for ( int l = m->card_index; l >= 0; --l ) { card = W[from][Wlen[from]-l-1]; Wp[from]--; if ( m->totype != O_Type ) { Wp[to]++; *Wp[to] = card; Wlen[to]++; } } Wlen[from] -= m->card_index + 1; hashpile(from); hashpile(to); #if PRINT print_layout(); #endif }
bool PSPKeyboard::handleCornersSelectedState(Common::Event &event, SceCtrlData &pad) { DEBUG_ENTER_FUNC(); // We care about 4 buttons + triggers (for letter selection) bool haveEvent = false; if (CHANGED(PSP_4BUTTONS | PSP_CTRL_RTRIGGER | PSP_CTRL_LTRIGGER)) haveEvent = getInputChoice(event, pad); if (!DOWN(PSP_4BUTTONS | PSP_CTRL_RTRIGGER | PSP_CTRL_LTRIGGER)) // Must be up to move cursor getCursorMovement(pad); return haveEvent; }
int do_link (struct inode *inode, struct inode *dir, const char *name, int len) { #if USE_DENTRY_F struct dentry *ref_dent; struct dentry *new_dent; #endif int ret; DOWN(&(dir->i_sem)); #if POST_20_KERNEL_F /* Get a dentry for the link source. */ ref_dent = ovlfs_inode2dentry(inode); if ( ref_dent == NULL ) { ret = -ENOENT; } else { /* Create a temporary negative dentry for the target. */ ret = ovlfs_inode_get_child_dentry(dir, name, len, &new_dent, OVLFS_DENT_GET_NEGATIVE); if ( ret != 0 ) dput(ref_dent); } if ( ret == 0 ) { /* Use the vfs_link function to do the dirty work. */ ret = vfs_link(ref_dent, dir, new_dent); dput(ref_dent); dput(new_dent); } #else IMARK(inode); IMARK(dir); ret = dir->i_op->link(inode, dir, name, len); #endif UP(&(dir->i_sem)); return ret; }
void Move_chessman(void) { int row=35,column=35,count=0,key=0,flag=1; void far *image1=0,*image2=0; setcolor(WHITE); setfillstyle(SOLID_FILL,WHITE); sector(column,row,0,360,15,15); getimage(50,50,80,80,image); image_null=image; while(key!=27) { key=Getkey(); switch(key) { case 72 : row=Limit(72,row); UP(column,row); Trace(72,row); break; case 80 : row=Limit(80,row); DOWN(column,row); Trace(80,row); break; case 75 : column=Limit(75,column); LIFT(column,row); Trace(75,column); break; case 77 : column=Limit(77,column); RIGHT(column,row); Trace(77,column); break; case 13 : Computer(column,row); Move_chessman(); break; case 27 : END(); break; default : break; } } }
bool PSPKeyboard::handleDefaultState(Common::Event &event, SceCtrlData &pad) { DEBUG_ENTER_FUNC(); bool haveEvent = false; if (PRESSED(PSP_CTRL_LTRIGGER)) // Don't say we used up the input _state = kLTriggerDown; else if (PRESSED(PSP_CTRL_RTRIGGER)) // Don't say we used up the input _state = kRTriggerDown; else if (CHANGED(PSP_4BUTTONS)) // We only care about the 4 buttons haveEvent = getInputChoice(event, pad); else if (!DOWN(PSP_4BUTTONS)) // Must be up to move cursor getCursorMovement(pad); return haveEvent; }
int do_readlink (struct inode *inode, char *buf, int size) { int ret; ret = 0; DOWN(&(inode->i_sem)); IMARK(inode); ret = inode->i_op->readlink(inode, buf, size); UP(&(inode->i_sem)); return ret; }
int do_create (struct inode *dir_i, const char *name, int len, int mode, struct inode **r_inode) { int ret; ret = 0; DOWN(&(dir_i->i_sem)); IMARK(dir_i); ret = dir_i->i_op->create(dir_i, name, len, ref->i_mode, r_inode); UP(&(dir_i->i_sem)); return ret; }
int do_readlink (struct dentry *dent, char *buf, int size) { int ret; ret = 0; DOWN(&(dent->d_inode->i_sem)); if ( dent == NULL ) ret = -ENOENT; else ret = dent->d_inode->i_op->readlink(dent, buf, size); UP(&(dent->d_inode->i_sem)); return ret; }
int do_rename (struct inode *olddir, const char *oname, int olen, struct inode *newdir, const char *nname, int nlen, int must_be_dir) { #if POST_20_KERNEL_F struct dentry *old_dent; struct dentry *new_dent; #endif int ret; #if POST_20_KERNEL_F ret = ovlfs_inode_get_child_dentry(olddir, oname, olen, &old_dent, OVLFS_DENT_GET_POSITIVE); if ( ret == 0 ) { /* Get a dentry for the target; note that this may */ /* be a positive or negative dentry. */ ret = ovlfs_inode_get_child_dentry(newdir, nname, nlen, &new_dent, OVLFS_DENT_GET_ANY); if ( ret != 0 ) dput(old_dent); } if ( ret == 0 ) { ret = vfs_rename(olddir, old_dent, newdir, new_dent); dput(old_dent); dput(new_dent); } #else DOWN(&(newdir->i_sem)); IMARK(olddir); IMARK(newdir); ret = o_olddir->i_op->rename(o_olddir, oname, olen, o_newdir, nname, nlen, must_be_dir); UP(&(newdir->i_sem)); #endif return ret; }
/* * Attempts to read a character from the controller * Uses the state machine. * returns whether we have an event */ bool PSPKeyboard::processInput(Common::Event &event, PspEvent &pspEvent, SceCtrlData &pad) { DEBUG_ENTER_FUNC(); bool haveEvent = false; // Whether we have an event for the event manager to process bool havePspEvent = false; event.kbd.flags = 0; _buttonsChanged = _prevButtons ^ pad.Buttons; if (!_init) // In case we never had init return false; if (_state == kInvisible) // Return if we're invisible return false; if (_state != kMove && PRESSED(PSP_CTRL_SELECT)) { _lastState = _state; _state = kMove; // Check for move or visible state } else if (CHANGED(PSP_CTRL_START)) { // Handle start button: enter, make KB invisible event.kbd.ascii = '\r'; event.kbd.keycode = Common::KEYCODE_RETURN; event.type = DOWN(PSP_CTRL_START) ? Common::EVENT_KEYDOWN : Common::EVENT_KEYUP; haveEvent = true; _dirty = true; if (UP(PSP_CTRL_START)) havePspEvent = true; } // Check for being in state of moving the keyboard onscreen or pressing select else if (_state == kMove) havePspEvent = handleMoveState(pad); else if (_state == kDefault) haveEvent = handleDefaultState(event, pad); else if (_state == kCornersSelected) haveEvent = handleCornersSelectedState(event, pad); else if (_state == kRTriggerDown) handleRTriggerDownState(pad); // Deal with trigger states else if (_state == kLTriggerDown) handleLTriggerDownState(pad); // Deal with trigger states if (havePspEvent) { pspEvent.type = PSP_EVENT_SHOW_VIRTUAL_KB; // tell the input handler we're off pspEvent.data = false; } _prevButtons = pad.Buttons; return haveEvent; }
int do_lookup3 (struct dentry *dent, const char *name, int len, struct dentry **result, int lock_f) { struct dentry *r_dent; int ret_code; if ( lock_f ) DOWN(&(dent->d_inode->i_sem)); /* Perform the lookup; this will call the filesystem's */ /* lookup entry-point, if needed. */ r_dent = lookup_one_len(name, dent, len); if ( IS_ERR(r_dent) ) { ret_code = PTR_ERR(r_dent); } else if ( r_dent == NULL ) { ret_code = -ENOENT; } else if ( r_dent->d_inode == NULL ) { dput(r_dent); ret_code = -ENOENT; } else { ret_code = 0; result[0] = r_dent; } if ( lock_f ) UP(&(dent->d_inode->i_sem)); return ret_code; }
int main(){ int i,j,k; stn=0; scanf("%s",s); len=strlen(s); n=0; for (i=0;i<len;i=j+1) if (s[i]=='<'){ for (j=i;s[j]!='>';j++); if (s[i+1]=='/'){ stn--; }else{ if (s[i+1]=='U') stack[++stn]=1;else stack[++stn]=2; } }else{ j=i; if (stn==0) st[n++]=s[i];else if (stack[stn]==1) st[n++]=UP(s[i]);else st[n++]=DOWN(s[i]); } for (i=0;i<n;i++) printf("%c",st[i]); printf("\n"); return 0; }
int do_symlink (struct inode *dir_i, const char *name, int len, const char *link_tgt) { #if USE_DENTRY_F struct dentry *dent; #endif int ret; ret = 0; DOWN(&(dir_i->i_sem)); #if USE_DENTRY_F ret = ovlfs_inode_get_child_dentry(dir_i, name, len, &dent, OVLFS_DENT_GET_NEGATIVE); if ( ret == 0 ) { /* Create the entry using vfs_create to do all the */ /* "dirty work". */ ret = vfs_symlink(dir_i, dent, link_tgt); dput(dent); } #else IMARK(dir_i); ret = dir_i->i_op->symlink(dir_i, name, len, sym_name); #endif UP(&(dir_i->i_sem)); return ret; }
int SimonSolver::get_possible_moves(int *a, int *numout) { MOVE *mp; /* Check for moves from W to O. */ int n = 0; mp = Possible; for (int w = 0; w < 10; ++w) { if (Wlen[w] >= 13 && RANK( *Wp[w] ) == PS_ACE ) { int ace_suit = SUIT( *Wp[w] ); bool stroke = true; for ( int l = 0; l < 13; ++l ) { if ( RANK( W[w][Wlen[w]-l-1] ) != l+1 || SUIT( W[w][Wlen[w]-l-1] ) != ace_suit ) { stroke = false; break; } } if ( !stroke ) continue; mp->card_index = 12; mp->from = w; int o = 0; while ( O[o] != -1) o++; // TODO I need a way to tell spades off from heart off mp->to = o; mp->totype = O_Type; mp->pri = 0; /* unused */ mp->turn_index = -1; n++; mp++; return 1; } } /* No more automoves, but remember if there were any moves out. */ *a = false; *numout = n; int conti[10]; for ( int j = 0; j < 10; ++j ) { conti[j] = 0; for ( ; conti[j] < Wlen[j]-1; ++conti[j] ) { if ( SUIT( *Wp[j] ) != SUIT( W[j][Wlen[j]-conti[j]-2] ) || DOWN( W[j][Wlen[j]-conti[j]-2] )) break; if ( RANK( W[j][Wlen[j]-conti[j]-1] ) != RANK( W[j][Wlen[j]-conti[j]-2] ) - 1) break; } conti[j]++; } for(int i=0; i<10; ++i) { int len = Wlen[i]; for (int l=0; l < len; ++l ) { card_t card = W[i][Wlen[i]-1-l]; if ( DOWN( card ) ) break; if ( l > 0 ) { card_t card_on_top = W[i][Wlen[i]-l]; if ( RANK( card ) != RANK( card_on_top ) + 1 ) break; if ( SUIT( card ) != SUIT( card_on_top ) ) break; } bool wasempty = false; for (int j = 0; j < 10; ++j) { if (i == j) continue; bool allowed = false; if ( Wlen[j] > 0 && RANK(card) == RANK(*Wp[j]) - 1 ) { allowed = true; } if ( Wlen[j] == 0 && !wasempty ) { if ( l != Wlen[i]-1 ) { allowed = true; wasempty = true; } } if ( allowed && Wlen[i] >= l+2 && Wlen[i] > 1 ) { Q_ASSERT( Wlen[i]-l-2 >= 0 ); card_t card_below = W[i][Wlen[i]-l-2]; if ( SUIT( card ) == SUIT( card_below ) && !DOWN( card_below ) && RANK( card_below ) == RANK( card ) + 1 ) { if ( conti[j]+l != 13 || conti[i]>conti[j]+l || SUIT( card ) != SUIT( *Wp[j] ) ) { // fprintf( stderr, "continue\n" ); continue; } } } if ( allowed ) { mp->card_index = l; mp->from = i; mp->to = j; mp->totype = W_Type; mp->turn_index = -1; int cont = conti[j]; if ( Wlen[j] ) cont++; if ( cont ) cont += l; mp->pri = 8 * cont + qMax( 0, 10 - Wlen[i] ); if ( Wlen[j] ) { if ( SUIT( card ) != SUIT( *Wp[j] ) ) { mp->pri /= 2; } } else { mp->pri = 2; // TODO: it should depend on the actual stack's order } if ( Wlen[i] == l+1 ) mp->pri = qMin( 127, mp->pri + 20 ); else mp->pri = qMin( 127, mp->pri + 2 ); /* and now check what sequence we open */ int conti_pos = l+1; for ( ; conti_pos < Wlen[i]-1; ++conti_pos ) { card_t top = W[i][Wlen[i]-l-2]; card_t theone = W[i][Wlen[i]-conti_pos-1]; card_t below = W[i][Wlen[i]-conti_pos-2]; if ( SUIT( top ) != SUIT( below ) || DOWN( below ) ) break; if ( RANK( theone ) != RANK( below ) - 1) break; } mp->pri = qMin( 127, mp->pri + 5 * ( conti_pos - l - 1 ) ); n++; mp++; } } } } return n; }
void KlondikeSolver::make_move(MOVE *m) { #if PRINT if ( m->totype == O_Type ) fprintf( stderr, "\nmake move %d from %d out (at %d)\n\n", m->card_index, m->from, m->turn_index ); else fprintf( stderr, "\nmake move %d from %d to %d (%d)\n\n", m->card_index, m->from, m->to, m->turn_index ); print_layout(); #else //print_layout(); #endif int from, to; card_t card = NONE; from = m->from; to = m->to; /* Remove from pile. */ if ( from == 7 && to == 8 ) { while ( Wlen[7] ) { card = W[7][Wlen[7]-1] + ( 1 << 7 ); Wlen[8]++; W[8][Wlen[8]-1] = card; Wlen[7]--; } Wp[7] = &W[7][0]; Wp[8] = &W[8][Wlen[8]-1]; hashpile( 7 ); hashpile( 8 ); #if PRINT print_layout(); #endif return; } // move to pile if ( from == 8 && to == 7 ) { for ( int i = 0; i < m->card_index; ++i ) { if ( !Wlen[8] ) continue; card = *Wp[8]; Wp[8]--; Wlen[8]--; card = ( SUIT( card ) << 4 ) + RANK( card ); Wp[7]++; *Wp[7] = card; Wlen[7]++; } hashpile( 7 ); hashpile( 8 ); #if PRINT print_layout(); #endif return; } for ( int l = m->card_index; l >= 0; --l ) { card = W[from][Wlen[from]-l-1]; Wp[from]--; if ( m->totype != O_Type ) { Wp[to]++; *Wp[to] = card; Wlen[to]++; } } Wlen[from] -= m->card_index + 1; if ( m->turn_index == 0 ) { if ( DOWN( card ) ) card = ( SUIT( card ) << 4 ) + RANK( card ); else card += ( 1 << 7 ); W[to][Wlen[to]-m->card_index-1] = card; } else if ( m->turn_index != -1 ) { card_t card2 = *Wp[from]; if ( DOWN( card2 ) ) card2 = ( SUIT( card2 ) << 4 ) + RANK( card2 ); *Wp[from] = card2; } hashpile(from); /* Add to pile. */ if (m->totype == O_Type) { O[to]++; Q_ASSERT( m->card_index == 0 ); } else { hashpile(to); } #if PRINT print_layout(); #endif }
int KlondikeSolver::get_possible_moves(int *a, int *numout) { int w, o, empty; card_t card; MOVE *mp; /* Check for moves from W to O. */ int n = 0; mp = Possible; for (w = 0; w < 8; ++w) { if (Wlen[w] > 0) { card = *Wp[w]; o = SUIT(card); empty = (O[o] == NONE); if ((empty && (RANK(card) == PS_ACE)) || (!empty && (RANK(card) == O[o] + 1))) { mp->card_index = 0; mp->from = w; mp->to = o; mp->totype = O_Type; mp->pri = 3; /* unused */ mp->turn_index = -1; if ( Wlen[w] > 1 && DOWN( W[w][Wlen[w]-2] ) ) mp->turn_index = 1; n++; mp++; /* If it's an automove, just do it. Automoves from the pile are problematic though in draw=3 because automoves can break the offset and break winnable games */ if (good_automove(o, RANK(card)) && (w != 7 || m_draw == 1 || Wlen[7] < 3)) { *a = true; mp[-1].pri = 127; if (n != 1) { Possible[0] = mp[-1]; return 1; } return n; } } } } /* No more automoves, but remember if there were any moves out. */ *a = false; *numout = n; /* check for deck->pile */ if ( Wlen[8] ) { mp->card_index = qMin( m_draw, Wlen[8] ); mp->from = 8; mp->to = 7; mp->totype = W_Type; mp->pri = 5; mp->turn_index = 0; n++; mp++; } // we first check where to put a king, so we don't // try each king on each empty pile int first_empty_pile = -1; for(int i=0; i<8; ++i) if ( !Wlen[i] ) { first_empty_pile = i; break; } for(int i=0; i<8; ++i) { int len = Wlen[i]; if ( i == 7 && Wlen[i] > 0) len = 1; for (int l=0; l < len; ++l ) { card_t card = W[i][Wlen[i]-1-l]; if ( DOWN( card ) ) break; for (int j = 0; j < 7; ++j) { if (i == j) continue; int allowed = 0; if ( Wlen[j] > 0 && RANK(card) == RANK(*Wp[j]) - 1 && suitable( card, *Wp[j] ) ) { allowed = 1; if ( Wlen[i] == l + 1 ) { allowed = 2; } else { if ( DOWN( W[i][Wlen[i]-l-2] ) ) allowed = 3; } } if ( RANK( card ) == PS_KING && j == first_empty_pile ) { if ( l != Wlen[i]-1 || i == 7 ) allowed = 4; } if ( allowed && i == 7 ) allowed = 5; if ( allowed == 1 ) { //print_layout(); card_t below = W[i][Wlen[i]-2-l]; int o = SUIT(below); bool empty = (O[o] == NONE); //fprintf( stderr, "%d %d\n", i, l ); //printcard( below, stderr ); if ( ( empty && RANK( below ) != PS_ACE ) || ( !empty && RANK( below ) != O[o] + 1 ) ) allowed = 0; //fprintf( stderr, " allowed %d %d %d %d\n",allowed, empty, RANK( below ), PS_ACE); } if ( allowed ) { mp->card_index = l; mp->from = i; mp->to = j; mp->totype = W_Type; mp->turn_index = -1; if ( Wlen[i] > l+1 && DOWN( W[i][Wlen[i]-l-2] ) ) mp->turn_index = 1; if ( i == 7 ) mp->pri = 40; else { if ( mp->turn_index > 0 || Wlen[i] == l+1) mp->pri = 30; else mp->pri = 1; } n++; mp++; } } } } if ( Wlen[8] == 0 && Wlen[7] > 1 ) { mp->card_index = 0; mp->from = 7; mp->to = 8; mp->totype = W_Type; mp->turn_index = 0; mp->pri = 2; n++; mp++; } return n; }
void KlondikeSolver::undo_move(MOVE *m) { #if PRINT if ( m->totype == O_Type ) fprintf( stderr, "\nundo move %d from %d out (at %d)\n\n", m->card_index, m->from, m->turn_index ); else fprintf( stderr, "\nundo move %d from %d to %d (%d)\n\n", m->card_index, m->from, m->to, m->turn_index ); print_layout(); #endif int from, to; card_t card; from = m->from; to = m->to; /* Remove from 'to' pile. */ if ( from == 7 && to == 8 ) { while ( Wlen[8] ) { card = W[8][Wlen[8]-1]; card = ( SUIT( card ) << 4 ) + RANK( card ); Wlen[7]++; W[7][Wlen[7]-1] = card; Wlen[8]--; } Wp[8] = &W[8][0]; Wp[7] = &W[7][Wlen[7]-1]; hashpile( 7 ); hashpile( 8 ); #if PRINT print_layout(); #endif return; } // move back to deck if ( from == 8 && to == 7 ) { for ( int i = 0; i < m->card_index; ++i ) { card = *Wp[7]; Wp[7]--; Wlen[7]--; card = ( SUIT( card ) << 4 ) + RANK( card ) + ( 1 << 7 ); Wp[8]++; *Wp[8] = card; Wlen[8]++; } hashpile( 7 ); hashpile( 8 ); #if PRINT print_layout(); #endif return; } /* Add to 'from' pile. */ if ( m->turn_index > 0 ) { card_t card2 = *Wp[from]; if ( !DOWN( card2 ) ) card2 = ( SUIT( card2 ) << 4 ) + RANK( card2 ) + ( 1 << 7 ); *Wp[from] = card2; } if (m->totype == O_Type) { card = O[to] + Osuit[to]; O[to]--; Wp[from]++; *Wp[from] = card; Wlen[from]++; } else { for ( int l = m->card_index; l >= 0; --l ) { card = W[to][Wlen[to]-l-1]; Wp[from]++; *Wp[from] = card; Wlen[from]++; Wp[to]--; } Wlen[to] -= m->card_index + 1; hashpile(to); } if ( m->turn_index == 0 ) { card_t card = *Wp[from]; if ( DOWN( card ) ) card = ( SUIT( card ) << 4 ) + RANK( card ); else card += ( 1 << 7 ); *Wp[from] = card; } hashpile(from); #if PRINT print_layout(); #endif }