././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1704433333.3020525 pysol_cards-0.16.0/0000755000076400007640000000000014545713265014070 5ustar00shlomifshlomif././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1704433292.0 pysol_cards-0.16.0/AUTHORS0000644000076400007640000000003714545713214015132 0ustar00shlomifshlomifShlomi Fish ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1704433293.0 pysol_cards-0.16.0/CHANGELOG.rst0000644000076400007640000000557414545713215016117 0ustar00shlomifshlomif===================== Appendix C. Changelog ===================== :Info: This is the changelog for pysol_cards. :Author: Shlomi Fish :Copyright: © 2020, Shlomi Fish. :License: BSD (see /LICENSE or :doc:`Appendix B `.) :Date: 2024-01-05 :Version: 0.16.0 .. index:: CHANGELOG GitHub holds releases, too ========================== More information can be found on GitHub in the `releases section `_. Version History =============== 0.16.0 ------ * Add support for dealing "binary_star". * Add tests. 0.14.3 ------ * Try to fix getstate() / setstate() ; with tests - https://github.com/shlomif/pysol_cards/issues/7 ( Thanks to @joeraz ) 0.14.2 ------ * Avoid requiring optional deps - https://github.com/shlomif/pysol_cards/issues/4 . 0.14.1 ------ * Avoid comments in requirements.txt - https://github.com/shlomif/pysol_cards/issues/4 . 0.14.0 ------ * Convert from pbr to https://pypi.org/project/pydistman/ . 0.12.0 ------ * bump ver * enhance the README * 'id' is a builtin * add a test using named arguments * optimize into a class var * optimize * add an integration test 0.10.2 ------ * setup.cfg: use underscores for identifiers 0.10.1 ------ * bump version * allow accepting "ms[0-9]+" game nums 0.10.0 ------ * add single\_deal\_args\_parse 0.8.18 ------ * bump version * optimize * add tests 0.8.17 ------ * better PySol compat: fix reset() 0.8.16 ------ * better PySol compat: str2int+int2str 0.8.15 ------ * bump version * better PySol compat: getstate * Extract a method or a function 0.8.14 ------ * add setstate 0.8.13 ------ * bump version * better PySol compat: getstate * better PySol compat: increaseSeed 0.8.12 ------ * bump version * better PySol compat 0.8.11 ------ * bump ver for real this time 0.8.10 ------ * better PySol compat 0.8.9 ----- * Python2 compatibility: add Game.next() (thanks to Travis-CI) 0.8.8 ----- * Clarified the license and copyright ownership * Add random2 to the requirements 0.8.7 ----- * add more * start adding \_\_init\_\_ * add .reset() 0.8.6 ----- * moved functionality to pysol-cards.py 0.8.5 ----- * add more pysol functionality 0.8.4 ----- * add pysol constants 0.8.3 ----- * add version 0.8.2 ----- * add some pysol methods 0.8.1 ----- * add match\_ms\_deal\_prefix * add match\_ms\_deal\_prefix 0.8.0 ----- * add seed-as-string 0.6.2 ----- * fix out of range deals 0.6.1 ----- * speedup 0.6.0 ----- * Extract random\_base as an attempt for optimize 0.4.3 ----- * fix super() * fix super() on python2 0.4.2 ----- * update metadata and text 0.4.1 ----- * fix print\_ in py v2 0.4.0 ----- * add the deal\_game module 0.2.2 ----- * fix oper sys cfg 0.2.1 ----- * fix mit license cfg 0.2.0 ----- * update meta data * change licence * add some tests * add the pysol\_cards.random module * add cards.py * Initial Cookiecutter Commit ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1704433292.0 pysol_cards-0.16.0/LICENSE0000644000076400007640000000275714545713214015102 0ustar00shlomifshlomifCopyright © 2020, Shlomi Fish. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions, and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions, and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. Neither the name of the author of this software nor the names of contributors to this software may be used to endorse or promote products derived from this software without specific prior written consent. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1704433292.0 pysol_cards-0.16.0/MANIFEST.in0000644000076400007640000000023714545713214015622 0ustar00shlomifshlomifgraft pysol_cards graft docs graft tests include README.rst AUTHORS LICENSE CHANGELOG.rst setup.py setup.cfg requirements.txt global-exclude __pycache__ *.pyc ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1704433333.3020525 pysol_cards-0.16.0/PKG-INFO0000644000076400007640000000711514545713265015171 0ustar00shlomifshlomifMetadata-Version: 2.1 Name: pysol_cards Version: 0.16.0 Summary: Deal PySol FC Cards Home-page: https://github.com/shlomif/pysol_cards Author: Shlomi Fish Author-email: shlomif@cpan.org License: 3-clause BSD Keywords: pysol_cards Platform: any Classifier: Development Status :: 1 - Planning Classifier: Programming Language :: Python Classifier: Programming Language :: Python :: 3 Classifier: Programming Language :: Python :: 3.6 Classifier: Programming Language :: Python :: 3.7 Classifier: Programming Language :: Python :: 3.8 Classifier: Programming Language :: Python :: 3.9 Classifier: Programming Language :: Python :: 3.10 Classifier: Programming Language :: Python :: 3.11 License-File: LICENSE License-File: AUTHORS ============================================================================== pysol_cards. Deal PySol FC Cards ============================================================================== :Info: This is the README file for pysol_cards. :Author: Shlomi Fish :Copyright: © 2020, Shlomi Fish. :Date: 2024-01-05 :Version: 0.16.0 .. index: README .. image:: https://travis-ci.org/shlomif/pysol_cards.svg?branch=master :target: https://travis-ci.org/shlomif/pysol_cards =============================== pysol_cards =============================== Deal PySol FC Cards The pysol-cards python modules allow the python developer to generate the initial deals of some PySol FC games. It also supports PySol legacy deals and Microsoft FreeCell / Freecell Pro deals. * Free software: Expat license * Documentation: pydoc * Source: https://github.com/shlomif/pysol_cards * Bugs: https://github.com/shlomif/pysol_cards/issues -------- Example: -------- :: from pysol_cards.cards import CardRenderer from pysol_cards.deal_game import Game from pysol_cards.random_base import RandomBase ms24_str = Game( game_id="freecell", game_num=24, which_deals=RandomBase.DEALS_MS, max_rank=13 ).calc_layout_string( CardRenderer(print_ts=True) ) print(ms24_str, end='') COPYRIGHT --------- Copyright © 2020, Shlomi Fish. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions, and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions, and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. Neither the name of the author of this software nor the names of contributors to this software may be used to endorse or promote products derived from this software without specific prior written consent. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1704433293.0 pysol_cards-0.16.0/README0000644000076400007640000000556414545713215014755 0ustar00shlomifshlomif============================================================================== pysol_cards. Deal PySol FC Cards ============================================================================== :Info: This is the README file for pysol_cards. :Author: Shlomi Fish :Copyright: © 2020, Shlomi Fish. :Date: 2024-01-05 :Version: 0.16.0 .. index: README .. image:: https://travis-ci.org/shlomif/pysol_cards.svg?branch=master :target: https://travis-ci.org/shlomif/pysol_cards =============================== pysol_cards =============================== Deal PySol FC Cards The pysol-cards python modules allow the python developer to generate the initial deals of some PySol FC games. It also supports PySol legacy deals and Microsoft FreeCell / Freecell Pro deals. * Free software: Expat license * Documentation: pydoc * Source: https://github.com/shlomif/pysol_cards * Bugs: https://github.com/shlomif/pysol_cards/issues -------- Example: -------- :: from pysol_cards.cards import CardRenderer from pysol_cards.deal_game import Game from pysol_cards.random_base import RandomBase ms24_str = Game( game_id="freecell", game_num=24, which_deals=RandomBase.DEALS_MS, max_rank=13 ).calc_layout_string( CardRenderer(print_ts=True) ) print(ms24_str, end='') COPYRIGHT --------- Copyright © 2020, Shlomi Fish. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions, and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions, and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. Neither the name of the author of this software nor the names of contributors to this software may be used to endorse or promote products derived from this software without specific prior written consent. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1704433293.0 pysol_cards-0.16.0/README.rst0000644000076400007640000000556414545713215015564 0ustar00shlomifshlomif============================================================================== pysol_cards. Deal PySol FC Cards ============================================================================== :Info: This is the README file for pysol_cards. :Author: Shlomi Fish :Copyright: © 2020, Shlomi Fish. :Date: 2024-01-05 :Version: 0.16.0 .. index: README .. image:: https://travis-ci.org/shlomif/pysol_cards.svg?branch=master :target: https://travis-ci.org/shlomif/pysol_cards =============================== pysol_cards =============================== Deal PySol FC Cards The pysol-cards python modules allow the python developer to generate the initial deals of some PySol FC games. It also supports PySol legacy deals and Microsoft FreeCell / Freecell Pro deals. * Free software: Expat license * Documentation: pydoc * Source: https://github.com/shlomif/pysol_cards * Bugs: https://github.com/shlomif/pysol_cards/issues -------- Example: -------- :: from pysol_cards.cards import CardRenderer from pysol_cards.deal_game import Game from pysol_cards.random_base import RandomBase ms24_str = Game( game_id="freecell", game_num=24, which_deals=RandomBase.DEALS_MS, max_rank=13 ).calc_layout_string( CardRenderer(print_ts=True) ) print(ms24_str, end='') COPYRIGHT --------- Copyright © 2020, Shlomi Fish. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions, and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions, and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. Neither the name of the author of this software nor the names of contributors to this software may be used to endorse or promote products derived from this software without specific prior written consent. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1704433333.2960525 pysol_cards-0.16.0/docs/0000755000076400007640000000000014545713265015020 5ustar00shlomifshlomif././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1704433293.0 pysol_cards-0.16.0/docs/CHANGELOG.rst0000644000076400007640000000103314545713215017031 0ustar00shlomifshlomif===================== Appendix C. Changelog ===================== :Info: This is the changelog for pysol_cards. :Author: Shlomi Fish :Copyright: © 2020, Shlomi Fish. :License: BSD (see /LICENSE or :doc:`Appendix B `.) :Date: 2024-01-05 :Version: 0.16.0 .. index:: CHANGELOG GitHub holds releases, too ========================== More information can be found on GitHub in the `releases section `_. Version History =============== 0.1.0 Initial release. ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1704433293.0 pysol_cards-0.16.0/docs/CONTRIBUTING.rst0000644000076400007640000000423614545713215017461 0ustar00shlomifshlomif============================== Appendix A. Contribution rules ============================== :Info: Those are the contribution rules for pysol_cards. :Copyright: © 2012-2023, Chris Warrick. :License: 3-clause BSD .. index:: contributing Do you want to contribute to this project? Great! I’d love to see some help, but you must comply with some rules. The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL” in this document are to be interpreted as described in RFC 2119. --------------- Issue reporting --------------- .. index:: issues GitHub Issues are the recommended way to report an issue. If you do not have an account there, get one or mail me. When pasting console sessions, you must paste them fully, *prompt-to-prompt*, to see all the messages and your input. Trim only stuff that you are 1000% sure that is not related to the project in question. -------------------------------------------- General preparations, rules and pull process -------------------------------------------- Prepare ======= A GitHub account is recommended. Patches by mail are accepted, but I’d prefer to work via GitHub. .. _Rules: Rules ===== 1. Commits must have short, informative and logical messages. Signoffs and long messages are recommended. “Fix #xxx” is required if an issue exists. 2. The following fancy Unicode characters should be used when needed: ``— “ ” ‘ ’``. ``…`` should not appear in console output, but may appear elsewhere. 3. For Python code, use the PEP 8 coding style and PEP 257 documentation style. For other languages, K&R style applies. Braces are mandatory in all blocks (even one-line blocks). Braces are on the same lines as class names and function signatures. Use 4-space indents. Request a Pull ============== Done? Go hit the **Pull Request** button over on GitHub! And if you don’t use GitHub, ``git format-patch``. Other formats are not accepted. Your commit should be pulled up in a (longer) while. If I like it. Because some commits may be bad. So, do your best not to do those bad commits. ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1704433293.0 pysol_cards-0.16.0/docs/LICENSE.rst0000644000076400007640000000355614545713215016640 0ustar00shlomifshlomif======================================================= Appendix B. License for pysol_cards ======================================================= :Info: This is the license for pysol_cards. :Author: Shlomi Fish :Copyright: © 2020, Shlomi Fish. :License: BSD (see /LICENSE or :doc:`Appendix B `.) :Date: 2024-01-05 :Version: 0.16.0 .. index:: LICENSE Copyright © 2020, Shlomi Fish. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions, and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions, and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. Neither the name of the author of this software nor the names of contributors to this software may be used to endorse or promote products derived from this software without specific prior written consent. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1704433293.0 pysol_cards-0.16.0/docs/README.rst0000644000076400007640000000556414545713215016514 0ustar00shlomifshlomif============================================================================== pysol_cards. Deal PySol FC Cards ============================================================================== :Info: This is the README file for pysol_cards. :Author: Shlomi Fish :Copyright: © 2020, Shlomi Fish. :Date: 2024-01-05 :Version: 0.16.0 .. index: README .. image:: https://travis-ci.org/shlomif/pysol_cards.svg?branch=master :target: https://travis-ci.org/shlomif/pysol_cards =============================== pysol_cards =============================== Deal PySol FC Cards The pysol-cards python modules allow the python developer to generate the initial deals of some PySol FC games. It also supports PySol legacy deals and Microsoft FreeCell / Freecell Pro deals. * Free software: Expat license * Documentation: pydoc * Source: https://github.com/shlomif/pysol_cards * Bugs: https://github.com/shlomif/pysol_cards/issues -------- Example: -------- :: from pysol_cards.cards import CardRenderer from pysol_cards.deal_game import Game from pysol_cards.random_base import RandomBase ms24_str = Game( game_id="freecell", game_num=24, which_deals=RandomBase.DEALS_MS, max_rank=13 ).calc_layout_string( CardRenderer(print_ts=True) ) print(ms24_str, end='') COPYRIGHT --------- Copyright © 2020, Shlomi Fish. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions, and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions, and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. Neither the name of the author of this software nor the names of contributors to this software may be used to endorse or promote products derived from this software without specific prior written consent. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1704433293.0 pysol_cards-0.16.0/docs/conf.py0000644000076400007640000001641714545713215016323 0ustar00shlomifshlomif# -*- coding: utf-8 -*- # # pysol_cards documentation build configuration file, created by # sphinx-quickstart on Fri Dec 14 21:02:58 2012. # # This file is execfile()d with the current directory set to its containing dir. # # Note that not all possible configuration values are present in this # autogenerated file. # # All configuration values have a default; values that are commented out # serve to show the default. import sys, os # If extensions (or modules to document with autodoc) are in another directory, # add these directories to sys.path here. If the directory is relative to the # documentation root, use os.path.abspath to make it absolute, like shown here. #sys.path.insert(0, os.path.abspath('.')) # -- General configuration ----------------------------------------------------- # If your documentation needs a minimal Sphinx version, state it here. #needs_sphinx = '1.0' # Add any Sphinx extension module names here, as strings. They can be extensions # coming with Sphinx (named 'sphinx.ext.*') or your custom ones. extensions = ['sphinx.ext.autodoc', 'sphinx.ext.doctest', 'sphinx.ext.intersphinx', 'sphinx.ext.todo', 'sphinx.ext.coverage', 'sphinx.ext.ifconfig', 'sphinx.ext.viewcode'] # Add any paths that contain templates here, relative to this directory. templates_path = ['_templates'] # The suffix of source filenames. source_suffix = '.rst' # The encoding of source files. #source_encoding = 'utf-8-sig' # The master toctree document. master_doc = 'index' # General information about the project. project = u'pysol_cards' copyright = u'2020, Shlomi Fish' # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the # built documents. # # The short X.Y version. version = '0.16.0' # The full version, including alpha/beta/rc tags. release = '0.16.0' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. #language = None # There are two options for replacing |today|: either, you set today to some # non-false value, then it is used: #today = '' # Else, today_fmt is used as the format for a strftime call. #today_fmt = '%B %d, %Y' # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. exclude_patterns = ['_build'] # The reST default role (used for this markup: `text`) to use for all documents. #default_role = None # If true, '()' will be appended to :func: etc. cross-reference text. #add_function_parentheses = True # If true, the current module name will be prepended to all description # unit titles (such as .. function::). #add_module_names = True # If true, sectionauthor and moduleauthor directives will be shown in the # output. They are ignored by default. #show_authors = False # The name of the Pygments (syntax highlighting) style to use. pygments_style = 'sphinx' # A list of ignored prefixes for module index sorting. #modindex_common_prefix = [] # -- Options for HTML output --------------------------------------------------- # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. html_theme = 'default' # Theme options are theme-specific and customize the look and feel of a theme # further. For a list of options available for each theme, see the # documentation. #html_theme_options = {} # Add any paths that contain custom themes here, relative to this directory. #html_theme_path = [] # The name for this set of Sphinx documents. If None, it defaults to # " v documentation". #html_title = None # A shorter title for the navigation bar. Default is the same as html_title. #html_short_title = None # The name of an image file (relative to this directory) to place at the top # of the sidebar. #html_logo = None # The name of an image file (within the static path) to use as favicon of the # docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 # pixels large. #html_favicon = None # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, # so a file named "default.css" will overwrite the builtin "default.css". html_static_path = ['_static'] # If not '', a 'Last updated on:' timestamp is inserted at every page bottom, # using the given strftime format. #html_last_updated_fmt = '%b %d, %Y' # If true, SmartyPants will be used to convert quotes and dashes to # typographically correct entities. #html_use_smartypants = True # Custom sidebar templates, maps document names to template names. #html_sidebars = {} # Additional templates that should be rendered to pages, maps page names to # template names. #html_additional_pages = {} # If false, no module index is generated. #html_domain_indices = True # If false, no index is generated. #html_use_index = True # If true, the index is split into individual pages for each letter. #html_split_index = False # If true, links to the reST sources are added to the pages. #html_show_sourcelink = True # If true, "Created using Sphinx" is shown in the HTML footer. Default is True. #html_show_sphinx = True # If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. #html_show_copyright = True # If true, an OpenSearch description file will be output, and all pages will # contain a tag referring to it. The value of this option must be the # base URL from which the finished HTML is served. #html_use_opensearch = '' # This is the file name suffix for HTML files (e.g. ".xhtml"). #html_file_suffix = None # Output file base name for HTML help builder. htmlhelp_basename = 'pysol_cardsdoc' # -- Options for LaTeX output -------------------------------------------------- # The paper size ('letter' or 'a4'). #latex_paper_size = 'letter' # The font size ('10pt', '11pt' or '12pt'). #latex_font_size = '10pt' # Grouping the document tree into LaTeX files. List of tuples # (source start file, target name, title, author, documentclass [howto/manual]). latex_documents = [ ('index', 'pysol_cards.tex', u'pysol_cards Documentation', u'Shlomi Fish', 'manual'), ] latex_elements = {'papersize': 'a4paper', 'fontpkg': '\\usepackage{tgheros}', 'fncychap': '\\usepackage[Sonny]{fncychap}'} # The name of an image file (relative to this directory) to place at the top of # the title page. #latex_logo = None # For "manual" documents, if this is true, then toplevel headings are parts, # not chapters. #latex_use_parts = False # If true, show page references after internal links. #latex_show_pagerefs = False # If true, show URL addresses after external links. #latex_show_urls = False # Additional stuff for the LaTeX preamble. #latex_preamble = '' # Documents to append as an appendix to all manuals. #latex_appendices = [] # If false, no module index is generated. #latex_domain_indices = True # -- Options for manual page output -------------------------------------------- # One entry per manual page. List of tuples # (source start file, name, description, authors, manual section). man_pages = [ ('index', 'pysol_cards', u'pysol_cards Documentation', [u'Shlomi Fish'], 1) ] # Example configuration for intersphinx: refer to the Python standard library. intersphinx_mapping = {'http://docs.python.org/': None} ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1704433333.2970526 pysol_cards-0.16.0/docs/html/0000755000076400007640000000000014545713265015764 5ustar00shlomifshlomif././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1704433293.0 pysol_cards-0.16.0/docs/html/index.html0000644000076400007640000000051514545713215017755 0ustar00shlomifshlomif Redirecting to Read The Docs The docs are at pysol_cards.readthedocs.org. You will be redirected there in a while. If not, click the link above. ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1704433293.0 pysol_cards-0.16.0/docs/index.rst0000644000076400007640000000042214545713215016652 0ustar00shlomifshlomif=============================== pysol_cards =============================== .. toctree:: :maxdepth: 2 README for pysol_cards CONTRIBUTING LICENSE CHANGELOG Indices and tables ================== * :ref:`genindex` * :ref:`modindex` * :ref:`search` ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1704433333.2990525 pysol_cards-0.16.0/pysol_cards/0000755000076400007640000000000014545713265016412 5ustar00shlomifshlomif././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1704433293.0 pysol_cards-0.16.0/pysol_cards/__init__.py0000755000076400007640000000377114545713215020531 0ustar00shlomifshlomif# -*- encoding: utf-8 -*- # pysol_cards v0.16.0 # Deal PySol FC Cards # Copyright © 2020, Shlomi Fish. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # 1. Redistributions of source code must retain the above copyright # notice, this list of conditions, and the following disclaimer. # # 2. Redistributions in binary form must reproduce the above copyright # notice, this list of conditions, and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # 3. Neither the name of the author of this software nor the names of # contributors to this software may be used to endorse or promote # products derived from this software without specific prior written # consent. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. """ Deal PySol FC Cards :Copyright: © 2020, Shlomi Fish. :License: BSD (see /LICENSE). """ __title__ = 'pysol_cards' __version__ = '0.16.0' __author__ = 'Shlomi Fish' __license__ = '3-clause BSD' __docformat__ = 'restructuredtext en' __all__ = () # import gettext # G = gettext.translation('pysol_cards', '/usr/share/locale', fallback='C') # _ = G.gettext VERSION = __version__ = (0, 12, 0) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1704433293.0 pysol_cards-0.16.0/pysol_cards/__main__.py0000755000076400007640000000076514545713215020512 0ustar00shlomifshlomif# -*- encoding: utf-8 -*- # pysol_cards v0.16.0 # Deal PySol FC Cards # Copyright © 2020, Shlomi Fish. # See /LICENSE for licensing information. """ Main routine of pysol_cards. :Copyright: © 2020, Shlomi Fish. :License: BSD (see /LICENSE). """ __all__ = ('main',) def main(): """Main routine of pysol_cards.""" print("Hello, world!") print("This is pysol_cards.") print("You should customize __main__.py to your liking (or delete it).") if __name__ == '__main__': main() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1704433293.0 pysol_cards-0.16.0/pysol_cards/cards.py0000644000076400007640000000347214545713215020061 0ustar00shlomifshlomif#! /usr/bin/env python # -*- coding: utf-8 -*- # vim:fenc=utf-8 # # Copyright © 2019 Shlomi Fish # # Distributed under terms of the Expat license. """ """ class Card(object): ACE = 1 KING = 13 def __init__(self, id, rank, suit): self.id, self.rank, self.suit = id, rank, suit self.empty, self.flipped = False, False def suit_s(self): return 'CSHD'[self.suit] def is_ace(self): return self.rank == self.ACE def is_king(self): return self.rank == self.KING def flip(self, flipped=True): ret = Card(self.id, self.rank, self.suit) ret.flipped = flipped return ret class CardRenderer(object): """docstring for CardRenderer""" def __init__(self, print_ts): self.print_ts = print_ts def to_s(self, card): if card.empty: return '-' ret = self.rank_s(card) + card.suit_s() if card.flipped: ret = '<' + ret + '>' return ret def found_s(self, card): return card.suit_s() + '-' + self.rank_s(card) def rank_s(self, card): ret = "0A23456789TJQK"[card.rank] if ((not self.print_ts) and ret == 'T'): ret = '10' return ret def render_l(self, lst): return [self.to_s(x) for x in lst] def l_concat(self, lst): return ' '.join(self.render_l(lst)) def createCards(num_decks, max_rank=13): ret = [] id_ = 0 for _ in range(num_decks): for s in range(4): for r in range(max_rank): ret.append(Card(id_, r + 1, s)) id_ += 1 return ret def ms_rearrange(cards): if len(cards) != 52: return cards c = [] for i in range(13): for j in (0, 39, 26, 13): c.append(cards[i + j]) return c ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1704433293.0 pysol_cards-0.16.0/pysol_cards/deal_game.py0000644000076400007640000002717114545713215020665 0ustar00shlomifshlomif# -*- coding: utf-8 -*- # vim:fenc=utf-8 # # Copyright © 2019 Shlomi Fish # # Distributed under terms of the Expat license. """ """ from pysol_cards.cards import Card from pysol_cards.cards import createCards from pysol_cards.random import shuffle from six import print_ def empty_card(): ret = Card(0, 0, 0) ret.empty = True return ret class Columns(object): def __init__(self, num): self.cols = [[] for _ in range(num)] def add(self, idx, card): self.cols[idx].append(card) def rev(self): self.cols.reverse() class Board(object): def __init__(self, num_columns, with_freecells=False, with_talon=False, with_foundations=False): self.with_freecells = with_freecells self.with_talon = with_talon self.with_foundations = with_foundations self.raw_foundations_cb = None self.raw_foundations_line = None self.columns = Columns(num_columns) if self.with_freecells: self.freecells = [] if self.with_talon: self.talon = [] if self.with_foundations: self.foundations = [empty_card() for s in range(4)] self._lines = [] def add_line(self, string): self._lines.append(string) def reverse_cols(self): self.columns.rev() def add(self, idx, card): self.columns.add(idx, card) def add_freecell(self, card): if not self.with_freecells: raise AttributeError("Layout does not have freecells!") self.freecells.append(card) def add_talon(self, card): if not self.with_talon: raise AttributeError("Layout does not have a talon!") self.talon.append(card) def put_into_founds(self, card): if not self.with_foundations: raise AttributeError("Layout does not have foundations!") res = self.foundations[card.suit].rank + 1 == card.rank if res: self.foundations[card.suit] = card return res def print_foundations(self, renderer): cells = [] for f in [2, 0, 3, 1]: if not self.foundations[f].empty: cells.append(renderer.found_s(self.foundations[f])) if len(cells): self.add_line("Foundations:" + ("".join([" " + s for s in cells]))) def gen_lines(self, renderer): self._lines = [] if self.with_talon: self.add_line("Talon: " + renderer.l_concat(self.talon)) if self.with_foundations: self.print_foundations(renderer) if self.raw_foundations_cb: self.add_line(self.raw_foundations_cb(renderer)) elif self.raw_foundations_line: self.add_line(self.raw_foundations_line) if self.with_freecells: self.add_line("Freecells: " + renderer.l_concat(self.freecells)) self._lines += [renderer.l_concat(c) for c in self.columns.cols] def calc_string(self, renderer): self.gen_lines(renderer) return "".join(line + "\n" for line in self._lines) class Game(object): REVERSE_MAP = \ { "freecell": ["forecell", "bakers_game", "ko_bakers_game", "kings_only_bakers_game", "relaxed_freecell", "eight_off"], "der_katz": ["der_katzenschwantz", "die_schlange"], "seahaven": ["seahaven_towers", "relaxed_seahaven", "relaxed_seahaven_towers"], "bakers_dozen": [], "gypsy": [], "klondike": ["klondike_by_threes", "casino_klondike", "small_harp", "thumb_and_pouch", "vegas_klondike", "whitehead"], "simple_simon": [], "yukon": [], "beleaguered_castle": ["streets_and_alleys", "citadel"], "fan": [], "black_hole": [], "all_in_a_row": [], "golf": [], "binary_star": [], } GAMES_MAP = {} for k, v in REVERSE_MAP.items(): for name in [k] + v: GAMES_MAP[name] = k def __init__(self, game_id, game_num, which_deals, max_rank=13): self.game_id = game_id self.game_num = game_num self.which_deals = which_deals self.max_rank = max_rank self.game_class = self.GAMES_MAP[self.game_id] if not self.game_class: raise ValueError("Unknown game type " + self.game_id + "\n") def is_two_decks(self): return self.game_id in ( "binary_star", "der_katz", "der_katzenschwantz", "die_schlange", "gypsy" ) def get_num_decks(self): return 2 if self.is_two_decks() else 1 def calc_deal_string(self, game_num, renderer): self.game_num = game_num self.deal() getattr(self, self.game_class)() return self.board.calc_string(renderer) def calc_layout_string(self, renderer): self.deal() getattr(self, self.game_class)() return self.board.calc_string(renderer) def print_layout(self, renderer): print_(self.calc_layout_string(renderer), sep='', end='') def new_cards(self, cards): self.cards = cards self.card_idx = 0 def deal(self): cards = shuffle(createCards(self.get_num_decks(), self.max_rank), self.game_num, self.which_deals) cards.reverse() self.new_cards(cards) def __iter__(self): return self def no_more_cards(self): return self.card_idx >= len(self.cards) def __next__(self): if self.no_more_cards(): raise StopIteration c = self.cards[self.card_idx] self.card_idx += 1 return c def next(self): return self.__next__() def add(self, idx, card): self.board.add(idx, card) def add_freecell(self, card): self.board.add_freecell(card) def cyclical_deal(self, num_cards, num_cols, flipped=False): for i in range(num_cards): self.add(i % num_cols, next(self).flip(flipped=flipped)) def add_all_to_talon(self): for c in self: self.board.add_talon(c) def add_empty_fc(self): self.add_freecell(empty_card()) def _shuffleHookMoveSorter(self, cards, cb, ncards): extracted, i, new = [], len(cards), [] for c in cards: select, ord_ = cb(c) if select: extracted.append((ord_, i, c)) if len(extracted) >= ncards: new += cards[(len(cards) - i + 1):] break else: new.append(c) i -= 1 return new, [x[2] for x in reversed(sorted(extracted))] def _shuffleHookMoveToBottom(self, inp, cb, ncards=999999): cards, scards = self._shuffleHookMoveSorter(inp, cb, ncards) return scards + cards def _shuffleHookMoveToTop(self, inp, cb, ncards=999999): cards, scards = self._shuffleHookMoveSorter(inp, cb, ncards) return cards + scards def all_in_a_row(game): game.board = Board(13) game.cards = game._shuffleHookMoveToTop( game.cards, lambda c: (c.id == 13, c.suit), 1) game.cyclical_deal(52, 13) game.board.raw_foundations_line = 'Foundations: -' def bakers_dozen(game): n = 13 cards = list(reversed(game.cards)) for i in [i for i, c in enumerate(cards) if c.is_king()]: j = i % n while j < i: if not cards[j].is_king(): cards[i], cards[j] = cards[j], cards[i] break j += n game.new_cards(cards) game.board = Board(13) game.cyclical_deal(52, 13) def beleaguered_castle(game): game.board = Board(8, with_foundations=True) if game.game_id in ('beleaguered_castle', 'citadel'): new = [] for c in game: if c.is_ace(): game.board.put_into_founds(c) else: new.append(c) game.new_cards(new) for _ in range(6): for s in range(8): c = next(game) cond1 = game.game_id == 'citadel' if not (cond1 and game.board.put_into_founds(c)): game.add(s, c) if game.no_more_cards(): break if game.game_id == 'streets_and_alleys': game.cyclical_deal(4, 4) def _black_hole_generic(game, num_decks, excludes, f): game.board = Board(17) game.cards = game._shuffleHookMoveToBottom( game.cards, lambda c: (c.id in excludes, c.suit), 2) for _ in range(num_decks): next(game) game.cyclical_deal(num_decks * (52 - 1), 17) game.board.raw_foundations_line = 'Foundations: ' + f def binary_star(game): return game._black_hole_generic( num_decks=2, excludes=frozenset((13, 38)), f='AS KH') def black_hole(game): return game._black_hole_generic( num_decks=1, excludes=frozenset((13, )), f='AS') def der_katz(game): is_ds = game.game_id == 'die_schlange' if is_ds: print_('Foundations: H-A S-A D-A C-A H-A S-A D-A C-A') game.board = Board(9) i = 0 for c in game: if c.is_king(): i += 1 if not (is_ds and c.is_ace()): game.add(i, c) def fan(game): game.board = Board(18) game.cyclical_deal(52 - 1, 17) game.add(17, next(game)) def freecell(game): is_fc = (game.game_id in ("forecell", "eight_off")) game.board = Board(8, with_freecells=is_fc) max_rank = (game.max_rank - 1 if is_fc else game.max_rank) game.cyclical_deal(4 * max_rank, 8) if is_fc: for c in game: game.add_freecell(c) if game.game_id == "eight_off": game.add_empty_fc() def golf(game): num_cols = 7 game.board = Board(num_cols, with_talon=True) game.cyclical_deal(num_cols * 5, num_cols) game.add_all_to_talon() card = game.board.talon.pop(0) game.board.raw_foundations_cb = lambda renderer: 'Foundations: ' + \ renderer.l_concat([card]) def gypsy(game): num_cols = 8 game.board = Board(num_cols, with_talon=True) game.cyclical_deal(num_cols * 2, num_cols, flipped=True) game.cyclical_deal(num_cols, num_cols) game.add_all_to_talon() def klondike(game): num_cols = 7 game.board = Board(num_cols, with_talon=True) for r in range(num_cols - 1, 0, -1): game.cyclical_deal(r, r, flipped=True) game.cyclical_deal(num_cols, num_cols) game.add_all_to_talon() if not (game.game_id == 'small_harp'): game.board.reverse_cols() def seahaven(game): game.board = Board(10, with_freecells=True) game.cyclical_deal(50, 10) game.add_empty_fc() for c in game: game.add_freecell(c) def simple_simon(game): game.board = Board(10) for num_cards in range(9, 2, -1): game.cyclical_deal(num_cards, num_cards) game.cyclical_deal(10, 10) def yukon(game): num_cols = 7 game.board = Board(num_cols) for i in range(1, num_cols): for j in range(i, num_cols): game.add(j, next(game).flip()) for i in range(4): for j in range(1, num_cols): game.add(j, next(game)) game.cyclical_deal(num_cols, num_cols) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1704433293.0 pysol_cards-0.16.0/pysol_cards/errors.py0000644000076400007640000000033014545713215020267 0ustar00shlomifshlomif#! /usr/bin/env python # -*- coding: utf-8 -*- # vim:fenc=utf-8 # # Copyright © 2019 Shlomi Fish # # Distributed under terms of the MIT license. class SubclassResponsibility(Exception): pass ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1704433293.0 pysol_cards-0.16.0/pysol_cards/random.py0000644000076400007640000001172414545713215020244 0ustar00shlomifshlomif#! /usr/bin/env python # -*- coding: utf-8 -*- # vim:fenc=utf-8 # # Copyright © 2019 Shlomi Fish # # Distributed under terms of the Expat license. import re from pysol_cards.cards import ms_rearrange from pysol_cards.random_base import RandomBase import random2 class PysolRandom(RandomBase): def setSeed(self, seed): seed = self._convertSeed(seed) if not 0 <= seed <= self.MAX_SEED: raise ValueError("seed is out of range") self.seed = seed return seed def _convertSeed(self, seed): return int(seed) # /*********************************************************************** # // Linear Congruential random generator # // # // Knuth, Donald.E., "The Art of Computer Programming,", Vol 2, # // Seminumerical Algorithms, Third Edition, Addison-Wesley, 1998, # // p. 106 (line 26) & p. 108 # ************************************************************************/ class _LCBase(PysolRandom): def __init__(self, seed=None): if seed is None: seed = self._getRandomSeed() PysolRandom.__init__(self, seed) self.initial_seed = seed self.setSeed(seed) self.origin = self.ORIGIN_UNKNOWN def reset(self): self.setSeed(self.initial_seed) def getSeedAsStr(self): return self._getSeedStrPrefix() + str(self.seed) def getSeedStr(self): return self._getSeedStrPrefix() + str(self.initial_seed) class LCRandom64(_LCBase): MAX_SEED = 0xffffffffffffffff # 64 bits def random(self): self.seed = (self.seed * 6364136223846793005 + 1) & self.MAX_SEED return ((self.seed >> 21) & 0x7fffffff) / 2147483648.0 def _getSeedStrPrefix(self): return "old" class LCRandom31(_LCBase): MAX_SEED = ((1 << (31 + 2)) - 1) # 33 bits def setSeed(self, seed): if not 1 <= seed <= self.MAX_SEED: raise ValueError("seed is out of range") self.seed = seed self.seedx = seed if (seed < 0x100000000) else (seed - 0x100000000) return self.seed def random(self): if (self.seed < 0x100000000): ret = self._rand() return (ret if (self.seed < 0x80000000) else (ret | 0x8000)) else: return self._randp() + 1 def _randp(self): self.seedx = ((self.seedx) * 214013 + 2531011) & self.MAX_SEED return (self.seedx >> 16) & 0xffff def _rand(self): self.seedx = ((self.seedx) * 214013 + 2531011) & self.MAX_SEED return (self.seedx >> 16) & 0x7fff def randint(self, a, b): return a + self.random() % (b + 1 - a) def _getSeedStrPrefix(self): return "ms" def increaseSeed(self, seed): """docstring for increaseSeed""" integer_seed = super(LCRandom31, self).increaseSeed(seed) return "ms{}".format(integer_seed) def str(self, seed): if match_ms_deal_prefix(seed) is None: return "%05d" % int(seed) return seed def getstate(self): return ( self.seed, self.seedx, ) def setstate(self, token): (self.seed, self.seedx,) = token # * Mersenne Twister random number generator class MTRandom(RandomBase, random2.Random): MAX_SEED = 100000000000000000000 # 20 digits def __init__(self, seed=None): if seed is None: seed = self._getRandomSeed() RandomBase.__init__(self) random2.Random.__init__(self, seed) self.initial_seed = seed self.initial_state = self.getstate() self.origin = self.ORIGIN_UNKNOWN def getstate(self): return ( RandomBase.getstate(self), random2.Random.getstate(self) ) def setstate(self, token): base, r2 = token RandomBase.setstate(self, base) random2.Random.setstate(self, r2) def setSeed(self, seed): random2.Random.__init__(self, seed) self.initial_state = self.getstate() return seed def reset(self): self.setSeed(self.initial_seed) def shuffle(cards, game_num, which_deals): ms = ((game_num <= 32000) or (which_deals == RandomBase.DEALS_MS)) r = LCRandom31() if ms else MTRandom() if which_deals == \ RandomBase.DEALS_PYSOLFC else LCRandom64() r.setSeed(game_num) return r.shuffle(ms_rearrange(cards) if ms else cards) _ms_pat = re.compile("ms([0-9]+)\\n?\\Z") def match_ms_deal_prefix(mystring): ret = re.match(_ms_pat, mystring) return None if not ret else int(ret.group(1)) MS_LONG_BIT = (1 << 1000) CUSTOM_BIT = (1 << 999) def random__str2int(s): if s == 'Custom': return CUSTOM_BIT | MS_LONG_BIT m = match_ms_deal_prefix(s) if m is not None: return (m | MS_LONG_BIT) else: return int(s) def random__int2str(myint): if ((myint & MS_LONG_BIT) != 0): if ((myint & CUSTOM_BIT) != 0): return 'Custom' return "ms" + str(myint & (~ MS_LONG_BIT)) else: return str(myint) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1704433293.0 pysol_cards-0.16.0/pysol_cards/random_base.py0000644000076400007640000000420014545713215021225 0ustar00shlomifshlomif#! /usr/bin/env python # -*- coding: utf-8 -*- # vim:fenc=utf-8 # # Copyright © 2019 Shlomi Fish # # Distributed under terms of the MIT license. from pysol_cards.errors import SubclassResponsibility class RandomBase(object): DEALS_PYSOL = 0 DEALS_PYSOLFC = 1 DEALS_MS = 2 MAX_SEED = 10 ** 20 ORIGIN_UNKNOWN = 0 ORIGIN_RANDOM = 1 ORIGIN_PREVIEW = 2 ORIGIN_SELECTED = 3 ORIGIN_NEXT_GAME = 4 def __init__(self, seed=None): """docstring for __init__""" self.seed_as_string = None def shuffle(self, seq): for n in range(len(seq) - 1, 0, -1): j = self.randint(0, n) seq[n], seq[j] = seq[j], seq[n] return seq def randint(self, a, b): """ Get a random integer in the range [a, b] including both ends.""" return a + int(self.random() * (b + 1 - a)) def randrange(self, a, b): """ Get a random integer in the range [a, b) excluding b.""" return self.randint(a, b - 1) def choice(self, sequence): """ Pick a random element of sequence """ return sequence[self.randrange(0, len(sequence))] def setSeedAsStr(self, new_s): self.seed_as_string = new_s def getSeedAsStr(self): if self.seed_as_string: return self.seed_as_string return str(self) def getSeedStr(self): return str(self.initial_seed) def __str__(self): return self.str(self.initial_seed) def str(self, seed): return '%020d' % (seed) def increaseSeed(self, seed): if seed < self.MAX_SEED: return seed + 1 return 0 def copy(self): ret = self.__class__() ret.__dict__.update(self.__dict__) return ret def reset(self): raise SubclassResponsibility def _getRandomSeed(self): import time ret = int(time.time() * 256.0) return ((ret ^ (ret >> 24)) % (self.MAX_SEED + 1)) def getstate(self): """getstate() for PySolFC""" return self.seed def setstate(self, new_state): """set to a new state""" self.seed = new_state ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1704433293.0 pysol_cards-0.16.0/pysol_cards/single_deal_args_parse.py0000644000076400007640000000270014545713215023432 0ustar00shlomifshlomif# -*- coding: utf-8 -*- # vim:fenc=utf-8 # # Copyright © 2020 Shlomi Fish # # Distributed under terms of the MIT license. """ """ from pysol_cards.random import RandomBase from pysol_cards.random import match_ms_deal_prefix class SingleDealArgsParser(object): def __init__(self, args): self.print_ts = False self.which_deals = RandomBase.DEALS_PYSOL self.max_rank = 13 while args[1][0] == '-': a = args[1] args.pop(1) if a == "-t": self.print_ts = True elif (a == "--max-rank"): self.max_rank = int(args.pop(1)) elif (a == "--pysolfc") or (a == "-F"): self.which_deals = RandomBase.DEALS_PYSOLFC elif (a == "--ms") or (a == "-M"): self.which_deals = RandomBase.DEALS_MS else: raise ValueError("Unknown flag " + a + "!") game_num_s = args[1] msgame = match_ms_deal_prefix(game_num_s) if msgame is not None: if self.which_deals == RandomBase.DEALS_MS or \ self.which_deals == RandomBase.DEALS_PYSOL: self.which_deals = RandomBase.DEALS_MS self.game_num = msgame else: raise ValueError("ms deals mismatch") else: self.game_num = int(game_num_s) self.which_game = args[2] if len(args) >= 3 else "freecell" ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1704433293.0 pysol_cards-0.16.0/pysol_cards/template.py0000755000076400007640000000041214545713215020572 0ustar00shlomifshlomif# -*- encoding: utf-8 -*- # pysol_cards v0.16.0 # Deal PySol FC Cards # Copyright © 2020, Shlomi Fish. # See /LICENSE for licensing information. """ INSERT MODULE DESCRIPTION HERE. :Copyright: © 2020, Shlomi Fish. :License: BSD (see /LICENSE). """ __all__ = () ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1704433333.3010526 pysol_cards-0.16.0/pysol_cards.egg-info/0000755000076400007640000000000014545713265020104 5ustar00shlomifshlomif././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1704433332.0 pysol_cards-0.16.0/pysol_cards.egg-info/PKG-INFO0000644000076400007640000000711514545713264021204 0ustar00shlomifshlomifMetadata-Version: 2.1 Name: pysol-cards Version: 0.16.0 Summary: Deal PySol FC Cards Home-page: https://github.com/shlomif/pysol_cards Author: Shlomi Fish Author-email: shlomif@cpan.org License: 3-clause BSD Keywords: pysol_cards Platform: any Classifier: Development Status :: 1 - Planning Classifier: Programming Language :: Python Classifier: Programming Language :: Python :: 3 Classifier: Programming Language :: Python :: 3.6 Classifier: Programming Language :: Python :: 3.7 Classifier: Programming Language :: Python :: 3.8 Classifier: Programming Language :: Python :: 3.9 Classifier: Programming Language :: Python :: 3.10 Classifier: Programming Language :: Python :: 3.11 License-File: LICENSE License-File: AUTHORS ============================================================================== pysol_cards. Deal PySol FC Cards ============================================================================== :Info: This is the README file for pysol_cards. :Author: Shlomi Fish :Copyright: © 2020, Shlomi Fish. :Date: 2024-01-05 :Version: 0.16.0 .. index: README .. image:: https://travis-ci.org/shlomif/pysol_cards.svg?branch=master :target: https://travis-ci.org/shlomif/pysol_cards =============================== pysol_cards =============================== Deal PySol FC Cards The pysol-cards python modules allow the python developer to generate the initial deals of some PySol FC games. It also supports PySol legacy deals and Microsoft FreeCell / Freecell Pro deals. * Free software: Expat license * Documentation: pydoc * Source: https://github.com/shlomif/pysol_cards * Bugs: https://github.com/shlomif/pysol_cards/issues -------- Example: -------- :: from pysol_cards.cards import CardRenderer from pysol_cards.deal_game import Game from pysol_cards.random_base import RandomBase ms24_str = Game( game_id="freecell", game_num=24, which_deals=RandomBase.DEALS_MS, max_rank=13 ).calc_layout_string( CardRenderer(print_ts=True) ) print(ms24_str, end='') COPYRIGHT --------- Copyright © 2020, Shlomi Fish. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions, and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions, and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. Neither the name of the author of this software nor the names of contributors to this software may be used to endorse or promote products derived from this software without specific prior written consent. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1704433333.0 pysol_cards-0.16.0/pysol_cards.egg-info/SOURCES.txt0000644000076400007640000000136414545713265021774 0ustar00shlomifshlomifAUTHORS CHANGELOG.rst LICENSE MANIFEST.in README README.rst requirements.txt setup.cfg setup.py docs/CHANGELOG.rst docs/CONTRIBUTING.rst docs/LICENSE.rst docs/README.rst docs/conf.py docs/index.rst docs/html/index.html pysol_cards/__init__.py pysol_cards/__main__.py pysol_cards/cards.py pysol_cards/deal_game.py pysol_cards/errors.py pysol_cards/random.py pysol_cards/random_base.py pysol_cards/single_deal_args_parse.py pysol_cards/template.py pysol_cards.egg-info/PKG-INFO pysol_cards.egg-info/SOURCES.txt pysol_cards.egg-info/dependency_links.txt pysol_cards.egg-info/entry_points.txt pysol_cards.egg-info/not-zip-safe pysol_cards.egg-info/requires.txt pysol_cards.egg-info/top_level.txt tests/__init__.py tests/test_pysol_cards.py tests/test_sanity.py././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1704433332.0 pysol_cards-0.16.0/pysol_cards.egg-info/dependency_links.txt0000644000076400007640000000000114545713264024151 0ustar00shlomifshlomif ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1704433332.0 pysol_cards-0.16.0/pysol_cards.egg-info/entry_points.txt0000644000076400007640000000007214545713264023400 0ustar00shlomifshlomif[console_scripts] pysol_cards = pysol_cards.__main__:main ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1704433321.0 pysol_cards-0.16.0/pysol_cards.egg-info/not-zip-safe0000644000076400007640000000000114545713251022325 0ustar00shlomifshlomif ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1704433332.0 pysol_cards-0.16.0/pysol_cards.egg-info/requires.txt0000644000076400007640000000001414545713264022476 0ustar00shlomifshlomifrandom2 six ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1704433332.0 pysol_cards-0.16.0/pysol_cards.egg-info/top_level.txt0000644000076400007640000000001414545713264022630 0ustar00shlomifshlomifpysol_cards ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1704433293.0 pysol_cards-0.16.0/requirements.txt0000644000076400007640000000001414545713215017342 0ustar00shlomifshlomifrandom2 six ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1704433333.3030524 pysol_cards-0.16.0/setup.cfg0000644000076400007640000000040314545713265015706 0ustar00shlomifshlomif[flake8] ignore = E741 max-line-length = 120 exclude = docs/* [wheel] universal = 1 [tool:pytest] norecursedirs = .git addopts = --cov=pysol_cards --cov-report term-missing [coverage:run] branch = True omit = tests/* [egg_info] tag_build = tag_date = 0 ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1704433293.0 pysol_cards-0.16.0/setup.py0000755000076400007640000000257114545713215015605 0ustar00shlomifshlomif#!/usr/bin/env python # -*- encoding: utf-8 -*- import io from setuptools import setup, find_packages setup(name='pysol_cards', version='0.16.0', description='Deal PySol FC Cards', keywords='pysol_cards', author='Shlomi Fish', author_email='shlomif@cpan.org', url='https://github.com/shlomif/pysol_cards', license='3-clause BSD', long_description=io.open( './docs/README.rst', 'r', encoding='utf-8').read(), platforms='any', zip_safe=False, # http://pypi.python.org/pypi?%3Aaction=list_classifiers classifiers=['Development Status :: 1 - Planning', 'Programming Language :: Python', 'Programming Language :: Python :: 3', 'Programming Language :: Python :: 3.6', 'Programming Language :: Python :: 3.7', 'Programming Language :: Python :: 3.8', 'Programming Language :: Python :: 3.9', 'Programming Language :: Python :: 3.10', 'Programming Language :: Python :: 3.11', ], packages=find_packages(exclude=('tests', 'tests.*')), include_package_data=True, install_requires=['random2','six'], entry_points={ 'console_scripts': [ 'pysol_cards = pysol_cards.__main__:main', ] }, ) ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1704433333.3020525 pysol_cards-0.16.0/tests/0000755000076400007640000000000014545713265015232 5ustar00shlomifshlomif././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1704433293.0 pysol_cards-0.16.0/tests/__init__.py0000755000076400007640000000313114545713215017337 0ustar00shlomifshlomif# -*- encoding: utf-8 -*- # pysol_cards test suite # Copyright © 2020, Shlomi Fish. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # 1. Redistributions of source code must retain the above copyright # notice, this list of conditions, and the following disclaimer. # # 2. Redistributions in binary form must reproduce the above copyright # notice, this list of conditions, and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # 3. Neither the name of the author of this software nor the names of # contributors to this software may be used to endorse or promote # products derived from this software without specific prior written # consent. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1704433293.0 pysol_cards-0.16.0/tests/test_pysol_cards.py0000755000076400007640000001640314545713215021167 0ustar00shlomifshlomif# -*- coding: utf-8 -*- # vim:fenc=utf-8 # # Copyright © 2019 Shlomi Fish # # Distributed under the terms of the MIT / Expat license: # # https://en.wikipedia.org/wiki/MIT_License """ test_pysol_cards ---------------------------------- Tests for `pysol_cards` module. """ from unittest import TestCase import pysol_cards.random class TestPysolCards(TestCase): def test_something(self): import pysol_cards.cards # noqa: F401 def test_import_deal_game(self): import pysol_cards.deal_game # noqa: F401 def test_import_random(self): class Foo(pysol_cards.random.LCRandom31): def bar(self): return super(pysol_cards.random.LCRandom31, self).shuffle([0]) r = Foo() r.setSeed(5) self.assertEqual(r.bar(), [0], "super()") def test_inc_seed(self): r = pysol_cards.random.LCRandom31(200000) seed = r.increaseSeed(200000) self.assertEqual(seed, 'ms200001', "increaseSeed()") def test_mtrandom_reset(self): r = pysol_cards.random.MTRandom(10000000) bef0 = r.randint(0, 100) bef1 = r.randint(0, 100) r.reset() aft0 = r.randint(0, 100) aft1 = r.randint(0, 100) self.assertEqual([aft0, aft1], [bef0, bef1], "MTRandom.reset()") def test_choice(self): r = pysol_cards.random.LCRandom64(500) result = r.choice([500, 600, 700]) self.assertTrue((result in (500, 600, 700)), "choice") def test_ms_single_deal(self): from pysol_cards.random import RandomBase from pysol_cards.single_deal_args_parse import SingleDealArgsParser obj = SingleDealArgsParser(["dealer.py", "ms2000000", ]) self.assertEqual(obj.which_deals, RandomBase.DEALS_MS) self.assertEqual(obj.game_num, 2000000) def test_ms_seed_prefix(self): from pysol_cards.random import match_ms_deal_prefix self.assertEqual(match_ms_deal_prefix('123'), None, "no prefix") self.assertEqual(match_ms_deal_prefix('ms200400'), 200400, "ms prefix") def test_msdeals_large_seed(self): from pysol_cards.cards import CardRenderer from pysol_cards.deal_game import Game from pysol_cards.random import RandomBase error = False which_deals = RandomBase.DEALS_MS max_rank = 13 print_ts = True try: Game("freecell", 2 ** 33 + 1, which_deals, max_rank).print_layout( CardRenderer(print_ts)) except ValueError: error = True self.assertEqual(error, True, "value out of range.") error = False try: Game("freecell", 0, which_deals, max_rank).print_layout( CardRenderer(print_ts)) except ValueError: error = True self.assertEqual(error, True, "value out of range.") def test_ms24_text(self): from pysol_cards.cards import CardRenderer from pysol_cards.deal_game import Game from pysol_cards.random_base import RandomBase ms24s = Game( "freecell", 24, RandomBase.DEALS_MS, max_rank=13 ).calc_layout_string(CardRenderer(True)) self.assertEqual( ms24s, """4C 2C 9C 8C QS 4S 2H 5H QH 3C AC 3H 4H QD QC 9S 6H 9H 3S KS 3D 5D 2S JC 5C JH 6D AS 2D KD TH TC TD 8D 7H JS KH TS KC 7C AH 5S 6S AD 8H JD 7S 6C 7D 4D 8S 9D """, "MS deal #24", ) def test_ms24_text__using_named_args(self): from pysol_cards.cards import CardRenderer from pysol_cards.deal_game import Game from pysol_cards.random_base import RandomBase ms24s = Game( game_id="freecell", game_num=24, which_deals=RandomBase.DEALS_MS, max_rank=13 ).calc_layout_string( CardRenderer(print_ts=True) ) self.assertEqual( ms24s, """4C 2C 9C 8C QS 4S 2H 5H QH 3C AC 3H 4H QD QC 9S 6H 9H 3S KS 3D 5D 2S JC 5C JH 6D AS 2D KD TH TC TD 8D 7H JS KH TS KC 7C AH 5S 6S AD 8H JD 7S 6C 7D 4D 8S 9D """, "MS deal #24", ) def test_pysolfc_text__using_named_args(self): from pysol_cards.cards import CardRenderer from pysol_cards.deal_game import Game from pysol_cards.random_base import RandomBase deal_s = Game( game_id="freecell", game_num=300000000000, which_deals=RandomBase.DEALS_PYSOLFC, max_rank=13 ).calc_layout_string( CardRenderer(print_ts=True) ) # /usr/bin/make_pysol_freecell_board.py -F -t 300000000000 freecell self.assertEqual( deal_s, """4S KD 6H 2D QC 4D AH QS 7S 5C AS KC 6S 8H TH JC 9S 2C 3D 4H 7D 5S 4C 8D 7C JD 8C JS QH TS AC KS TC 5H 6C 9D 9H 2H JH 3C 9C 2S 8S 3H 6D QD KH 3S TD 5D 7H AD """, "pysolfc deal #300000000000", ) def test_set_get_state(self): for class_, seed in [ (pysol_cards.random.LCRandom31, 240), (pysol_cards.random.LCRandom31, 6 + (1 << 32)), (pysol_cards.random.LCRandom64, 240), (pysol_cards.random.LCRandom64, 20000000000), (pysol_cards.random.MTRandom, 10000000), ]: r = class_(seed) r.randint(0, 100) state = r.getstate() bef0 = r.randint(0, 100) bef1 = r.randint(0, 100) r.setstate(state) aft0 = r.randint(0, 100) aft1 = r.randint(0, 100) self.assertEqual([aft0, aft1], [bef0, bef1], "MTRandom.setState()") def test_pysolfc_binary_star(self): from pysol_cards.cards import CardRenderer from pysol_cards.deal_game import Game from pysol_cards.random_base import RandomBase deal_s = Game( game_id="binary_star", game_num=240000, which_deals=RandomBase.DEALS_PYSOLFC, max_rank=13 ).calc_layout_string( CardRenderer(print_ts=True) ) # make_pysol_freecell_board.py -F -t 240000 binary_star self.assertEqual( deal_s, """Foundations: AS KH 5H 6H 2C QD 4H 4C 2S KH 5D 9D 4H 6C KC KS 5S TS QD TH JH QH 5D 6H 7H 7H 7D QS QC JS TH AH AD 9D 2S 7S 6D JD AH KD 2C 3H 3S 8H TD 8H 7C 4S JC 7C 8S AC 4S 3C QC 9S KC KS 9C JD AS 9C 2H 7D TC 4D 9H 8C QS 7S 6D 3D 6C TD 4C 5H 5C 5S JS 3H 9S 5C TS 2H 4D 3S KD AC QH 6S 3D 3C 2D 8C 6S 8D TC 9H 8D 8S JH JC AD 2D """, "pysolfc binary_star deal #240000", ) def test_pysolfc_black_hole(self): from pysol_cards.cards import CardRenderer from pysol_cards.deal_game import Game from pysol_cards.random_base import RandomBase deal_s = Game( game_id="black_hole", game_num=240000, which_deals=RandomBase.DEALS_PYSOLFC, max_rank=13 ).calc_layout_string( CardRenderer(print_ts=True) ) # make_pysol_freecell_board.py -F -t 240000 black_hole self.assertEqual( deal_s, """Foundations: AS 3S 8H JH 7H 9C 5C 6H 5H 8S 5S 2S 3C 8D 3H 4H 5D TD AH KC 3D 7S 4S QC QH TC AC 2C 6C 9H 4D TH JD KS JC 7C 4C QS AD 2H 9D 6D 8C 7D KD JS 2D 9S TS 6S QD KH """, "pysolfc black_hole deal #240000", ) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1704433293.0 pysol_cards-0.16.0/tests/test_sanity.py0000755000076400007640000000174114545713215020153 0ustar00shlomifshlomif#!/usr/bin/env python # -*- encoding: utf-8 -*- # pysol_cards test suite # Copyright © 2020, Shlomi Fish. # See /LICENSE for licensing information. import pysol_cards import pysol_cards.template def test_true(): """Test if True is truthy.""" assert True def test_false(): """Test if False is falsey.""" assert not False def test_trueexpr(): """Test if this evaluates as True.""" assert 1 == 1 def test_falseexpr(): """Test if this evaluates as False.""" assert 1 != 2 def test_math(): """Test basic arithmetic skills of Python.""" assert 2 + 2 == 4 assert 2 - 2 == 0 assert 2 * 2 == 4 assert 2 / 2 == 1 assert 3 % 2 == 1 def test_bitwise(): """Test bitwise operators.""" assert 0b11 ^ 0b10 == 0b01 assert 0b100 | 0b010 == 0b110 assert 0b101 & 0b011 == 0b001 assert 0b10 << 2 == 0b1000 assert 0b1111 >> 2 == 0b11 def test_import(): """Test imports.""" pysol_cards pysol_cards.template