예제 #1
0
def str_to_card(str_card):
    '''
    Return a Card obj from a string representation.

    >>> str_to_card('102')
    10♡
    >>> str_to_card('!102')
    10♡
    '''
    if str_card.startswith('!'):
        str_card = str_card[1:]
    return Card(int(str_card[-1]), str_card[:-1])
예제 #2
0
def decode_card(card_str):
    """
    Parse card for gameflow

    >>> decode_card('!10♡')
    (1, [10♡])
    >>> decode_card('J♡;R')
    (0, [J♡], 'Rook')
    """

    burned = 1 if card_str[0] == '!' else 0

    if ';' in card_str:
        assert not burned
        col = decode_card_color(card_str[-3])
        rank = card_str[:-3] if not burned else card_str[1:-3]
        jack_choice = card_str[-1]
        return (burned, [Card(col, rank)], nawaleta(jack_choice))

    col = decode_card_color(card_str[-1])
    rank = card_str[:-1] if not burned else card_str[1:-1]
    return (burned, [Card(col, rank)])
예제 #3
0
파일: gameplay.py 프로젝트: tadeoos/chessao
    def get_move(self, ovr=None):
        """Second stage of a move: get a chess move."""
        self.zamiana = False
        player = self.get_gracz(self.to_move)
        # after ace or king of spikes there is no move
        if not self.burned and (self.now_card.ran == 'A' or
                                (self.now_card.ran == 'K'
                                 and self.now_card.kol == 1)):
            return []

        w = self.what_happened()
        all_moves = self.possible_moves(self.to_move, self.capture,
                                        self.now_card, self.burned, w)
        if len(all_moves) == 0:
            return []
        crd = self.now_card if not self.burned else Card(1, '5')
        move = player.choose_move(all_moves, self.plansza,
                                  crd) if ovr is None else ovr
        return move
예제 #4
0
from itertools import permutations
import pytest

from chessao import BLACK_COLOR, WHITE_COLOR
from chessao.cards import Card
from chessao.chess import Board, EMPTY
from chessao.pieces import Pawn, ChessaoPieceException
from chessao.helpers import get_mapdict


DEFAULT_CARD = Card(1, '5')
DEFAULT_BOARD = Board()
MAPDICT = get_mapdict()


def test_pawns_ineqaulity():
    pieces_pairs = permutations([piece for piece in Board().pieces()], 2)
    for p1, p2 in pieces_pairs:
        assert p1 != p2


def test_pawn_moves():
    black_pawn = Pawn(color=BLACK_COLOR, position=87)
    assert black_pawn.moves(DEFAULT_CARD, DEFAULT_BOARD) == [77, 67]
    white_pawn = Pawn(color=WHITE_COLOR, position=31)
    assert white_pawn.moves(DEFAULT_CARD, DEFAULT_BOARD) == [41, 51]


def test_cant_move_on_wrong_tile():
    black_pawn = Pawn(color=BLACK_COLOR, position=MAPDICT['D5'])
    assert DEFAULT_BOARD.get_piece('D5') == EMPTY
