Skip to main content

Python CLI to explore chessboard positions.

Project description

Chessboard

Python CLI to explore chessboard positions.

Stable release: Last release Requirements freshness Software license Popularity

Development: Unit-tests status Coverage Status Code Quality

Motivation

This project is a playground to test some optimization strategies in Python, but is essentially an example of a real-life Python package, and serve me as a boilerplate project for future CLI.

Development philosophy

  1. First create something that work (to provide business value).

  2. Then something that’s beautiful (to lower maintenance costs).

  3. Finally works on performance (to avoid wasting time on premature optimizations).

Install

This package is available on PyPi, so you can install the latest stable release and its dependencies with a simple pip call:

$ pip install chessboard

Usage

$ chessboard --help
Usage: chessboard [OPTIONS]

  Python CLI to explore chessboard positions.

Options:
  --version             Show the version and exit.
  -l, --length INTEGER  Length of the board.  [required]
  -h, --height INTEGER  Height of the board.  [required]
  -s, --silent          Do not display result board, only final count.
  -v, --verbose         Print much more debug statements.
  -p, --profile         Produce a profiling graph.
  --rook INTEGER        Number of rooks to add to the board.
  --knight INTEGER      Number of knights to add to the board.
  --queen INTEGER       Number of queens to add to the board.
  --bishop INTEGER      Number of bishops to add to the board.
  --king INTEGER        Number of kings to add to the board.
  --help                Show this message and exit.

Examples

Simple 3x3 board with 2 kings and a rook:

$ chessboard --length=3 --height=3 --king=2 --rook=1
<SolverContext: length=3, height=3, pieces={'rook': 1, 'king': 2, 'queen': 0, 'bishop': 0, 'knight': 0}>
Searching positions...
┌───┬───┬───┐
        
├───┼───┼───┤
        
├───┼───┼───┤
        
└───┴───┴───┘
┌───┬───┬───┐
        
├───┼───┼───┤
        
├───┼───┼───┤
        
└───┴───┴───┘
┌───┬───┬───┐
       
├───┼───┼───┤
         
├───┼───┼───┤
        
└───┴───┴───┘
┌───┬───┬───┐
        
├───┼───┼───┤
         
├───┼───┼───┤
       
└───┴───┴───┘
4 results found in 0.03 seconds.

Famous eight queens puzzle, without printing the solutions to speed things up:

$ chessboard --length=8 --height=8 --queen=8 --silent
<SolverContext: length=8, height=8, pieces={'rook': 0, 'king': 0, 'queen': 8, 'bishop': 0, 'knight': 0}>
Searching positions...
92 results found in 119.87 seconds.

Huge combinatoric problem can take some time to solve:

$ chessboard --length=7 --height=7 --king=2 --queen=2 --bishop=2 --knight=1 --silent
<SolverContext: length=7, height=7, pieces={'rook': 0, 'king': 2, 'queen': 2, 'bishop': 2, 'knight': 1}>
Searching positions...
3063828 results found in 9328.33 seconds.

The CLI allow the production of a profiling graph, to identify code hot spots and bottleneck:.

$ chessboard --length=6 --height=6 --king=2 --queen=2 --bishop=2 --knight=1 --silent --profile
<SolverContext: length=6, height=6, pieces={'rook': 0, 'king': 2, 'queen': 2, 'bishop': 2, 'knight': 1}>
Searching positions...
23752 results found in 207.25 seconds.
Execution profile saved at /homr/kevin/chessboard/solver-profile.png
Solver profiling graph

Performances

Results below are given in seconds, and were run with the --silent option.

Pieces

Size

Solutions

MacBook Air [1]

C1 instance [2]

2 kings, 1 rook

3x3

4

0.01

0.04

2 rooks, 4 knights

4x4

8

0.12

0.91

1 queen

1x1

1

0

0

2 queens

2x2

0

0

0

3 queens

3x3

0

0

0.02

4 queens

4x4

2

0.02

0.10

5 queens

5x5

10

0.10

0.80

6 queens

6x6

4

0.90

7.10

