예제 #1
0
파일: table.py 프로젝트: tcdude/pyos
 def refresh_table(self):
     """
     Execute callback for every card on the table.
     """
     for i, t_card in enumerate(self._stack):
         self._callback(
             t_card,
             common.TableLocation(area=common.TableArea.STACK,
                                  visible=False,
                                  card_id=i))
     for i, t_card in enumerate(self._waste):
         pile_id = min(len(self._waste) - i - 1, 3)
         self._callback(
             t_card,
             common.TableLocation(area=common.TableArea.WASTE,
                                  visible=True,
                                  pile_id=pile_id,
                                  card_id=i))
     for i, pile in enumerate(self._tableau.piles):
         for j, t_card in enumerate(pile):
             self._callback(
                 t_card,
                 common.TableLocation(area=common.TableArea.TABLEAU,
                                      visible=t_card.visible,
                                      pile_id=i,
                                      card_id=j))
     for i, pile in enumerate(self._foundation.piles):
         for j, t_card in enumerate(pile):
             self._callback(
                 t_card,
                 common.TableLocation(area=common.TableArea.FOUNDATION,
                                      visible=True,
                                      pile_id=i,
                                      card_id=j))
예제 #2
0
파일: table.py 프로젝트: tcdude/pyos
    def __flip(self, pile: int) -> bool:
        """
        Tries to flip the top most card of the specified pile.

        Args:
            pile: pile index.

        Returns:
            True if a move is performed otherwise False.
        """
        res = self._tableau.flip(pile)
        if res:
            self._history.append(
                Move(from_area=common.TableArea.TABLEAU,
                     from_pile_id=pile,
                     pile_count=1,
                     to_area=common.TableArea.TABLEAU,
                     to_pile_id=pile))
            self._callback(
                self._tableau.top_card(pile),
                common.TableLocation(area=common.TableArea.TABLEAU,
                                     visible=True,
                                     pile_id=pile,
                                     card_id=len(self._tableau.piles[pile]) -
                                     1))
        return False
예제 #3
0
파일: table.py 프로젝트: tcdude/pyos
 def _update_tableau_pile(self, pile_id: int) -> None:
     """Make sure all cards in a tableau pile get updated."""
     for i, t_card in enumerate(self._tableau.piles[pile_id]):
         self._callback(
             t_card,
             common.TableLocation(area=common.TableArea.TABLEAU,
                                  visible=t_card.visible,
                                  pile_id=pile_id,
                                  card_id=i))
예제 #4
0
파일: table.py 프로젝트: tcdude/pyos
 def _reset_waste(self) -> None:
     """Make sure all waste card callbacks are executed."""
     w_len = len(self._waste)
     for i in range(min(5, w_len)):
         card_id = w_len - i - 1
         self._callback(
             self._waste[card_id],
             common.TableLocation(area=common.TableArea.WASTE,
                                  visible=True,
                                  pile_id=min(i, 3),
                                  card_id=card_id))
예제 #5
0
파일: table_layout.py 프로젝트: tcdude/pyos
    def refresh_all(self):
        """Force refresh all card nodes."""
        table = self._table.table
        for i, t_card in enumerate(table.stack):
            self._cards[t_card.index[0]].location = common.TableLocation(
                common.TableArea.STACK, False, card_id=i)
        w_len = len(table.waste)
        for i, t_card in enumerate(table.waste):
            pile_id = min(3, w_len - i - 1)
            self._cards[t_card.index[0]].location = common.TableLocation(
                common.TableArea.WASTE, True, pile_id=pile_id, card_id=i)
        for i, pile in enumerate(table.foundation):
            for j, t_card in enumerate(pile):
                self._cards[t_card.index[0]].location = common.TableLocation(
                    common.TableArea.FOUNDATION, True, pile_id=i, card_id=j)
        for i, pile in enumerate(table.tableau):
            for j, t_card in enumerate(pile):
                self._cards[t_card.index[0]].location = common.TableLocation(
                    common.TableArea.TABLEAU,
                    t_card.index[1] == 0,
                    pile_id=i,
                    card_id=j)

        meths = {
            common.TableArea.STACK: self._callback_stack,
            common.TableArea.WASTE: self._callback_waste,
            common.TableArea.FOUNDATION: self._callback_foundation,
            common.TableArea.TABLEAU: self._callback_tableau,
            common.TableArea.NONE: None
        }
        c_loc = common.TableLocation(common.TableArea.NONE)
        for k in self._cards:
            card_node = self._cards[k]
            if meths[card_node.location.area] is None:
                continue
            meths[card_node.location.area](c_loc, card_node.location,
                                           card_node)