예제 #5
0
파일: gameplay.py 프로젝트: tadeoos/chessao
    def possible_moves(self,
                       color,
                       okzbi=True,
                       kar=Card(1, '5'),
                       burned=False,
                       flag=(0, )):
        """
        Return a dict of possible moves.
        """
        if burned:
            kar = Card(1, '5')

        d = {v: k for (k, v) in self.plansza.mapdict.items()}

        if flag[0] == 1:
            return {}

        elif flag[0] == 2:  # king of spades
            a = [self.plansza.mapdict[flag[1][0]]]
        elif flag[0] == 3:  # king of hearts
            a = [self.plansza.mapdict[flag[1]]]
        elif flag[0] == 4:  # jack
            a = [
                i for i in self.plansza.all_taken()
                if self.plansza[i].color == color
                and self.plansza[i].name == flag[1]
            ]
        elif kar.ran == 'Q' and len(
                self.plansza.positions_of_piece('Queen', color)) > 0:
            assert flag[0] == 0
            if self.plansza.piece_types_left(color) != {'King', 'Queen'}:
                a = self.plansza.positions_of_piece('Queen', color)
            else:
                kar = Card(1, '5')
                a = [
                    i for i in self.plansza.all_taken()
                    if self.plansza[i].color == color
                ]
        else:
            a = [
                i for i in self.plansza.all_taken()
                if self.plansza[i].color == color
            ]

        res = {}
        for i in a:
            skad = d[i]
            if okzbi:
                gdzie = [
                    d[c] for c in self.plansza[i].moves(kar, self.plansza)
                    if type(self.plansza[c]) != King
                ]
            else:
                gdzie = [
                    d[c] for c in self.plansza[i].moves(kar, self.plansza)
                    if type(self.plansza[c]) != King and
                    (self.plansza.is_empty(c) or self.plansza[c].color == color
                     )
                ]

            if flag[0] == 2:
                try:
                    gdzie.remove(flag[1][1])
                except Exception as e:
                    raise ChessaoGameplayError(
                        'Error in remove! color:{} okzbi:{} karta:{} burned: {} flag {} gdzie: {} skad {} a: {}\n{}'
                        .format(color, okzbi, kar, burned, flag, gdzie, skad,
                                a, self.snapshot()),
                        gameplay=self,
                        errors=e)
            if len(gdzie) > 0:
                res[skad] = gdzie

        res2 = deepcopy(res)
        for key in res2:
            for where in res2[key]:
                try:
                    pln = self.plansza.simulate_move(key, where, kar)
                except Exception as e:
                    raise ChessaoGameplayError(
                        '\n color: {} from {} to {} karta {}\nSNAPSHOT:{}'.
                        format(color, key, where, kar, self.snapshot()),
                        gameplay=self,
                        errors=e)
                if pln.color_is_checked(color) == (True, color):
                    res[key].remove(where)
                del pln
        final = {k: v for (k, v) in res.items() if v != []}
        return final
