Example #1
0
int				get_next_tetri(int const fd, t_list **head, char letter)
{
	int			ret;
	char		buf[22];
	int			resval;

	ret = read(fd, buf, 21);
	buf[ret] = '\0';
	if (!(resval = is_valid(buf)) && *buf)
		return (0);
	if (ret != 0)
		create_piece(head, buf, letter);
	return (ret);
}
/*
 * Fill the provided list with all pseudolegal captures in the given position.
 */
static int generate_pseudo_captures(const position_t* pos, move_t* moves)
{
    move_t* moves_head = moves;
    color_t side = pos->side_to_move;
    piece_t piece;
    square_t from;
    for (int i = 0; i < pos->num_pieces[side]; ++i) {
        from = pos->pieces[side][i];
        piece = pos->board[from];
        generate_piece_captures(pos, from, piece, &moves);
    }
    piece = create_piece(side, PAWN);
    for (int i=0; i<pos->num_pawns[side]; ++i) {
        from = pos->pawns[side][i];
        generate_pawn_captures(pos, from, piece, &moves);
    }
    *moves = 0;
    return moves-moves_head;
}
/*
 * Add all pseudo-legal non-capturing promotions.
 */
static int generate_promotions(const position_t* pos, move_t* moves)
{
    move_t* moves_head = moves;
    color_t side = pos->side_to_move;
    piece_t piece = create_piece(side, PAWN);
    for (int i = 0; i < pos->num_pawns[side]; ++i) {
        square_t from = pos->pawns[side][i];
        rank_t r_rank = relative_rank[side][square_rank(from)];
        if (r_rank < RANK_7) continue;
        square_t to = from + pawn_push[side];
        if (pos->board[to]) continue;
        for (piece_type_t type=KNIGHT; type<=QUEEN; ++type) {
            moves = add_move(pos,
                    create_move_promote(from, to, piece, EMPTY, type),
                    moves);
        }
    }
    *moves = 0;
    return (moves-moves_head);
}
Example #4
0
static void init_army_pieces( army_type * owner )
{
  unsigned int row = 7*(1-owner->colour);

  // piece[0].Init( this, row, 3, 4 ); ...
  create_piece( owner, row, 3, 4 );           // Queen
  create_piece( owner, row, 0, 3 );           // Rooks
  create_piece( owner, row, 7, 3 );
  create_piece( owner, row, 2, 2 );           // Bishops
  create_piece( owner, row, 5, 2 );
  create_piece( owner, row, 1, 1 );           // Knights
  create_piece( owner, row, 6, 1 );
  create_piece( owner, row, 4, 5 );           // King
  row = 5*(1-owner->colour)+1;
  create_piece( owner, row, 0, 0 );           // Pawns
  create_piece( owner, row, 1, 0 );
  create_piece( owner, row, 2, 0 );
  create_piece( owner, row, 3, 0 );
  create_piece( owner, row, 4, 0 );
  create_piece( owner, row, 5, 0 );
  create_piece( owner, row, 6, 0 );
  create_piece( owner, row, 7, 0 );
} // init_army_pieces()
Example #5
0
static void construct_study( army_type army[] )
{
  char str[10];
  unsigned int i, row, col, pc_num, colour;
  army_type * owner;
  piece_type * pc;

  close_open_book( army->sh );

  // Automatically create the 2 kings,
  // prompting user for coords

  for( i = 0; i < 2; i++ ) {
    owner = &army[i];

    do {
      printf( "Coordinates of %s king: ",
        owner->name );
      scanf( "%s", str );
    } while( !coord_ext_to_int( str, &row, &col )
      ||  !create_piece( owner, row, col, 5 ) );

    if( row != 7*(1-i)  ||  col != 4 ) {
      printf( "Castling disallowed for %s\n", owner->name );
      owner->castle_lost[0] = owner->castle_lost[1] = 0;
    }
  }

  /* Allow creation of extra pieces */

  for( ; ; ) {
    print_board( army );

    for( i = 0; i < NUM_PIECE_DEFS; i++ ) {
      printf( "%d: %s  ", i,
        army->sh->pc_def[i].name );
    }

    printf( "\nCreate which piece (-1 to exit): " );
    scanf( "%d", &pc_num );

    if( pc_num >= NUM_PIECE_DEFS ) break;

    do {
      printf( "Colour (white=%d, black=%d): ",
        O_WHITE, O_BLACK );
      scanf( "%d", &colour );
    } while( colour >= 2 );

    owner = &army[colour];

    if( owner->num_pieces >= MAX_ARMY_SIZE ) {
      printf( "%s already has %d pieces\n",
        owner->name, owner->num_pieces );
      continue;
    }

    do {
      printf( "Coordinates: " );
      scanf( "%s", str );
    } while( !coord_ext_to_int( str, &row, &col )
      ||  !create_piece( owner, row, col, pc_num ) );
  }

  // Check rooks for castling

  for( colour = 0; colour <= 1; colour++ ) {	// Army num
    owner = &army[colour];

    for( i = 0; i <= 1; i++ ) {		// Castle type

      if( owner->castle_lost[i] == 0 ) continue;

      pc = read_board(owner,7*(1-colour),7*(1-i));

      if( pc == NULL  ||  pc->owner != owner
        ||  pc->def->token != ROOK_TOKEN ) {

        printf( "%sside castling disallowed for %s\n",
          (i == 0) ? "King" : "Queen", owner->name );
        owner->castle_lost[i] = 0;
      }
    }
  }
} // construct_study()
/*
 * Generate all moves that evade check in the given position. This is purely
 * legal move generation; no pseudo-legal moves.
 */
