void AGENT::update_normal(void) { int tx, ty; state = AGENT::NORMAL; // Logic if (!is_dest() && !at_unreachable_dest()) { // move faster if out of position if (within_dist_dest(unitData->radius * 2)) move_mult(1.0); else if (within_dist_dest(unitData->radius * 4)) move_mult(1.1); else move_mult(1.8); // animation setAnimation(ANIMATION_DATA::MOVE, true); } else { // clear last swap memory last_swap = -1; // don't move if (!is_dest_angle() && group->task_type() == TASK::MOVE) rotate_towards((int)group->get_angle_dest()); // rotate towards target else if (rotate_to_group) { if (!is_angle(group->get_rotation())) rotate_towards((int)group->get_rotation()); // rotate to group direction else end_rotate_to_group(); } move_stop(); if (!is_moving()) setAnimation(ANIMATION_DATA::STAND, true); } // Movement if (group->is_single_unit()) sync_to(group); else { swap_count--; if (!collision) move((int)get_dest_x(), (int)get_dest_y(), !group->is_moving()); // no collision else if (!is_dest() && (!agent_collided || agent_collided->getGroup() != getGroup()) && dist_dest() < group->get_radius()) { if (agent_collided) shorten_dest(2 * getRadius()); else { set_dest(group->get_x(), group->get_y()); shorten_dest(100); } } else if (agent_collided && !is_dest() && group->is_dest_angle() && agent_collided->is_near_dest_angle(35) && agent_collided->is_near_dest() && is_near_angle(agent_collided->get_rotation(), 35) && agent_collided->getGroup() == getGroup() && ((!is_last_swap(agent_collided->get_sort_id()) && !agent_collided->is_last_swap(sort_id)) || swap_count < 0)) { // swap group positions swap_positions(agent_collided); // in same group, do it } else collision_avoid(); // collision } // generic update update(); }
// ------------------------------------------------------------------- // Determine king mobility // - returns a list of all squares where the king may move // ------------------------------------------------------------------- move_list ChessBoard::mobility_king(int from) const { chessmove m; move_list ml; m.promotion=Empty; m.from=from; // Potential destinations relative to king's position static const int relative_destination[] = {-Rank-File, -Rank, -Rank+File, -File, File, Rank-File, Rank, Rank+File}; for (int i=0;i<8;i++) { m.to=from+relative_destination[i]; if (is_dest(m.from,m.to) && abs(which_file(from)-which_file(m.to))<=1 && !causes_check(m)) ml.push_front(m); } // Can king castle kingside? register bool white=is_white(square[from]); if (// 1) Castling flag is set (i.e. king/rook not moved/captured) (white ? w_castle_k : b_castle_k) == true && // 2) King is not castling to escape check (white ? w_check : b_check) == false && // 3) King is not castling through check is_attacked(!white, from+File) == false && // 4) King is not castling into check is_attacked(!white, from+2*File) == false && // 5) Squares between king and rook are empty square[from+File]==Empty && square[from+2*File]==Empty ) { m.to=from+2*File; ml.push_front(m); } // Can king castle queenside? if (// 1) Castling flag is set (i.e. king/rook not moved/captured) (white ? w_castle_q : b_castle_q) == true && // 2) King is not castling to escape check (white ? w_check : b_check) == false && // 3) King is not castling through check is_attacked(!white, from-File) == false && // 4) King is not castling into check is_attacked(!white, from-2*File) == false && // 5) Squares between king and rook are empty square[from-File]==Empty && square[from-2*File]==Empty && square[from-3*File]==Empty) { m.to=from-2*File; ml.push_front(m); } return ml; }
// ------------------------------------------------------------------- // Determine knight mobility // - returns a list of all squares where the knight may move // ------------------------------------------------------------------- move_list ChessBoard::mobility_knight(int from) const { chessmove m; move_list ml; m.promotion=Empty; m.from=from; // Potential destinations relative to knight's position static const int relative_destination[] = {-2*Rank-File, -2*Rank+File, -2*File-Rank, -2*File+Rank, 2*Rank-File, 2*Rank+File, 2*File-Rank, 2*File+Rank}; for (int i=0;i<8;i++) { m.to=from+relative_destination[i]; if (is_dest(m.from,m.to) && abs(which_file(from)-which_file(m.to))<3 && !causes_check(m)) ml.push_front(m); } return ml; }
// ------------------------------------------------------------------- // Determine bishop mobility // - returns a list of all squares where the bishop may move // ------------------------------------------------------------------- move_list ChessBoard::mobility_bishop(int from) const { chessmove m; move_list ml; m.promotion=Empty; m.from=from; int i; static const int increment[]={-Rank-File, Rank-File, -Rank+File, Rank+File}; for(i=0;i<4;i++) { for (m.to=from+increment[i]; abs(which_file(m.to)-which_file(m.to-increment[i]))==1; m.to+=increment[i]) { if (!is_dest(m.from, m.to)) break; if (!causes_check(m)) ml.push_front(m); if (square[m.to]!=Empty) break; } } return ml; }