예제 #6
0
    def move(self, pos_from, pos_to=None, card=Card(1, '5'), only_bool=False):
        """
        Move a piece on a board.

        Args:
            pos_from (str): e.g. 'A2'
            pos_to (str): e.g. 'A4'
            card (Card): a Card that is played alongisde the move
            only_bool (bool): check if move is valid, don't change state

        >>> Board(fenrep='R3K2R/8/8/8/8/8/8/8').move('E1','C1')  # roszada
        Board: 2KR3R/8/8/8/8/8/8/8 - - 1 0
        >>> Board(fenrep='R3K2R/8/8/pP6/8/NnrRqQbB/8/7k KQ').move('E1','G1')  # zła roszada
        Traceback (most recent call last):
        ...
        AssertionError: Move is not possible: E1 -> G1; R3K2R/8/8/pP6/8/NnrRqQbB/8/7k KQ - 0 0
        >>> Board(fenrep='R3K2R/8/8/pP6/8/NnrRqQbB/8/7k KQ').move('E1','C1')  #doctest: +ELLIPSIS
        Traceback (most recent call last):
        ...
        AssertionError: ...
        >>> Board(fenrep='K7/8/8/pP6/8/NnrRqQbB/8/r3k2r KQ').move('E8','C8')  #doctest: +ELLIPSIS
        Traceback (most recent call last):
        ...
        AssertionError: ...
        >>> Board(fenrep='R3K2R/8/8/Q7/8/8/8/8').move('A4','A1', Card(1,'Q'))
        Board: Q3K2R/8/8/R7/8/8/8/8 K - 1 0
        >>> Board(fenrep='R3K2R/8/8/P7/8/8/8/8').move('A4','A5', Card(1,'Q'))
        Board: R3K2R/8/8/8/P7/8/8/8 KQ - 0 0
        >>> Board(fenrep='R3K2R/8/8/P7/q7/8/8/8').move('A5','A4', Card(1,'6'))
        Board: R3K2R/8/8/q7/8/8/8/8 KQ - 0 1
        >>> Board(fenrep='R3K2R/8/8/P7/q7/8/1N6/8').move('B7','A5', Card(1,'6'))
        Board: R3K2R/8/8/P7/N7/8/8/8 KQ - 0 0
        >>> b = Board()
        >>> b.move('D2','D4')
        Board: RNBQKBNR/PPP1PPPP/8/3P4/8/8/pppppppp/rnbqkbnr KQkq D3 0 0
        >>> b.move('A7','A6')
        Board: RNBQKBNR/PPP1PPPP/8/3P4/8/p7/1ppppppp/rnbqkbnr KQkq - 0 1
        >>> b.move('D4', 'D5')
        Board: RNBQKBNR/PPP1PPPP/8/8/3P4/p7/1ppppppp/rnbqkbnr KQkq - 0 1
        >>> b.move('E7','E5')
        Board: RNBQKBNR/PPP1PPPP/8/8/3Pp3/p7/1ppp1ppp/rnbqkbnr KQkq E6 0 2
        >>> b.move('D5','E6')
        Board: RNBQKBNR/PPP1PPPP/8/8/8/p3P3/1ppp1ppp/rnbqkbnr KQkq - 0 2
        >>> b.move('A6','A5')
        Board: RNBQKBNR/PPP1PPPP/8/8/p7/4P3/1ppp1ppp/rnbqkbnr KQkq - 0 3
        >>> b.move('A5', 'A4')
        Board: RNBQKBNR/PPP1PPPP/8/p7/8/4P3/1ppp1ppp/rnbqkbnr KQkq - 0 4
        >>> b.move('B2','B4')
        Board: RNBQKBNR/P1P1PPPP/8/pP6/8/4P3/1ppp1ppp/rnbqkbnr KQkq B3 0 4
        >>> b.move('A4','B3')
        Board: RNBQKBNR/P1P1PPPP/1p6/8/8/4P3/1ppp1ppp/rnbqkbnr KQkq - 0 5
        >>> b.move('H2', 'H5', only_bool=True)
        Traceback (most recent call last):
        ...
        AssertionError: Move is not possible: H2 -> H5; RNBQKBNR/P1P1PPPP/1p6/8/8/4P3/1ppp1ppp/rnbqkbnr KQkq - 0 5
        """

        self.capture_took_place = False
        start_position_int = self.mapdict[pos_from]
        end_position_int = self.mapdict[pos_to]

        if self.is_empty(start_position_int):
            raise ValueError('There is no Piece in that field {}'.format(pos_from))

        assert end_position_int in self[start_position_int].moves(card, self), \
            f"Move is not possible: {pos_from} -> {pos_to}; {self.fen()}"

        # first check if the move is an enappsant one
        if self[start_position_int].name == 'Pawn':
            if self.enpass == end_position_int:
                return self._enpassant_move(start_position_int, end_position_int, only_bool)
            elif self[start_position_int].mvs_number == 0 and \
                    abs(start_position_int - end_position_int) == 20:  # then set enpassant
                self.enpass = (start_position_int + end_position_int) / 2
            else:
                self.enpass = 300

        # checking for castle
        if all([card.ran != 'K' or card.kol not in (3, 4),
                self[start_position_int].name == 'King',
                abs(end_position_int - start_position_int) == 2]):
            return self._castle_move(start_position_int, end_position_int, only_bool)

        # checking for Queen card and valid Queen move
        enemy_pieces_left = self.piece_types_left(self[start_position_int].color)
        if all([card.ran == 'Q',
                self[start_position_int].name == 'Queen',
                enemy_pieces_left != {'King', 'Queen'}]):
            return self._queen_move(start_position_int, end_position_int, only_bool)

        else:
            # default move
            if only_bool:
                return True
            if self[start_position_int].name == 'Pawn':
                clock_value = 0
            else:
                clock_value = 1
            if not self.is_empty(end_position_int):
                self.capture_took_place = True
                clock_value = 0
                self.captured_pieces.append(self[end_position_int])
            self._move_piece(pos_from=start_position_int, pos_to=end_position_int)
            self._turn_clock(piece_color=end_position_int, clock=clock_value)
            return self

        raise ValueError(
            'BŁĄD w funkcji move! skad {} dokad {} card {} mvs {}, enpas {}'.format(
                pos_from, pos_to, card, self[start_position_int].mvs_number, self.enpass))
예제 #7
0
 def test_wrong_card(self):
     assert not self.gameplay.capture
     assert self.gameplay.to_move == BLACK_COLOR
     with pytest.raises(helpers.ChessaoGameplayError):
         self.gameplay.make_an_overriden_move_in_one_func(
             card=(0, [Card(1, '5')]), move=['A7', 'A6'])