Home
Name Modified Size InfoDownloads / Week
README.md 2024-01-09 7.6 kB
PyMancala-0.4.zip 2024-01-09 202.9 kB
PyMancala-0.3a.zip 2023-10-19 222.2 kB
PyMancala-0.2a.zip 2023-10-15 210.0 kB
PyMancala-0.1a.zip 2023-10-13 302.5 kB
Totals: 5 Items   945.1 kB 0

PyMancala: A Python API for the Mancala game

This is the PyMancala tool, under the terms of the GNU General Public License version 3. PyMancala implements the Mancala - also called Awale, game.

Install PyMancala

Download the repository and unpack it, or clone with git. PyMancala package includes the following folders:

  1. "mancala": the source code package;
  2. "tests": the tests of the source code;
  3. "doc": the documentation of the source code in HTML and Markdown formats.

Quick Start

Open a terminal application and change directory to PyMancala folder. Then, PyMancala can optionally be installed with:

>python -m pip install .
>python -m pip install ".[doc, dev, test]"

Start to play with:

>python main.py

Continue to play an existing saved game:

>python main.py saved_games/my_saved_game.json

Game configuration

The game can be configured by fixing the following options:

  • name of each player: enter a max 8-chars string for a human, or hit enter for the computer;
  • game strategy for each player: if human, it is used when asking for an advice, for the computer, it's its game strategy.

Playing

When playing, the user can interact with the game by either:

  1. Enter a hole number among the given ones;
  2. Enter a character to perform an action among:

    • h: print the help
    • r: print the rules
    • a: get an advice
    • s: save the game
    • q: quit the game

Enabling/Disabling messages

By default, the logging messages are enabled. It allows to see information about the distribution. Disable these messages by changing the 0 value to 30 in the main.py file, at line:

>>>import logging
>>>logging.getLogger().setLevel(0)

Game variants

The PyMancala API implements several variants of its rules:

  1. set_distribution_ignore_initial_hole: When there are many seeds in a hole - i.e., more than 12, the distribution goes around the board completely. You can choose at that time whether you want to feed the starting hole or not.
  2. set_distribution_ignore_player_store: You can choose whether you want to feed the store of the player when distributing or not.
  3. set_distribution_ignore_opponent_store: You can choose whether you want to feed the store of the opponent when distributing or not.
  4. set_distribution_collect_player_seed_arrived_empty: If the last seed you drop is in an empty hole on your side, you capture seeds in the hole directly opposite. You can choose whether you want to capture that seed too or not.
  5. keep_turn_when_arrived_empty: If the last seed you drop is in an empty hole on your side, you play again.
  6. must_feed_if_opponent_empty: When the opponent is empty, you must play a hole to feed him/her.

Change these boolean values into the main.py file to play with the desired rule variants:

>>>import mancala
>>>game = mancala.MancalaGame()
>>>game.set_distribution_ignore_initial_hole(True)
>>>game.set_distribution_ignore_player_store(False)
>>>game.set_distribution_ignore_opponent_store(True)
>>>game.set_distribution_collect_player_seed_arrived_empty(False)
>>>game.set_distribution_keep_turn_when_arrived_empty(False)
>>>game.set_distribution_must_feed_if_opponent_empty(True)

Implement your custom computer game strategy

Add your strategy

Edit the mancala.mancalagame.strategies.py file and add your custom function in the class Strategies. This function must return an integer value corresponding to the hole to play. Below is an example of a function:

import random
def awesome(self) -> int:
    """Return intelligently a non-empty hole or -1 if the player can't play.

    The awesome strategy consists in... doing things to be described here.

    :return: (int) Index of a hole

    """
    # Get the list of hole indexes that can be played.
    candidates = self.__board.candidate_holes()
    # Choose one of them
    if len(candidates) > 0:
        # Choosing a hole among the candidates: That's the point!
        # Do the job here...
        # ...
        my_selected_candidates = candidates
        # ...
        # Return a random hole among my selected ones
        return random.choice(my_selected_candidates)
    # Should never happen.
    return -1

Evaluate your strategy

The strategies can be evaluated thanks to the compare_strategies.py script. As soon as you added your custom strategy in the class Strategies, it will be compared to the "randomly" one. Your "awesome" strategy should be better!

The script compares all available strategies to the random one on 100 samples. It creates 50 different games in order to perform 100 comparisons. Actually each game is played twice: each strategy is alternatively assigned to the Player 1, the player who starts to play.

>python compare_strategies.py

The script is displaying the results like for example:

  • Evaluate awesome strategy

  • random strategy won 40 games.

  • awesome strategy won 54 games.
  • ex aequo on 4 games.

It is supposed that any strategy should be better than the random one - i.e., should win more often; a very good strategy should significantly win more games.

Basic strategies' results

Here are the currently evaluated strategies:

  • Evaluate strategy always_first

  • random strategy won 76 games.

  • always_first strategy won 21 games.
  • ex aequo on 3 games.

  • Evaluate strategy always_last

  • random strategy won 37 games.

  • always_last strategy won 57 games.
  • ex aequo on 6 games.

  • Evaluate strategy always_max

  • random strategy won 23 games.

  • always_max strategy won 69 games.
  • ex aequo on 8 games.

  • Evaluate strategy always_min

  • random strategy won 77 games.

  • always_min strategy won 20 games.
  • ex aequo on 3 games.

  • Evaluate strategy can_play_again_or_random

  • random strategy won 12 games.

  • can_play_again_or_random strategy won 86 games.
  • ex aequo on 2 games.

  • Evaluate strategy earn_max_in_store

  • random strategy won 6 games.

  • earn_max_in_store strategy won 93 games.
  • ex aequo on 1 games.

API documentation

The documentation of the API - Application Programming Interface, is available in HTML and Markdown formats. Open either the file docs/index.html in a web browser, or the ".md" files.

Author/Copyright

Copyright (C) 2023-2024 Brigitte Bigi, contact@sppas.org.

Author web page is https://sppas.org/bigi/.

History of versions

  • 2023-10-13: Release 0.1a

    • Tested with Python 3.11.3 on macOS 13.4.1.
    • Tests coverage is 82%
  • 2023-10-15: Release 0.2a

    • Tested with Python 3.11.3 on macOS 13.4.1, Python 3.9 under Windows 10, Python 3.7 under iOS
    • Added unittests. Tests coverage is 84%.
    • Added two distribution options: keep_turn_when_arrived_empty, must_feed_if_opponent_empty
  • 2023-10-18, Release 0.3a

    • A better design of the ASCII board.
    • A better solution to manage the distribution rules.
    • Bug correction with board.copy(). In previous versions, distribution rules were not copied.
    • Added a strategy example with cascading candidates' selection. Its purpose is to illustrate a Rules-Based game strategy by filtering candidates. It is not intended to be used as it!
  • 2024-01-09, Release 0.4

    • Re-organized code into sub-packages mancalagame and mancalaui.
    • Requires Clamming>=1.4 to make the documentation.
    • Modified the file format of the internal dictionaries so does the exported games, with no backward compatibility.
    • Tests coverage is 88%.
Source: README.md, updated 2024-01-09