Пример #1
0
    def _tipo_casa(
        self,
        pos: tp.coord,
        click: tp.coord | None,
        movimento: tp.movements | None,
    ) -> str:
        i, j = pos

        if click is not None and pos == click:
            return "click"

        if movimento is not None and movimento[i][j] is not None:
            mov = movimento[i][j]
            if mov is not None:
                if isinstance(mov, MovimentoComplexo) and mov.especial:
                    return "especial"
                else:
                    return "movimento"

        if (
            tp.coord(i, j) == self._rei.branco
            or tp.coord(i, j) == self._rei.preto
        ) and testar_xeque(self.tabuleiro, self.flags, tp.coord(i, j)):
            return "xeque"

        return "vazio"
Пример #2
0
def testar_xeque(tabuleiro: tp.board, flags: list, pos_rei: tp.coord) -> bool:
    """
    Testa se o rei está em xeque
    :param pos_rei: posição do rei
    """
    from .rei import Rei

    ri, rj = pos_rei
    rei = tabuleiro[ri][rj]
    if rei is None or not isinstance(rei, Rei):
        raise Exception(
            "testar_xeque não recebeu uma posição válida para o rei"
        )

    for pi, linha in enumerate(tabuleiro):
        for pj, peca in enumerate(linha):
            if peca is not None and peca.cor != rei.cor:
                movimentos = peca.get_movimentos_simples(
                    tabuleiro, flags, tp.coord(pi, pj)
                )
                mov = movimentos[ri][rj]
                if isinstance(mov, Movimento):
                    return True
                elif isinstance(mov, MovimentoComplexo) and not mov.avanco:
                    return True
    return False
