Exemple #1
0
void move_towards(int x1, int y1, int x2, int y2) {
    int diff_x = x1 - x2;
    int diff_y = y1 - y2;
    fprintf(stderr, "Our position = %d %d\n", x1 + 1, y1 + 1);
    fprintf(stderr, "Closest enemy position = %d %d\n", x2 + 1, y2 + 1);
    fprintf(stderr, "Differences in x and y positions = %d %d\n", diff_x, diff_y);
    if (diff_x != 0 && diff_y != 0) {
        fprintf(stderr, "Moving diagonally\n");
        //we move diagonally until we are on the same line
        //if we can't move diagonally, then we move straight in the best direction.
        //if we cant' even do that, then dang.
        int sign_y = x1 > x2 ? -1 : 1;
        int sign_x = y1 > y2 ? -1 : 1;
        if(can_move(x1, y1, x1 + 1 * sign_x, y1 + 1 * sign_y)) {
            move(x1, y1, x1 + 1 * sign_x, y1 + 1 * sign_y);
            fprintf(stdout, "MOVE %d %d %d %d\n", x1 + 1, y1 + 1, x1 + 1 + 1 * sign_x, y1 + 1 + 1 * sign_y);
        } else {
            if(can_move(x1, y1, x1 + 1*sign_x, y1)) {
                move(x1, y1, x1 + 1 * sign_x, y1);
                fprintf(stdout, "MOVE %d %d %d %d\n", x1 + 1, y1 + 1, x1 + 1 + 1 * sign_x, y1 + 1);
            } else if(can_move(x1, y1, x1, y1 + 1*sign_y)) {
                move(x1, y1, x1, y1 + 1 * sign_y);
                fprintf(stdout, "MOVE %d %d %d %d\n", x1 + 1, y1 + 1, x1 + 1, y1 + 1 + 1 * sign_y);
            }
        }
    } else
        fprintf(stderr, "Moving forward!\n");
    //we move forward, deviating only, if we cant move straight forward
    //if there is no possibility to move forward, then we don't move
    if(x1 - x2 == 0) {
        int sign = y1 > y2 ? -1 : 1;
        if(can_move(x1, y1, x1, y1 + sign * 1)) {
            move(x1, y1, x1, y1 + sign * 1);
            fprintf(stdout, "MOVE %d %d %d %d\n", x1 + 1, y1 + 1, x1 + 1, y1 + 1 + sign * 1);
        } else
        if(can_move(x1, y1, x1 + 1, y1 + sign*1)) {
            move(x1, y1, x1 + 1, y1 + sign * 1);
            fprintf(stdout, "MOVE %d %d %d %d\n", x1 + 1, y1 + 1, x1 + 1 + 1, y1 + 1 + sign * 1);
        } else if(can_move(x1, y1, x1 - 1, y1 + sign*1)) {
            move(x1, y1, x1 - 1, y1 + sign * 1);
            fprintf(stdout, "MOVE %d %d %d %d\n", x1 + 1, y1 + 1, x1 - 1 + 1, y1 + 1 + sign * 1);
        }
    } else {
        int sign = x1 > x2 ? -1 : 1;
        if(can_move(x1, y1, x1 + sign*1, y1)) {
            move(x1, y1, x1 + sign * 1, y1);
            fprintf(stdout, "MOVE %d %d %d %d\n", x1 + 1, y1 + 1, x1 + 1 + sign * 1, y1 + 1);
        } else
        if(can_move(x1, y1, x1 + sign*1, y1 + 1)) {
            move(x1, y1, x1 + sign * 1, y1 + 1);
            fprintf(stdout, "MOVE %d %d %d %d\n", x1 + 1, y1 + 1, x1 + 1 + sign * 1, y1 + 1 + 1);
        } else if(can_move(x1, y1, x1 + sign*1, y1 - 1)) {
            move(x1, y1, x1 + sign * 1, y1 - 1);
            fprintf(stdout, "MOVE %d %d %d %d\n", x1 + 1, y1 + 1, x1 + 1 + sign * 1, y1 + 1 - 1);
        }
    }
}
void texpedite::type_selected(twindow& window)
{
	tlistbox& list = find_widget<tlistbox>(&window, "type_list", false);

	twindow::tinvalidate_layout_blocker invalidate_layout_blocker(window);
	list.invalidate_layout();

	troop_index_ = list.get_selected_row();
	refresh_tooltip(window);

	// There is maybe no troop after disband. so troop_index_ maybe equal -1.
	if (troop_index_ >= 0) {
		int size = city_.reside_troops().size();
		const unit& u = *city_.reside_troops()[troop_index_];
		for (int index = 0; index < size; index ++) {
			tgrid* grid_ptr = list.get_row_grid(index);
			// tbutton& disband = find_widget<tbutton>(&window, "disband", false);
			tbutton& disband = *dynamic_cast<tbutton*>(grid_ptr->find("disband", false));
			if (index == troop_index_) {
				disband.set_visible(twidget::VISIBLE);
				disband.set_active(u.human());
			} else {
				disband.set_visible(twidget::INVISIBLE);
			}
		}

		tbutton* ok = find_widget<tbutton>(&window, "ok", false, true);
		ok->set_active(u.human() && can_move(u));
	}
}
Exemple #3
0
void solve()
{
    Zero(ans);
    Zero(cnt);

    int r = b - 1;
    int c = 0;
    int dir = 0;

    for (int i = 0; i < b; ++i)
        for (int j = 0; j < w; ++j)
            if (maze[i][j] == '0') ++ans[0];

    while (true) {
        while (! can_move(r, c, dir))
            dir = move_left(dir);

        r += dd[dir][0];
        c += dd[dir][1];

        if (cnt[r][c] <= 4) --ans[cnt[r][c]];
        ++cnt[r][c];
        if (cnt[r][c] <= 4) ++ans[cnt[r][c]];

        if (r == b - 1 && c == 0) break;

        if (! wall_right(r, c, dir))
            dir = move_right(dir);
    }
}
Exemple #4
0
void		ft_while_main(int tab[4][4])
{
	int c;

	while ((c = getch()))
	{
		if (c == 27)
			break ;
		if (c == KEY_RIGHT)
			ft_down(tab);
		if (c == KEY_LEFT)
			ft_up(tab);
		if (c == KEY_UP)
			ft_left(tab);
		if (c == KEY_DOWN)
			ft_right(tab);
		if (!can_move(tab))
		{
			refresh();
			clear();
			printw("Can't move mother f****r");
			getch();
		}
		ft_aff_square(tab);
		if (!ft_aff_square(tab))
			printw("Window too small.\nThat's what she said.");
	}
}
Exemple #5
0
/**
 * @brief Move generator performance test function.
 *
 * @param board
 * @param depth
 * @param global_stats statistics
 */