int generate_evasions(const position_t* pos, move_t* moves)
{
    assert(pos->is_check && pos->board[pos->check_square]);
    move_t* moves_head = moves;
    color_t side = pos->side_to_move, other_side = side^1;
    square_t king_sq = pos->pieces[side][0];
    square_t check_sq = pos->check_square;
    piece_t king = create_piece(side, KING);
    piece_t checker = pos->board[check_sq];

    // Generate king moves.
    // Don't let the king mask its possible destination squares in calls
    // to is_square_attacked.
    square_t from = king_sq, to = INVALID_SQUARE;
    ((position_t*)pos)->board[king_sq] = EMPTY;
    for (const direction_t* delta = piece_deltas[king]; *delta; ++delta) {
        to = from + *delta;
        piece_t capture = pos->board[to];
        if (capture != EMPTY && !can_capture(king, capture)) continue;
        if (is_square_attacked((position_t*)pos,to,other_side)) continue;
        ((position_t*)pos)->board[king_sq] = king;
        moves = add_move(pos, create_move(from, to, king, capture), moves);
        ((position_t*)pos)->board[king_sq] = EMPTY;
    }
    ((position_t*)pos)->board[king_sq] = king;
    // If there are multiple checkers, only king moves are possible.
    if (pos->is_check > 1) {
        *moves = 0;
        return moves-moves_head;
    }
    
    // First, the most common case: a check that can be evaded via an
    // en passant capture. Note that if we're in check and an en passant
    // capture is available, the only way the en passant capture would evade
    // the check is if it's the newly moved pawn that's checking us.
    direction_t pin_dir;
    if (pos->ep_square != EMPTY &&
            check_sq+pawn_push[side] == pos->ep_square &&
            pos->board[pos->ep_square] == EMPTY) {
        piece_t our_pawn = create_piece(side, PAWN);
        to = pos->ep_square;
        for (int i=0; i<2; ++i) {
            from = to-piece_deltas[our_pawn][i];
            if (pos->board[from] && pos->board[from] == our_pawn) {
                pin_dir = pin_direction(pos, from, king_sq);
                if (pin_dir) continue;
                moves = add_move(pos,
                        create_move_enpassant(from, to, our_pawn, checker),
                        moves);
            }
        }
    }
    // Generate captures of the checker.
    for (int i = 0; i < pos->num_pawns[side]; ++i) {
        from = pos->pawns[side][i];
        piece_t piece = create_piece(side, PAWN);
        pin_dir = pin_direction(pos, from, king_sq);
        if (pin_dir) continue;
        if (!possible_attack(from, check_sq, piece)) continue;
        if (relative_rank[side][square_rank(from)] == RANK_7) {
            // Capture and promote.
            for (piece_t promoted=QUEEN; promoted > PAWN; --promoted) {
                moves = add_move(pos,
                        create_move_promote(from, check_sq, piece,
                            checker, promoted),
                        moves);
            }
        } else {
            moves = add_move(pos,
                    create_move(from, check_sq, piece, checker),
                    moves);
        }
    }
    for (int i = 1; i < pos->num_pieces[side]; ++i) {
        from = pos->pieces[side][i];
        piece_t piece = pos->board[from];
        pin_dir = pin_direction(pos, from, king_sq);
        if (pin_dir) continue;
        if (!possible_attack(from, check_sq, piece)) continue;
        if (piece_slide_type(piece) == NONE) {
            moves = add_move(pos,
                    create_move(from, check_sq, piece, checker),
                    moves);
        } else {
            // A sliding piece, keep going until we hit something.
            direction_t check_dir = direction(from, check_sq);
            for (to=from+check_dir; pos->board[to] == EMPTY; to+=check_dir) {}
            if (to == check_sq) {
                moves = add_move(pos,
                        create_move(from, to, piece, checker),
                        moves);
                continue;
            }
        }
    }
    if (piece_slide_type(checker) == NONE) {
        *moves = 0;
        return moves-moves_head;
    }
    
    // A slider is doing the checking; generate blocking moves.
    direction_t block_dir = direction(check_sq, king_sq);
    for (int i = 0; i < pos->num_pawns[side]; ++i) {
        from = pos->pawns[side][i];
        piece_t piece = create_piece(side, PAWN);
        direction_t k_dir;
        pin_dir = pin_direction(pos, from, king_sq);
        if (pin_dir) continue;
        to = from + pawn_push[side];
        if (pos->board[to] != EMPTY) continue;
        rank_t rank = relative_rank[side][square_rank(from)];
        k_dir = direction(to, king_sq);
        if (k_dir == block_dir &&
                ((king_sq < to && check_sq > to) ||
                 (king_sq > to && check_sq < to))) {
            if (rank == RANK_7) {
                // Block and promote.
                for (piece_t promoted=QUEEN; promoted > PAWN; --promoted) {
                    moves = add_move(pos,
                        create_move_promote(from, to, piece, EMPTY, promoted),
                        moves);
                }
            } else {
                moves = add_move(pos,
                        create_move(from, to, piece, EMPTY),
                        moves);
            }
        }
        if (rank != RANK_2) continue;
        to += pawn_push[side];
        if (pos->board[to]) continue;
        k_dir = direction(to, king_sq);
        if (k_dir == block_dir &&
                ((king_sq < to && check_sq > to) ||
                 (king_sq > to && check_sq < to))) {
            moves = add_move(pos,
                    create_move(from, to, piece, EMPTY),
                    moves);
        }
    }

    for (int i=1; i<pos->num_pieces[side]; ++i) {
        from = pos->pieces[side][i];
        piece_t piece = pos->board[from];
        direction_t k_dir;
        pin_dir = pin_direction(pos, from, king_sq);
        if (pin_dir) continue;
        if (piece_is_type(piece, KNIGHT)) {
            for (const direction_t* delta=piece_deltas[piece];
                    *delta; ++delta) {
                to = from + *delta;
                if (pos->board[to] != EMPTY) continue;
                k_dir = direction(to, king_sq);
                if (k_dir == block_dir &&
                        ((king_sq < to && check_sq > to) ||
                         (king_sq > to && check_sq < to))) {
                    moves = add_move(pos,
                            create_move(from, to, piece, EMPTY),
                            moves);
                }
            }
        } else {
           for (const direction_t* delta=piece_deltas[piece];
                   *delta; ++delta) {
                for (to = from+*delta; pos->board[to] == EMPTY; to+=*delta) {
                    k_dir = direction(to, king_sq);
                    if (k_dir == block_dir &&
                            ((king_sq < to && check_sq > to) ||
                             (king_sq > to && check_sq < to))) {
                        moves = add_move(pos,
                                create_move(from, to, piece, EMPTY),
                                moves);
                        break;
                    }
                }
            }
        }
    }
    *moves = 0;
    return moves-moves_head;
}
/*
 * Generate pseudo-legal moves which are neither captures nor promotions.
 */