Пример #3
0
    def event(self, event: pg.event.EventType) -> None:
        match event:
            case pg.event.EventType(type=pg.MOUSEBUTTONDOWN, button=1):
                # click esquerdo
                click_antigo = self._click

                self._click = tp.coord(
                    int(event.pos[1] // self._qsize[1]),
                    int(event.pos[0] // self._qsize[0]),
                )

                movimentado = False
                if self.movimento and click_antigo:
                    movimento_oconteceu = self.tabuleiro.movimenta_peca(
                        tp.action(click_antigo, self._click)
                    )
                    if movimento_oconteceu:
                        self.movimento = None
                        movimentado = True

                if not movimentado:
                    self.atualiza_movimentos(self._click)
                else:
                    # TODO isso não deveria ser resposabilidade de xadrez
                    self.tabuleiro.vez = not self.tabuleiro.vez

                self._atualizacao = True
            case pg.event.EventType(type=pg.KEYDOWN, key=pg.K_ESCAPE):
                self._escape = True
Пример #4
0
    def draw(self, canvas: pg.Surface) -> None:
        if not self.atualizacao:
            return

        recursos = Recursos()

        size = canvas.get_size()
        self._qsize = size[0] // 8, size[1] // 8

        canvas.fill(pg.Color(0, 0, 0))
        tabuleiro = pg.Surface((6 * self._qsize[0], 6 * self._qsize[1]))
        self.xadrez.draw(tabuleiro)
        canvas.blit(tabuleiro, (self._qsize[0], 2 * self._qsize[1]))

        offset_i, offset_j = 0, 2
        for jj, peca in enumerate(self.pecas):
            # i, j = y, x
            i, j = offset_i, offset_j + jj

            surf = pg.Surface(self._qsize)
            recursos.config.quadrado(surf, tp.coord(j, i), "vazio")
            peca.draw(surf)
            pos = j * self._qsize[0], i * self._qsize[1]
            canvas.blit(surf, pos)

        self.atualizacao = False
        self.xadrez.atualizacao = True
        pg.display.set_caption(recursos.config.titulo(self.cor))
        pg.display.flip()
Пример #5
0
def calcula_direcao(
    res: tp.movements,
    tabuleiro: tp.board,
    pos: tp.coord,
    direcoes: tuple[tp.direction, ...],
    cor: bool,
    rei: bool = False,
) -> None:
    for direcao in direcoes:
        p = pos + direcao
        while p.valida():
            i, j = p
            peca = tabuleiro[i][j]
            if peca is None:
                res[i][j] = Movimento(tp.action(pos, tp.coord(i, j)), rei)
            else:
                if cor != peca.cor:
                    res[i][j] = Movimento(tp.action(pos, tp.coord(i, j)), rei)
                break  # Se a casa não está vazia, não tem porquê olhar adiante
            p += direcao
Пример #6
0
    def draw(
        self,
        canvas: pg.Surface,
        click: tp.coord | None,
        movimento: tp.movements | None,
    ) -> None:
        recursos = Recursos()

        size = canvas.get_size()
        size = size[0] // 8, size[1] // 8

        for y, linha in enumerate(self.tabuleiro):
            for x, peca in enumerate(linha):
                # i, j = y, x

                surf = pg.Surface(size)
                tipo = self._tipo_casa(tp.coord(y, x), click, movimento)
                recursos.config.quadrado(surf, tp.coord(y, x), tipo)

                if peca:
                    peca.draw(surf)

                pos = x * size[0], y * size[1]
                canvas.blit(surf, pos)
Пример #7
0
 def get_movimentos(self, tabuleiro: tp.board, flags: list,
                    pos_rei: tp.coord, pos: tp.coord) -> tp.movements:
     """
     :param flags: flags do tabuleiro
     :param pos: posição da peça, cujos movimentos estão sendo calculados
     :return: matriz movements com todos os movimentos legais
     """
     res = movements_vazio()
     movimentos = self.get_movimentos_simples(tabuleiro, flags, pos)
     for i, linha in enumerate(movimentos):
         for j, mov in enumerate(linha):
             teste = testar_movimento(tabuleiro, flags, pos_rei,
                                      tp.action(pos, tp.coord(i, j)))
             res[i][j] = mov if teste else None
     return res
Пример #8
0
    def get_movimentos_simples(
        self, tabuleiro: tp.board, flags: list, pos: tp.coord
    ) -> tp.movements:
        res = movements_vazio()
        linha_promocao = 0 if self.cor else 7

        i, j = pos
        i += -1 if self.cor else 1
        if tp.coord.valida_componente(i) and tabuleiro[i][j] is None:
            if i == linha_promocao:
                res[i][j] = Promocao(tp.action(pos, tp.coord(i, j)), self.cor)
            else:
                res[i][j] = Avanco(self.cor, pos)

            ii = i - 1 if self.cor else i + 1
            avanco_duplo = (
                not self.movimentou
                and tp.coord.valida_componente(ii)
                and tabuleiro[ii][j] is None
            )
            if avanco_duplo:
                if i == linha_promocao:
                    res[ii][j] = Promocao(
                        tp.action(pos, tp.coord(ii, j)), self.cor
                    )
                else:
                    res[ii][j] = AvancoDuplo(
                        self.cor,
                        tp.pathaction(pos, tp.coord(i, j), tp.coord(ii, j)),
                    )

        i, j = pos
        i += -1 if self.cor else 1
        if tp.coord(i, j - 1).valida():
            res[i][j - 1] = self._criar_captura(
                tabuleiro, flags, tp.action(pos, tp.coord(i, j - 1))
            )
        if tp.coord(i, j + 1).valida():
            res[i][j + 1] = self._criar_captura(
                tabuleiro, flags, tp.action(pos, tp.coord(i, j + 1))
            )

        return res
Пример #9
0
 def __init__(self):
     self.tabuleiro = board_inicial()
     self.vez = True
     self.flags = list()
     self._rei = tp.pb(tp.coord(0, 4), tp.coord(7, 4))
Пример #10
0
    def get_movimentos_simples(self, tabuleiro: tp.board, flags: list,
                               pos: tp.coord) -> tp.movements:
        # TODO Cuidado com xeque
        res = movements_vazio()
        i, j = pos

        # Posições a verificar
        DIRECOES = (
            # Casas acima do rei
            tp.direction(-1, -1),
            tp.direction(-1, 0),
            tp.direction(-1, 1),
            # Casas do meio
            tp.direction(0, -1),
            tp.direction(0, 1),
            # Casas abaixo do rei
            tp.direction(1, -1),
            tp.direction(1, 0),
            tp.direction(1, 1),
        )

        for direcao in DIRECOES:
            nova_pos = pos + direcao
            if nova_pos.valida():
                m, n = nova_pos
                res[m][n] = self._criar_movimento(tabuleiro,
                                                  tp.action(pos, nova_pos))

        # Verifica se é possível fazer o Roque
        if not self.movimentou:
            torre = tabuleiro[i][0]
            eh_realmente_torre = (torre is not None
                                  and isinstance(torre, Torre)
                                  and torre.movimentou)
            if eh_realmente_torre:
                # TODO verifica se deixa o rei em xeque ou passa em casas em xeque

                pecas_entre = False
                for jj in range(1, j):
                    pecas_entre = pecas_entre or tabuleiro[i][jj] is not None

                tab = board_copia(tabuleiro)
                tab[i][3] = Rei(self.cor)
                tab[i][4] = None
                xeque = testar_xeque(tab, flags, tp.coord(i, 3))

                if not xeque:
                    tab = board_copia(tabuleiro)
                    tab[i][2] = Rei(self.cor)
                    tab[i][4] = None
                    xeque = testar_xeque(tab, flags, tp.coord(i, 2))

                if not pecas_entre and not xeque:
                    res[i][j - 2] = Roque(
                        tp.action(tp.coord(i, j), tp.coord(i, j - 2)),
                        tp.action(tp.coord(i, 0), tp.coord(i, j - 1)),
                    )

            torre = tabuleiro[i][7]
            eh_realmente_torre = (torre is not None
                                  and isinstance(torre, Torre)
                                  and torre.movimentou)
            if eh_realmente_torre:
                pecas_entre = False
                for jj in range(j + 1, 7):
                    pecas_entre = pecas_entre or tabuleiro[i][jj] is not None

                if not pecas_entre:
                    res[i][j + 2] = Roque(
                        tp.action(tp.coord(i, j), tp.coord(i, j + 2)),
                        tp.action(tp.coord(i, 7), tp.coord(i, j + 1)),
                    )

        return res
Пример #11
0
 def executar(self, tabuleiro: tp.board, flags: list):
     i, j = self.pos
     i += -1 if self.cor else 1
     mover_peca(tabuleiro, tp.action(self.pos, tp.coord(i, j)))