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"
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
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
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()
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
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)
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
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
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))
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
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)))