예제 #6
0
파일: table.py 프로젝트: tcdude/pyos
    def __draw(self) -> Union[bool, int]:
        """
        Try to draw from stack.

        Returns:
            Union[bool, int] -> 1 = draw, 2 = reset stack, False = empty.
        """
        if not self._stack:
            if not self._waste:
                logger.debug('no more cards')
                return False
            self._stack = list(reversed(self._waste))
            self._waste = []
            for i, s_card in enumerate(self._stack):
                s_card.visible = False
                self._callback(
                    s_card,
                    common.TableLocation(area=common.TableArea.STACK,
                                         visible=False,
                                         card_id=i))
            self._state.points -= 100 if self._state.draw_count == 1 else 0
            self._state.points = max(self._state.points, 0)
            logger.info('reset stack')
            self._history.append(
                Move(from_area=common.TableArea.WASTE,
                     to_area=common.TableArea.STACK))
            self._state.points -= 100 if self.draw_count == 1 else 0
            self._state.points = max(0, self._state.points)
            return 2
        card_count = min(self._state.draw_count, len(self._stack))
        for _ in range(self._state.draw_count):
            if self._stack:
                self._waste.append(self._stack.pop())
                self._waste[-1].visible = True
            else:
                break
        self._history.append(
            Move(from_area=common.TableArea.STACK,
                 to_area=common.TableArea.WASTE,
                 pile_count=card_count))
        self._reset_waste()
        logger.info('draw successful')
        return 1
예제 #7
0
파일: table.py 프로젝트: tcdude/pyos
    def __tableau_to_foundation(self,
                                tableau_pile: Optional[int] = None,
                                foundation_pile: Optional[int] = None) -> bool:
        """
        Tries to move a card from Tableau to Foundation.

        Args:
            tableau_pile: pile index on Tableau.
            foundation_pile: pile index on Foundation.

        Returns:
            True if a move is performed otherwise False.
        """
        if tableau_pile is None:
            test_cards = [(i, self._tableau.top_card(i)) for i in range(7)]
        else:
            test_cards = [(tableau_pile, self._tableau.top_card(tableau_pile))]
        for from_pile, t_card in test_cards:
            if t_card is None:
                continue
            dest_pile = self._foundation.add_card(t_card, foundation_pile)
            if dest_pile > -1:
                self._history.append(
                    Move(from_area=common.TableArea.TABLEAU,
                         from_pile_id=from_pile,
                         pile_count=1,
                         to_area=common.TableArea.FOUNDATION,
                         to_pile_id=dest_pile))
                self._tableau.remove(from_pile)
                logger.debug('valid move found')
                self._state.points += 10
                self._callback(
                    self._foundation.top_card(dest_pile),
                    common.TableLocation(
                        area=common.TableArea.FOUNDATION,
                        visible=True,
                        pile_id=dest_pile,
                        card_id=len(self._foundation.piles[dest_pile]) - 1))
                self._update_tableau_pile(from_pile)
                return True
        logger.debug('no valid move found')
        return False
예제 #8
0
파일: table.py 프로젝트: tcdude/pyos
    def __undo_draw(self, move: Move) -> bool:
        """
        Undo a draw operation.

        Args:
            move: Move

        Returns:
            bool -> True if successful otherwise False.
        """
        for _ in range(move.pile_count):
            w_card = self._waste.pop()
            w_card.visible = False
            self._stack.append(w_card)
            self._callback(
                w_card,
                common.TableLocation(area=common.TableArea.STACK,
                                     visible=False,
                                     card_id=len(self._stack) - 1))
        self._reset_waste()
        return True
