diff --git a/common.py b/common.py index 35d1ca2..9fb05c5 100755 --- a/common.py +++ b/common.py @@ -1,214 +1,4 @@ -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 diff --git a/game.py b/game.py index ad22bd0..c6c160b 100644 --- a/game.py +++ b/game.py @@ -1,5 +1,12 @@ -from common import * +import time +import random +from json import JSONEncoder +from typing import List +import mariadb +from constants import * from cards import * + + class Player: def __init__(self, player_id, name): self.player_id = player_id @@ -69,6 +76,7 @@ class Player: } return roles_dict + class Game: def __init__(self, game_state): self.game_id = game_state['game_id'] @@ -359,6 +367,206 @@ class Game: return +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) + # 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) + # 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 + + class SummaryEncoder(JSONEncoder): def default(self, obj): if isinstance(obj, Player): @@ -441,4 +649,4 @@ class GameObjectEncoder(JSONEncoder): "action_required": obj.action_required } else: - return super().default(obj) \ No newline at end of file + return super().default(obj) diff --git a/vckonline.py b/vckonline.py index 59e09e4..01486e7 100755 --- a/vckonline.py +++ b/vckonline.py @@ -1,4 +1,8 @@ -from common import * +import json +import shortuuid +import uuid +from game import * + player1_id = shortuuid.uuid() player2_id = shortuuid.uuid() player1 = Player(player1_id, "Player 1")