# Bunco Simulator

Every year my family plays a ≈30-person game of Bunco. If you’ve never played, [the rules](http://worldbunco.com/rules.html) are complicated but in practice it basically involves rolling a 3d6 repeatedly, as fast as you can, for about an hour. There is no strategy involved, only lots of dice rolling. This makes it a great candidate for automation.

By simulating the entire game, you eliminate the most tedious part (the actual dice-rolling). With the option of texting updates to players that can receive them, everyone can still get the social feels. And because the computer is keeping track of everything, there are a lot more statistics you can track that aren’t very feasible in a normal game: streaks of scoring rolls, longest time at a particular table, longest time holding the traveling fuzzy die, etc.

## The Experience

1. You fire up the simulator: it loads up your list of players and randomly assigns them to tables. 

2. Before every round, you hit a button and each player gets a text telling them what table they’re at, who their teammate is and who their opponents are.

3. You hit a button, the simulator plays one round and then texts everyone the results of their play, and (if applicable) which table they move to as a result. The scoreboard on your screen updates, showing the scores of all players in each round. Repeat steps 2 and 3 until all the rounds are done (a regulation game is 24 rounds).

4. At the end, you hit one more button and the simulator saves the game results in an Excel spreadsheet, which contains an Overview tab showing all the rounds and scores, and a list of who one each prize.

<figure>
 <a href="https://thenotepad.org/repos/bunco/uv/unversioned/screenshot-terminal.png">
 <img src="https://thenotepad.org/repos/bunco/uv/unversioned/screenshot-terminal.png" width="500">
 </a>
 <figcaption>Scoreboard shown in terminal output</figcaption>
</figure>
<figure>
 <a href="https://thenotepad.org/repos/bunco/uv/unversioned/screenshot-sms.png">
 <img src="https://thenotepad.org/repos/bunco/uv/unversioned/screenshot-sms.png" height="500">
 </a>
 <figcaption>Players can get texts about their simulated Bunco gameplay</figcaption>
</figure>
<figure>
 <a href="https://thenotepad.org/repos/bunco/uv/unversioned/screenshot-scoresheet.png">
 <img src="https://thenotepad.org/repos/bunco/uv/unversioned/screenshot-scoresheet.png" width="500">
 </a>
 <figcaption>Sample auto-generated Excel score sheet saved as a PDF</figcaption>
</figure>

## Installation

### Dependencies

This code was developed with Python 3.7+ so it may not work with earlier versions. The core Bunco library (`bunco.py`) has no extra dependencies; the app (`bunco-app.py`) needs a few additional packages: [XlsxWriter](https://github.com/jmcnamara/XlsxWriter) (for Excel output), [Twilio](https://github.com/twilio/twilio-python) (for texting updates to the players), and [Blessings](https://github.com/erikrose/blessings) (for pretty terminal output). 

The score sheets that the program spits out in Excel use two free fonts (which you should just get anyway): [Back Issues BB](http://www.blambot.com/font_backissues.shtml) and [Milk Mustache BB](http://www.blambot.com/font_milkmustache.shtml).

Additionally, if you want to use the feature that texts all the players before and after each round, you'll need a paid Twilio account. To get an idea of the costs, in our 2018 game 15 of our players had texting enabled for the game. Over 24 rounds, the program sent 1,290 SMS messages at a cost to me of $14.77 USD (and note, one of our players was in Switzerland).

Once you have your Twilio account info, put it in a file `creds.py` like so:

    SID = "ACxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
    token = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
    sender = "+1xxxxxxxxxx"

(Since this is sensitive info, this file is excluded from the Fossil repository (in the `.fossil-settings/ignore-glob` file) to protect it from being publicly leaked.)

### Getting the Code

You can download a copy of all the code by visiting <https://thenotepad.org/repos/bunco/zip>.

Or, you can clone this repo if you have Fossil installed.

    $ fossil clone https://thenotepad.org/repos/bunco

For more info on this subject, see [How to use Fossil with this repo](https://thenotepad.org/repos/bunco/wiki?name=How+to+use+Fossil+with+this+repo).

## Usage

### Game Setup

Create a comma-separated file `players.csv` in the same folder as the code, with a row for each player. The first value in each row is the player’s name. Optionally, add a second value containing the player’s SMS-enabled mobile phone number, including the country code (like this `+1717123456`) Make sure the number of players is divisible by 4 (since you need four players per table). The best way to make up the number is to add the names of your favourite celebrities (make sure you @ them on Twitter about it too).

### Running the Game

For now, the Python REPL *is* the interface, so get ready to manually set variables and call some functions.

    $ python3.7
    >>> import bunco_app
    # The above will immediately load the players from players.csv and display
    # an empty scoreboard showing table assignments.

    # Enable SMS (off by default for safety)
    >>> bunco_app.enable_sms = True

    # Send a welcome text
    >>> bunco_app.sms_all("Welcome! Let’s get started!")
    
    # Do this before each round to text players a description of where and 
    # with whom they’re sitting:
    >>> bunco_app.sms_all_situations()

    # Then: GO! This will play a single round and text everyone their results:
    >>> bunco_app.do1()

    # When you’ve played all the rounds, do this to save the spreadsheet
    # containing the results and everyone's score sheets, ready for printing:
    >>> bunco_app.excel_sheet("2018 Bunco Game at the Dueck House")


## Gameplay

The simulator follows [the official Bunco rules](http://worldbunco.com/rules.html) with a few additional house rules.

Upon the start of a round, the first player to roll at each table is decided randomly.

In addition to the regular prizes (Most Buncos, Most Wins, Most Losses, Last Fuzzy Die Holder) the game awards the following prizes:

* Highest Team Contributor
* Most Rolls
* Fewest Rolls
* Longest Scoring Roll Streak
* Longest Time Holding Fuzzy Die
* Most Average Total Score
* Closest to Median Total Score