예제 #9
0
파일: table.py 프로젝트: tcdude/pyos
    def __undo_foundation_to(self, move: Move) -> bool:
        """
        Undo a Foundation to Tableau operation.

        Args:
            move: Move

        Returns:
            bool -> True if successful otherwise False.
        """
        f_card = self._tableau.top_card(move.to_pile_id)
        self._foundation.add_card_force(f_card, move.from_pile_id)
        self._tableau.remove(move.to_pile_id)
        self._callback(
            self._foundation.top_card(move.from_pile_id),
            common.TableLocation(
                area=common.TableArea.FOUNDATION,
                visible=True,
                pile_id=move.from_pile_id,
                card_id=len(self._foundation.piles[move.from_pile_id]) - 1))
        self._update_tableau_pile(move.to_pile_id)
        return True
예제 #10
0
파일: table.py 프로젝트: tcdude/pyos
    def __undo_tableau_to(self, move: Move) -> bool:
        """
        Undo a Tableau to ... operation.

        Args:
            move: Move

        Returns:
            bool -> True if successful otherwise False.
        """
        if move.to_area == common.TableArea.TABLEAU and \
                move.from_pile_id != move.to_pile_id:
            self._tableau.move_pile_force(move.to_pile_id, move.pile_count,
                                          move.from_pile_id)
            self._update_tableau_pile(move.to_pile_id)
            self._update_tableau_pile(move.from_pile_id)
        elif move.to_area == common.TableArea.TABLEAU and \
                move.from_pile_id == move.to_pile_id:
            self._tableau.top_card(move.from_pile_id).visible = False
            self._callback(
                self._tableau.top_card(move.from_pile_id),
                common.TableLocation(
                    area=common.TableArea.TABLEAU,
                    visible=False,
                    pile_id=move.from_pile_id,
                    card_id=len(self._tableau.piles[move.from_pile_id]) - 1))
            move = self._history.pop()
            self.__undo_tableau_to(move)
        elif move.to_area == common.TableArea.FOUNDATION:
            t_card = self._foundation.top_card(move.to_pile_id)
            self._tableau.add_card_force(t_card, move.from_pile_id)
            self._foundation.remove(move.to_pile_id)
            self._update_tableau_pile(move.from_pile_id)
        else:
            return False
        return True
예제 #11
0
파일: table.py 프로젝트: tcdude/pyos
    def __undo_waste_to(self, move: Move) -> bool:
        """
        Undo a Waste to ... operation.

        Args:
            move: Move

        Returns:
            bool -> True if successful otherwise False.
        """
        if move.to_area == common.TableArea.TABLEAU:
            w_card = self._tableau.top_card(move.to_pile_id)
            self._waste.append(w_card)
            self._tableau.remove(move.to_pile_id)
            self._update_tableau_pile(move.to_pile_id)
        elif move.to_area == common.TableArea.FOUNDATION:
            w_card = self._foundation.top_card(move.to_pile_id)
            self._waste.append(w_card)
            self._foundation.remove(move.to_pile_id)
        elif move.to_area == common.TableArea.STACK:
            self._waste = list(reversed(self._stack))
            self._stack = []
            w_len = len(self._waste)
            for i, w_card in enumerate(self._waste):
                pile_id = min(3, w_len - i - 1)
                w_card.visible = True
                self._callback(
                    w_card,
                    common.TableLocation(area=common.TableArea.WASTE,
                                         visible=True,
                                         pile_id=pile_id,
                                         card_id=i))
        else:
            return False
        self._reset_waste()
        return True