7 queens

7x7

40

8.53

65.55

8 queens

8x8

92

85.80

673.28

9 queens

9x9

352

900.20

7 282.56

2 kings, 2 queens, 2 bishops, 1 knight

5x5

8

3.29

23.79

6x6

23 752

187.40

1 483.31

7x7

3 063 828

8 150.86

62 704.99

Results from the table above came from running the benchmark.sh script in a detached background process:

$ nohup ./benchmark.sh > benchmark.out 2> benchmark.err < /dev/null &
$ tail -F benchmark.out

Development

Check out latest development branch:

$ git clone git@github.com:kdeldycke/chessboard.git
$ cd ./chessboard
$ python ./setup.py develop

Run unit-tests:

$ python ./setup.py nosetests

Run PEP8 and Pylint code style checks:

$ pip install pep8 pylint
$ pep8 chessboard
$ pylint --rcfile=setup.cfg chessboard

Stability policy

Here is a bunch of rules we’re trying to follow regarding stability:

  • Patch releases (0.x.n0.x.(n+1) upgrades) are bug-fix only. These releases must not break anything and keeps backward-compatibility with 0.x.* and 0.(x-1).* series.

  • Minor releases (0.n.*0.(n+1).0 upgrades) includes any non-bugfix changes. These releases must be backward-compatible with any 0.n.* version but are allowed to drop compatibility with the 0.(n-1).* series and below.

  • Major releases (n.*.*(n+1).0.0 upgrades) are not planned yet: we’re still in beta and the final feature set of the 1.0.0 release is not decided yet.

Release process

Start from the develop branch:

$ git clone git@github.com:kdeldycke/chessboard.git
$ git checkout develop

Revision should already be set to the next version, so we just need to set the released date in the changelog:

$ vi ./CHANGES.rst

Create a release commit, tag it and merge it back to master branch:

$ git add ./chessboard/__init__.py ./CHANGES.rst
$ git commit -m "Release vX.Y.Z"
$ git tag "vX.Y.Z"
$ git push
$ git push --tags
$ git checkout master
$ git pull
$ git merge "vX.Y.Z"
$ git push

Push packaging to the test cheeseshop:

$ pip install wheel
$ python ./setup.py register -r testpypi
$ rm -rf ./build ./dist
$ python ./setup.py sdist bdist_egg bdist_wheel upload -r testpypi

Publish packaging to PyPi:

$ python ./setup.py register -r pypi
$ rm -rf ./build ./dist
$ python ./setup.py sdist bdist_egg bdist_wheel upload -r pypi

Bump revision back to its development state:

$ pip install bumpversion
$ git checkout develop
$ bumpversion --verbose patch
$ git add ./chessboard/__init__.py ./CHANGES.rst
$ git commit -m "Post release version bump."
$ git push

Now if the next revision is no longer bug-fix only:

$ bumpversion --verbose minor
$ git add ./chessboard/__init__.py ./CHANGES.rst
$ git commit -m "Next release no longer bug-fix only. Bump revision."
$ git push

Third-party

This project package’s boilerplate is sourced from the code I wrote for Scaleway’s postal-address module, which is published under a GPLv2+ License.

The CLI code is based on the one I wrote for the kdenlive-tools module, published under a BSD license.

License

This software is licensed under the GNU General Public License v2 or later (GPLv2+).

ChangeLog

1.3.0 (2015-09-06)

  • Only compute 2D coordinates of each piece instance when needed, so we can reach immediately the cache if we’re only interested by the territory. Adds a 1.21x speedup.

  • Add custom PEP8 configuration.

  • Add custom Pylint configuration.

1.2.0 (2015-09-03)

  • Pre-compute some Board properties. Adds a 1.12x speedup.

  • Reuse Board object. Adds a 1.06x speedup.

  • Use list of boolean instead of bytearray for states in Board. Adds a 1.11x speedup.

  • Add a little benchmark suite.

1.1.0 (2015-08-28)

  • Use bytearray to represent board states. Closes #4.

  • Cache piece territories to speed solver up to 3x on board with big population of pieces.

