int simulate(int x, int y, int dir, int life) { int nx, ny, s = 0; while (life > 1) { step(dir,x,y,&nx,&ny); life--; if (grid[nx][ny]) { dir = next_direction(dir); s += grid[nx][ny]->val; life -= grid[nx][ny]->cost; } else if (nx == 1 || nx == m) { life -= wcost; dir = next_direction(dir); } else if (ny == 1 || ny == n) { life -= wcost; dir = next_direction(dir); } else { x = nx; y = ny; } } return s; }
short next_position(short ptyp, short *d, short sq, short u) { if (*d < 4 && psweep[ptyp]) { short to = nunmap[inunmap[u] + direc[ptyp][*d]]; if (to < 0) return next_direction(ptyp, d, sq); else return to; } else { return next_direction(ptyp, d, sq); } }
bool Solver::unlocate_last_piece() { if (located_piece_indice.empty()) return false; current_piece_index = located_piece_indice.back(); current_direction = puzzle.get_piece(current_piece_index).get_direction(); located_piece_indice.pop_back(); if (!puzzle.unlocate_piece(current_piece_index)) throw std::logic_error("Ubongo::Solver::unlocate_last_piece"); if (!find_location()) throw std::logic_error("Ubongo::Solver::unlocate_last_piece"); if (next_direction()) return true; return next_piece(); }
int SqAttacked(short square, short side, short *blockable) { #ifdef SAVE_NEXTPOS short d; #else unsigned char *ppos, *pdir; #endif short u, ptyp; if (MatchSignature(threats_signature[side])) { *blockable = true; /* don't know */ return Anyattack(side, square); } /* * First check neighbouring squares, * then check Knights. * then check Bishops, * then (last) check Rooks, */ *blockable = false; /* try a capture from direct neighboured squares */ ptyp = ptype[black][king]; #ifdef SAVE_NEXTPOS u = first_direction(ptyp, &d, square); #else pdir = (*nextdir[ptyp])[square]; u = pdir[square]; #endif do { if (color[u] == side) /* can piece reach square in one step ? */ #ifdef CHECK_DISTANCE { if (piece_distance(side, board[u], u, square) == 1) return true; } #else { short v; short ptypv = ptype[side][board[u]]; #ifdef SAVE_NEXTPOS short dv; v = first_direction(ptypv, &dv, u); #else unsigned char *qdir; qdir = (*nextdir[ptypv])[u]; v = qdir[u]; #endif do { if (v == square) return true; #ifdef SAVE_NEXTPOS v = next_direction(ptypv, &dv, u); #else v = qdir[v]; #endif } while (v != u); } #endif #ifdef SAVE_NEXTPOS u = next_direction(ptyp, &d, square); #else u = pdir[u]; #endif } while (u != square); /* try a knight capture (using xside's knight moves) */ ptyp = ptype[side ^ 1][knight]; #ifdef SAVE_NEXTPOS u = first_direction(ptyp, &d, square); #else pdir = (*nextdir[ptyp])[square]; u = pdir[square]; #endif do { if (color[u] == side && board[u] == knight) return true; #ifdef SAVE_NEXTPOS u = next_direction(ptyp, &d, square); #else u = pdir[u]; #endif } while (u != square); *blockable = true; /* try a (promoted) bishop capture */ ptyp = ptype[black][bishop]; #ifdef SAVE_NEXTPOS u = first_direction(ptyp, &d, square); #else ppos = (*nextpos[ptyp])[square]; pdir = (*nextdir[ptyp])[square]; u = ppos[square]; #endif do { if (color[u] == neutral) #ifdef SAVE_NEXTPOS u = next_position(ptyp, &d, square, u); #else u = ppos[u]; #endif else { if (color[u] == side && (unpromoted[board[u]] == bishop)) return true; #ifdef SAVE_NEXTPOS u = next_direction(ptyp, &d, square); #else u = pdir[u]; #endif } }
short first_direction(short ptyp, short *d, short sq) { *d = -1; return next_direction(ptyp, d, sq); }
bool Solver::find_solution() { if (complete) return false; if (located_piece_indice.size() >= puzzle.get_piece_count()) { unlocate_last_piece(); for (;;) { if (unlocate_last_piece()) break; if (located_piece_indice.empty()) { complete = true; return false; } } #ifdef DEBUG std::cout << puzzle.dump_board(); #endif } for (;;) { bool located = false; for (;;) { #ifdef DEBUG std::cout << "location(" << current_location.x << "," << current_location.y << "), "; std::cout << "piece(" << current_piece_index << "), "; std::cout << "direction(" << current_direction << ")\n"; #endif if (locate_piece()) { located = true; break; } if (!next_direction()) break; } if (located) { #ifdef DEBUG std::cout << puzzle.dump_board(); #endif if (located_piece_indice.size() >= puzzle.get_piece_count()) return true; } else { if (!next_piece()) { for (;;) { if (unlocate_last_piece()) break; if (located_piece_indice.empty()) { complete = true; return false; } } #ifdef DEBUG std::cout << puzzle.dump_board(); #endif } } } return false; // not reached. }