From dd291ab5b38c9c3d3cd0f5bc9d9f0ef8f5e09922 Mon Sep 17 00:00:00 2001 From: Ben Date: Thu, 26 Mar 2020 22:20:03 +0000 Subject: [PATCH] Fix potential cyclic import issue & move minigame logic into handler module --- houdini/__init__.py | 50 +++++++++++ houdini/data/room.py | 24 +---- houdini/games/__init__.py | 49 ----------- houdini/games/four.py | 45 ---------- houdini/games/mancala.py | 63 -------------- houdini/games/sled.py | 19 ---- houdini/games/treasure.py | 129 --------------------------- houdini/handlers/games/four.py | 48 +++++++++- houdini/handlers/games/mancala.py | 66 +++++++++++++- houdini/handlers/games/sled.py | 22 ++++- houdini/handlers/games/treasure.py | 130 +++++++++++++++++++++++++++- houdini/handlers/play/navigation.py | 44 ++++++++-- 12 files changed, 343 insertions(+), 346 deletions(-) delete mode 100644 houdini/games/__init__.py delete mode 100644 houdini/games/four.py delete mode 100644 houdini/games/mancala.py delete mode 100644 houdini/games/sled.py delete mode 100644 houdini/games/treasure.py diff --git a/houdini/__init__.py b/houdini/__init__.py index b1d4b90..32d6afd 100644 --- a/houdini/__init__.py +++ b/houdini/__init__.py @@ -36,6 +36,56 @@ class _AbstractManager(dict): """Loads entries from module""" +class ITable(ABC): + """ + All table game logic classes must implement this interface. + """ + + @abstractmethod + def make_move(self, *args): + """Tells logic a move has been made.""" + + @abstractmethod + def is_valid_move(self, *args): + """Returns true if the move is valid.""" + + @abstractmethod + def get_string(self): + """Returns string representation of the game.""" + + +class IWaddle(ABC): + """ + All waddle game logic classes must implement this interface. + """ + + @property + @abstractmethod + def room_id(self): + """External ID of waddle game room.""" + + def __init__(self, waddle): + self.penguins = list(waddle.penguins) + self.seats = waddle.seats + + async def start(self): + room_id = type(self).room_id + for penguin in self.penguins: + penguin.waddle = self + await penguin.join_room(penguin.server.rooms[room_id]) + + async def remove_penguin(self, p): + self.penguins.remove(p) + p.waddle = None + + async def send_xt(self, *data): + for penguin in self.penguins: + await penguin.send_xt(*data) + + def get_seat_id(self, p): + return self.penguins.index(p) + + class PenguinStringCompiler(OrderedDict): def __init__(self, *args, **kwargs): diff --git a/houdini/data/room.py b/houdini/data/room.py index 7d1c899..3e65de6 100644 --- a/houdini/data/room.py +++ b/houdini/data/room.py @@ -194,12 +194,6 @@ class RoomTable(db.Model): nullable=False) game = db.Column(db.String(20), nullable=False) - GameClassMapping = { - 'four': ConnectFourLogic, - 'mancala': MancalaLogic, - 'treasure': TreasureHuntLogic - } - def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.penguins = [] @@ -267,9 +261,8 @@ class RoomWaddle(db.Model): seats = db.Column(db.SmallInteger, nullable=False, server_default=db.text("2")) game = db.Column(db.String(20), nullable=False) - GameClassMapping = { + def __init__(self, *args, **kwargs): self.temporary = kwargs.pop('temporary', False) - } self.penguins = [] self.logic = None self.room = None @@ -288,7 +281,7 @@ class RoomWaddle(db.Model): p.waddle = self if self.penguins.count(None) == 0: - game_instance = RoomWaddle.GameClassMapping[self.game](self) + game_instance = self.logic(self) await game_instance.start() await self.reset() @@ -330,16 +323,3 @@ class RoomCollection(AbstractDataCollection): @property def spawn_rooms(self): return [room for room in self.values() if room.spawn] - - async def setup_tables(self): - async with db.transaction(): - async for table in RoomTable.query.gino.iterate(): - self[table.room_id].tables[table.id] = table - table.room = self[table.room_id] - table.logic = RoomTable.GameClassMapping[table.game]() - - async def setup_waddles(self): - async with db.transaction(): - async for waddle in RoomWaddle.query.gino.iterate(): - self[waddle.room_id].waddles[waddle.id] = waddle - waddle.room = self[waddle.room_id] diff --git a/houdini/games/__init__.py b/houdini/games/__init__.py deleted file mode 100644 index eaa2648..0000000 --- a/houdini/games/__init__.py +++ /dev/null @@ -1,49 +0,0 @@ -from abc import ABC -from abc import abstractmethod - - -class ITable(ABC): - """ - All table game logic classes must implement this interface. - """ - - @abstractmethod - def make_move(self, *args): - """Tells logic a move has been made.""" - - @abstractmethod - def is_valid_move(self, *args): - """Returns true if the move is valid.""" - - @abstractmethod - def get_string(self): - """Returns string representation of the game.""" - - -class IWaddle(ABC): - """ - All waddle game logic classes must implement this interface. - """ - - @property - @abstractmethod - def __room_id__(self): - """External ID of waddle game room.""" - - def __init__(self, waddle): - self.penguins = list(waddle.penguins) - self.seats = waddle.seats - - async def start(self): - room_id = type(self).__room_id__ - for penguin in self.penguins: - penguin.waddle = self - await penguin.join_room(penguin.server.rooms[room_id]) - - async def remove_penguin(self, p): - self.penguins.remove(p) - p.waddle = None - - async def send_xt(self, *data): - for penguin in self.penguins: - await penguin.send_xt(*data) diff --git a/houdini/games/four.py b/houdini/games/four.py deleted file mode 100644 index 630675e..0000000 --- a/houdini/games/four.py +++ /dev/null @@ -1,45 +0,0 @@ -from houdini.games import ITable - - -class ConnectFourLogic(ITable): - - def __init__(self): - self.current_player = 1 - self.board = [[0 for _ in range(6)] for _ in range(7)] - - def make_move(self, col, row): - self.board[col][row] = self.current_player - - def is_valid_move(self, col, row): - if 0 <= row <= 5 and 0 <= col <= 6: - if row == 5 or (self.board[col][row] == 0 and self.board[col][row + 1]): - return True - return False - - def get_string(self): - return ','.join(str(item) for row in self.board for item in row) - - def is_position_win(self, col, row): - for delta_row, delta_col in [(1, 0), (0, 1), (1, 1), (1, -1)]: - streak = 1 - for delta in (1, -1): - delta_row *= delta - delta_col *= delta - next_row = row + delta_row - next_col = col + delta_col - while 0 <= next_row < 6 and 0 <= next_col < 7: - if self.board[next_col][next_row] == self.current_player: - streak += 1 - else: - break - if streak == 4: - return True - next_row += delta_row - next_col += delta_col - return False - - def is_board_full(self): - for col in self.board: - if not col[0]: - return False - return True diff --git a/houdini/games/mancala.py b/houdini/games/mancala.py deleted file mode 100644 index da51fc2..0000000 --- a/houdini/games/mancala.py +++ /dev/null @@ -1,63 +0,0 @@ -from houdini.games import ITable - - -class MancalaLogic(ITable): - - def __init__(self): - self.current_player = 1 - self.board = [ - 4, 4, 4, 4, 4, 4, 0, - 4, 4, 4, 4, 4, 4, 0 - ] - - def make_move(self, hollow): - capture = False - hand = self.board[hollow] - self.board[hollow] = 0 - - while hand > 0: - hollow = (hollow + 1) % len(self.board) - my_mancala, opponent_mancala = (6, 13) if self.current_player == 1 else (13, 6) - - if hollow == opponent_mancala: - continue - opposite_hollow = 12 - hollow - - if hand == 1 and self.board[hollow] == 0: - if (self.current_player == 1 and hollow in range(0, 6)) or (self.current_player == 2 and hollow in range(7, 13)): - self.board[my_mancala] += self.board[opposite_hollow] + 1 - self.board[opposite_hollow] = 0 - capture = True - break - - self.board[hollow] += 1 - hand -= 1 - - if (self.current_player == 1 and hollow != 6) or (self.current_player == 2 and hollow != 13): - return 'c' if capture else str() - else: - self.current_player = 2 if self.current_player == 1 else 1 - return 'f' - - def is_valid_move(self, hollow): - if self.current_player == 1 and hollow not in range(0, 6): - return False - elif self.current_player == 2 and hollow not in range(7, 13): - return False - return True - - def get_string(self): - return ','.join(map(str, self.board)) - - def is_position_win(self): - if sum(self.board[0:6]) == 0 or sum(self.board[7:-1]) == 0: - if sum(self.board[0:6]) > sum(self.board[7:-1]): - return self.current_player == 1 - return self.current_player == 2 - return False - - def is_position_tie(self): - if sum(self.board[0:6]) == 0 or sum(self.board[7:-1]) == 0: - if sum(self.board[0:6]) == sum(self.board[7:-1]): - return True - return False diff --git a/houdini/games/sled.py b/houdini/games/sled.py deleted file mode 100644 index 9706f62..0000000 --- a/houdini/games/sled.py +++ /dev/null @@ -1,19 +0,0 @@ -from houdini.games import IWaddle - - -class SledRacingLogic(IWaddle): - - __room_id__ = 999 - - def __init__(self, waddle): - super().__init__(waddle) - - self.payouts = [20, 10, 5, 5] - - async def remove_penguin(self, p): - await super().remove_penguin(p) - await self.send_xt('uz', self.seats, *(f'{penguin.safe_name}|{penguin.color}|' - f'{penguin.hand}|{penguin.safe_name}' for penguin in self.penguins)) - - def get_payout(self): - return self.payouts.pop(0) diff --git a/houdini/games/treasure.py b/houdini/games/treasure.py deleted file mode 100644 index 349878e..0000000 --- a/houdini/games/treasure.py +++ /dev/null @@ -1,129 +0,0 @@ -from houdini.games import ITable - -import random - - -class TreasureHuntLogic(ITable): - - def __init__(self): - self.map_width = 10 - self.map_height = 10 - self.coins_hidden = 0 - self.gems_hidden = 0 - self.turns = 12 - self.gem_value = 25 - self.coin_value = 1 - self.gem_locations = [] - self.treasure_map = [] - self.coins_found = 0 - self.gems_found = 0 - self.emerald_found = 0 - self.dig_record_names = [] - self.dig_record_directions = [] - self.dig_record_numbers = [] - self.emerald = 0 - self.current_player = 1 - self.generate_map() - - def make_move(self, movie, direction, spade): - if direction == 'right': - row = self.treasure_map[spade] - for column, tiles in enumerate(row): - self.dig(spade, column) - elif direction == 'down': - for row, columns in enumerate(self.treasure_map): - self.dig(row, spade) - self.turns -= 1 - self.dig_record_names.append(movie) - self.dig_record_directions.append(direction) - self.dig_record_numbers.append(spade) - - def is_valid_move(self, movie, direction, spade): - test_movie = direction + 'button' + str(spade) + '_mc' - if test_movie == movie and direction in ['down', 'right'] and 0 <= spade <= 9: - if direction == 'right': - row = self.treasure_map[spade] - for column, tiles in enumerate(row): - treasure, digs = self.treasure_map[spade][column] - if digs == 2: - return False - elif direction == 'down': - for row, columns in enumerate(self.treasure_map): - treasure, digs = self.treasure_map[row][spade] - if digs == 2: - return False - return True - return False - - def get_string(self): - treasure_map = ','.join(str(item) for row in self.treasure_map for item, digs in row) - gem_locations = ','.join(self.gem_locations) - game_array = [self.map_width, self.map_height, self.coins_hidden, self.gems_hidden, self.turns, - self.gem_value, self.coin_value, gem_locations, treasure_map] - if self.dig_record_numbers: - game_array += [self.coins_found, self.gems_found, self.emerald_found] - game_array += [','.join(self.dig_record_names), ','.join(self.dig_record_directions), - ','.join(map(str, self.dig_record_numbers))] - return '%'.join(map(str, game_array)) - - def generate_map(self): - for row in range(self.map_height): - self.treasure_map.append([]) - for column in range(self.map_width): - self.treasure_map[row].append([self.generate_treasure(row, column), 0]) - - def generate_treasure(self, row, column): - treasure_type = [('None', 0), ('Coin', 1), ('Gem', 2), ('Emerald', 4)] - if self.get_gem_by_piece(row, column): - return 3 - if row + 1 == self.map_height or column + 1 == self.map_width: - treasure_type = treasure_type[:2] - name, value = random.choices(treasure_type, weights=[60, 40, 1, 0.5][:len(treasure_type)])[0] - self.coins_hidden += 1 if value == 1 else self.coins_hidden - if value > 1: - self.gems_hidden += 1 - self.gem_locations.append(str(row) + ',' + str(column)) - if self.emerald: - return 2 - if value == 4 and not self.emerald: - self.emerald = 1 - return value - - def get_gem_by_piece(self, row, column): - for delta_row, delta_col in [(0, -1), (-1, -1), (-1, 0)]: - if row > 0 and column > 0: - treasure, digs = self.treasure_map[row + delta_row][column + delta_col] - if treasure == 2 or treasure == 4: - return row + delta_row, column + delta_col - return False - - def is_gem_uncovered(self, row, column): - for delta_row, delta_col in [(0, 1), (1, 1), (1, 0)]: - treasure, digs = self.treasure_map[row + delta_row][column + delta_col] - if digs != 2: - return False - return True - - def dig(self, row, column): - self.treasure_map[row][column][1] += 1 - treasure, digs = self.treasure_map[row][column] - if digs == 2: - if treasure == 1: - self.coins_found += 1 - elif treasure == 2 or treasure == 4: - if not self.is_gem_uncovered(row, column): - return - self.gems_found += 1 - elif treasure == 3: - treasure_row, treasure_col = self.get_gem_by_piece(row, column) - if not self.is_gem_uncovered(treasure_row, treasure_col): - return - self.gems_found += 1 - if treasure == 4: - self.emerald_found = 1 - - def determine_winnings(self): - total = self.coins_found * self.coin_value - total += self.gems_found * self.gem_value - total += self.emerald_found * self.gem_value * 3 - return total diff --git a/houdini/handlers/games/four.py b/houdini/handlers/games/four.py index 15c1f6d..07392e0 100644 --- a/houdini/handlers/games/four.py +++ b/houdini/handlers/games/four.py @@ -2,16 +2,58 @@ from houdini import ITable, handlers from houdini.handlers import XTPacket +class ConnectFourLogic(ITable): + + def __init__(self): + self.current_player = 1 + self.board = [[0 for _ in range(6)] for _ in range(7)] + + def make_move(self, col, row): + self.board[col][row] = self.current_player + + def is_valid_move(self, col, row): + if 0 <= row <= 5 and 0 <= col <= 6: + if row == 5 or (self.board[col][row] == 0 and self.board[col][row + 1]): + return True + return False + + def get_string(self): + return ','.join(str(item) for row in self.board for item in row) + + def is_position_win(self, col, row): + for delta_row, delta_col in [(1, 0), (0, 1), (1, 1), (1, -1)]: + streak = 1 + for delta in (1, -1): + delta_row *= delta + delta_col *= delta + next_row = row + delta_row + next_col = col + delta_col + while 0 <= next_row < 6 and 0 <= next_col < 7: + if self.board[next_col][next_row] == self.current_player: + streak += 1 + else: + break + if streak == 4: + return True + next_row += delta_row + next_col += delta_col + return False + + def is_board_full(self): + for col in self.board: + if not col[0]: + return False + return True @handlers.handler(XTPacket('gz', ext='z')) -@table_handler(ConnectFourLogic) +@handlers.table(ConnectFourLogic) async def handle_get_game(p): await p.send_xt('gz', p.table.get_string()) @handlers.handler(XTPacket('jz', ext='z')) -@table_handler(ConnectFourLogic) +@handlers.table(ConnectFourLogic) async def handle_join_game(p): game_full = len(p.table.penguins) > 2 if not game_full: @@ -24,7 +66,7 @@ async def handle_join_game(p): @handlers.handler(XTPacket('zm', ext='z')) -@table_handler(ConnectFourLogic) +@handlers.table(ConnectFourLogic) async def handle_send_move(p, col: int, row: int): try: seat_id = p.table.get_seat_id(p) diff --git a/houdini/handlers/games/mancala.py b/houdini/handlers/games/mancala.py index 6107deb..292e7c6 100644 --- a/houdini/handlers/games/mancala.py +++ b/houdini/handlers/games/mancala.py @@ -2,16 +2,76 @@ from houdini import ITable, handlers from houdini.handlers import XTPacket +class MancalaLogic(ITable): + + def __init__(self): + self.current_player = 1 + self.board = [ + 4, 4, 4, 4, 4, 4, 0, + 4, 4, 4, 4, 4, 4, 0 + ] + + def make_move(self, hollow): + capture = False + hand = self.board[hollow] + self.board[hollow] = 0 + + while hand > 0: + hollow = (hollow + 1) % len(self.board) + my_mancala, opponent_mancala = (6, 13) if self.current_player == 1 else (13, 6) + + if hollow == opponent_mancala: + continue + opposite_hollow = 12 - hollow + + if hand == 1 and self.board[hollow] == 0: + if (self.current_player == 1 and hollow in range(0, 6)) or (self.current_player == 2 and hollow in range(7, 13)): + self.board[my_mancala] += self.board[opposite_hollow] + 1 + self.board[opposite_hollow] = 0 + capture = True + break + + self.board[hollow] += 1 + hand -= 1 + + if (self.current_player == 1 and hollow != 6) or (self.current_player == 2 and hollow != 13): + return 'c' if capture else str() + else: + self.current_player = 2 if self.current_player == 1 else 1 + return 'f' + + def is_valid_move(self, hollow): + if self.current_player == 1 and hollow not in range(0, 6): + return False + elif self.current_player == 2 and hollow not in range(7, 13): + return False + return True + + def get_string(self): + return ','.join(map(str, self.board)) + + def is_position_win(self): + if sum(self.board[0:6]) == 0 or sum(self.board[7:-1]) == 0: + if sum(self.board[0:6]) > sum(self.board[7:-1]): + return self.current_player == 1 + return self.current_player == 2 + return False + + def is_position_tie(self): + if sum(self.board[0:6]) == 0 or sum(self.board[7:-1]) == 0: + if sum(self.board[0:6]) == sum(self.board[7:-1]): + return True + return False @handlers.handler(XTPacket('gz', ext='z')) -@table_handler(MancalaLogic) +@handlers.table(MancalaLogic) async def handle_get_game(p): await p.send_xt('gz', p.table.get_string()) @handlers.handler(XTPacket('jz', ext='z')) -@table_handler(MancalaLogic) +@handlers.table(MancalaLogic) async def handle_join_game(p): game_full = len(p.table.penguins) > 2 if not game_full: @@ -24,7 +84,7 @@ async def handle_join_game(p): @handlers.handler(XTPacket('zm', ext='z')) -@table_handler(MancalaLogic) +@handlers.table(MancalaLogic) async def handle_send_move(p, hollow: int): try: seat_id = p.table.get_seat_id(p) diff --git a/houdini/handlers/games/sled.py b/houdini/handlers/games/sled.py index 3bee224..4c5584e 100644 --- a/houdini/handlers/games/sled.py +++ b/houdini/handlers/games/sled.py @@ -2,23 +2,39 @@ from houdini import IWaddle, handlers from houdini.handlers import XTPacket +class SledRacingLogic(IWaddle): + + room_id = 999 + + def __init__(self, waddle): + super().__init__(waddle) + + self.payouts = [20, 10, 5, 5] + + async def remove_penguin(self, p): + await super().remove_penguin(p) + await self.send_xt('uz', self.seats, *(f'{penguin.safe_name}|{penguin.color}|' + f'{penguin.hand}|{penguin.safe_name}' for penguin in self.penguins)) + + def get_payout(self): + return self.payouts.pop(0) @handlers.handler(XTPacket('jz', ext='z')) -@waddle_handler(SledRacingLogic) +@handlers.waddle(SledRacingLogic) async def handle_join_game(p): await p.send_xt('uz', p.waddle.seats, *(f'{penguin.safe_name}|{penguin.color}|' f'{penguin.hand or 0}|{penguin.nickname}' for penguin in p.waddle.penguins)) @handlers.handler(XTPacket('zm', ext='z')) -@waddle_handler(SledRacingLogic) +@handlers.waddle(SledRacingLogic) async def handle_send_move(p, player_id: int, x: float, y: float, time: float): await p.waddle.send_xt('zm', player_id, x, y, time) @handlers.handler(XTPacket('zo', ext='z')) -@waddle_handler(SledRacingLogic) +@handlers.waddle(SledRacingLogic) async def handle_game_over(p): coins = p.waddle.get_payout() await p.add_coins(coins) diff --git a/houdini/handlers/games/treasure.py b/houdini/handlers/games/treasure.py index d0c476d..1fa35bb 100644 --- a/houdini/handlers/games/treasure.py +++ b/houdini/handlers/games/treasure.py @@ -4,10 +4,134 @@ from houdini import ITable, handlers from houdini.handlers import XTPacket +class TreasureHuntLogic(ITable): + + def __init__(self): + self.map_width = 10 + self.map_height = 10 + self.coins_hidden = 0 + self.gems_hidden = 0 + self.turns = 12 + self.gem_value = 25 + self.coin_value = 1 + self.gem_locations = [] + self.treasure_map = [] + self.coins_found = 0 + self.gems_found = 0 + self.emerald_found = 0 + self.dig_record_names = [] + self.dig_record_directions = [] + self.dig_record_numbers = [] + self.emerald = 0 + self.current_player = 1 + self.generate_map() + + def make_move(self, movie, direction, spade): + if direction == 'right': + row = self.treasure_map[spade] + for column, tiles in enumerate(row): + self.dig(spade, column) + elif direction == 'down': + for row, columns in enumerate(self.treasure_map): + self.dig(row, spade) + self.turns -= 1 + self.dig_record_names.append(movie) + self.dig_record_directions.append(direction) + self.dig_record_numbers.append(spade) + + def is_valid_move(self, movie, direction, spade): + test_movie = direction + 'button' + str(spade) + '_mc' + if test_movie == movie and direction in ['down', 'right'] and 0 <= spade <= 9: + if direction == 'right': + row = self.treasure_map[spade] + for column, tiles in enumerate(row): + treasure, digs = self.treasure_map[spade][column] + if digs == 2: + return False + elif direction == 'down': + for row, columns in enumerate(self.treasure_map): + treasure, digs = self.treasure_map[row][spade] + if digs == 2: + return False + return True + return False + + def get_string(self): + treasure_map = ','.join(str(item) for row in self.treasure_map for item, digs in row) + gem_locations = ','.join(self.gem_locations) + game_array = [self.map_width, self.map_height, self.coins_hidden, self.gems_hidden, self.turns, + self.gem_value, self.coin_value, gem_locations, treasure_map] + if self.dig_record_numbers: + game_array += [self.coins_found, self.gems_found, self.emerald_found] + game_array += [','.join(self.dig_record_names), ','.join(self.dig_record_directions), + ','.join(map(str, self.dig_record_numbers))] + return '%'.join(map(str, game_array)) + + def generate_map(self): + for row in range(self.map_height): + self.treasure_map.append([]) + for column in range(self.map_width): + self.treasure_map[row].append([self.generate_treasure(row, column), 0]) + + def generate_treasure(self, row, column): + treasure_type = [('None', 0), ('Coin', 1), ('Gem', 2), ('Emerald', 4)] + if self.get_gem_by_piece(row, column): + return 3 + if row + 1 == self.map_height or column + 1 == self.map_width: + treasure_type = treasure_type[:2] + name, value = random.choices(treasure_type, weights=[60, 40, 1, 0.5][:len(treasure_type)])[0] + self.coins_hidden += 1 if value == 1 else self.coins_hidden + if value > 1: + self.gems_hidden += 1 + self.gem_locations.append(str(row) + ',' + str(column)) + if self.emerald: + return 2 + if value == 4 and not self.emerald: + self.emerald = 1 + return value + + def get_gem_by_piece(self, row, column): + for delta_row, delta_col in [(0, -1), (-1, -1), (-1, 0)]: + if row > 0 and column > 0: + treasure, digs = self.treasure_map[row + delta_row][column + delta_col] + if treasure == 2 or treasure == 4: + return row + delta_row, column + delta_col + return False + + def is_gem_uncovered(self, row, column): + for delta_row, delta_col in [(0, 1), (1, 1), (1, 0)]: + treasure, digs = self.treasure_map[row + delta_row][column + delta_col] + if digs != 2: + return False + return True + + def dig(self, row, column): + self.treasure_map[row][column][1] += 1 + treasure, digs = self.treasure_map[row][column] + if digs == 2: + if treasure == 1: + self.coins_found += 1 + elif treasure == 2 or treasure == 4: + if not self.is_gem_uncovered(row, column): + return + self.gems_found += 1 + elif treasure == 3: + treasure_row, treasure_col = self.get_gem_by_piece(row, column) + if not self.is_gem_uncovered(treasure_row, treasure_col): + return + self.gems_found += 1 + if treasure == 4: + self.emerald_found = 1 + + def determine_winnings(self): + total = self.coins_found * self.coin_value + total += self.gems_found * self.gem_value + total += self.emerald_found * self.gem_value * 3 + return total @handlers.handler(XTPacket('gz', ext='z')) -@table_handler(TreasureHuntLogic) +@handlers.table(TreasureHuntLogic) async def handle_get_game(p): if len(p.table.penguins) == 2: player_one = p.table.penguins[0] @@ -17,7 +141,7 @@ async def handle_get_game(p): @handlers.handler(XTPacket('jz', ext='z')) -@table_handler(TreasureHuntLogic) +@handlers.table(TreasureHuntLogic) async def handle_join_game(p): game_full = len(p.table.penguins) > 2 if not game_full: @@ -29,7 +153,7 @@ async def handle_join_game(p): @handlers.handler(XTPacket('zm', ext='z')) -@table_handler(TreasureHuntLogic) +@handlers.table(TreasureHuntLogic) async def handle_send_move(p, movie: str, direction: str, spade: int): try: seat_id = p.table.get_seat_id(p) diff --git a/houdini/handlers/play/navigation.py b/houdini/handlers/play/navigation.py index a0bf043..9ee7f02 100644 --- a/houdini/handlers/play/navigation.py +++ b/houdini/handlers/play/navigation.py @@ -19,18 +19,48 @@ from houdini.handlers.games.ninja.water import CardJitsuWaterLogic, WaterSenseiL from houdini.handlers.games.sled import SledRacingLogic from houdini.handlers.games.treasure import TreasureHuntLogic -import random -import time -import pytz -import hashlib -from datetime import date, datetime +TableLogicMapping = { + 'four': ConnectFourLogic, + 'mancala': MancalaLogic, + 'treasure': TreasureHuntLogic +} + + +WaddleLogicMapping = { + 'sled': SledRacingLogic, + + 'card': CardJitsuLogic, + 'sensei': SenseiLogic, + + 'water': CardJitsuWaterLogic, + 'watersensei': WaterSenseiLogic, + + 'fire': CardJitsuFireLogic, + 'firesensei': FireSenseiLogic +} + + +async def setup_tables(room_collection): + async with db.transaction(): + async for table in RoomTable.query.gino.iterate(): + room_collection[table.room_id].tables[table.id] = table + table.room = room_collection[table.room_id] + table.logic = TableLogicMapping[table.game]() + + +async def setup_waddles(room_collection): + async with db.transaction(): + async for waddle in RoomWaddle.query.gino.iterate(): + room_collection[waddle.room_id].waddles[waddle.id] = waddle + waddle.room = room_collection[waddle.room_id] + waddle.logic = WaddleLogicMapping[waddle.game] @handlers.boot async def rooms_load(server): server.rooms = await RoomCollection.get_collection() - await server.rooms.setup_tables() - await server.rooms.setup_waddles() + await setup_tables(server.rooms) + await setup_waddles(server.rooms) server.logger.info(f'Loaded {len(server.rooms)} rooms ({len(server.rooms.spawn_rooms)} spawn)')