ADDED .fossil-settings/ignore-glob Index: .fossil-settings/ignore-glob ================================================================== --- .fossil-settings/ignore-glob +++ .fossil-settings/ignore-glob @@ -0,0 +1,5 @@ +unversioned/* +__pycache__/* +*.xlsx +*.sqlite + ADDED bunco.py Index: bunco.py ================================================================== --- bunco.py +++ bunco.py @@ -0,0 +1,246 @@ +# 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: + 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 + + def __repr__(self): + return f"" \ + + 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.turn_progress = 0 + self.current_streak = 0 + + def tick(self, current_round): + result = TurnInProgress() + + 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: + # Reading the numbers + # 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 + if roll_result == 21: + self.bunco_count += 1 + 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 "" + + 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 + +def load_players(filename): + players = [] + + with open(filename) as tsvfile: + tsvreader = csv.reader(tsvfile) + for line in tsvreader: + players.append(Player(line[0],0,0,0)) + + return players + +class Game: + def __init__(self, playerfile): + self.players = load_players(playerfile) + self.tables = assign_teams(self.players) + self.current_round = 1 + + def tick(self): + for table in self.tables: + table.tick(self.current_round) + + 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 + headtable_losers = self.tables[0].losers() + round_winners = self.tables[1].swap_for_winners(headtable_losers) + + # 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()