/** * is_become_king * input : int row, int col, player_e turn * output : TRUE/FALSE * functionality : returns TRUE a the disc should be king (after a move) else return FALSE */ bool is_become_king(int row, int col, player_e turn){ bool king; color_e mine; king = FALSE; if (turn == USER) { mine = user.color; } else { mine = computer.color; } if (mine == WHITE) { if (((row == BOARD_SIZE - 1) && (is_empty_position(row, col)) && (is_valid_position(row, col)))) { king = TRUE; } } else { if (((row == 0) && (is_empty_position(row, col)) && (is_valid_position(row, col)))) { king = TRUE; } } return king; }
bool MapCollision::small_step(float &x, float &y, float step_x, float step_y, MOVEMENTTYPE movement_type, bool is_hero) { if (is_valid_position(x + step_x, y + step_y, movement_type, is_hero)) { x += step_x; y += step_y; assert(is_valid_position(x,y,movement_type, is_hero)); return true; } else { return false; } }
bool MapCollision::small_step_forced_slide_along_grid(float &x, float &y, float step_x, float step_y, MOVEMENTTYPE movement_type, bool is_hero) { if (is_valid_position(x + step_x, y, movement_type, is_hero)) { // slide along wall if (step_x == 0) return true; x += step_x; assert(is_valid_position(x,y,movement_type, is_hero)); } else if (is_valid_position(x, y + step_y, movement_type, is_hero)) { if (step_y == 0) return true; y += step_y; assert(is_valid_position(x,y,movement_type, is_hero)); } else { return false; } return true; }
/** * remove_disc * input : int row, int col, player_e rm_from_this_player * output : int -1 if the position is not valid. 1 discwas removed successfully. * functionality : removes a given disc on the board */ int remove_disc(int row, int col, player_e rm_from_this_player){ if (!is_valid_position(row, col)) { print_message(WRONG_POSITION); return -1; } game_board[row][col] = EMPTY; return 1; }
bool MapCollision::small_step_forced_slide(float &x, float &y, float step_x, float step_y, MOVEMENTTYPE movement_type, bool is_hero) { // is there a singular obstacle or corner we can step around? // only works if we are moving straight const float epsilon = 0.01f; if (step_x != 0) { assert(step_y == 0); float dy = y - static_cast<float>(floor(y)); if (is_valid_tile(int(x), int(y) + 1, movement_type, is_hero) && is_valid_tile(int(x) + sgn(step_x), int(y) + 1, movement_type, is_hero) && dy > 0.5) { y += std::min(1 - dy + epsilon, float(fabs(step_x))); } else if (is_valid_tile(int(x), int(y) - 1, movement_type, is_hero) && is_valid_tile(int(x) + sgn(step_x), int(y) - 1, movement_type, is_hero) && dy < 0.5) { y -= std::min(dy + epsilon, float(fabs(step_x))); } else { return false; } assert(is_valid_position(x,y,movement_type, is_hero)); } else if (step_y != 0) { assert(step_x == 0); float dx = x - static_cast<float>(floor(x)); if (is_valid_tile(int(x) + 1, int(y), movement_type, is_hero) && is_valid_tile(int(x) + 1, int(y) + sgn(step_y), movement_type, is_hero) && dx > 0.5) { x += std::min(1 - dx + epsilon, float(fabs(step_y))); } else if (is_valid_tile(int(x) - 1, int(y), movement_type, is_hero) && is_valid_tile(int(x) - 1, int(y) + sgn(step_y), movement_type, is_hero) && dx < 0.5) { x -= std::min(dx + epsilon, float(fabs(step_y))); } else { return false; } } else { assert(false); } return true; }
/** * set_disc * input : char char_on_board, int row, int col, color_e tool_color, type_e tool_type * output : int -1 standart function failed. 1 seccesfull set on the board. * functionality : sets a given disc on the board updates compuer's and user's men and kings linked list * return : -1 if the was memory allocation problems, 1 seccesfull set on the board */ int set_disc(char char_on_board, int row, int col, color_e tool_color, type_e tool_type) { coordinate_t *temp_linkedlist; if ((!is_valid_position(row, col))) { print_message(WRONG_POSITION); return 1; } game_board[row][col] = char_on_board; if (State == GAME_STATE) { if (user.color == tool_color) { temp_linkedlist = creat_linkedList_pointer(tool_type, USER); if (tool_type == KING) { user.num_of_kings++; } else { user.num_of_men++; } } else { temp_linkedlist = creat_linkedList_pointer(tool_type, COMPUTER); if (tool_type == KING) { computer.num_of_kings++; } else { computer.num_of_men++; } } temp_linkedlist = updating_linked_list(row, col, temp_linkedlist); if (temp_linkedlist == NULL) { return -1; } } return 1; }
/** * Given a target, trys to return one of the 8+ adjacent tiles * Returns the retargeted position on success, returns the original position on failure */ FPoint MapCollision::get_random_neighbor(Point target, int range, bool ignore_blocked) { FPoint new_target = target; std::vector<FPoint> valid_tiles; for (int i=-range; i<=range; i++) { for (int j=-range; j<=range; j++) { if (i == 0 && j == 0) continue; // skip the middle tile new_target.x = static_cast<float>(target.x + i) + 0.5f; new_target.y = static_cast<float>(target.y + j) + 0.5f; if (is_valid_position(new_target.x,new_target.y,MOVEMENT_NORMAL,false) || ignore_blocked) valid_tiles.push_back(new_target); } } if (!valid_tiles.empty()) return valid_tiles[rand() % valid_tiles.size()]; else return target; }
/** * Does not have the "slide" submovement that move() features * Line can be arbitrary angles. */ bool MapCollision::line_check(const float& x1, const float& y1, const float& x2, const float& y2, int check_type, MOVEMENTTYPE movement_type) { float x = x1; float y = y1; float dx = static_cast<float>(fabs(x2 - x1)); float dy = static_cast<float>(fabs(y2 - y1)); float step_x; float step_y; int steps = (int)std::max(dx, dy); if (dx > dy) { step_x = 1; step_y = dy / dx; } else { step_y = 1; step_x = dx / dy; } // fix signs if (x1 > x2) step_x = -step_x; if (y1 > y2) step_y = -step_y; if (check_type == CHECK_SIGHT) { for (int i=0; i<steps; i++) { x += step_x; y += step_y; if (is_wall(x, y)) return false; } } else if (check_type == CHECK_MOVEMENT) { for (int i=0; i<steps; i++) { x += step_x; y += step_y; if (!is_valid_position(x, y, movement_type, false)) return false; } } return true; }
/** * is_enemy_position * input : int row, int col * output : TRUE/FALSE * functionality : returns TRUE a given coordinate is enemy's coordinate else return FALSE */ bool is_enemy_position(int row, int col){ char tool; bool enemy; color_e mine; enemy = FALSE; tool = game_board[row][col]; if ((is_valid_position(row, col)) && (game_board[row][col] != EMPTY)) { if (Turn == USER) { mine = user.color; } else { mine = computer.color; } if (mine == WHITE) { if ((tool == BLACK_M) || (tool == BLACK_K)) { enemy = TRUE; } } else { if ((tool == WHITE_M) || (tool == WHITE_K)) { enemy = TRUE; } } } return enemy; }
bool Util::is_valid_position(const Pose &pose) { return is_valid_position(round(pose.x), round(pose.y), GlobalState::cost_map.config); }
bool Util::is_valid_position(const Pose &pose, const carmen_map_config_t &map_config) { return is_valid_position(round(pose.x), round(pose.y), map_config); }
bool Util::is_valid_position(const int &x, const int &y) { return is_valid_position(x, y, GlobalState::cost_map.config); }
void document_abner(DocumentEdit *edit, DocumentPosition begin, DocumentPosition end) { hale_assert_input(begin <= end); _check_edit(edit); auto document = edit->document; hale_assert(is_valid_position(document, begin)); hale_assert(is_valid_position(document, end)); edit->offset_begin = position_to_offset(document, begin); edit->offset_end = position_to_offset(document, end); edit->length = edit->offset_end - edit->offset_begin; if (edit->length == 0) { return; } edit->type = DocumentEdit::Remove; edit->pos_begin = begin; edit->pos_end = end; edit->block_changed = begin.block; edit->blocks_changed_count = edit->pos_end.block - edit->pos_begin.block; if (!edit->undo) { UndoWriter writer(&edit->document->undo, Document::UndoEvent_Remove); undo_write(writer.undo, &edit->offset_begin, sizeof(memi)); undo_write(writer.undo, &edit->length, sizeof(memi)); void *text = undo_write(writer.undo, edit->length * sizeof(ch)); document_text(document, edit->offset_begin, edit->length, (ch*)text, edit->length); } _buffer_remove(&document->buffer, edit->offset_begin, edit->length); if (edit->blocks_changed_count) { vector_remove(&document->blocks, edit->pos_begin.block, edit->pos_end.block - edit->pos_begin.block); edit->blocks_changed_at = begin.block + 1; } else { edit->blocks_changed_at = begin.block; } for (memi i = begin.block; i != vector_count(document->blocks); i++) { document->blocks[i].end -= edit->length; } document->blocks[edit->block_changed].flags = 0; // Move the parser head if (document_parser_set_head(document, edit->pos_begin.block)) { // TODO(cohen): If the time distance between caret types is small, // do not parse immediately. document_parse(document, 0.01f); } _notify_views_about_abner(edit); }
void document_insert(DocumentEdit *edit, DocumentPosition position, ch *text, memi text_length) { _check_edit(edit); //#ifdef _DEBUG // for (memi i = 0; i < text_length; i++) { // hale_assert(text[i] != '\r'); // } //#endif auto document = edit->document; memi old_document_end = _buffer_length(document->buffer); hale_assert(is_valid_position(document, position)); edit->type = DocumentEdit::Insert; // edit->undo_head = document->undo->writingHead(); edit->offset_begin = position_to_offset(document, position); Vector<memi> offsets; vector_init(&offsets); if (!edit->undo) { UndoWriter writer(&edit->document->undo, Document::UndoEvent_Insert); undo_write(writer.undo, &edit->offset_begin, sizeof(memi)); memi length_index = writer.undo->data.count; undo_write(writer.undo, &edit->length, sizeof(memi)); text_length = convert_and_insert(edit, text, text_length, &offsets); *((memi*)(writer.undo->data.ptr + length_index)) = text_length; } else { text_length = convert_and_insert(edit, text, text_length, &offsets); } edit->offset_end = edit->offset_begin + text_length; edit->length = text_length; edit->blocks_changed_count = vector_count(offsets); if (edit->blocks_changed_count == 0) { edit->block_changed = position.block; edit->blocks_changed_at = position.block; } else if (position.position == 0) { // Inserting at the beginning of a block. if (edit->offset_begin == 0) { // Inserting at document begin. edit->block_changed = position.block + vector_count(offsets); edit->blocks_changed_at = position.block; } else if (edit->offset_begin == old_document_end) { // If we're inserting at the end of the document to an empty block. edit->block_changed = position.block; edit->blocks_changed_at = position.block + 1; } else { // Anywhere at the block begin. // If we're inserting at the beginning of a block, // it's quite possible, that actually nothing changes. // But that depend on the things that use this notification. edit->block_changed = position.block + vector_count(offsets); edit->blocks_changed_at = position.block; } } else { // Inside the block edit->block_changed = position.block; edit->blocks_changed_at = position.block + 1; } // // Blocks // if (edit->blocks_changed_count > 0) { Document::Block block = {}; // We're inserting this *before* the position.block. vector_insert(&document->blocks, position.block, vector_count(offsets), block); for (memi i = 0; i != edit->blocks_changed_count; i++) { document->blocks[position.block + i].end = offsets[i]; } } for (memi i = position.block + edit->blocks_changed_count; i != vector_count(document->blocks); i++) { document->blocks[i].end += text_length; } document->blocks[edit->block_changed].flags = 0; edit->pos_begin = position; edit->pos_end = position_plus_offset(document, edit->pos_begin, text_length); // _write_undo(edit, Document::UndoEvent_Insert, edit->offset_begin, text_length); // Mark all views' layout to be invalid. document->view_flags = HALE_DOCUMENT_VIEW_LAYOUT_INVALID; // Invalidate block // Call this before we go for document_parse, so that the view's // is actually updated. _notify_views_about_insert(edit); // Move the parser head if (document_parser_set_head(document, edit->pos_begin.block)) { // TODO(cohen): If the time distance between inserts is small, // do not parse immediately. document_parse(document, 0.01f); } }