예제 #12
0
파일: table.py 프로젝트: tcdude/pyos
    def __waste_to_foundation(self, pile: Optional[int] = None) -> bool:
        """
        Tries to move a card from Waste to Foundation.

        Args:
            pile: pile index.

        Returns:
            True if a move is performed otherwise False.
        """
        w_card = self.waste_card
        if w_card is None:
            logger.debug('no waste card')
            return False
        dest_pile = self._foundation.add_card(w_card, pile)
        if dest_pile < 0:
            logger.debug('no valid move found')
            return False
        logger.debug('valid move found')
        self._history.append(
            Move(from_area=common.TableArea.WASTE,
                 from_pile_id=-1,
                 pile_count=1,
                 to_area=common.TableArea.FOUNDATION,
                 to_pile_id=dest_pile))
        self._waste.pop()
        self._state.points += 10
        self._callback(
            self._foundation.top_card(dest_pile),
            common.TableLocation(
                area=common.TableArea.FOUNDATION,
                visible=True,
                pile_id=dest_pile,
                card_id=len(self._foundation.piles[dest_pile]) - 1))
        self._reset_waste()
        return True
예제 #13
0
파일: table_layout.py 프로젝트: tcdude/pyos
    def __init__(self, card_ratio: float, padding: float,
                 status_size: Tuple[float, float],
                 toolbar_size: Tuple[float, float]) -> None:
        card_size = (1 / (7 + 8 * padding),
                     card_ratio * (1 / (7 + 8 * padding)))
        self._cfg = TableConfig(card_size=card_size,
                                padding=(card_size[0] * padding,
                                         card_size[1] * padding),
                                status_size=status_size,
                                toolbar_size=toolbar_size)
        root = node.Node('Table Root')
        root.distance_relative = True
        root.depth = -100
        self._nodes = TableNodes(
            root=root,
            stack=root.attach_image_node('Stack', common.STACK),
            waste=root.attach_node('Waste Root'),
            foundation=root.attach_node('Foundation Root'),
            tableau=root.attach_node('Tableau Root'),
            status=root.attach_node('Status'),
            toolbar=root.attach_node('Toolbar'))
        self._children = ChildNodes(
            waste=[
                self._nodes.waste.attach_image_node(f'Waste {i}', common.WASTE)
                if not i else self._nodes.waste.attach_node(f'Waste {i}')
                for i in range(4)
            ],
            foundation=[
                self._nodes.foundation.attach_image_node(
                    f'Foundation {i}', common.FOUNDATION) for i in range(4)
            ],
            tableau=[
                self._nodes.tableau.attach_image_node(f'Tableau {i}',
                                                      common.TABLEAU)
                for i in range(7)
            ])

        # Background
        background = self._nodes.root.attach_node('BG Root')
        background.depth = -500
        offset = .1
        for x_pos in range(26):
            for y_pos in range(26):
                tmp_node = background.attach_image_node(
                    image=common.BACKGROUND)
                tmp_node.pos = x_pos * offset, y_pos * offset
        self._v_offset = (0.0, self._cfg.card_size[1] / 3)

        # Cards
        card_dummy = self._nodes.root.attach_node('Card Layer')
        card_dummy.depth = 99
        self._cards: Dict[Tuple[int, int], CardNode] = {
            (suit, value):
            CardNode(k=(suit, value),
                     node=card_dummy.attach_image_node(
                         f'{suit},{value}', f'images/{common.COLORS[suit]}'
                         f'{common.DENOMINATIONS[value]}.png'),
                     location=common.TableLocation(area=common.TableArea.NONE,
                                                   visible=False))
            for suit in range(4) for value in range(13)
        }
        for k in self._cards:
            self._cards[k].node.add_image(common.CARDBACK)
            self._cards[k].node.index = 1

        self._drag_info: DragInfo = DragInfo()
        self._depth_queue = DepthQueue()
        self._relative_positions = RelativePositions(
            stack=vec2.Vec2(),
            waste=[vec2.Vec2() for _ in range(4)],
            foundation=[vec2.Vec2() for _ in range(4)],
            tableau=[vec2.Vec2() for _ in range(7)])
        self._table: Optional[Table] = None