static void count_game(const Board *board, const int depth, GameStatistics *global_stats)
{
	GameStatistics stats = GAME_STATISTICS_INIT;
	unsigned long long moves;
	int x;
	Board next[1];

	if (depth == 1) {
		moves = get_moves(board->player, board->opponent);
		stats.n_moves = stats.max_mobility = stats.min_mobility = bit_count(moves);
		if (moves == 0) {
			if (can_move(board->opponent, board->player)) {
				stats.n_passes = 1;
			} else {
				const int n_player = bit_count(board->player);
				const int n_opponent = bit_count(board->opponent);
				if (n_player > n_opponent) stats.n_wins = 1;
				else if (n_player == n_opponent) stats.n_draws = 1;
				else stats.n_losses = 1;
			}
		}
	} else {
		moves = get_moves(board->player, board->opponent);
		if (moves) {
			foreach_bit (x, moves) {
				board_next(board, x, next);
				count_game(next, depth - 1, &stats);
			}
		} else {
bool KnightsTour::solve_backtrack(int row, int col) {
    // No solution if the initial state is out of board bounds
    if (row < 0 || row >= n || col < 0 || col >= n) return false;
    clean();

    // Create a knight's tour tracker
    int tracker = 0;
    board[row][col] = ++tracker;

    // Set the initial direction
    State state(row, col, LEFT_UP);
    // Push the initial state on stack
    stack.push(state);

    timestamp_t t1 = get_timestamp();
    // While we have not visited all the cells on a single tour
    // and the tracking stack is not empty, do
    while (tracker < n * n && !stack.empty()) {
        timestamp_t t2 = get_timestamp();
        if ((t2 - t1) / 1000000.0L > 180) break;
        // Get the last state
        state = stack.top();
        // Set up the next-to-come state
        State new_state;

        // While we are not done and there are moves to make, move and increase the direction
        while(state.dir < ALL_DONE && !can_move(state.row, state.col, state.dir, &new_state)) {
            state.dir++;
        }

        // If there are no moves but we are not done yet
        if (state.dir != ALL_DONE) {
            // Pop the last state
            stack.pop();
            // Increase the direction
            state.dir++;
            // Save the updated state
            stack.push(state);
            // Mark the board cell as visited
            board[new_state.row][new_state.col] = ++tracker;
            // Update the old state with the new one
            state.row = new_state.row; state.col = new_state.col; state.dir = LEFT_UP;
            // Push the new state on stack
            stack.push(state);
        } else {
            // If there was no successful tour found
            // Pop the current state
            stack.pop();
            // Reset the board cell
            board[state.row][state.col] = 0;
            // Backtrack
            tracker--;
        }
    }
    // If all the paths have been tried and the
    // tracker indicated all the cells as visited
    // return true, else false (no solution)
    return tracker == n * n;
}
dir play_move(strategy s, grid g)
{
    // If precedent move was right, we put all left again
    /*if(((memory)(s->mem))->nbStages > 0 && (((((memory)(s->mem))->container)[((memory)(s->mem))->nbStages])->decision) == RIGHT && can_move(g, LEFT))
      {
        printf("test\n");
        save_stage(s->mem, g, LEFT);
        print_grid(g);
        return LEFT;
        }*/

    if(((memory)(s->mem))->nbStages >=0)
    {
        //int temp = ((memory)(s->mem))->nbStages;
        //printf("Test : [%d]%p\n", temp, (((memory)(s->mem))->container[5]));
        printf("Base memory adress : %p.\n", (memory)(s->mem));
        printf("Base container adress : %p.\n", ((memory)(s->mem))->container);
        printf("Element at [%d] : %p.\n", ((memory)(s->mem))->nbStages, (((memory)(s->mem))->container)[(int)(((memory)(s->mem))->nbStages)]);
    }
    //printf("Test 2 : %d\n", ((memory)(s->mem))->nbStages);

    if(can_move(g, DOWN))
    {
        save_stage(s->mem, g, DOWN);
        print_grid(g);
        return DOWN;
    }
    if(can_move(g, LEFT))
    {
        save_stage(s->mem, g, LEFT);
        print_grid(g);
        return LEFT;
    }
    if(can_move(g, RIGHT))
    {
        save_stage(s->mem, g, RIGHT);
        print_grid(g);
        return RIGHT;
    }
    if(can_move(g, UP))
    {
        save_stage(s->mem, g, UP);
        print_grid(g);
        return UP;
    }
}
Exemple #8
0
int move(int x1, int y1, int x2, int y2) {
    /*fprintf(stderr, "coords = %d %d %d %d\n", x1, y1, x2, y2);
    fprintf(stderr, "x1 and board size = %d %d\n", x1, board.size - 1);
    fprintf(stderr, "x2 and board size = %d %d\n", x2, board.size - 1);
    fprintf(stderr, "y1 and board size = %d %d\n", y1, board.size - 1);
    fprintf(stderr, "y2 and board size = %d %d\n", y2, board.size - 1);
    fprintf(stderr, "empty = %d\n",is_empty(x1, y1));
    fprintf(stderr, "our unit = %d\n",(get_unit(x1, y1)->owner == PLAYER_1) != player_1_turn);
    fprintf(stderr, "unit owner = %d\n", get_unit(x1, y1)->owner);
    fprintf(stderr, "Player 1 = %d\n", PLAYER_1);
    fprintf(stderr, "unit owner is player 1 = %d\n", get_unit(x1, y1)->owner == PLAYER_1);
    fprintf(stderr, "player 1 turn = %d\n", player_1_turn);
    fprintf(stderr, "our turn = %d\n", our_turn);
    fprintf(stderr, "non empty theirs + their unit = %d\n",!(is_empty(x2, y2)) && (get_unit(x2, y2)->owner == PLAYER_1) == player_1_turn);
    fprintf(stderr, "not adjacent = %d\n", not_adjacent(x1, y1, x2, y2));
    fprintf(stderr, "cant move = %d\n", get_unit(x1, y1)->last_move == cur_turn);*/
    if(can_move(x1, y1, x2, y2)) {
        if(is_empty(x2, y2)) {
            unit_ptr unit_temp = get_unit(x1, y1);
            unit_temp->x = x2;
            unit_temp->y = y2;
            unit_temp->last_move = cur_turn;
        } else {
            unit_ptr my_unit = get_unit(x1, y1);
            unit_ptr their_unit = get_unit(x2, y2);
            if(their_unit->type < my_unit->type) {
                if(their_unit->type == KING) {
                    if(player_1_turn)
                        player_2.king = null;
                    else
                        player_1.king = null;
                }
                erase_unit(their_unit);
                my_unit->x = x2;
                my_unit->y = y2;
                my_unit->last_move = cur_turn;
            } else if(their_unit->type == my_unit->type) {
                if(their_unit->type == KING) {
                    player_1.king = null;
                    player_2.king = null;
                }
                erase_unit(their_unit);
                erase_unit(my_unit);
            } else {
                if(my_unit->type == KING) {
                    if(player_1_turn)
                        player_1.king = null;
                    else
                        player_2.king = null;
                }
                erase_unit(my_unit);
            }
        }
        return OK;
    } else
        return MOVE_ERROR;
}
Exemple #9
0
byte game_over() {
	byte count_white = 0;
	byte count_black = 0;
	byte count_wdamka = 0;
	byte count_bdamka = 0;
	byte can_move_white = 0;
	byte can_move_black = 0;
	for (byte y=0; y<8; y++)
		for (byte x=0; x<8; x++) {
			byte cell = board[y][x];
			switch (cell) {
				case White:
					count_white++;
					if (!can_move_white) can_move_white = can_move(x, y, White);
					break;
				case Black:
					count_black++;
					if (!can_move_black) can_move_black = can_move(x, y, Black);
					break;
				case WDamka:
					count_wdamka++;
					if (!can_move_white) can_move_white = can_move(x, y, White);
					break;
				case BDamka:
					count_bdamka++;
					if (!can_move_black) can_move_black = can_move(x, y, Black);
					break;
				default: {}
			}
		}
	if (count_black + count_bdamka == 0 || !can_move_black || (!count_wdamka && !count_bdamka && count_black == 1 && count_white > 1)) {
		debug_print("Победа белых!", 13, 4);
		return 1;
	}
	if (count_white + count_wdamka == 0 || !can_move_white || (!count_wdamka && !count_bdamka && count_white == 1 && count_black > 1)) {
		debug_print("Победа черных!", 14, 4);
		return 1;
	}
	if (!count_white && !count_black && count_wdamka == 1 && count_bdamka == 1) {
		debug_print("Ничья!", 6, 4);
		return 1;
	}
	return 0;
}
Exemple #10
0
void king_acts() {
    unit_ptr king_temp = us.king;
    bool potential_moves[3][3];
    bool has_to_evade = false;
    for(int i = 0; i < 3; i++)
        for(int j = 0; j < 3; j++)
            potential_moves[i][j] = true;
    unit_list_elem_ptr enemy_list = us.king == player_1.king ? board.player_2_list : board.player_1_list;
    fprintf(stderr, "our king = %d\n", (int) us.king);
    fprintf(stderr, "player 1 king = %d\n", (int) player_1.king);
    fprintf(stderr, "our king is player 1 king = %d\n", us.king == player_1.king);
    while(enemy_list != null) {
        int diff_x = enemy_list->unit->x - king_temp->x;
        int diff_y = enemy_list->unit->y - king_temp->y;
        if(abs(diff_x) <= 1 && abs(diff_y) <= 1) {
            has_to_evade = true;
            if(diff_x == 0 && diff_y == 0) {
                //you shouldn't be here!!! :x
            } else if(diff_x == 0) {
                potential_moves[0][diff_y + 1] = false;
                potential_moves[1][diff_y + 1] = false;
                potential_moves[2][diff_y + 1] = false;
                potential_moves[0][1] = false;
                potential_moves[1][1] = false;
                potential_moves[2][1] = false;
            } else if(diff_y == 0) {
                potential_moves[diff_x + 1][0] = false;
                potential_moves[diff_x + 1][1] = false;
                potential_moves[diff_x + 1][2] = false;
                potential_moves[1][0] = false;
                potential_moves[1][1] = false;
                potential_moves[1][2] = false;
            } else { //if(diff_y != 0 || diff_x != 0)
                potential_moves[diff_x + 1][diff_y + 1] = false;
                potential_moves[diff_x + 1 - 1*diff_x][diff_y + 1] = false;
                potential_moves[diff_x][diff_y + 1 - 1*diff_y] = false;
            }
        }
        enemy_list = enemy_list->next;
    }
    if(has_to_evade) {
        fprintf(stderr, "King has to evade!");
        bool has_evaded = false;
        for(int i = 0; i < 3 && !has_evaded; i++)
            for(int j = 0; j < 3 && !has_evaded; j++)
                if(potential_moves[i][j]) {
                    int x = king_temp->x;
                    int y = king_temp->y;
                    if(can_move(x, y, x + i + 1, y + j + 1)) {
                        move(x, y, x + i + 1, y + j + 1);
                        has_evaded = true;
                        fprintf(stdout, "MOVE %d %d %d %d\n", x + 1, y + 1, x + 1 + i + 1, y + 1 + j + 1);
                    }
                }
    }
}
Exemple #11
0
/*=============================================================================
  Return NO_ERROR if MOVE was completely legal in THIS board; otherwise
  return the appropiate error code (KING_LEFT_IN_CHECK, OPPONENTS_TURN,
  WRONG_MOVEMENT)

  Precondition: MOVE.from () and MOVE.to () return values in range [0, SQUARES)
  Postcondition: The board has been updated to show the effect of MOVE.
  ===========================================================================*/
MaeBoard::Error
MaeBoard::make_move (Move& move, bool is_computer_move)
{
   Error move_error;

   if (this->board[move.from ()] == EMPTY_SQUARE)
      return NO_PIECE_IN_SQUARE;

   BoardSquare start = move.from ();
   BoardSquare end = move.to ();

   move.set_moving_piece (board[start].piece);
   if (board[end] != EMPTY_SQUARE)
      move.set_captured_piece (board[end].piece);

   // Assume that moves generated by the computer are pseudo-legal, so don't
   // bother making a verification.
   if (!is_computer_move)
      if ((move_error = can_move (move)) != NO_ERROR)
         return move_error;

   label_move (move);
   save_restore_information (move);

   Square initial = board[start];
   Square final = this->board[end];
   remove_piece (start);
   remove_piece (end);
   add_piece (end, initial.piece, initial.player);

   if (move.get_type () == Move::EN_PASSANT_CAPTURE)
   {
      uint offset = this->is_whites_turn ? BOARD_SIZE: -((int) BOARD_SIZE);
      uint position = util::Util::MSB_position (this->en_passant_capture_square) + offset;
      remove_piece (BoardSquare (position));
   }

   int king_position = util::Util::MSB_position (this->piece[player][Piece::KING]);
   if (attacks_to (BoardSquare (king_position), true /* include_king */))
   {
      remove_piece (end);
      add_piece (start, initial.piece, initial.player);
      if (final.piece != Piece::NULL_PIECE)
         add_piece (end, final.piece, final.player);

      if (move.get_type () == Move::EN_PASSANT_CAPTURE)
      {
         int offset = (this->is_whites_turn ? BOARD_SIZE: -((int) BOARD_SIZE));
         uint position = util::Util::MSB_position (en_passant_capture_square) + offset;
         add_piece (BoardSquare (position), Piece::PAWN, opponent);
      }
      this->game_history.pop ();

      return KING_LEFT_IN_CHECK;
   }
void texpedite::disband(bool& handled, bool& halt, int index)
{
	twindow& window = *window_;
	tlistbox* list = find_widget<tlistbox>(&window, "type_list", false, true);

	if (!disband_->button_pressed(index)) {
		return;
	}

	list->remove_row(index);

	int size = city_.reside_troops().size();
	for (int i = index; i < size; i ++) {
		tgrid* grid_ptr = list->get_row_grid(i);
		// tbutton& disband = find_widget<tbutton>(&window, "disband", false);
		tbutton& disband = *dynamic_cast<tbutton*>(grid_ptr->find("disband", false));

		disconnect_signal_mouse_left_click(
			disband
			, boost::bind(
				&texpedite::disband
				, this
				, _3, _4
				, i + 1));

		connect_signal_mouse_left_click(
			disband
			, boost::bind(
				&texpedite::disband
				, this
				, _3, _4
				, i));

		disband.set_active(city_.reside_troops()[i]->human());
	}

	tbutton* ok = find_widget<tbutton>(&window, "ok", false, true);
	if (!city_.reside_troops().empty()) {
		if (index == size) {
			index --;
		}
		list->select_row(index);
		const unit& u = *city_.reside_troops()[index];
		ok->set_active(can_move(u) && u.human());
	} else {
		ok->set_active(false);
	}
	type_selected(window);

	handled = true;
	halt = true;

	window.invalidate_layout();
}
Exemple #13
0
void UnitB::process_wait()
{
	err_when(cur_action != SPRITE_WAIT);

	//move if the next tile is ready
	int stepMagn = move_step_magn();
	if(can_move((cur_x+stepMagn*move_x_pixel_array[final_dir])/LOCATE_WIDTH, (cur_y+stepMagn*move_y_pixel_array[final_dir])/LOCATE_WIDTH))
	{
		wait_state = 0;
		cur_action = SPRITE_MOVE;
		return;
	}
	else //find a new path if the thing occupying the next tile no longer move
	{
/*		int occUnitNum;
		Unit* occStuff;
		occUnitNum = checking_who_occupy_my_next_tile((cur_x+stepMagn*move_x_pixel_array[final_dir])/LOCATE_WIDTH, (cur_y+stepMagn*move_y_pixel_array[final_dir])/LOCATE_WIDTH);

		//##### begin trevor 21/1 #####//

		enum{ SEARCH_NEW_PATH_PROBABILITY = 10 };

		if( (!occUnitNum || (occUnitNum && (occStuff=unit_array[occUnitNum])
			 && (occStuff->cur_action != SPRITE_MOVE
			 && occStuff->cur_action != SPRITE_WAIT)))
			 || (SEARCH_NEW_PATH_PROBABILITY > m.random(100) && sprite_speed() <= occStuff->sprite_speed() && !is_in_formation()) )
		{
			wait_state = 0;
			move_to(move_to_loc_x, move_to_loc_y);
		//	retry_state++;
			return;
		}

		//##### end trevor 21/1 #####//*/
	}
	//find a new path if wait too long	
	// ####### begin Gilbert 28/4 ########//
	if(wait_state++ > (retry_state <= MAX_UNIT_WAIT_STATE ? retry_state+MAX_UNIT_WAIT_STATE_FIRST : MAX_UNIT_WAIT_STATE) )
	{
		wait_state = 0;

		int backupRetryState = retry_state;
		move_to(move_to_loc_x, move_to_loc_y);
		retry_state = backupRetryState + 1;		// restore and increase
	}
	// ####### end Gilbert 28/4 ########//
	//if retrying too many times, stop move
	if(retry_state > MAX_RETRY_STATE) 
	{
		stop_move();
		retry_state = 0;
	}
}
Exemple #14
0
/*==========================================
 * (x0,y0)から(dx,dy)方向へcountセル分
 * 吹き飛ばしたあとの座標を取得
 *	flag = 0: 壁補正あり、1: 壁補正なし
 *------------------------------------------
 */
int path_blownpos(int m,int x0,int y0,int dx,int dy,int count,int flag)
{
	struct map_data *md = &map[m];

	if(!map[m].gat)
		return -1;

	if(count > MAX_BLOWNPOS) {
		if(battle_config.error_log)
			printf("path_blownpos: count too many %d !\n",count);
		count = MAX_BLOWNPOS;
	}
	if(dx > 1 || dx < -1 || dy > 1 || dy < -1) {
		if(battle_config.error_log)
			printf("path_blownpos: illegal dx=%d or dy=%d !\n",dx,dy);
		dx = (dx >= 0)? 1: ((dx < 0)? -1: 0);
		dy = (dy >= 0)? 1: ((dy < 0)? -1: 0);
	}

	while( (count--) > 0 && (dx || dy) ) {
		if( !can_move(md,x0,y0,x0+dx,y0+dy,0) ) {
			int fx, fy;
			if( flag )
				break;
			fx = (dx != 0 && can_move(md,x0,y0,x0+dx,y0,0));
			fy = (dy != 0 && can_move(md,x0,y0,x0,y0+dy,0));
			if( fx && fy ) {
				if(atn_rand()&1) dx = 0;
				else             dy = 0;
			}
			if( !fx ) dx = 0;
			if( !fy ) dy = 0;
		}
		x0 += dx;
		y0 += dy;
	}
	return (x0<<16)|y0;
}
Exemple #15
0
void
fight(boolean to_the_death)
{
	short ch, c, d;
	short row, col;
	boolean first_miss = 1;
	short possible_damage;
	object *monster;

	while (!is_direction(ch = rgetchar(), &d)) {
		sound_bell();
		if (first_miss) {
			message("direction?", 0);
			first_miss = 0;
		}
	}
	check_message();
	if (ch == CANCEL) {
		return;
	}
	row = rogue.row; col = rogue.col;
	get_dir_rc(d, &row, &col, 0);

	c = mvinch(row, col);
	if (((c < 'A') || (c > 'Z')) ||
		(!can_move(rogue.row, rogue.col, row, col))) {
		message("I see no monster there", 0);
		return;
	}
	if (!(fight_monster = object_at(&level_monsters, row, col))) {
		return;
	}
	if (!(fight_monster->m_flags & STATIONARY)) {
		possible_damage = ((get_damage(fight_monster->m_damage, 0) * 2) / 3);
	} else {
		possible_damage = fight_monster->stationary_damage - 1;
	}
	while (fight_monster) {
		one_move_rogue(ch, 0);
		if (((!to_the_death) && (rogue.hp_current <= possible_damage)) ||
			interrupted || (!(dungeon[row][col] & MONSTER))) {
			fight_monster = NULL;
		} else {
			monster = object_at(&level_monsters, row, col);
			if (monster != fight_monster) {
				fight_monster = NULL;
			}
		}
	}
}
Exemple #16
0
/*==========================================
 * (x0,y0)から(dx,dy)方向へcountセル分
 * 吹き飛ばしたあとの座標を所得
 *------------------------------------------
 */
int path_blownpos(int m,int x0,int y0,int dx,int dy,int count)
{
	struct map_data *md;

	if(!map[m].gat)
		return -1;
	md=&map[m];

	if(count>15){	// 最大10マスに制限
		if(battle_config.error_log)
			printf("path_blownpos: count too many %d !\n",count);
		count=15;
	}
	if(dx>1 || dx<-1 || dy>1 || dy<-1){
		if(battle_config.error_log)
			printf("path_blownpos: illeagal dx=%d or dy=%d !\n",dx,dy);
		dx=(dx>=0)?1:((dx<0)?-1:0);
		dy=(dy>=0)?1:((dy<0)?-1:0);
	}
	
	while( (count--)>0 && (dx!=0 || dy!=0) ){
		if( !can_move(md,x0,y0,x0+dx,y0+dy,0) ){
			int fx=(dx!=0 && can_move(md,x0,y0,x0+dx,y0,0));
			int fy=(dy!=0 && can_move(md,x0,y0,x0,y0+dy,0));
			if( fx && fy ){
				if(rand()&1) dx=0;
				else		 dy=0;
			}
			if( !fx )		dx=0;
			if( !fy )		dy=0;
		}
		x0+=dx;
		y0+=dy;
	}
	return (x0<<16)|y0;
}
Exemple #17
0
//---------- Begin of function UnitB::process_blocked -----//
// 
// retry move to destination if the unit is blocked
//
void UnitB::process_blocked()
{
	if(number_of_times_being_blocked++ > MAX_UNIT_BLOCKED_TIME  || 
		(next_x_loc() == move_to_loc_x && next_y_loc() == move_to_loc_y) || 
		((abs(move_to_loc_x - next_x_loc()) <= obj_loc_width()) && 
		 (abs(move_to_loc_y - next_y_loc()) <= obj_loc_height()) && 
		 !can_move(move_to_loc_x, move_to_loc_y) &&
		 !checking_who_occupy_the_place_i_want_to_go(move_to_loc_x, move_to_loc_y)))
	{
		set_no_longer_blocked();
		stop_move();
	}
	else
		move_to(move_to_loc_x, move_to_loc_y);
}
Exemple #18
0
int move( stk * from, stk * to )
{
  if( can_move( from, to ) )
    {
      int ifrom;

      ifrom = pop( from );
      push( to, ifrom );
      return ifrom;
    }
  else
    {
      return -1;
    }
}
Exemple #19
0
//----------- Begin of function UnitB::process_idle----------//
//
// when a unit is idling, if it is block, process block
// if it is in formation but fnot yet reach destination, go there again
//
void UnitB::process_idle()
{
	cur_action = SPRITE_IDLE;
	if(is_blocked() && cur_order.mode != UNIT_ATTACK)
		process_blocked();
	else
	if(/*is_in_formation() && */
		is_blocked() &&
		((next_x_loc() != move_to_loc_x) || (next_y_loc() != move_to_loc_y)) &&
		can_move(move_to_loc_x, move_to_loc_y))

		move_to(move_to_loc_x, move_to_loc_y);
	
	else
		Sprite::process_idle();
}
Exemple #20
0
int take_piece_num(game g, char* buf, int* piece_num){
  while(true){
    printf("What piece do you want to move?\n");
    read(0, buf, sizeof(char)*100);
    if(strcmp(buf, "cancel") == 10)
      break;
    if(strcmp(buf, "exit") == 10)
      return -1;
    if(buf[0]<48 || buf[0]>=48+game_nb_pieces(g) || buf[1] != 10)
      printf("Write a number between 0 and %dt\tor write cancel or exit.\n",game_nb_pieces(g)-1);
    else{
      *(piece_num) = atoi(buf);
      if(!can_move(g,*(piece_num)))
	printf("The piece %d cannot move.\n", *(piece_num));
      else
	return 1;
    }
  }
  return 0;
}
/**
* check_movement(void)
*
* @brief
* @param void
* @return void
*/
void check_movement(void)
{
	if(is_trying_to_move()){
		if(can_move()){
			if(tempdata()->shift)
				player(myindex())->moving = MOVEMENT_RUNNING;
			else
				player(myindex())->moving = MOVEMENT_WALKING;

			switch(player(myindex())->dir){
			case DIR_UP:
				send_player_move();
				player(myindex())->offsety = PIC_SIZE;
				player(myindex())->y--;
				break;
			case DIR_DOWN:
				send_player_move();
				player(myindex())->offsety = PIC_SIZE * -1;
				player(myindex())->y++;
				break;
			case DIR_LEFT:
				send_player_move();
				player(myindex())->offsetx = PIC_SIZE;
				player(myindex())->x--;
				break;
			case DIR_RIGHT:
				send_player_move();
				player(myindex())->offsetx = PIC_SIZE * -1;
				player(myindex())->x++;
				break;
			}

			if(player(myindex())->offsetx == 0 && player(myindex())->offsety == 0){
				if(map()->tile[GETXY(player(myindex())->x,player(myindex())->y)].type == TILE_TYPE_WARP){
					tempdata()->gettingmap = TRUE;
					tempdata()->canmovenow = FALSE;
				}
			}
		}
	}
}
Exemple #22
0
/**
 * tests whether we can legally move node node after node after
 * (only works for nodes in same block)
 */
static bool can_move(ir_node *node, ir_node *after)
{
	ir_node *node_block = get_nodes_block(node);
	assert(node_block == get_nodes_block(after));

	/** all users have to be after the after node */
	foreach_out_edge(node, edge) {
		ir_node *out = get_edge_src_irn(edge);
		if (get_nodes_block(out) != node_block)
			continue;
		/* phi represents a usage at block end */
		if (is_Phi(out))
			continue;
		if (arch_is_irn_not_scheduled(out)) {
			if (!can_move(out, after))
				return false;
		} else {
			if (sched_get_time_step(out) <= sched_get_time_step(after))
				return false;
		}
	}
Exemple #23
0
/* nie uzywane */
int need_help(CHAR_DATA *ch, CHAR_DATA *gch)
{
    int hp_percent, ret;

    hp_percent = (100*gch->hit)/get_max_hp(gch);

    if( hp_percent < 30 )
	ret = 5;
    else if( hp_percent < 45 )
	ret = 4;
    else if( hp_percent < 60 )
	ret = 2;
    else if( hp_percent < 75)
	ret = 1;
    else
	ret = 0;

    if(!can_move(gch) && ret > 0)
	ret++;

    return ret;
}
Exemple #24
0
int					move_ants(t_ant *ants, t_pipe *pipes)
{
	t_room		*next;
	int			res;

	res = 0;
	next = NULL;
	while (ants)
	{
		if ((next = can_move(ants->pos, ants->previous, pipes)))
		{
			if (res++)
				ft_putchar(' ');
			put_path(ants->num, next->name);
			ants->previous = ants->pos;
			ants->pos->state = ants->pos->state - 1;
			next->state = next->state + 1;
			ants->pos = next;
		}
		ants = ants->next;
	}
	return (res);
}
Exemple #25
0
/*==========================================
 * path探索 (x0,y0)->(x1,y1)
 *------------------------------------------
 */
int path_search(struct walkpath_data *wpd, map_local *m, int x0, int y0, int x1, int y1, int flag)
{
    int heap[MAX_HEAP + 1];
    int i, rp, x, y;
    int dx, dy;

    nullpo_ret(wpd);

    assert (m->gat);
    map_local *md = m;
    if (x1 < 0 || x1 >= md->xs || y1 < 0 || y1 >= md->ys
        || bool(read_gatp(md, x1, y1) & MapCell::UNWALKABLE))
        return -1;

    // easy
    dx = (x1 - x0 < 0) ? -1 : 1;
    dy = (y1 - y0 < 0) ? -1 : 1;
    for (x = x0, y = y0, i = 0; x != x1 || y != y1;)
    {
        if (i >= sizeof(wpd->path))
            return -1;
        if (x != x1 && y != y1)
        {
            if (!can_move(md, x, y, x + dx, y + dy))
                break;
            x += dx;
            y += dy;
            wpd->path[i++] = (dx < 0)
                ? ((dy > 0) ? DIR::SW : DIR::NW)
                : ((dy < 0) ? DIR::NE : DIR::SE);
        }
        else if (x != x1)
        {
            if (!can_move(md, x, y, x + dx, y))
                break;
            x += dx;
            wpd->path[i++] = (dx < 0) ? DIR::W : DIR::E;
        }
        else
        {                       // y!=y1
            if (!can_move(md, x, y, x, y + dy))
                break;
            y += dy;
            wpd->path[i++] = (dy > 0) ? DIR::S : DIR::N;
        }
        if (x == x1 && y == y1)
        {
            wpd->path_len = i;
            wpd->path_pos = 0;
            wpd->path_half = 0;
            return 0;
        }
    }
    if (flag & 1)
        return -1;

    struct tmp_path tp[MAX_WALKPATH * MAX_WALKPATH] {};

    i = calc_index(x0, y0);
    tp[i].x = x0;
    tp[i].y = y0;
    tp[i].dist = 0;
    tp[i].dir = DIR::S;
    tp[i].before = 0;
    tp[i].cost = calc_cost(&tp[i], x1, y1);
    tp[i].flag = 0;
    heap[0] = 0;
    push_heap_path(heap, tp, calc_index(x0, y0));
    while (1)
    {
        int e = 0;

        if (heap[0] == 0)
            return -1;
        rp = pop_heap_path(heap, tp);
        x = tp[rp].x;
        y = tp[rp].y;
        if (x == x1 && y == y1)
        {
            int len, j;

            for (len = 0, i = rp; len < 100 && i != calc_index(x0, y0);
                 i = tp[i].before, len++);
            if (len == 100 || len >= sizeof(wpd->path))
                return -1;
            wpd->path_len = len;
            wpd->path_pos = 0;
            wpd->path_half = 0;
            for (i = rp, j = len - 1; j >= 0; i = tp[i].before, j--)
                wpd->path[j] = tp[i].dir;

            return 0;
        }
        if (can_move(md, x, y, x + 1, y - 1))
            e += add_path(heap, tp, x + 1, y - 1, tp[rp].dist + 14, DIR::NE, rp, x1, y1);
        if (can_move(md, x, y, x + 1, y))
            e += add_path(heap, tp, x + 1, y, tp[rp].dist + 10, DIR::E, rp, x1, y1);
        if (can_move(md, x, y, x + 1, y + 1))
            e += add_path(heap, tp, x + 1, y + 1, tp[rp].dist + 14, DIR::SE, rp, x1, y1);
        if (can_move(md, x, y, x, y + 1))
            e += add_path(heap, tp, x, y + 1, tp[rp].dist + 10, DIR::S, rp, x1, y1);
        if (can_move(md, x, y, x - 1, y + 1))
            e += add_path(heap, tp, x - 1, y + 1, tp[rp].dist + 14, DIR::SW, rp, x1, y1);
        if (can_move(md, x, y, x - 1, y))
            e += add_path(heap, tp, x - 1, y, tp[rp].dist + 10, DIR::W, rp, x1, y1);
        if (can_move(md, x, y, x - 1, y - 1))
            e += add_path(heap, tp, x - 1, y - 1, tp[rp].dist + 14, DIR::NW, rp, x1, y1);
        if (can_move(md, x, y, x, y - 1))
            e += add_path(heap, tp, x, y - 1, tp[rp].dist + 10, DIR::N, rp, x1, y1);
        tp[rp].flag = 1;
        if (e || heap[0] >= MAX_HEAP - 5)
            return -1;
    }
}
Exemple #26
0
int swmain(int argc, char *argv[])
{
	int nexttic;

	nobjects = (OBJECTS *) malloc(100 * sizeof(OBJECTS));

	swinit(argc, argv);
	setjmp(envrestart);

	// sdh 28/10/2001: playmode is called from here now
	// makes for a more coherent progression through the setup process

	if (!playmode)
		getgamemode();
	swinitlevel();

	nexttic = Timer_GetMS();
        skip_time = 0;

	for (;;) {
                int nowtime;

		/* generate a new move command periodically
		 * and send to other players if neccessary */

                nowtime = Timer_GetMS();

		if (nowtime > nexttic
		 && latest_player_time[player] - countmove < MAX_NET_LAG) {

			new_move();

                        /* Be accurate (exact amount between tics);
                         * However, if a large spike occurs between tics,
                         * catch up immediately.
                         */

                        if (nowtime - nexttic > 1000)
                                nexttic = nowtime + (1000/FPS);
                        else
			        nexttic += (1000 / FPS);

                        // wait a bit longer to compensate for lag

                        nexttic += skip_time;
                        skip_time = 0;
		}

		asynupdate();
		swsndupdate();

		/* if we have all the tic commands we need, we can move */

		if (can_move()) {
                        calculate_lag();
			//dump_cmds();
			swmove();
			swdisp();
			swcollsn();
			swsound();
		}

		// sdh 15/11/2001: dont thrash the 
		// processor while waiting
		Timer_Sleep(10);
	}

	return 0;
}
void texpedite::pre_show(CVideo& /*video*/, twindow& window)
{
	window_ = &window;

	int side_num = city_.side();
	team& current_team = teams_[side_num - 1];
	std::stringstream str;

	tlistbox* list = find_widget<tlistbox>(&window, "type_list", false, true);

	int cost_exponent = current_team.cost_exponent();
	std::vector<unit*>& reside_troops = city_.reside_troops();
	int troop_index = 0;
	for (std::vector<unit*>::const_iterator it = reside_troops.begin(); it != reside_troops.end(); ++ it, troop_index ++) {
		unit& u = **it;
		/*** Add list item ***/
		string_map list_item;
		std::map<std::string, string_map> list_item_item;

		list_item["label"] = u.absolute_image() + "~RC(" + u.team_color() + ">" + team::get_side_color_index(side_num) + ")";
		list_item_item.insert(std::make_pair("icon", list_item));

		// type/name
		str.str("");
		str << u.type_name() << "(Lv" << u.level() << ")\n";
		str << u.name();
		list_item["label"] = str.str();
		list_item_item.insert(std::make_pair("type", list_item));

		// list_item["label"] = it->name();
		// list_item_item.insert(std::make_pair("name", list_item));

		// hp
		str.str("");
		str << u.hitpoints() << "/\n" << u.max_hitpoints();
		list_item["label"] = str.str();
		list_item_item.insert(std::make_pair("hp", list_item));

		// xp
		str.str("");
		str << u.experience() << "/\n";
		if (u.can_advance()) {
			str << u.max_experience();
		} else {
			str << "-";
		}
		list_item["label"] = str.str();
		list_item_item.insert(std::make_pair("xp", list_item));

		// movement
		str.str("");
		str << u.movement_left() << "/" << u.total_movement();
		list_item["label"] = str.str();
		list_item_item.insert(std::make_pair("movement", list_item));

		str.str("");
		str << u.cost() * cost_exponent / 100 << "/" << calculate_disband_income(u, cost_exponent);
		list_item["label"] = str.str();
		list_item_item.insert(std::make_pair("cost", list_item));

		list->add_row(list_item_item);

		tgrid* grid_ptr = list->get_row_grid(troop_index);
		twidget* widget = grid_ptr->find("human", false);
		widget->set_visible(u.human()? twidget::VISIBLE: twidget::INVISIBLE);

		// tbutton& disband = find_widget<tbutton>(&window, "disband", false);
		tbutton& disband = *dynamic_cast<tbutton*>(grid_ptr->find("disband", false));
		connect_signal_mouse_left_click(
			disband
			, boost::bind(
				&texpedite::disband
				, this
				, _3, _4
				, troop_index));
		if (troop_index) {
			disband.set_visible(twidget::INVISIBLE);
		} else {
			disband.set_visible(twidget::VISIBLE);
			disband.set_active(reside_troops[troop_index]->human());
		}

	}

	list->set_callback_value_change(dialog_callback<texpedite, &texpedite::type_selected>);

	connect_signal_mouse_left_click(
		find_widget<tbutton>(&window, "merit", false)
		, boost::bind(
			&texpedite::merit
			, this
			, boost::ref(window)));

	refresh_tooltip(window);

	tbutton* ok = find_widget<tbutton>(&window, "ok", false, true);
	const unit& u = *reside_troops[troop_index_];
	ok->set_active(can_move(u) && u.human());
}
Exemple #28
0
void
process_command(int descr, dbref player, char *command)
{
	char *arg1;
	char *arg2;
	char *full_command;
	char *p;					/* utility */
	char pbuf[BUFFER_LEN];
	char xbuf[BUFFER_LEN];
	char ybuf[BUFFER_LEN];
	struct timeval starttime;
	struct timeval endtime;
	double totaltime;

	if (command == 0)
		abort();

	/* robustify player */
	if (player < 0 || player >= db_top ||
		(Typeof(player) != TYPE_PLAYER && Typeof(player) != TYPE_THING)) {
		log_status("process_command: bad player %d", player);
		return;
	}

	if ((tp_log_commands || Wizard(OWNER(player)))) {
		if (!(FLAGS(player) & (INTERACTIVE | READMODE))) {
			if (!*command) {
				return; 
			}
			log_command("%s: %s", whowhere(player), command);
		} else {
			if (tp_log_interactive) {
				log_command("%s: %s%s", whowhere(player),
						(FLAGS(player) & (READMODE)) ? "[READ] " : "[INTERP] ", command);
			}
		}
	}

	if (FLAGS(player) & INTERACTIVE) {
		interactive(descr, player, command);
		return;
	}
	/* eat leading whitespace */
	while (*command && isspace(*command))
		command++;

	/* Disable null command once past READ line */
	if (!*command)
		return;

	/* check for single-character commands */
	if (!tp_enable_prefix) {
		if (*command == SAY_TOKEN) {
			snprintf(pbuf, sizeof(pbuf), "say %s", command + 1);
			command = &pbuf[0];
		} else if (*command == POSE_TOKEN) {
			snprintf(pbuf, sizeof(pbuf), "pose %s", command + 1);
			command = &pbuf[0];
		} else if (*command == EXIT_DELIMITER) {
			snprintf(pbuf, sizeof(pbuf), "delimiter %s", command + 1);
			command = &pbuf[0];
		}
	}

	/* profile how long command takes. */
	gettimeofday(&starttime, NULL);

	/* if player is a wizard, and uses overide token to start line... */
	/* ... then do NOT run actions, but run the command they specify. */
	if (!(TrueWizard(OWNER(player)) && (*command == OVERIDE_TOKEN))) {
		if (can_move(descr, player, command, 0)) {
			do_move(descr, player, command, 0);	/* command is exact match for exit */
			*match_args = 0;
			*match_cmdname = 0;
		} else {
			if (tp_enable_prefix) {
				if (*command == SAY_TOKEN) {
					snprintf(pbuf, sizeof(pbuf), "say %s", command + 1);
					command = &pbuf[0];
				} else if (*command == POSE_TOKEN) {
					snprintf(pbuf, sizeof(pbuf), "pose %s", command + 1);
					command = &pbuf[0];
				} else if (*command == EXIT_DELIMITER) {
					snprintf(pbuf, sizeof(pbuf), "delimiter %s", command + 1);
					command = &pbuf[0];
				} else {
					goto bad_pre_command;
				}
				if (can_move(descr, player, command, 0)) {
					do_move(descr, player, command, 0);	/* command is exact match for exit */
					*match_args = 0;
					*match_cmdname = 0;
				} else {
					goto bad_pre_command;
				}
			} else {
				goto bad_pre_command;
			}
		}
	} else {
	  bad_pre_command:
		if (TrueWizard(OWNER(player)) && (*command == OVERIDE_TOKEN))
			command++;
		full_command = strcpyn(xbuf, sizeof(xbuf), command);
		for (; *full_command && !isspace(*full_command); full_command++) ;
		if (*full_command)
			full_command++;

		/* find arg1 -- move over command word */
		command = strcpyn(ybuf, sizeof(ybuf), command);
		for (arg1 = command; *arg1 && !isspace(*arg1); arg1++) ;
		/* truncate command */
		if (*arg1)
			*arg1++ = '\0';

		/* remember command for programs */
		strcpyn(match_args, sizeof(match_args), full_command);
		strcpyn(match_cmdname, sizeof(match_cmdname), command);

		/* move over spaces */
		while (*arg1 && isspace(*arg1))
			arg1++;

		/* find end of arg1, start of arg2 */
		for (arg2 = arg1; *arg2 && *arg2 != ARG_DELIMITER; arg2++) ;

		/* truncate arg1 */
		for (p = arg2 - 1; p >= arg1 && isspace(*p); p--)
			*p = '\0';

		/* go past delimiter if present */
		if (*arg2)
			*arg2++ = '\0';
		while (*arg2 && isspace(*arg2))
			arg2++;

		switch (command[0]) {
		case '@':
			switch (command[1]) {
			case 'a':
			case 'A':
				/* @action, @armageddon, @attach */
				switch (command[2]) {
				case 'c':
				case 'C':
					Matched("@action");
					NOGUEST("@action", player);
					BUILDERONLY("@action", player);
					do_action(descr, player, arg1, arg2);
					break;
				case 'r':
				case 'R':
					if (strcmp(command, "@armageddon"))
						goto bad;
/*
					WIZARDONLY("@armageddon", player);
					PLAYERONLY("@armageddon", player);
*/
					do_armageddon(player, full_command);
					break;
				case 't':
				case 'T':
					Matched("@attach");
					NOGUEST("@attach", player);
					BUILDERONLY("@attach", player);
					do_attach(descr, player, arg1, arg2);
					break;
				default:
					goto bad;
				}
				break;
			case 'b':
			case 'B':
				/* @bless, @boot */
				switch (command[2]) {
				case 'l':
				case 'L':
					Matched("@bless");
					WIZARDONLY("@bless", player);
					PLAYERONLY("@bless", player);
					NOFORCE("@bless", force_level, player);
					do_bless(descr, player, arg1, arg2);
					break;
				case 'o':
				case 'O':
					Matched("@boot");
					WIZARDONLY("@boot", player);
					PLAYERONLY("@boot", player);
					do_boot(player, arg1);
					break;
				default:
					goto bad;
				}
				break;
			case 'c':
			case 'C':
				/* @chlock, @chown, @chown_lock, @clone,
				   @conlock, @contents, @create, @credits */
				switch (command[2]) {
				case 'h':
				case 'H':
					switch (command[3]) {
					case 'l':
					case 'L':
						Matched("@chlock");
						NOGUEST("@chlock", player);
						set_standard_lock(descr, player, arg1, MESGPROP_CHLOCK, "Chown Lock", arg2);
						break;
					case 'o':
					case 'O':
						if(strlen(command) < 7) {
							Matched("@chown");
							do_chown(descr, player, arg1, arg2);
						} else {
							Matched("@chown_lock");
							NOGUEST("@chown_lock", player);
							set_standard_lock(descr, player, arg1, MESGPROP_CHLOCK, "Chown Lock", arg2);
						}
						break;
					default:
						goto bad;
					}
					break;
				case 'l':
				case 'L':
					Matched("@clone");
					NOGUEST("@clone", player);
					BUILDERONLY("@clone", player);
					do_clone(descr, player, arg1);
					break;
				case 'o':
				case 'O':
					switch (command[4]) {
					case 'l':
					case 'L':
						Matched("@conlock");
						NOGUEST("@conlock", player);
						set_standard_lock(descr, player, arg1, MESGPROP_CONLOCK, "Container Lock", arg2);
						break;
					case 't':
					case 'T':
						Matched("@contents");
						do_contents(descr, player, arg1, arg2);
						break;
					default:
						goto bad;
					}
					break;
				case 'r':
				case 'R':
					if (string_compare(command, "@credits")) {
						Matched("@create");
						NOGUEST("@create", player);
						BUILDERONLY("@create", player);
						do_create(player, arg1, arg2);
					} else {
						do_credits(player);
					}
					break;
				default:
					goto bad;
				}
				break;
			case 'd':
			case 'D':
				/* @dbginfo, @describe, @dig, @doing,
				   @drop, @dump */
				switch (command[2]) {
#ifdef DISKBASE
				case 'b':
				case 'B':
					Matched("@dbginfo");
					WIZARDONLY("@dbginfo", player);
					diskbase_debug(player);
					break;
#endif
				case 'e':
				case 'E':
					Matched("@describe");
					NOGUEST("@describe", player);
					set_standard_property(descr, player, arg1, MESGPROP_DESC, "Object Description", arg2);
					break;
				case 'i':
				case 'I':
					Matched("@dig");
					NOGUEST("@dig", player);
					BUILDERONLY("@dig", player);
					do_dig(descr, player, arg1, arg2);
					break;
				case 'o':
				case 'O':
					Matched("@doing");
					if (!tp_who_doing)
						goto bad;
					NOGUEST("@doing", player);
					set_standard_property(descr, player, arg1, MESGPROP_DOING, "Doing", arg2);
					break;
				case 'r':
				case 'R':
					Matched("@drop");
					NOGUEST("@drop", player);
					set_standard_property(descr, player, arg1, MESGPROP_DROP, "Drop Message", arg2);
					break;
				case 'u':
				case 'U':
					Matched("@dump");
					WIZARDONLY("@dump", player);
					PLAYERONLY("@dump", player);
					do_dump(player, full_command);
					break;
				default:
					goto bad;
				}
				break;
			case 'e':
			case 'E':
				/* @edit, @entrances, @examine */
				switch (command[2]) {
				case 'd':
				case 'D':
					Matched("@edit");
					NOGUEST("@edit", player);
					PLAYERONLY("@edit", player);
					MUCKERONLY("@edit", player);
					do_edit(descr, player, arg1);
					break;
				case 'n':
				case 'N':
					Matched("@entrances");
					do_entrances(descr, player, arg1, arg2);
					break;
				case 'x':
				case 'X':
					Matched("@examine");
					GODONLY("@examine", player);
					sane_dump_object(player, arg1);
					break;
				default:
					goto bad;
				}
				break;
			case 'f':
			case 'F':
				/* @fail, @find, @flock, @force, @force_lock */
				switch (command[2]) {
				case 'a':
				case 'A':
					Matched("@fail");
					NOGUEST("@fail", player);
					set_standard_property(descr, player, arg1, MESGPROP_FAIL, "Fail Message", arg2);
					break;
				case 'i':
				case 'I':
					Matched("@find");
					do_find(player, arg1, arg2);
					break;
				case 'l':
				case 'L':
					Matched("@flock");
					NOGUEST("@flock", player);
					NOFORCE("@flock", force_level, player);
					set_standard_lock(descr, player, arg1, MESGPROP_FLOCK, "Force Lock", arg2);
					break;
				case 'o':
				case 'O':
					if(strlen(command) < 7) {
						Matched("@force");
						do_force(descr, player, arg1, arg2);
					} else {
						Matched("@force_lock");
						NOGUEST("@force_lock", player);
						NOFORCE("@force_lock", force_level, player);
						set_standard_lock(descr, player, arg1, MESGPROP_FLOCK, "Force Lock", arg2);
					}
					break;
				default:
					goto bad;
				}
				break;
			case 'h':
			case 'H':
				/* @hashes */
				Matched("@hashes");
				do_hashes(player, arg1);
				break;
			case 'i':
			case 'I':
				/* @idescribe */
				Matched("@idescribe");
				NOGUEST("@idescribe", player);
				set_standard_property(descr, player, arg1, MESGPROP_IDESC, "Inside Description", arg2);
				break;
			case 'k':
			case 'K':
				/* @kill */
				Matched("@kill");
				do_dequeue(descr, player, arg1);
				break;
			case 'l':
			case 'L':
				/* @link, @list, @lock */
				switch (command[2]) {
				case 'i':
				case 'I':
					switch (command[3]) {
					case 'n':
					case 'N':
						Matched("@link");
						NOGUEST("@link", player);
						do_link(descr, player, arg1, arg2);
						break;
					case 's':
					case 'S':
						Matched("@list");
						match_and_list(descr, player, arg1, arg2);
						break;
					default:
						goto bad;
					}
					break;
				case 'o':
				case 'O':
					Matched("@lock");
					NOGUEST("@lock", player);
					set_standard_lock(descr, player, arg1, MESGPROP_LOCK, "Lock", arg2);
					break;
				default:
					goto bad;
				}
				break;
			case 'm':
			case 'M':
				/* @mcpedit, @mcpprogram, @memory, @mpitops,
				   @muftops */
				switch (command[2]) {
#ifdef MCP_SUPPORT
				case 'c':
				case 'C':
					if (string_prefix("@mcpedit", command)) {
						Matched("@mcpedit");
						NOGUEST("@mcpedit", player);
						PLAYERONLY("@mcpedit", player);
						MUCKERONLY("@mcpedit", player);
						do_mcpedit(descr, player, arg1);
						break;
					} else {
						Matched("@mcpprogram");
						NOGUEST("@mcpprogram", player);
						PLAYERONLY("@mcpprogram", player);
						MUCKERONLY("@mcpprogram", player);
						do_mcpprogram(descr, player, arg1);
						break;
					}
#endif
#ifndef NO_MEMORY_COMMAND
				case 'e':
				case 'E':
					Matched("@memory");
					WIZARDONLY("@memory", player);
					do_memory(player);
					break;
#endif
				case 'p':
			    case 'P':
			        Matched("@mpitops");
				WIZARDONLY("@mpitops", player);
			        do_mpi_topprofs(player, arg1);
			        break;
			    case 'u':
			    case 'U':
			        Matched("@muftops");
				WIZARDONLY("@muftops", player);
			        do_muf_topprofs(player, arg1);
			        break;
				default:
					goto bad;
				}
				break;
			case 'n':
			case 'N':
				/* @name, @newpassword */
				switch (command[2]) {
				case 'a':
				case 'A':
					Matched("@name");
					NOGUEST("@name", player);
					do_name(descr, player, arg1, arg2);
					break;
				case 'e':
				case 'E':
					if (strcmp(command, "@newpassword"))
						goto bad;
					WIZARDONLY("@newpassword", player);
					PLAYERONLY("@newpassword", player);
					do_newpassword(player, arg1, arg2);
					break;
				default:
					goto bad;
				}
				break;
			case 'o':
			case 'O':
				/* @odrop, @oecho, @ofail, @open, @osuccess,
				   @owned */
				switch (command[2]) {
				case 'd':
				case 'D':
					Matched("@odrop");
					NOGUEST("@odrop", player);
					set_standard_property(descr, player, arg1, MESGPROP_ODROP, "ODrop Message", arg2);
					break;
				case 'e':
				case 'E':
					Matched("@oecho");
					NOGUEST("@oecho", player);
					set_standard_property(descr, player, arg1, MESGPROP_OECHO, "Outside-echo Prefix", arg2);
					break;
				case 'f':
				case 'F':
					Matched("@ofail");
					NOGUEST("@ofail", player);
					set_standard_property(descr, player, arg1, MESGPROP_OFAIL, "OFail Message", arg2);
					break;
				case 'p':
				case 'P':
					Matched("@open");
					NOGUEST("@open", player);
					BUILDERONLY("@open", player);
					do_open(descr, player, arg1, arg2);
					break;
				case 's':
				case 'S':
					Matched("@osuccess");
					NOGUEST("@osuccess", player);
					set_standard_property(descr, player, arg1, MESGPROP_OSUCC, "OSuccess Message", arg2);
					break;
				case 'w':
				case 'W':
					Matched("@owned");
					do_owned(player, arg1, arg2);
					break;
				default:
					goto bad;
				}
				break;
			case 'p':
			case 'P':
				/* @password, @pcreate, @pecho, @program, 
				   @propset, @ps */
				switch (command[2]) {
				case 'a':
				case 'A':
					Matched("@password");
					PLAYERONLY("@password", player);
					NOGUEST("@password", player);
					do_password(player, arg1, arg2);
					break;
				case 'c':
				case 'C':
					Matched("@pcreate");
					WIZARDONLY("@pcreate", player);
					PLAYERONLY("@pcreate", player);
					do_pcreate(player, arg1, arg2);
					break;
				case 'e':
				case 'E':
					Matched("@pecho");
					NOGUEST("@pecho", player);
					set_standard_property(descr, player, arg1, MESGPROP_PECHO, "Puppet-echo Prefix", arg2);
					break;
				case 'r':
				case 'R':
					if (string_prefix("@program", command)) {
						Matched("@program");
						NOGUEST("@program", player);
						PLAYERONLY("@program", player);
						MUCKERONLY("@program", player);
						do_prog(descr, player, arg1);
						break;
					} else {
						Matched("@propset");
						NOGUEST("@propset", player);
						do_propset(descr, player, arg1, arg2);
						break;
					}
				case 's':
				case 'S':
					Matched("@ps");
					list_events(player);
					break;
				default:
					goto bad;
				}
				break;
			case 'r':
			case 'R':
				/* @recycle, @reconfiguressl, @relink, @restart, @restrict */
				switch (command[3]) {
				case 'c':
				case 'C':
#ifdef USE_SSL
                                        if (!strcmp(command, "@reconfiguressl")) {
                                                WIZARDONLY("@reconfiguressl", player);
                                                PLAYERONLY("@reconfiguressl", player);
                                                do_reconfigure_ssl(player);
                                                break;
                                        }
#endif
                                        Matched("@recycle");
                                        NOGUEST("@recycle", player);
                                        do_recycle(descr, player, arg1);
                                        break;
				case 'l':
				case 'L':
					Matched("@relink");
					NOGUEST("@relink", player);
					do_relink(descr, player, arg1, arg2);
					break;
				case 's':
				case 'S':
					if (!strcmp(command, "@restart")) {
/*
						WIZARDONLY("@restart", player);
						PLAYERONLY("@restart", player);
*/
						do_restart(player);
					} else if (!strcmp(command, "@restrict")) {
						WIZARDONLY("@restrict", player);
						PLAYERONLY("@restrict", player);
						do_restrict(player, arg1);
					} else {
						goto bad;
					}
					break;
				default:
					goto bad;
				}
				break;
			case 's':
			case 'S':
				/* @sanity, @sanchange, @sanfix, @set,
				   @shutdown, @stats, @success, @sweep */
				switch (command[2]) {
				case 'a':
				case 'A':
					if (!strcmp(command, "@sanity")) {
						GODONLY("@sanity", player);
						sanity(player);
					} else if (!strcmp(command, "@sanchange")) {
						GODONLY("@sanchange", player);
						sanechange(player, full_command);
					} else if (!strcmp(command, "@sanfix")) {
						GODONLY("@sanfix", player);
						sanfix(player);
					} else {
						goto bad;
					}
					break;
				case 'e':
				case 'E':
					Matched("@set");
					NOGUEST("@set", player);
					do_set(descr, player, arg1, arg2);
					break;
				case 'h':
				case 'H':
					if (strcmp(command, "@shutdown"))
						goto bad;
/*
					WIZARDONLY("@shutdown", player);
					PLAYERONLY("@shutdown", player);
*/
					do_shutdown(player);
					break;
				case 't':
				case 'T':
					Matched("@stats");
					do_stats(player, arg1);
					break;
				case 'u':
				case 'U':
					Matched("@success");
					NOGUEST("@success", player);
					set_standard_property(descr, player, arg1, MESGPROP_SUCC, "Success Message", arg2);
					break;
				case 'w':
				case 'W':
					Matched("@sweep");
					do_sweep(descr, player, arg1);
					break;
				default:
					goto bad;
				}
				break;
			case 't':
			case 'T':
				/* @teleport, @toad, @trace, @tune */
				switch (command[2]) {
				case 'e':
				case 'E':
					Matched("@teleport");
					do_teleport(descr, player, arg1, arg2);
					break;
				case 'o':
				case 'O':
					if (!strcmp(command, "@toad")) {
						WIZARDONLY("@toad", player);
						PLAYERONLY("@toad", player);
						do_toad(descr, player, arg1, arg2);
					} else if (!strcmp(command, "@tops")) {
						WIZARDONLY("@tops", player);
						do_all_topprofs(player, arg1);
					} else {
						goto bad;
					}
					break;
				case 'r':
				case 'R':
					Matched("@trace");
					do_trace(descr, player, arg1, atoi(arg2));
					break;
				case 'u':
				case 'U':
					Matched("@tune");
					WIZARDONLY("@tune", player);
					PLAYERONLY("@tune", player);
					do_tune(player, arg1, arg2, !!strchr(full_command, ARG_DELIMITER));
					break;
				default:
					goto bad;
				}
				break;
			case 'u':
			case 'U':
				/* @unbless, @unlink, @unlock, @uncompile,
				   @usage */
				switch (command[2]) {
				case 'N':
				case 'n':
					if (string_prefix(command, "@unb")) {
						Matched("@unbless");
						WIZARDONLY("@unbless", player);
						PLAYERONLY("@unbless", player);
						NOFORCE("@unbless", force_level, player);
						do_unbless(descr, player, arg1, arg2);
					} else if (string_prefix(command, "@unli")) {
						Matched("@unlink");
						NOGUEST("@unlink", player);
						do_unlink(descr, player, arg1);
					} else if (string_prefix(command, "@unlo")) {
						Matched("@unlock");
						NOGUEST("@unlock", player);
						set_standard_lock(descr, player, arg1, MESGPROP_LOCK, "Lock", "");
					} else if (string_prefix(command, "@uncom")) {
						Matched("@uncompile");
						WIZARDONLY("@uncompile", player);
						PLAYERONLY("@uncompile", player);
						do_uncompile(player);
					} else {
						goto bad;
					}
					break;
#ifndef NO_USAGE_COMMAND
				case 'S':
				case 's':
					Matched("@usage");
					WIZARDONLY("@usage", player);
					do_usage(player);
					break;
#endif
				default:
					goto bad;
					break;
				}
				break;
			case 'v':
			case 'V':
				/* @version */
				Matched("@version");
				do_version(player);
				break;
			case 'w':
			case 'W':
				/* @wall */
				if (strcmp(command, "@wall"))
					goto bad;
				WIZARDONLY("@wall", player);
				PLAYERONLY("@wall", player);
				do_wall(player, full_command);
				break;
			default:
				goto bad;
			}
			break;
		case 'd':
		case 'D':
			/* disembark, drop */
			switch (command[1]) {
			case 'i':
			case 'I':
				Matched("disembark");
				do_leave(descr, player);
				break;
			case 'r':
			case 'R':
				Matched("drop");
				do_drop(descr, player, arg1, arg2);
				break;
			default:
				goto bad;
			}
			break;
		case 'e':
		case 'E':
			/* examine */
			Matched("examine");
			do_examine(descr, player, arg1, arg2);
			break;
		case 'g':
		case 'G':
			/* get, give, goto, gripe */
			switch (command[1]) {
			case 'e':
			case 'E':
				Matched("get");
				do_get(descr, player, arg1, arg2);
				break;
			case 'i':
			case 'I':
				Matched("give");
				do_give(descr, player, arg1, atoi(arg2));
				break;
			case 'o':
			case 'O':
				Matched("goto");
				do_move(descr, player, arg1, 0);
				break;
			case 'r':
			case 'R':
				if (string_compare(command, "gripe"))
					goto bad;
				do_gripe(player, full_command);
				break;
			default:
				goto bad;
			}
			break;
		case 'h':
		case 'H':
			/* help */
			Matched("help");
			do_help(player, arg1, arg2);
			break;
		case 'i':
		case 'I':
			/* inventory, info */
			if (string_compare(command, "info")) {
				Matched("inventory");
				do_inventory(player);
			} else {
				Matched("info");
				do_info(player, arg1, arg2);
			}
			break;
		case 'k':
		case 'K':
			/* kill */
			Matched("kill");
			do_kill(descr, player, arg1, atoi(arg2));
			break;
		case 'l':
		case 'L':
			/* leave, look */
			if (string_prefix("look", command)) {
				Matched("look");
				do_look_at(descr, player, arg1, arg2);
				break;
			} else {
				Matched("leave");
				do_leave(descr, player);
				break;
			}
		case 'm':
		case 'M':
			/* man, motd, move, mpi */
			if (string_prefix(command, "move")) {
				do_move(descr, player, arg1, 0);
				break;
			} else if (!string_compare(command, "motd")) {
				do_motd(player, full_command);
				break;
			} else if (!string_compare(command, "mpi")) {
				do_mpihelp(player, arg1, arg2);
				break;
			} else {
				if (string_compare(command, "man"))
					goto bad;
				do_man(player, (!*arg1 && !*arg2 && arg1 != arg2) ? "=" : arg1, arg2);
			}
			break;
		case 'n':
		case 'N':
			/* news */
			Matched("news");
			do_news(player, arg1, arg2);
			break;
		case 'p':
		case 'P':
			/* page, pose, put */
			switch (command[1]) {
			case 'a':
			case 'A':
				Matched("page");
				do_page(player, arg1, arg2);
				break;
			case 'o':
			case 'O':
				Matched("pose");
				do_pose(player, full_command);
				break;
			case 'u':
			case 'U':
				Matched("put");
				do_drop(descr, player, arg1, arg2);
				break;
			default:
				goto bad;
			}
			break;
		case 'r':
		case 'R':
			/* read, rob */
			switch (command[1]) {
			case 'e':
			case 'E':
				Matched("read");	/* undocumented alias for look */
				do_look_at(descr, player, arg1, arg2);
				break;
			case 'o':
			case 'O':
				Matched("rob");
				do_rob(descr, player, arg1);
				break;
			default:
				goto bad;
			}
			break;
		case 's':
		case 'S':
			/* say, score */
			switch (command[1]) {
			case 'a':
			case 'A':
				Matched("say");
				do_say(player, full_command);
				break;
			case 'c':
			case 'C':
				Matched("score");
				do_score(player);
				break;
			default:
				goto bad;
			}
			break;
		case 't':
		case 'T':
			/* take, throw */
			switch (command[1]) {
			case 'a':
			case 'A':
				Matched("take");
				do_get(descr, player, arg1, arg2);
				break;
			case 'h':
			case 'H':
				Matched("throw");
				do_drop(descr, player, arg1, arg2);
				break;
			default:
			goto bad;
			}
			break;
		case 'w':
		case 'W':
			/* whisper */
			Matched("whisper");
			do_whisper(descr, player, arg1, arg2);
			break;
		default:
		  bad:
			if (tp_m3_huh != 0)
			{
				char hbuf[BUFFER_LEN];
				snprintf(hbuf,BUFFER_LEN,"HUH? %s", command);
				if(can_move(descr, player, hbuf, 3)) {
					do_move(descr, player, hbuf, 3);
					*match_args = 0;
					*match_cmdname = 0;
					break;
				}
			}	
			notify(player, tp_huh_mesg);
			if (tp_log_failed_commands && !controls(player, LOCATION(player))) {
				log_status("HUH from %s(%d) in %s(%d)[%s]: %s %s",
						   NAME(player), player, NAME(LOCATION(player)),
						   LOCATION(player),
						   NAME(OWNER(LOCATION(player))), command, full_command);
			}
			break;
		}
	}

	/* calculate time command took. */
	gettimeofday(&endtime, NULL);
	if (starttime.tv_usec > endtime.tv_usec) {
		endtime.tv_usec += 1000000;
		endtime.tv_sec -= 1;
	}
	endtime.tv_usec -= starttime.tv_usec;
	endtime.tv_sec -= starttime.tv_sec;

	totaltime = endtime.tv_sec + (endtime.tv_usec * 1.0e-6);
	if (totaltime > (tp_cmd_log_threshold_msec / 1000.0)) {
		log2file(LOG_CMD_TIMES, "%6.3fs, %.16s: %s: %s",
					totaltime, ctime((time_t *)&starttime.tv_sec),
					whowhere(player), command);
	}
}
Exemple #29
0
void hunt_victim( CHAR_DATA *ch )
{
	CHAR_DATA *tmp;
	int        dir,chance;
	bool       found;

    if ( !ch || !ch->hunting )
    {
        return;
    }
    /*
     * Make sure the victim still exists.
     */
    for ( found = FALSE, tmp = char_list; tmp && !found; tmp = tmp->next )
    {
        if ( ch->hunting == tmp )
        {
            found = TRUE;
        }
    }

    if ( !can_move( ch) || !found || !can_see( ch, ch->hunting ) )
    {
        stop_hunting( ch );
        return;
    }


    if ( ch->in_room == ch->hunting->in_room )
    {
        if ( ch->fighting )
            return;

        found_prey( ch, ch->hunting );
        return;
    }

    if ( !IS_NPC ( ch ) )
    {
        WAIT_STATE( ch, skill_table[gsn_track].beats );
    }
	dir = find_path( ch->in_room->vnum, ch->hunting->in_room->vnum, ch, -40000, TRUE );

	if ( dir < 0 || dir >= MAX_DIR )
	{
	stop_hunting( ch );
	return;
	}

	/*
	* Give a random direction if the mob misses the die roll.
    *
    * 20% for PC
    *  2% for NPC
	*/
    chance = IS_NPC ( ch ) ? 2 : 20;
    if ( number_percent( ) < chance + 1 )
    {
        do
        {
            dir = number_door( );
        }
        while (   !( ch->in_room->exit[dir] )
                || !( ch->in_room->exit[dir]->u1.to_room ) );
    }


	if ( IS_SET(ch->in_room->exit[dir]->exit_info, EX_SECRET) &&
		!IS_SET(ch->in_room->exit[dir]->exit_info, EX_HIDDEN) &&
        IS_AFFECTED(ch, AFF_DETECT_HIDDEN) )
    {
        //	do_secret(ch, (char *)dir_name[dir]);
        return;
    }

	if ( IS_SET( ch->in_room->exit[dir]->exit_info, EX_CLOSED ) )
	{
	do_open( ch, (char *) dir_name[dir] );
	return;
	}

	if(	IS_SET(sector_table[ch->in_room->exit[dir]->u1.to_room->sector_type].flag, SECT_UNDERWATER)
	||	IS_SET(ch->in_room->exit[dir]->exit_info, EX_NO_MOB)
	||	EXT_IS_SET(ch->in_room->exit[dir]->u1.to_room->room_flags, ROOM_NO_MOB)
	||  ( EXT_IS_SET(ch->act, ACT_STAY_AREA)
		&&   ch->in_room->exit[dir]->u1.to_room->area != ch->in_room->area )
	||	( EXT_IS_SET(ch->act, ACT_STAY_SECTOR)
		&&  ch->in_room->exit[dir]->u1.to_room->sector_type != ch->in_room->sector_type )
	||	( EXT_IS_SET(ch->act, ACT_OUTDOORS)
	&&   EXT_IS_SET(ch->in_room->exit[dir]->u1.to_room->room_flags,ROOM_INDOORS))
	||	( EXT_IS_SET(ch->act, ACT_INDOORS)
	&&   EXT_IS_SET(ch->in_room->exit[dir]->u1.to_room->room_flags,ROOM_INDOORS)))
		return;

	move_char( ch, dir, FALSE, NULL );

	if ( !ch->hunting )
	{
	if ( !ch->in_room )
	{
		char buf [ MAX_STRING_LENGTH ];

		sprintf( buf, "Hunt_victim: no ch->in_room!  Mob #%d, name: %s.  Placing mob in limbo (char_to_room).",
			ch->pIndexData->vnum, ch->name );
		bug( buf, 0 );
		char_to_room( ch, get_room_index( ROOM_VNUM_LIMBO ) );
		return;
	}
	return;
	}

	if ( ch->in_room == ch->hunting->in_room )
	found_prey( ch, ch->hunting );

	return;
}
Exemple #30
0
/*==========================================
 * path探索 (x0,y0)->(x1,y1)
 *------------------------------------------
 */
int path_search(struct walkpath_data *wpd,int m,int x0,int y0,int x1,int y1,int flag)
{
	int heap[MAX_HEAP+1];
	struct tmp_path tp[MAX_WALKPATH*MAX_WALKPATH];
	int i,rp,x,y;
	struct map_data *md;
	int dx,dy;

	if(!map[m].gat)
		return -1;
	md=&map[m];
	if(x1<0 || x1>=md->xs || y1<0 || y1>=md->ys || (i=read_gatp(md,x1,y1))==1 || i==5)
		return -1;

	// easy
	dx = (x1-x0<0) ? -1 : 1;
	dy = (y1-y0<0) ? -1 : 1;
	for(x=x0,y=y0,i=0;x!=x1 || y!=y1;){
		if(i>=sizeof(wpd->path))
			return -1;
		if(x!=x1 && y!=y1){
			if(!can_move(md,x,y,x+dx,y+dy,flag))
				break;
			x+=dx;
			y+=dy;
			wpd->path[i++]=(dx<0) ? ((dy>0)? 1 : 3) : ((dy<0)? 5 : 7);
		} else if(x!=x1){
			if(!can_move(md,x,y,x+dx,y   ,flag))
				break;
			x+=dx;
			wpd->path[i++]=(dx<0) ? 2 : 6;
		} else { // y!=y1
			if(!can_move(md,x,y,x   ,y+dy,flag))
				break;
			y+=dy;
			wpd->path[i++]=(dy>0) ? 0 : 4;
		}
		if(x==x1 && y==y1){
			wpd->path_len=i;
			wpd->path_pos=0;
			wpd->path_half=0;
			return 0;
		}
	}
	if(flag&1)
		return -1;

	memset(tp,0,sizeof(tp));

	i=calc_index(x0,y0);
	tp[i].x=x0;
	tp[i].y=y0;
	tp[i].dist=0;
	tp[i].dir=0;
	tp[i].before=0;
	tp[i].cost=calc_cost(&tp[i],x1,y1);
	tp[i].flag=0;
	heap[0]=0;
	push_heap_path(heap,tp,calc_index(x0,y0));
	while(1){
		int e=0,fromdir;

		if(heap[0]==0)
			return -1;
		rp=pop_heap_path(heap,tp);
		x=tp[rp].x;
		y=tp[rp].y;
		if(x==x1 && y==y1){
			int len,j;

			for(len=0,i=rp;len<100 && i!=calc_index(x0,y0);i=tp[i].before,len++);
			if(len==100 || len>=sizeof(wpd->path))
				return -1;
			wpd->path_len=len;
			wpd->path_pos=0;
			wpd->path_half=0;
			for(i=rp,j=len-1;j>=0;i=tp[i].before,j--)
				wpd->path[j]=tp[i].dir;

			return 0;
		}
		fromdir=tp[rp].dir;
		if(can_move(md,x,y,x+1,y-1,flag))
			e+=add_path(heap,tp,x+1,y-1,tp[rp].dist+14,5,rp,x1,y1);
		if(can_move(md,x,y,x+1,y  ,flag))
			e+=add_path(heap,tp,x+1,y  ,tp[rp].dist+10,6,rp,x1,y1);
		if(can_move(md,x,y,x+1,y+1,flag))
			e+=add_path(heap,tp,x+1,y+1,tp[rp].dist+14,7,rp,x1,y1);
		if(can_move(md,x,y,x  ,y+1,flag))
			e+=add_path(heap,tp,x  ,y+1,tp[rp].dist+10,0,rp,x1,y1);
		if(can_move(md,x,y,x-1,y+1,flag))
			e+=add_path(heap,tp,x-1,y+1,tp[rp].dist+14,1,rp,x1,y1);
		if(can_move(md,x,y,x-1,y  ,flag))
			e+=add_path(heap,tp,x-1,y  ,tp[rp].dist+10,2,rp,x1,y1);
		if(can_move(md,x,y,x-1,y-1,flag))
			e+=add_path(heap,tp,x-1,y-1,tp[rp].dist+14,3,rp,x1,y1);
		if(can_move(md,x,y,x  ,y-1,flag))
			e+=add_path(heap,tp,x  ,y-1,tp[rp].dist+10,4,rp,x1,y1);
		tp[rp].flag=1;
		if(e || heap[0]>=MAX_HEAP-5)
			return -1;
	}
	return -1;
}