bool Board::is_valid_move(Move move) { if (move.is_pass()) return true; if (blocks()[move.block_id()]) return false; Rotation* rot = &block_set[move.block_id()]->rotations[move.direction()]; int px = move.x() + rot->offset_x; int py = move.y() + rot->offset_y; Piece *piece = rot->piece; if (px + piece->minx < 0 || px + piece->maxx >= XSIZE || py + piece->miny < 0 || py + piece->maxy >= YSIZE || !is_movable(px, py, piece)) return false; for (int i = 0; i < piece->size; i++) { int x = px + piece->coords[i].x; int y = py + piece->coords[i].y; if (at(x, y) & (is_violet() ? VIOLET_EDGE : ORANGE_EDGE)) return true; } return false; }
void input_control0001(component* hero, int *current_scene, int ikeytype, char input) { // show hero if (hero->hidden != 0) hero->hidden = 0; // move hero if (ikeytype==IKEYTYPE_ARRUP) { if (is_movable(hero->x, hero->y-1)) hero->y--; } else if (ikeytype==IKEYTYPE_ARRDOWN) { if (is_movable(hero->x, hero->y+1)) hero->y++; } else if (ikeytype==IKEYTYPE_ARRLEFT) { if (is_movable(hero->x-1, hero->y)) hero->x--; } else if (ikeytype==IKEYTYPE_ARRRIGHT) { if (is_movable(hero->x+1, hero->y)) hero->x++; } if (hero->y==1 && hero->x>=14 && hero->x<=17) { switch_scene(current_scene, 2); hero->y = 13; } }
std::list<Cell> Game::reachables_of(Cell cell, bool able_to_turn) const { std::list<Cell> result; for(int i=0; i<4631; i++) { if(is_valid_cell_id(i)) { Cell target(i); if(is_movable(cell, target, true, able_to_turn? Piece(32): Piece(0))) { result.push_back(target); } // movable } // valid cell id } // for cell id return result; }
static dary_status find_movable_location(dary *da, const int *conflicts, int *first_loc) { int i = da->free_head; int offsets[UCHAR_MAX+1]; calc_offsets(conflicts, offsets); // dary_dump(da); // validate_array(da); dprint("free_head %d", da->free_head); if (da->free_head < 0) { *first_loc = -1; return DARY_STATUS_FAIL; } while (i != - da->check[i]) { assert(i > UCHAR_MAX); if (is_movable(da, i, offsets)) { dprint("movable to %d", i); *first_loc = i; return DARY_STATUS_SUCCESS; } i = - da->check[i]; } if (is_movable(da, i, offsets)) { dprint("movable to %d", i); *first_loc = i; return DARY_STATUS_SUCCESS; } else { *first_loc = -1; return DARY_STATUS_FAIL; } }
bool Game::has_living_piece(Player player) const { assert(enabled[player]); for(int i=0; i<4631; i++) { if(is_valid_cell_id(i)) { if(!board[i].is_empty()) { assert(!board[i].is_unknown()); if(board[i].get_player() == player) { Cell cell(i); std::list<Bound> bounds = cell.get_adjacents(); for(auto I=bounds.begin(); I!=bounds.end(); I++) { if(is_movable(cell, I->get_target()) ) { return true; } // movable } // for adjacents } // this player } // not empty } // valid cell id } // for cell id return false; }
bool Board::each_movable(MovableVisitor* visitor) { if (turn() < 2) { const unsigned short *move = (turn() == 0) ? violet_first_moves : orange_first_moves; for (; *move; move++) { Move m(*move); if (move_filter(block_set[m.block_id()]-> rotations[m.direction()].piece)) { if (!visitor->visit_move(m)) return false; } } return true; } Edge edges[100], *pedge; { unsigned char edge_mask = is_violet() ? VIOLET_MASK | ORANGE_BLOCK : ORANGE_MASK | VIOLET_BLOCK; unsigned char edge_bit = is_violet() ? VIOLET_EDGE : ORANGE_EDGE; unsigned char side_bit = is_violet() ? VIOLET_SIDE : ORANGE_SIDE; pedge = edges; for (int ey = 0; ey < YSIZE; ey++) { for (int ex = 0; ex < XSIZE; ex++) { if ((at(ex, ey) & edge_mask) == edge_bit) { pedge->x = ex; pedge->y = ey; pedge->direction = (ey > 0 && at(ex, ey-1) & side_bit) ? (ex > 0 && (at(ex-1, ey) & side_bit) ? 0 : 1) : (ex > 0 && (at(ex-1, ey) & side_bit) ? 2 : 3); pedge++; } } } pedge->x = -1; } int nmove = 0; for (int blk = 0; blk < NBLOCK; blk++) { if (blocks()[blk]) continue; Block* block = block_set[blk]; for (Piece **variation = block->variations; *variation; variation++) { if (!move_filter(*variation)) continue; short checked[YSIZE]; memset(checked, 0, sizeof(checked)); for (pedge = edges; pedge->x >= 0; pedge++) { for (int i = 0; i < (*variation)->nedge[pedge->direction]; i++) { int x = pedge->x - (*variation)->edges[pedge->direction][i].x; int y = pedge->y - (*variation)->edges[pedge->direction][i].y; if (y + (*variation)->miny < 0 || y + (*variation)->maxy >= YSIZE || x + (*variation)->minx < 0 || x + (*variation)->maxx >= XSIZE || (checked[y] & 1 << x)) continue; checked[y] |= 1 << x; if (is_movable(x, y, *variation)) { if (!visitor->visit_move(Move(x, y, (*variation)->id))) return false; nmove++; } } } } } if (nmove == 0) return visitor->visit_move(PASS); return true; }