import json import time from json import JSONEncoder, JSONDecoder import random from typing import List, Dict from constants import * import mariadb import shortuuid import uuid from cards import * from game import * class LobbyMember: def __init__(self, player_name, player_id): self.name = player_name self.player_id = player_id self.is_ready = False self.last_active_time = 0 class GameMember: def __init__(self, player_id, player_name, game_id): self.name = player_name self.player_id = player_id self.game_id = game_id def load_game_data(game_id, preset, player_list_from_lobby): monster_query = "" monster_stack = [] citizen_query = "" citizen_stack = [] domain_query = "select_random_domains" domain_stack = [] duke_query = "select_random_dukes" duke_stack = [] starter_query = "SELECT * FROM starters" starter_stack = [] player_list = [] citizen_grid: List[List[Citizen]] = [[] for _ in range(10)] domain_grid: List[List[Domain]] = [[] for _ in range(5)] monster_grid: List[List[Monster]] = [[] for _ in range(5)] die_one = 0 die_two = 0 die_sum = 0 exhausted_count = 0 effects = { "roll_phase": [], "harvest_phase": [], "action_phase": [] } action_required = { "player_id": "", "action": "" } match preset: case "base1": monster_query = "select_base1_monsters" citizen_query = "select_base1_citizens" case "base2": monster_query = "select_base2_monsters" citizen_query = "select_base2_citizens" try: my_connect = mariadb.connect(user='vckonline', password='vckonline', host='127.0.0.1', database='vckonline') my_cursor = my_connect.cursor(dictionary=True) my_cursor.callproc(monster_query) results = my_cursor.fetchall() for row in results: my_monster = Monster(row['id_monsters'], row['name'], row['area'], row['monster_type'], row['monster_order'], row['strength_cost'], row['magic_cost'], row['vp_reward'], row['gold_reward'], row['strength_reward'], row['magic_reward'], row['has_special_reward'], row['special_reward'], row['has_special_cost'], row['special_cost'], row['is_extra'], row['expansion']) monster_stack.append(my_monster) my_cursor.callproc(citizen_query) citizen_count = 5 if len(player_list_from_lobby) == 5: citizen_count = 6 results = my_cursor.fetchall() for row in results: for i in range(citizen_count): my_citizen = Citizen(row['id_citizens'], row['name'], row['gold_cost'], row['roll_match1'], row['roll_match2'], row['shadow_count'], row['holy_count'], row['soldier_count'], row['worker_count'], row['gold_payout_on_turn'], row['gold_payout_off_turn'], row['strength_payout_on_turn'], row['strength_payout_off_turn'], row['magic_payout_on_turn'], row['magic_payout_off_turn'], row['has_special_payout_on_turn'], row['has_special_payout_off_turn'], row['special_payout_on_turn'], row['special_payout_off_turn'], row['special_citizen'], row['expansion']) citizen_stack.append(my_citizen) my_cursor.callproc(domain_query) results = my_cursor.fetchall() for row in results: my_domain = Domain(row['id_domains'], row['name'], row['gold_cost'], row['shadow_count'], row['holy_count'], row['soldier_count'], row['worker_count'], row['vp_reward'], row['has_activation_effect'], row['has_passive_effect'], row['passive_effect'], row['activation_effect'], row['text'], row['expansion']) domain_stack.append(my_domain) my_cursor.callproc(duke_query) results = my_cursor.fetchall() for row in results: my_duke = Duke(row['id_dukes'], row['name'], row['gold_mult'], row['strength_mult'], row['magic_mult'], row['shadow_mult'], row['holy_mult'], row['soldier_mult'], row['worker_mult'], row['monster_mult'], row['citizen_mult'], row['domain_mult'], row['boss_mult'], row['minion_mult'], row['beast_mult'], row['titan_mult'], row['expansion']) duke_stack.append(my_duke) my_cursor.execute(starter_query) my_result = my_cursor.fetchall() for row in my_result: my_starter = Starter(row['id_starters'], row['name'], row['roll_match1'], row['roll_match2'], row['gold_payout_on_turn'], row['gold_payout_off_turn'], row['strength_payout_on_turn'], row['strength_payout_off_turn'], row['magic_payout_on_turn'], row['magic_payout_off_turn'], row['has_special_payout_on_turn'], row['has_special_payout_off_turn'], row['special_payout_on_turn'], row['special_payout_off_turn'], row['expansion']) starter_stack.append(my_starter) my_cursor.close() my_connect.close() except Exception as e: print(f"Error: {e}") # print(f"size of monster stack: {len(monster_stack)}") # print(f"size of citizen stack: {len(citizen_stack)}") # print(f"size of domain stack: {len(domain_stack)}") # print(f"size of duke stack: {len(duke_stack)}") # print(f"size of starter stack: {len(starter_stack)}") # create players and determine order if not all([player_list_from_lobby, starter_query, monster_stack, citizen_stack, domain_stack, duke_stack]): raise ValueError("One or more required lists are empty.") else: for player in player_list_from_lobby: my_player = Player(player.player_id, player.name) player_list.append(my_player) random.shuffle(player_list) player_list[0].is_first = True # give players starters and dukes for player in player_list: player.owned_starters.append(starter_stack[0]) player.owned_starters.append(starter_stack[1]) for i in range(2): player.owned_dukes.append(duke_stack.pop()) # deal monsters onto the board grouped_monsters = {} for monster in monster_stack: area = monster.area if area in grouped_monsters: grouped_monsters[area].append(monster) else: grouped_monsters[area] = [monster] # Reverse the order of each group by monster_order for area, monsters in grouped_monsters.items(): monsters.sort(key=lambda item: item.order, reverse=True) areas = list(grouped_monsters.keys()) chosen_areas = random.sample(areas, 5) for i, area in enumerate(chosen_areas): monsters = grouped_monsters[area] monster_grid[i].extend(monsters) for i, stack in enumerate(monster_grid): for monster in stack: monster.toggle_visibility(True) # Make the last monster in the stack accessible stack[-1].toggle_accessibility(True) monster_stack = [] # deal citizens onto the board # Create a dictionary to store citizen lists with roll numbers as keys citizens_by_roll = {roll: [] for roll in [1, 2, 3, 4, 5, 6, 7, 8, 9, 11]} # Group citizens by roll number for citizen in citizen_stack: citizen.toggle_visibility() citizens_by_roll[citizen.roll_match1].append(citizen) for roll in citizens_by_roll: # Map 11 roll to index 9 index = roll - 1 if roll < 11 else 9 citizens = citizens_by_roll[roll] citizen_grid[index].extend(list(citizens)) # Make the first citizen in each list accessible citizen_grid[index][-1].toggle_accessibility(True) citizen_stack = [] # Deal the domains into the stacks for i in range(5): stack = domain_grid[i] for j in range(3): if j == 2: # top domain is visible and accessible domain = domain_stack.pop() domain.toggle_visibility(True) domain.toggle_accessibility(True) stack.append(domain) else: # other domains are not visible or accessible domain = domain_stack.pop() stack.append(domain) # Create a dictionary to store all the stacks game_state = {'game_id': game_id, 'player_list': player_list, 'monster_grid': monster_grid, 'citizen_grid': citizen_grid, 'domain_grid': domain_grid, 'die_one': die_one, 'die_two': die_two, 'die_sum': die_sum, 'exhausted_count': exhausted_count, 'effects': effects, 'action_required': action_required} # Return the dictionary return game_state