int generate_pseudo_quiet_moves(const position_t* pos, move_t* moves)
{
    move_t* moves_head = moves;
    color_t side = pos->side_to_move;
    piece_t piece;
    square_t from;

    // Castling. Castles are considered pseudo-legal if we have appropriate
    // castling rights, the squares between king and rook are unoccupied,
    // and the intermediate square is unattacked. Therefore checking for
    // legality just requires seeing if we're in check afterwards.
    // This is messy for Chess960, so it's separated into separate cases.
    square_t my_king_home = king_home + side*A8;
    if (!options.chess960) {
        if (has_oo_rights(pos, side) &&
                pos->board[my_king_home+1] == EMPTY &&
                pos->board[my_king_home+2] == EMPTY &&
                !is_square_attacked((position_t*)pos,my_king_home+1,side^1)) {
            assert(pos->board[my_king_home] ==
                    create_piece(pos->side_to_move, KING));
            moves = add_move(pos,
                    create_move_castle(my_king_home, my_king_home+2,
                        create_piece(side, KING)),
                    moves);
        }
        if (has_ooo_rights(pos, side) &&
                pos->board[my_king_home-1] == EMPTY &&
                pos->board[my_king_home-2] == EMPTY &&
                pos->board[my_king_home-3] == EMPTY &&
                !is_square_attacked((position_t*)pos,my_king_home-1,side^1)) {
            assert(pos->board[my_king_home] ==
                    create_piece(pos->side_to_move, KING));
            moves = add_move(pos,
                    create_move_castle(my_king_home, my_king_home-2,
                        create_piece(side, KING)),
                    moves);
        }
    } else {
        if (has_oo_rights(pos, side)) {
            square_t my_f1 = F1 + side*A8;
            square_t my_g1 = G1 + side*A8;
            square_t my_kr = king_rook_home + side*A8;
            bool castle_ok = true;
            // Check that rook is unimpeded.
            for (square_t sq = MIN(my_kr, my_f1);
                    sq <= MAX(my_kr, my_f1); ++sq) {
                if (sq != my_kr  && sq != my_king_home &&
                        pos->board[sq] != EMPTY) {
                    castle_ok = false;
                    break;
                }
            }
            // Check that the king is unimpeded and unattacked
            if (castle_ok) {
                for (square_t sq = MIN(my_king_home, my_g1);
                        sq <= my_g1; ++sq) {
                    if (sq != my_king_home && sq != my_kr &&
                            pos->board[sq] != EMPTY) {
                        castle_ok = false;
                        break;
                    }
                    if (sq != my_g1 &&
                            is_square_attacked((position_t*)pos, sq, side^1)) {
                        castle_ok = false;
                        break;
                    }
                }
            }
            if (castle_ok) moves = add_move(pos,
                    create_move_castle(my_king_home, my_g1,
                        create_piece(side, KING)), moves);
        }
        if (has_ooo_rights(pos, side)) {
            square_t my_d1 = D1 + side*A8;
            square_t my_c1 = C1 + side*A8;
            square_t my_qr = queen_rook_home + side*A8;
            bool castle_ok = true;
            // Check that rook is unimpeded.
            for (square_t sq = MIN(my_qr, my_d1);
                    sq <= MAX(my_qr, my_d1); ++sq) {
                if (sq != my_qr && sq != my_king_home &&
                        pos->board[sq] != EMPTY) {
                    castle_ok = false;
                    break;
                }
            }
            // Check that the king is unimpeded and unattacked
            if (castle_ok) {
                for (square_t sq = MIN(my_king_home, my_c1);
                        sq <= MAX(my_king_home, my_c1); ++sq) {
                    if (sq != my_king_home && sq != my_qr &&
                            pos->board[sq] != EMPTY) {
                        castle_ok = false;
                        break;
                    }
                    if (sq != my_c1 &&
                            is_square_attacked((position_t*)pos, sq, side^1)) {
                        castle_ok = false;
                        break;
                    }
                }
            }
            if (castle_ok) moves = add_move(pos,
                    create_move_castle(my_king_home, my_c1,
                        create_piece(side, KING)),
                    moves);
        }
    }

    for (int i = 0; i < pos->num_pieces[side]; ++i) {
        from = pos->pieces[side][i];
        piece = pos->board[from];
        assert(piece_color(piece) == side && piece_type(piece) != PAWN);
        generate_piece_noncaptures(pos, from, piece, &moves);
    }
    piece = create_piece(side, PAWN);
    for (int i=0; i<pos->num_pawns[side]; ++i) {
        from = pos->pawns[side][i];
        assert(pos->board[from] == piece);
        generate_pawn_quiet_moves(pos, from, piece, &moves);
    }

    *moves = 0;
    return (moves-moves_head);
}