Escreva uma função que verifica se ocorreu xeque em um determinado jogo de xadrez. O tabuleiro de xadrez é representado por uma matriz inteira 8 \times 8. Nesta matriz, o valor 0 indica a ausência de peça em uma determinada posição do tabuleiro. Peças são representadas pelos valores indicados na Tabela 1.
Table 1: Tabela 1: Valores que representam as peças de um jogo de xadrez.
\captionsetup{labelformat=empty}
Valor Peça
1 Peão preto
2 Cavalo preto
3 Torre preta
4 Bispo preto
5 Rei preto
6 Rainha preta
7 Peão branco
8 Cavalo branco
9 Torre branca
10 Bispo branco
11 Rei branco
12 Rainha branca

Passo 1

O que o problema pede e quais informações são dadas.
  • Pede-se uma função que verifica se ocorreu xeque num jogo de xadrez representado por uma matriz inteira 8 \times 8.
  • A matriz usa o valor 0 para casa vazia.
  • As peças são codificadas com os inteiros 1 até 12 conforme a tabela:
    • 1: Peão preto
    • 2: Cavalo preto
    • 3: Torre preta
    • 4: Bispo preto
    • 5: Rei preto
    • 6: Rainha preta
    • 7: Peão branco
    • 8: Cavalo branco
    • 9: Torre branca
    • 10: Bispo branco
    • 11: Rei branco
    • 12: Rainha branca
  • Deve-se determinar se um rei está sendo atacado por qualquer peça adversária (i.e., se há xeque). Vou retornar informação para ambos os reis (preto e branco).
  • Convenção adotada para orientações do tabuleiro: a matriz é indexada por linhas e colunas com índices inteiros. A linha aumenta para baixo (linha 0 é o topo, linha 7 o fundo). Nesse sistema:
    • Peões pretos atacam nas casas (r+1,c-1) e (r+1,c+1) a partir de (r,c).
    • Peões brancos atacam nas casas (r-1,c-1) e (r-1,c+1) a partir de (r,c).
  • Resultado final esperado da função: indicar se o rei preto está em xeque e se o rei branco está em xeque (duas flags booleanas).

Passo 2

Localizar os reis no tabuleiro — por que e como.
  • Antes de checar ataques precisamos conhecer as posições exatas dos reis: procurar na matriz o valor do rei preto ( 5) e do rei branco ( 11).
  • Procedimento prático:
    • Percorrer todas as linhas r=0 até r=7 e colunas c=0 até c=7.
    • Quando encontrar valor 5, guardar (r,c) como posição do rei preto.
    • Quando encontrar valor 11, guardar (r,c) como posição do rei branco.
  • Se algum dos reis não for encontrado, a posição é inválida. (Vou assumir que o enunciado dá posições válidas, mas o código pode checar e sinalizar erro.)

Passo 3

Como decidir se uma casa está sendo atacada — ideia geral.
  • Um rei está em xeque se existir ao menos uma peça adversária que possa, num movimento legal de ataque, ocupar a casa do rei.
  • Em vez de simular movimentos de todas as peças, é mais simples e eficiente testar se a casa do rei é “atacada” segundo os padrões de ataque de cada tipo de peça:
    • ataques de peão (padrão fixo),
    • saltos de cavalo (padrão fixo),
    • ataques deslizantes de torre, bispo e rainha (varrem direções até encontrar um bloqueio),
    • ataque pelo rei adversário (caso de casas adjacentes).
  • Implementação: escrever uma função auxiliar is_attacked(r,c,attacker_color) que verifica se a casa (r,c) é atacada por alguma peça da cor atacante.

Passo 4

Regras de ataque específicas — peões e cavalos (casos simples).
  • Peões:
    • Se estiver testando se uma casa (r,c) é atacada por peões pretos, então verificar se há um peão preto nas casas (r-1,c-1) ou (r-1,c+1) com relação à casa atacada? Cuidado com a orientação!
    • Usando a convenção adotada (linha aumenta para baixo):
      • Um peão preto numa posição (rp,cp) ataca (rp+1,cp\pm1). Logo, para saber se (r,c) é atacada por peão preto, verificar se existe um peão preto em (r-1,c-1) ou (r-1,c+1).
      • Um peão branco numa posição (rp,cp) ataca (rp-1,cp\pm1). Logo, para saber se (r,c) é atacada por peão branco, verificar se existe um peão branco em (r+1,c-1) ou (r+1,c+1).
    • Em resumo (fórmula prática para is_attacked):
      • Se attacker_color é “black”: olhar peças pretas em (r-1,c-1) e (r-1,c+1) e ver se são peões pretos ( 1).
      • Se attacker_color é “white”: olhar peças brancas em (r+1,c-1) e (r+1,c+1) e ver se são peões brancos ( 7).
    • Lembre-se de checar limites do tabuleiro antes de acessar a matriz.
  • Cavalos:
    • O cavalo tem 8 saltos: offsets (\pm2,\pm1) e (\pm1,\pm2).
    • Para cada um desses offsets, verificar se há um cavalo do atacante (código 2 para preto, 8 para branco) na casa correspondente.

