Exemplo n.º 1
0
void pickPiece(int col, int row){
    Piece* piece = piece_at(col,row);
    if(piece != NULL){
        if((piece->color == BLACK && gamestate == BLACK_TURN) || (piece->color == WHITE && gamestate == WHITE_TURN)){

            if(piece == selected_piece){
                for(int j = 0; j <= pieces.size()-1; j++){
                    pieces.at(j)->unpick();
                }
                selected_piece = NULL;

                for(int i = 0; i < 56; i++)
                    for(int j = 0; j < 2; j++)
                        highlighted_tiles[i][j] = 0;
                }
                else{
                    for(int j = 0; j <= pieces.size()-1; j++){
                        pieces.at(j)->unpick();
                    }
                    piece->pick();
                    selected_piece = piece;
                }
            }
        }
    }
Exemplo n.º 2
0
AIMoves *ai_marks(const Board *b, PIECE min)
{
    AIMoves *moves = aimoves_new();
    AIMove move;
    PIECE p;

    for (move.y = 0; move.y < board_size; move.y++)
        for (move.x = 0; move.x < board_size; move.x++)
            if ((p = piece_at(b, move.x, move.y)) >= min) {
                move.weight = p - PIECE_THREAT0;
                aimoves_set(moves, &move);
            }
    return moves;
}
Exemplo n.º 3
0
AIMoves *ai_random(const Board *b)
/* Returns a list of all empty tiles */
{
    AIMove move;
    AIMoves *moves;

    moves = aimoves_new();
    for (move.y = 0; move.y < board_size; move.y++)
        for (move.x = 0; move.x < board_size; move.x++)
            if (piece_empty(piece_at(b, move.x, move.y))) {
                move.weight =
                    g_random_int_range(AIW_MIN, AIW_MAX);
                aimoves_append(moves, &move);
            }
    return moves;
}
Exemplo n.º 4
0
static gboolean is_adjacent(const Board *b, BCOORD x, BCOORD y, int dist)
{
    int dx, dy, count;
    PIECE p;

    if (!piece_empty(piece_at(b, x, y)))
        return FALSE;
    for (dy = -1; dy < 2; dy++)
        for (dx = -1; dx < 2; dx++) {
            if (!dx && !dy)
                continue;
            count = count_pieces(b, x, y, PIECE_NONE, dx, dy, &p);
            if (count - 1 < dist && p != PIECE_NONE)
                return TRUE;
        }
    return FALSE;
}
Exemplo n.º 5
0
bool can_castle(string input, unordered_map< string, string > *board, struct PlayerStatus &player_ps)
//if can successfully castle, updates board and returns true; returns false otherwise
{
	char player = piece_at(board, to_cart(player_ps.k_pos))[0];
	int row = (player == 'W')? 1:8;
	vector<int> king_start {5,row};
	vector<int> rook_start, rook_end, king_end;		
	if (input == "0-0"){ //king-side castling
		if (!player_ps.castle_k_side)
			return false;
		vector<int> rook_start {8,row};
		vector<int> rook_end {6,row};
		vector<int> king_end {7,row};
	}
	
	else{ //queen-side castling
		vector<int> queen_spot {4, row}; 
		if (!player_ps.castle_q_side || occupied(board, queen_spot))
			return false;
		
		vector<int> rook_start {1,row};
		vector<int> rook_end {4,row};
		vector<int> king_end {3,row};
	}
					
	if (!occupied(board,king_end) && !occupied(board,rook_end)){
		unordered_map<string,string> board2 = unordered_map<string,string>(*board); //make copy of board
		update_board(rook_start, rook_end, &board2);
		update_board(king_start, king_end, &board2);
		
		if (is_king_safe(&board2, player_ps)){
			update_board(rook_start, rook_end, board);
			update_board(king_start, king_end, board);
			
			player_ps.k_pos = to_str(king_end);
			player_ps.castle_k_side = false;
			player_ps.castle_q_side = false;
			return true;
		} 		
	}
	return false;

}
Exemplo n.º 6
0
bool is_legal_move(vector<int> start, vector<int> end, const unordered_map< string, string > *board)
{
	int x1 = start[0], y1= start[1]; // 'start' coordinates
	int x2 = end[0], y2 = end[1]; // 'end' coordinates
	int devX = (x2 - x1 >= 0)? x2-x1: x1-x2; //absolute column deviation
	int devY = (y2 - y1 >= 0)? y2-y1: y1-y2; //absolute row deviation
		
	bool start_in_range = (x1 >= 1) && (x1 <= 8) && (y1 >= 1) && (y1 <= 8); // is valid starting point
	bool end_in_range = (x2 >= 1) && (x2 <= 8) && (y2 >= 1) && (y2 <= 8); // is valid ending point

	if (!(start_in_range && end_in_range)) // position(s) are off the board!
		return false;
	
	char colour = piece_at(board, start)[0];
	char piece = piece_at(board, start)[1];
	vector<int> intermediate;

	if (piece_at(board, end)[0] != colour){ //ending point is not already occupied by you
	
		if (piece == 'P'){ //PAWN
			int sign = (colour == 'W')? 1: -1;
			if( !occupied(board,end) && y2 == y1 + sign && devX == 0){ //standard jump
				return true;
			}
			else if (colour == 'W' && y1 == 2 && y2 == 4 && devX == 0){ //if white's first move, double jump allowed
				vector<int> intermediate {x1,3}; //intermediate position
				if (!occupied(board, end) && !occupied(board,intermediate))
					return true;
			}
			else if (colour == 'B' && y1 == 7 && y2 == 5 && devX == 0){ //if black's first move, double jump allowed
				vector<int> intermediate {x1,6}; //intermediate position
				if (!occupied(board, end) && !occupied(board,intermediate))
					return true;
			}
			else if (occupied(board,end) && y2 == y1 + sign  && devX == 1) //pawn makes a kill
				return true;
		}
		 
		else if (piece == 'R' || piece == 'Q'){ //ROOK/QUEEN
			int sign;			
			if (devY == 0) //no row deviation; moves along row
				sign = (x2 - x1) > 0? 1: -1;
				int j;
				for(j = 1; j < devX; ++j) {
					vector<int> intermediate {x1 + sign*j, y1};  //jth intermediate space
					if (occupied(board, intermediate))
						return false;
                }
				return true;
					
			if (devX == 0) //no column deviation; moves along column
				sign = (y2 - y1) > 0? 1: -1;
				int i;
				for(i = 1; i < devY; ++i) {
					vector<int> intermediate {x1,y1 + sign*i}; //jth intermediate space
					if (occupied(board, intermediate))
						return false;
                }
				return true;
			
		}
		else if (piece == 'N'){ //KNIGHT
			if ( (devY == 2 && devX == 1) || (devY == 1 && devX == 2))
				return true;
		}
		else if (piece == 'B' || piece == 'Q'){ //BISHOP/QUEEN
			if (devX == devY) {//absolute row deviation = absolute column deviation
				int y_sign = (y2 - y1) > 0? 1: -1;
				int x_sign = (x2 - x1) > 0? 1: -1;
				int k;
				
				for (k=1; k < devX; ++k){
					vector<int> intermediate {x1 + (x_sign)*k,y1 + (y_sign)*k}; //kth intermediate space
					if (occupied(board,intermediate))
						return false;
				}
				return true;
			}
		}			
		
		else if (piece == 'K'){ //KING
			if ( devX <= 1 && devY <= 1) //ensures that 'end' is only one move away from 'start'
				return true;
		}
		return false;
	}
	else
		return false;
}
Exemplo n.º 7
0
// does the proposed move put player 'colour' in check?
// **will run after is_legal_move, so proposed move will always be legal**
bool is_king_safe(const unordered_map< string, string > *board, struct PlayerStatus player_ps) 
{
	vector<int> king_pos = to_cart(player_ps.k_pos);
	char player = (piece_at(board, king_pos)[0] == 'W')?'W':'B';
	char opponent = (player == 'W')? 'B': 'W';
	
	int king_x = king_pos[0], king_y = king_pos[1];
	int i;
	string piece;
		
	
	//determine if enemy rook (or queen) is in striking distance
	
	for(i=1; i < 8; ++i){ //searching right
		vector<int> position {king_x + i, king_y};
		if (!((board -> find(to_str(position))) == (board -> end()))) {
			piece = piece_at(board, position);
			if( (piece[0] == opponent) && ( piece[1] == 'R' || piece[1] == 'Q')){ //if piece is an enemy rook or queen
				return false;
			}
		else
			i = 8;
		}
	}
	
	for(i=1; i < 8; ++i){ //searching left
		vector<int> position {king_x - i, king_y};
		if (!((board -> find(to_str(position))) == (board -> end()))) {
			piece = piece_at(board, position);
			if( (piece[0] == opponent) && ( piece[1] == 'R' || piece[1] == 'Q')){ //if piece is an enemy rook or queen
				return false;
			}
		else
			i = 8;
		}
	}
	
	for(i=1; i < 8; ++i){ //searching up
		vector<int> position {king_x, king_y + i};
		if (!((board -> find(to_str(position))) == (board -> end()))) {
			piece = piece_at(board, position);
			if( (piece[0] == opponent) && ( piece[1] == 'R' || piece[1] == 'Q')){ //if piece is an enemy rook or queen
				return false;
			}
		else
			i = 8;
		}
	}
	for(i=1; i < 8; ++i){ //searching down
		vector<int> position {king_x, king_y - i};
		if (!((board -> find(to_str(position))) == (board -> end()))) {
			piece = piece_at(board, position);
			if( (piece[0] == opponent) && ( piece[1] == 'R' || piece[1] == 'Q')){ //if piece is an enemy rook or queen
				return false;
			}
		else
			i = 8;
		}
	}
	
	//determine if enemy bishop (or queen) is in striking distance
	for(i= 1; i < 8; ++i){ //searching right-up direction
		vector<int> position {king_x + i, king_y + i};
		if (!((board -> find(to_str(position))) == (board -> end()))){ 
			piece = piece_at(board,position);
			if( (piece[0] == opponent) && ( piece[1] == 'B' || piece[1] == 'Q')){ //if piece is an enemy bishop or queen
				return false;
			}
		else
			i = 8;
		}
	}
	
	for(i= 1; i < 8; ++i){ //searching right-down direction
		vector<int> position {king_x + i, king_y - i};
		if (!((board -> find(to_str(position))) == (board -> end()))){ 
			piece = piece_at(board,position);
			if( (piece[0] == opponent) && ( piece[1] == 'B' || piece[1] == 'Q')){ //if piece is an enemy bishop or queen
				return false;
			}
		else
			i = 8;
		}
	}
	
	for(i= 1; i < 8; ++i){ //searching left-up direction
		vector<int> position {king_x - i, king_y + i};
		if (!((board -> find(to_str(position))) == (board -> end()))){ 
			piece = piece_at(board,position);
			if( (piece[0] == opponent) && ( piece[1] == 'B' || piece[1] == 'Q')){ //if piece is an enemy bishop or queen
				return false;
			}
		else
			i = 8;
		}
	}
	
	for(i= 1; i < 8; ++i){ //searching left-down direction
		vector<int> position {king_x - i, king_y - i};
		if (!((board -> find(to_str(position))) == (board -> end()))){ //if position is on board (and not where king is)
			piece = piece_at(board,position);
			if( (piece[0] == opponent) && ( piece[1] == 'B' || piece[1] == 'Q')){ //if piece is an enemy bishop or queen
				return false;
			}
		else
			i = 8;
		}
	}
	
	
	//determine if enemy knight is in striking distance
	vector<int> N_positions {king_x - 2,king_y - 1,king_x - 2,
		king_y + 1, king_x + 2, king_y - 1, king_x + 2, king_y + 1,
		king_x - 1, king_y - 2, king_x - 1, king_y + 2, king_x + 1,
		king_y - 2, king_x + 1, king_y + 2};

	for (i = 0; i < 16; i = i+2){
			vector<int> position {N_positions[i], N_positions[i+1]};
			if (!((board -> find(to_str(position))) == (board -> end()) )) {
				piece = piece_at(board,position);
				if ((piece[0] == opponent) && (piece[1] == 'N'))
					return false;
			}
	}
	
	//determine if enemy pawn is in striking distance
	int sign = (player == 'W')? 1 : -1 ;
	vector<int> P_positions {king_x - 1, king_y + sign, king_x + 1, king_y + sign};

	for (i=0; i < 4; i=i+2){
		vector<int> position {P_positions[i], P_positions[i+1]};
		if (!((board -> find(to_str(position))) == (board -> end()))) {
			piece = piece_at(board,position);
			if ((piece[0] == opponent) && (piece[1] == 'P'))
				return false;
		}
	}	

	//determine if enemy king is in striking distance
	vector<int> K_positions {king_x-1,king_y-1,king_x,king_y-1,king_x+1,
		king_y-1,king_x-1,king_y,king_x+1,king_y,king_x-1,king_y+1,king_x,
		king_y+1,king_x+1,king_y+1};

	for (i = 0; i < 16; i = i + 2){
		vector<int> position {K_positions[i], K_positions[i+1]};
		if (!((board -> find(to_str(position))) == (board -> end()) )) {
			piece = piece_at(board,position);
			if ((piece[0] == opponent) && (piece[1] == 'K'))
				return false;
		}
	}
	
	return true;
}
static int threat_window(int x, int y, int dx, int dy,
                         PIECE *ptype, int *pdouble)
{
        int min, max, count = 0;
        PIECE p, type = PIECE_NONE;

        /* Check if this tile is empty */
        p = piece_at(b, x, y);
        if (!piece_empty(p))
                return 0;

        /* Push forward the max and find the window type */
        for (max = 1; max < connect_k; max++) {
                p = piece_at(b, x + dx * max, y + dy * max);
                if (p == PIECE_ERROR)
                        break;
                if (!piece_empty(p)) {
                        if (type == PIECE_NONE)
                                type = p;
                        else if (type != p)
                                break;
                        count++;
                }
        }
        max--;

        /* Try to push the entire window back */
        for (min = -1; min > -connect_k; min--) {
                p = piece_at(b, x + dx * min, y + dy * min);
                if (p == PIECE_ERROR || piece_empty(p))
                        break;
                if (type == PIECE_NONE)
                        type = p;
                else if (type != p)
                        break;
                if (max - min > connect_k - 1) {
                        p = piece_at(b, x + dx * max, y + dy * max);
                        if (p == type)
                                count--;
                        max--;
                }
                count++;
        }
        min++;

        /* Push back min if we haven't formed a complete window, this window
           can't be a double */
        if (max - min < connect_k - 1) {
                for (min--; min > max - connect_k; min--) {
                        p = piece_at(b, x + dx * min, y + dy * min);
                        if (p == PIECE_ERROR)
                                break;
                        if (!piece_empty(p)) {
                                if (type != p)
                                        break;
                                if (type == PIECE_NONE)
                                        type = p;
                                count++;
                        }
                }
                *pdouble = 0;
                min++;
        }

        *ptype = type;
        if (max - min >= connect_k - 1)
                return count;
        return 0;
}
static AIWEIGHT threat_line(int x, int y, int dx, int dy)
{
        int i;
        AIWEIGHT weight = 0;

        /* Mark the maximum threat for each */
        for (i = 0; x >= 0 && x < board_size && y >= 0 && y < board_size; i++) {
                int count[2], tmp, double_threat = 1;
                PIECE type[2];

                count[0] = threat_window(x, y, dx, dy, type, &double_threat);
                count[1] = threat_window(x, y, -dx, -dy, type + 1,
                                         &double_threat);
                if (count[1] > count[0]) {
                        tmp = count[1];
                        count[1] = count[0];
                        count[0] = tmp;
                        tmp = type[1];
                        type[1] = type[0];
                        type[0] = tmp;
                }
                line[i].threat[0] = 0;
                line[i].threat[1] = 0;
                threat_mark(i, count[0], type[0]);
                if (double_threat)
                        threat_mark(i, count[1], type[1]);
                x += dx;
                y += dy;
        }

        /* Commit stored line values to the board */
        x -= dx;
        y -= dy;
        for (i--; x >= 0 && x < board_size && y >= 0 && y < board_size; i--) {
                AIWEIGHT bits[2];
                PIECE p;

                bits[0] = threat_bits(line[i].threat[0], line[i].turn[0]);
                bits[1] = threat_bits(line[i].threat[1], line[i].turn[1]);
                p = piece_at(b, x, y);
                if (piece_empty(p) && line[i].threat[0]) {
                        threat_counts[line[i].threat[0]][line[i].turn[0] - 1]++;
                        if (line[i].threat[1])
                                threat_counts[line[i].threat[1]]
                                             [line[i].turn[1] - 1]++;
                        if (p >= PIECE_THREAT0)
                                place_threat(b, x, y, p - PIECE_THREAT0 +
                                             bits[0] + bits[1]);
                        else
                                place_threat(b, x, y, bits[0] + bits[1]);
                }
                if (b->turn != line[i].turn[0])
                        bits[0] = -bits[0];
                if (b->turn != line[i].turn[1])
                        bits[1] = -bits[1];
                weight += bits[0] + bits[1];
                x -= dx;
                y -= dy;
        }

        return weight;
}