1.0.0 (2015-08-27)

  • Do not spend time converting back and forth linear position to 2D position. Provides a 1.16x speedup.

  • Proceed permutation exploration with pieces of biggest territory coverage first. Adds 16x speed-up. Closes #5.

  • Add support for bumpversion.

  • Add new --profile option to produce an execution profile of the solver.

0.9.1 (2015-08-25)

  • Fix rendering of unicode string in terminal.

  • Document stability policy and release process.

  • Add PyPi-based badges.

0.9.0 (2015-08-25)

  • Validate CLI user inputs and provides hints.

  • Abandon branches of the search space as soon as possible. Closes #3.

  • Deduplicate per-kind piece group permutations early. Closes #7.

  • Add --silent option to skip displaying of all board results in ASCII art.

0.8.0 (2015-08-15)

  • Refactor solver to deduplicate positions by kind (combination) before iterating the search space by brute force (cartesian product).

0.7.0 (2015-08-14)

  • Display results in unicode-art.

0.6.0 (2015-08-14)

  • Add Knight model.

0.5.0 (2015-08-13)

  • Add Rook and Bishop models.

  • Allow overlapping but non-threatening territory of pieces to co-exists.

0.4.0 (2015-08-13)

  • Add project status badges.

  • Enable continuous integration metrics: build status, coverage and code quality.

  • Fix index to position computation in non-square boards.

  • Remove restriction on board dimensions.

  • Unit-tests result sets produced by the solver.

0.3.0 (2015-08-12)

  • Add Queen piece.

  • Fix displaying of piece representation.

  • Fix persistence of square occupancy between each piece addition.

0.2.1 (2015-08-11)

  • Fix King displacement map.

0.2.0 (2015-08-11)

  • Allow initialization of board pieces.

  • Implement brute-force solver.

0.1.1 (2015-08-08)

  • Package re-release to fix bad version number.

0.1.0 (2015-08-08)

  • First public release.

  • Implements a CLI to inititalize the chessboard.

0.0.0 (2015-08-08)

  • First commit.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

chessboard-1.3.0.tar.gz (31.4 kB view details)

Uploaded Source

Built Distributions

chessboard-1.3.0-py2.7.egg (23.3 kB view details)

Uploaded Source

chessboard-1.3.0-py2-none-any.whl (29.4 kB view details)

Uploaded Python 2

File details

Details for the file chessboard-1.3.0.tar.gz.

File metadata

  • Download URL: chessboard-1.3.0.tar.gz
  • Upload date:
  • Size: 31.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No

File hashes

Hashes for chessboard-1.3.0.tar.gz
Algorithm Hash digest
SHA256 16f32bec3a83867262328d60b49041ad9e56baeb7090984419a7a795e864f2e6
MD5 a06efe3e071ec530f52f8797f5f029d2
BLAKE2b-256 2614fb5080c68d73f0de4c7752bb43d7594b0ddbc4d1186843a1641b5ffd31d2

See more details on using hashes here.

File details

Details for the file chessboard-1.3.0-py2.7.egg.

File metadata

File hashes

Hashes for chessboard-1.3.0-py2.7.egg
Algorithm Hash digest
SHA256 674147383e3d97bde6c04569c09baab825655644332ec4270b67bc59e3de2ad1
MD5 48c1f5a34957189c93ef2e1c71e32f40
BLAKE2b-256 7f9a57a588981adb5a5bb7fc0fa7f1f7753add047421172181095967c0897ff7

See more details on using hashes here.

File details

Details for the file chessboard-1.3.0-py2-none-any.whl.

File metadata

File hashes

Hashes for chessboard-1.3.0-py2-none-any.whl
Algorithm Hash digest
SHA256 b8328ceea2bab5f2ae82e5ea1b9c5ef1e765ba5aa1dda8a3dafa3f82f96a8806
MD5 502c33e7002a5470e01a66a793f70535
BLAKE2b-256 24faed36cfc68d289f9ecf2aa5bec4fefce9fdf0eace0a2ad91b65f8043ebca6

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page