Source code for hanabython.Modules.ConfigurationDeck

# -*- coding: utf-8 -*-
"""
Copyright François Durand
fradurand@gmail.com

This file is part of Hanabython.

    Hanabython is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    Hanabython is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with Hanabython.  If not, see <http://www.gnu.org/licenses/>.
"""
from typing import Iterable, Tuple
from hanabython.Modules.Colored import Colored
from hanabython.Modules.Color import Color
from hanabython.Modules.Colors import Colors
from hanabython.Modules.ConfigurationColorContents \
    import ConfigurationColorContents
from collections import OrderedDict


[docs]class ConfigurationDeck(Colored, OrderedDict): """ The contents of the deck for a game of Hanabi. This is essentially an OrderedDict. To each :class:`Color` in the deck, it associates the contents of the color, an object of class :class:`ConfigurationColorContents`. The order of the colors is important: it will be used in many occasions (including for display). :param contents: the iterable used to construct the ordered dictionary. Typically it is an :class:`OrderedDict` or a list of pairs (`color`, `contents`). :param name: the name of the configuration. Can be None (default value). Should not be capitalized (e.g. "my favorite configuration" and not "My favorite configuration"). >>> cfg = ConfigurationDeck.NORMAL >>> print(cfg.name) normal >>> print(cfg) normal >>> cfg = ConfigurationDeck( ... contents=[ ... (Colors.BLUE, ConfigurationColorContents.NORMAL), ... (Colors.RED, ConfigurationColorContents([3, 2, 1])) ... ] ... ) >>> print(cfg.name) None >>> print(cfg) B normal, R [3, 2, 1] """ def __init__(self, contents: Iterable[Tuple[Color, ConfigurationColorContents]], name: str = None): super(ConfigurationDeck, self).__init__(contents) self.name = name
[docs] def colored(self) -> str: if self.name is None: return ', '.join([ c.color_str('%s %s') % (c, v) for c, v in self.items() ]) else: return self.name
[docs] def copy(self) -> 'ConfigurationDeck': """ Copy the deck configuration. :return: a copy of this deck configuration. You can modify the copy without modifying the original. However, it is not a deep copy, (most of time, it would not be useful). >>> cfg = ConfigurationDeck.NORMAL.copy() >>> cfg.name = None >>> del(cfg[Colors.WHITE], cfg[Colors.YELLOW]) >>> print(cfg) B normal, G normal, R normal >>> print(ConfigurationDeck.NORMAL[Colors.WHITE]) normal """ return ConfigurationDeck(contents=self.items(), name=self.name)
[docs] @staticmethod def normal_plus( contents: Iterable[Tuple[Color, ConfigurationColorContents]], name: str = None ) -> 'ConfigurationDeck': """ Shortcut to define a deck configuration from the normal one. :param contents: the additional contents (typically multicolor, etc.) :param name: the name of the configuration. :return: the new configuration. >>> cfg = ConfigurationDeck.normal_plus(contents=[ ... (Colors.SIXTH, ConfigurationColorContents.NORMAL), ... (Colors.MULTICOLOR, ConfigurationColorContents.SHORT) ... ]) >>> print(cfg) B normal, G normal, R normal, W normal, Y normal, P normal, M short """ result = ConfigurationDeck.NORMAL.copy() result.update(contents) result.name = name return result
#: Normal deck (5 colors of 10 cards). NORMAL = None #: Deck with long sixth color (6 colors of 10 cards). W_SIXTH = None #: Deck with short sixth color (5 colors of 10 cards + 1 color of 5 cards). W_SIXTH_SHORT = None #: Deck with long multicolor (5 colors of 10 cards + 1 multi of 10 cards). W_MULTICOLOR = None #: Deck with short multicolor (5 colors of 10 cards + 1 multi of 5 cards). W_MULTICOLOR_SHORT = None #: Deck with 8 colors (6 colors + multicolor + colorless, all of 10 cards). EIGHT_COLORS = None
ConfigurationDeck.NORMAL = ConfigurationDeck( contents=[ (c, ConfigurationColorContents.NORMAL) for c in [Colors.BLUE, Colors.GREEN, Colors.RED, Colors.WHITE, Colors.YELLOW] ], name='normal' ) ConfigurationDeck.W_SIXTH = ConfigurationDeck.normal_plus( contents=[(Colors.SIXTH, ConfigurationColorContents.NORMAL)], name='with normal sixth color (10 cards)' ) ConfigurationDeck.W_SIXTH_SHORT = ConfigurationDeck.normal_plus( contents=[(Colors.SIXTH, ConfigurationColorContents.SHORT)], name='with short sixth color (5 cards)' ) ConfigurationDeck.W_MULTICOLOR = ConfigurationDeck.normal_plus( contents=[(Colors.MULTICOLOR, ConfigurationColorContents.NORMAL)], name='with normal multicolor (10 cards)' ) ConfigurationDeck.W_MULTICOLOR_SHORT = ConfigurationDeck.normal_plus( contents=[(Colors.MULTICOLOR, ConfigurationColorContents.SHORT)], name='with short multicolor (5 cards)' ) ConfigurationDeck.EIGHT_COLORS = ConfigurationDeck.normal_plus( contents=[ (Colors.SIXTH, ConfigurationColorContents.NORMAL), (Colors.MULTICOLOR, ConfigurationColorContents.NORMAL), (Colors.COLORLESS, ConfigurationColorContents.NORMAL) ], name='with sixth color, multicolor and colorless (10 cards each)' ) if __name__ == '__main__': print('A deck configuration with a name:') my_cfg = ConfigurationDeck.W_MULTICOLOR my_cfg.test_str() print('\nA deck configuration with no name:') my_cfg = ConfigurationDeck( contents=[ (Colors.BLUE, ConfigurationColorContents.NORMAL), (Colors.RED, ConfigurationColorContents([3, 2, 1])) ] ) my_cfg.test_str() print('\nChange a part of the configuration:') my_cfg[Colors.BLUE] = ConfigurationColorContents([1, 1]) print(my_cfg.colored()) print('\nTest the copy method:') my_cfg = ConfigurationDeck.NORMAL.copy() my_cfg.name = None del(my_cfg[Colors.BLUE]) print('New configuration:', my_cfg.colored()) print('Blue in the old configuration:', ConfigurationDeck.NORMAL[Colors.BLUE]) import doctest doctest.testmod()