Passo 5

Regras de ataque específicas — peças deslizantes: torre, bispo e rainha.
  • Conceito: torre, bispo e rainha atacam varrendo retas (linhas, colunas, diagonais) até o primeiro obstáculo. Se o primeiro obstáculo nessa direção é uma peça atacante do tipo compatível, então a casa é atacada por esse tipo.
  • Direções para verificar:
    • Para torre (e também rainha em modo torre): quatro direções ortogonais:
      • cima: (-1,0)
      • baixo: (+1,0)
      • esquerda: (0,-1)
      • direita: (0,+1)
    • Para bispo (e também rainha em modo bispo): quatro direções diagonais:
      • (-1,-1), (-1,+1), (+1,-1), (+1,+1)
  • Procedimento por direção:
    • Partir da casa alvo (r,c), avançar uma casa por vez na direção escolhida (i.e., incrementar r e c conforme offset) — equivalently, olhar as casas ao longo da reta até encontrar a primeira peça ou sair do tabuleiro.
    • Se encontrar a primeira peça e ela pertence ao atacante e é do tipo certo (torre para ortogonais, bispo para diagonais, rainha para qualquer uma das direções), então a casa está atacada.
    • Se encontrar qualquer peça que não seja do atacante, a direção está bloqueada e não há ataque nessa direção.
  • Observação: é comum começar do rei e olhar para fora, mas o mesmo raciocínio vale iniciando da casa do rei e caminhando.

Passo 6

Ataque de rei (caso de casas adjacentes) e resumo da rotina is_attacked.
  • Rei adversário ataca as oito casas adjacentes. Embora posições legais não permitam reis adjacentes, é prudente checar: olhar as 8 vizinhanças imediatas por um rei do atacante (código 5 para rei preto, 11 para rei branco).
  • Ordem prática de checagem dentro de is_attacked (por eficiência e simplicidade):
    1. Checar ataques de peão (já são verificados em poucas casas).
    2. Checar ataques de cavalo (8 testes).
    3. Checar ataques deslizantes: primeiro ortogonais para torre/rei/rainha; depois diagonais para bispo/rei/rainha.
    4. Checar vizinhança por rei (pode ser feito junto com cavalo ou depois).
  • Se qualquer uma dessas checagens confirmar a presença de peça atacante que possa atingir (r,c), retornar verdadeiro (a casa está atacada). Caso contrário, falso.

Passo 7

Complexidade, cuidados e exemplos simples para fixar.
  • Complexidade: cada chamada a is_attacked faz um número limitado de verificações (constante) e varre no máximo 8 raios até bloqueio. Em um tabuleiro 8 \times 8 isto é muito eficiente.
  • Cuidados:
    • Sempre verificar limites das coordenadas antes de acessar a matriz.
    • Identificar corretamente a cor da peça lida: valores 1 a 6 são pretos; 7 a 12 são brancos.
  • Exemplo pequeno (mental):
    • Rei preto em (4,4). Se houver um cavalo branco em (6,5) (offset (+2,+1) relativo ao rei), então is_attacked devolve verdadeiro para ataque de cavalo.
    • Rei branco em (0,4). Se há uma torre preta em (0,0) e nenhuma peça entre (0,0) e (0,4), então o raio ortogonal detecta torre preta e conclui xeque.

Passo 8

Montagem final da função principal.
  • Passos da função check_check(board):
    1. Procurar posições do rei preto ( 5) e do rei branco ( 11).
    2. Chamar is_attacked( pos_rei_preto, attacker_color = “white” ) para saber se o rei preto está em xeque.
    3. Chamar is_attacked( pos_rei_branco, attacker_color = “black” ) para saber se o rei branco está em xeque.
    4. Retornar as duas flags booleanas, por exemplo como tupla (preto_em_xeque, branco_em_xeque).
  • Observação sobre retorno: este formato é útil em provas/implementações porque descreve claramente o estado de xeque para ambos os dois lados.

Passo 9

