Exemple #1
0
bool abstract_piece::can_i_move(const board &m_board) const
{
    int8_t pieces_in_between = 0;
    bool found_one_g = false;
    bool am_i_in_between = false;
    for (int8_t irank = 0; irank < board::RANK_NUM; irank++) {
        auto piece = m_board.at(pos.file, irank);
        if (piece) {
            if (found_one_g) {
                if (piece->is_king()) {
                    break;
                }
                
                pieces_in_between++;
                if (*piece == *this) {
                    am_i_in_between = true;
                }
            } else if (piece->is_king()) {
                found_one_g = true;
            }
        }
    }
    
    return !am_i_in_between || pieces_in_between != 1;
}
Exemple #2
0
string game::generate_fen(const board &bd)
{
    std::string fen;
    int8_t space = 0;
    for (int8_t rank = board::RANK_NUM - 1; rank >= 0; --rank) {
        for (int8_t file = 0; file < board::FILE_NUM; ++file) {
            auto p = bd.at(file, rank);
            if (p) {
                if (space != 0) {
                    fen.push_back(static_cast<char>(space) + '0');
                    space = 0;
                }
                fen.push_back(p->abbr_name());
            } else {
                space++;
            }
        }
        if (space != 0) {
            fen.push_back(static_cast<char>(space) + '0');
            space = 0;
        }
        fen.push_back('/');
    }
    fen.pop_back();//remove last '/'
    return fen;
}
Exemple #3
0
	//If this move will close any of the surrounding cells
	point will_close_any(const board & board, point idx, border_names border)
	{
		auto orig_idx = idx;
		auto orig_idx2 = idx;
		switch (border)
		{
		case top:    orig_idx2 += point(0, -1); break;
		case left:   orig_idx2 += point(-1, 0); break;
		case right:  orig_idx2 += point(1, 0); break;
		case bottom: orig_idx2 += point(0, 1); break;
		}

		class board copy(board);
		fix_move(idx, border);

		if ((board.at(idx).owner & player_owned) != empty)
			return false;

		copy.place(idx, border);

		point idx2;
		if (border == top)  idx2 = idx + point(0, -1);
		if (border == left) idx2 = idx + point(-1, 0);

		if (border_change(board, copy, orig_idx, 3, 4))
			return orig_idx;

		if (border_change(board, copy, orig_idx2, 3, 4))
			return orig_idx2;

		return point(-1, -1);
	}
Exemple #4
0
	//Fill this move leaves the given cell to be closed on 2 turns
	bool will_remain_with_2lines(const board & board, point idx, border_names border)
	{
		auto orig_idx = idx;
		class board copy(board);
		fix_move(idx, border);

		if ((board.at(idx).owner & player_owned) != empty)
			return false;

		copy.place(idx, border);
		return border_change(board, copy, orig_idx, 1, 2);
	}
Exemple #5
0
bool king::is_flying_king(const position &proposed, const board &m_board) const
{
    int8_t king_rank = -1;

    for (int8_t irank = 0; irank < board::RANK_NUM; irank++) {
        auto p = m_board.at(proposed.file, irank);
        if (p) {
            if (p->is_king()) {
                king_rank = irank;
                break;
            }
        }
    }

    if (king_rank == -1) {//there is no king, don't bother the flying king rule
        return false;
    }

    bool triggered = true;

    if (red_side) {
        for (int8_t irank = proposed.rank + 1; irank < king_rank; irank++) {//proposed.rank is equal to current position's rank
            if (m_board.at(proposed.file, irank)) {
                triggered = false;
                break;
            }
        }
    } else {
        for (int8_t irank = proposed.rank - 1; irank > king_rank; irank--) {
            if (m_board.at(proposed.file, irank)) {
                triggered = false;
                break;
            }
        }
    }

    return triggered;
}
Exemple #6
0
void abstract_piece::remove_invalid_moves(const board &m_board, int8_t min_file, int8_t max_file, int8_t min_rank, int8_t max_rank)
{
    for (auto it = avail_pos.begin(); it != avail_pos.end();) {
        bool invalid = false;
        if (it->not_in_range(min_file, max_file, min_rank, max_rank)) {
            invalid = true;
        } else {
            auto target_piece = m_board.at(*it);
            if (target_piece) {
                //can't capture same-side pieces
                if (target_piece->red_side == this->red_side) {
                    invalid = true;
                }
            }
        }

        if (invalid) {
            it = avail_pos.erase(it);
        } else {
            ++it;
        }
    }
}
Exemple #7
0
//for checking if they won, we can simplify because if we check every turn
//then we *know* that a winning sequence must include that cell
bool check_win(board& b, unsigned x, char id, unsigned to_win) { //x == bin of last move
	unsigned h = b.height();
	unsigned w = b.num_bins();
	unsigned y = 0;
	for (; y < h; ++y) {
		if (b[x][y] == 0) {
			break;
		}
	}
	--y;
	//last move was at x,y
	
	//check row
	if (check_win(range<adapters::horiz_it>(b.at(0, y), b.at(w, y)), id, to_win)) {
		return true;
	}
	
	//check column
	if (check_win(range<adapters::vert_it>(b.at(x, 0), b.at(x, h)), id, to_win)) {
		return true;
	}
	
	//check diagonals
	int intercept;
	int hs = h; //h signed
	int ws = w; //w signed
	unsigned xi;
	unsigned xf;
	unsigned yi;
	unsigned yf;
	
	//up slope:
	intercept = y - x;
	//all of these magic numbers are based off geometry.  I'm not going
	//to prove it, as this is a program, not a proof, but if you want to
	//see it, it's not hard.  My copy is on a receipt somewhere in the
	//trash :/
	if (intercept < 0) {
		xi = (unsigned) -intercept;
		yi = 0;
	}
	else {
		xi = 0;
		yi = (unsigned) intercept;
	}
	if (intercept < hs - ws) {
		xf = w;
		yf = (unsigned)(ws + intercept);
	}
	else {
		xf = (unsigned)(hs - intercept);
		yf = h;
	}
	
	if (check_win(range<adapters::pos_diag_it>(b.at(xi, yi), b.at(xf, yf)), id, to_win)) {
		return true;
	}
	
	//down slope
	//there are some unsigned -1s because i need an invalid index that is
	//= to --0, so the underflow is OK.  It will never be dereferenced.
	intercept = x + y;
	if (intercept < hs) {
		xi = 0;
		yi = (unsigned) intercept;
	}
	else {
		xi = (unsigned)(intercept - hs) + 1;
		yi = h - 1;
	}
	if (intercept < ws) {
		xf = (unsigned) intercept + 1;
		yf = (unsigned) -1;
	}
	else {
		xf = w;
		yf = (unsigned)(intercept - ws);
	}
	
	if (check_win(range<adapters::neg_diag_it>(b.at(xi, yi), b.at(xf, yf)), id, to_win)) {
		return true;
	}
	
	return false;
}