# Bunco Simulator

Artifact [28f635]

## Artifact 28f63556401e75045163b343cdebfd043ec542333b0c5e311ceb4fef6ed5b5fb:

``````# Test
import csv, random

teammate = {
1: 3,
2: 4,
3: 1,
4: 2
}

def TurnInProgress():
return -1

def roll_dice(name, current_round, roll_count):
dice = []
result = 0

desired_num = current_round % 6
desired_num = 6 if desired_num == 0 else desired_num

for _ in range(3):
dice.append(random.randint(1,6))

if all(die == desired_num for die in dice):
# Bunco!
result = 21
elif all(die == dice[0] for die in dice):
# All three dice match, but not Bunco
result = 5
else:
for die in dice:
result += 1 if die == desired_num else 0

print(f"In round {current_round} {name} rolled {dice} = {result}")
return result

class Player:
fuzzydie_holder = None

def __init__(self, name, dex, math, speed):
self.name = name
self.dex = dex
self.math_comprehension = math
self.roll_speed = speed
self.max_streak = 0
self.bunco_count = 0
self.round_scores = [0]
self.round_roll_counts = [0]
self.personal_roll_scores = [0]
self.turn_progress = 0
self.current_streak = 0
self.max_fuzzydie_streak = 0
self.current_fuzzydie_streak = 0
self.rolled_bunco = False

def __repr__(self):
return f"<Player {self.name}: " \
+ f"\tscores\t\t{self.round_scores}>" \
+ f"\troll counts\t{self.round_roll_counts}>"

def prep_new_round(self):
self.round_scores.append(0)
self.round_roll_counts.append(0)
self.personal_roll_scores.append(0)
self.turn_progress = 0
self.current_streak = 0

def tick(self, current_round):
result = TurnInProgress()

if self.fuzzydie_holder is self:
self.current_fuzzydie_streak += 1
self.max_fuzzydie_streak = max(self.max_fuzzydie_streak, self.current_fuzzydie_streak)
else:
self.current_fuzzydie_streak = 0

if self.turn_progress < 25:
# Grabbing the dice
# TODO: Incorporate DEXTERITY stat
self.turn_progress += random.randint(12,25)
elif self.turn_progress < 50:
# Rolling the dice
# TODO: Incorporate ROLL SPEED stat
self.turn_progress += random.randint(12,25)
elif self.turn_progress < 75:
# TODO: Incorporate MATH COMPREHENSION stat
self.turn_progress += random.randint(12,25)
else:
# Finished rolling
self.round_roll_counts[current_round - 1] += 1
roll_result = roll_dice(self.name, current_round, self.round_roll_counts[current_round - 1])

if roll_result > 0:
self.current_streak += 1
self.max_streak = max(self.current_streak, self.max_streak)
self.round_scores[current_round - 1] += roll_result
self.personal_roll_scores[current_round - 1] += roll_result
if roll_result == 21:
self.bunco_count += 1
self.rolled_bunco = True
else:
self.current_streak = 0

result = roll_result
self.turn_progress = 0
return result

class Table:
def __init__(self):
self.team1_score = 0
self.team2_score = 0
self.players = []
self.active_player = -1

def __repr__(self):
names = ", ".join([p.name for p in self.players])
return "<Table: " + names + ">"

def tick(self, current_round):
if self.active_player == -1:
# First tick for the table this round
self.active_player = random.randint(1, len(self.players)) - 1

result = self.players[self.active_player].tick(current_round)

if result != TurnInProgress():
# Player rolled
if result > 0:
if (self.active_player % 2) == 0:
self.team1_score += result
else:
self.team2_score += result

self.players[teammate[self.active_player + 1]-1].round_scores[current_round - 1] += result
else:
self.active_player += 1
if self.active_player > (len(self.players) - 1): self.active_player = 0

def losers(self):
if self.team1_score > self.team2_score:
return self.players[1::2]
else:
return self.players[0::2]

def winners(self):
if self.team1_score > self.team2_score:
return self.players[0::2]
else:
return self.players[1::2]

def swap_for_winners(self, new_players):
if self.team1_score > self.team2_score:
# Team 1 (evens) won
winners = self.players[0::2]
# Player 1 move to spot 0
self.players[0] = self.players[1]
else:
# Team 2 (odds) won
winners = self.players[1::2]
# Player 2 move to spot 3
self.players[3] = self.players[2]
# Replace middle two players
self.players[1:3] = new_players
return winners

def swap_for_losers(self, new_players):
if self.team1_score < self.team2_score:
# Team 1 (evens) lost
losers = self.players[0::2]
# Player 1 move to spot 0
self.players[0] = self.players[1]
else:
# Team 2 (odds) lost
losers = self.players[1::2]
# Player 2 move to spot 3
self.players[3] = self.players[2]
# Replace middle two players
self.players[1:3] = new_players
return losers

def prep_new_round(self):
self.team1_score = 0
self.team2_score = 0
self.active_player = -1
for player in self.players:
player.prep_new_round()

def assign_teams(player_list):
players_per_table = 4
tables = []
random.seed()

if len(player_list) % players_per_table != 0:
print("Wrong number of players!")
return tables
else:
table_count = len(player_list) // players_per_table
random.shuffle(player_list)
tables = [Table() for _ in range(table_count)]

for n in range(table_count):
first = n * players_per_table
stop_before = first + players_per_table
tables[n].players = player_list[first:stop_before]

return tables

players = []

with open(filename) as tsvfile:
players.append(Player(line[0],0,0,0))

return players

class Game:
def __init__(self, playerfile):
self.tables = assign_teams(self.players)
self.current_round = 1

def tick(self):
for table in self.tables:
table.tick(self.current_round)

bunco_rollers = [p for p in self.players if p.rolled_bunco is True]

# If multiple people rolled Bunco this tick, and one of them already has the
# fuzzy die, they retain it.
# Otherwise, the last person in the list gets the fuzzy die.
if bunco_rollers and Player.fuzzydie_holder not in bunco_rollers:
Player.fuzzydie_holder = bunco_rollers[-1]
for player in bunco_rollers:
player.rolled_bunco = False # Reset flag

def print_status(self):
for n, table in enumerate(self.tables):
print(f"== TABLE {n+1} == Team 1:{table.team1_score} pts, Team 2:{table.team2_score} pts")
for player in table.players:
print(f"    {player.name} {player.round_scores[self.current_round - 1]} points, streak {player.max_streak} buncos {player.bunco_count}")

def prep_next_round(self):
# losers from head table move to next table

# winners from other tables move to next table
for n in range(2, len(self.tables)):
round_winners = self.tables[n].swap_for_winners(round_winners)
# last set of winners moves to head table
self.tables[0].swap_for_losers(round_winners)

for table in self.tables:
table.prep_new_round()

self.current_round += 1

def play_one_round(self):
# Go until one of the head table teams reaches 21 pts
while max(self.tables[0].team1_score, self.tables[0].team2_score) < 21:
self.tick()

print("\n\n\t\tB U N C O !!!\n\n")

self.print_status()```
```