Implementação pronta (pseudocódigo explicado linha a linha).
  • Abaixo está uma implementação em Python, com as funções auxiliares dentro de check_check. Ela segue exatamente os passos ensinados: localiza reis, define checagens de peão, cavalo, deslizantes e rei, e retorna os dois booleanos.

Resposta

def check_check(board):
“”"
Recebe board, uma matriz 8x8 (lista de listas) com inteiros conforme a tabela:
0: casa vazia
1…6: peças pretas (1 peão, 2 cavalo, 3 torre, 4 bispo, 5 rei, 6 rainha)
7…12: peças brancas (7 peão, 8 cavalo, 9 torre, 10 bispo, 11 rei, 12 rainha)
Retorna uma tupla (preto_em_xeque, branco_em_xeque) com booleans indicando
se o rei preto (5) ou o rei branco (11) está sob ataque.
Convenção: linhas indexadas 0…7 de cima para baixo; colunas 0…7 da esquerda para a direita.
“”"
ROWS, COLS = 8, 8
def in_bounds(r, c):
    return 0 <= r < ROWS and 0 <= c < COLS

def piece_color(val):
    if val == 0:
        return None
    if 1 <= val <= 6:
        return 'black'
    if 7 <= val <= 12:
        return 'white'
    return None

def find_kings():
    pos_black = None
    pos_white = None
    for r in range(ROWS):
        for c in range(COLS):
            if board[r][c] == 5:
                pos_black = (r, c)
            elif board[r][c] == 11:
                pos_white = (r, c)
            if pos_black and pos_white:
                return pos_black, pos_white
    return pos_black, pos_white

# checa se a casa (r,c) é atacada por alguma peça de attacker_color ('black' or 'white')
def is_attacked(r, c, attacker_color):
    # códigos de peças por cor
    if attacker_color == 'black':
        pawn_code = 1
        knight_code = 2
        rook_code = 3
        bishop_code = 4
        king_code = 5
        queen_code = 6
    else:
        pawn_code = 7
        knight_code = 8
        rook_code = 9
        bishop_code = 10
        king_code = 11
        queen_code = 12

    # 1) ataques de peão
    # lembrando convenção: peões pretos atacam para baixo (r+1), peões brancos atacam para cima (r-1)
    if attacker_color == 'black':
        # procurar peão em (r-1, c-1) ou (r-1, c+1)
        for dc in (-1, 1):
            rp, cp = r - 1, c + dc
            if in_bounds(rp, cp) and board[rp][cp] == pawn_code:
                return True
    else:
        # attacker white: peão branco estaria em (r+1, c-1) ou (r+1, c+1)
        for dc in (-1, 1):
            rp, cp = r + 1, c + dc
            if in_bounds(rp, cp) and board[rp][cp] == pawn_code:
                return True

    # 2) ataques de cavalo
    knight_offsets = [(-2, -1), (-2, 1), (-1, -2), (-1, 2), (1, -2), (1, 2), (2, -1), (2, 1)]
    for dr, dc in knight_offsets:
        rr, cc = r + dr, c + dc
        if in_bounds(rr, cc) and board[rr][cc] == knight_code:
            return True

    # 3) ataques deslizantes - torres/rei/rainha em ortogonais
    orth_dirs = [(-1, 0), (1, 0), (0, -1), (0, 1)]
    for dr, dc in orth_dirs:
        rr, cc = r + dr, c + dc
        while in_bounds(rr, cc):
            val = board[rr][cc]
            if val != 0:
                # encontrou a primeira peça nessa direção
                if val == rook_code or val == queen_code:
                    return True
                # rei adversário em casa adjacente também conta (checar apenas na primeira casa)
                if (rr, cc) == (r + dr, c + dc) and val == king_code:
                    return True
                break
            rr += dr
            cc += dc

    # 4) ataques deslizantes - bispo/rei/rainha em diagonais
    diag_dirs = [(-1, -1), (-1, 1), (1, -1), (1, 1)]
    for dr, dc in diag_dirs:
        rr, cc = r + dr, c + dc
        while in_bounds(rr, cc):
            val = board[rr][cc]
            if val != 0:
                if val == bishop_code or val == queen_code:
                    return True
                if (rr, cc) == (r + dr, c + dc) and val == king_code:
                    return True
                break
            rr += dr
            cc += dc

    return False

pos_black, pos_white = find_kings()
if pos_black is None or pos_white is None:
    raise ValueError("Posição inválida: algum dos reis não foi encontrado no tabuleiro.")

preto_em_xeque = is_attacked(pos_black[0], pos_black[1], 'white')
branco_em_xeque = is_attacked(pos_white[0], pos_white[1], 'black')

return preto_em_xeque, branco_em_xeque

Exercícios relacionados