mirror of
https://github.com/solero/houdini.git
synced 2024-12-23 05:53:38 +00:00
Move all minigame logic to its own module
This commit is contained in:
parent
2c911aa856
commit
9bd7bada62
@ -1,242 +1,11 @@
|
||||
from random import uniform
|
||||
from houdini.games.sled import SledRacingLogic
|
||||
from houdini.games.four import ConnectFourLogic
|
||||
from houdini.games.mancala import MancalaLogic
|
||||
from houdini.games.treasure import TreasureHuntLogic
|
||||
|
||||
from houdini.data import db, AbstractDataCollection
|
||||
|
||||
|
||||
class ConnectFourLogic:
|
||||
|
||||
def __init__(self):
|
||||
self.current_player = 1
|
||||
self.board = [[0 for _ in range(6)] for _ in range(7)]
|
||||
|
||||
def place_chip(self, col, row):
|
||||
self.board[col][row] = self.current_player
|
||||
|
||||
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_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 is_board_full(self):
|
||||
for col in self.board:
|
||||
if not col[0]:
|
||||
return False
|
||||
return True
|
||||
|
||||
def get_string(self):
|
||||
return ','.join(str(item) for row in self.board for item in row)
|
||||
|
||||
|
||||
class MancalaLogic:
|
||||
|
||||
def __init__(self):
|
||||
self.current_player = 1
|
||||
self.board = [4, 4, 4, 4, 4, 4, 0, 4, 4, 4, 4, 4, 4, 0]
|
||||
|
||||
def place_stone(self, hollow):
|
||||
capture = False
|
||||
hand = self.board[hollow]
|
||||
self.board[hollow] = 0
|
||||
|
||||
while hand > 0:
|
||||
hollow += 1 if hollow + 1 < len(self.board) else 0
|
||||
myMancala, opponentMancala = (6, 13) if self.current_player == 1 else (13, 6)
|
||||
|
||||
if hollow == opponentMancala: continue
|
||||
oppositeHollow = 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[myMancala] += self.board[oppositeHollow] + 1
|
||||
self.board[oppositeHollow] = 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_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
|
||||
|
||||
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))
|
||||
|
||||
|
||||
class TreasureHuntLogic:
|
||||
|
||||
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 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, 60), ('Coin', 1, 40), ('Gem', 2, 1), ('Emerald', 4, 0.5)
|
||||
]
|
||||
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]
|
||||
total = sum(weight for name, value, weight in treasure_type)
|
||||
r, i = uniform(0, total), 0
|
||||
for name, value, weight in treasure_type:
|
||||
if i + weight >= r:
|
||||
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
|
||||
i += weight
|
||||
|
||||
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 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 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
|
||||
|
||||
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 stealth_mod_filter(stealth_mod_id):
|
||||
def f(p):
|
||||
return not p.stealth_moderator or p.id == stealth_mod_id
|
||||
|
49
houdini/games/__init__.py
Normal file
49
houdini/games/__init__.py
Normal file
@ -0,0 +1,49 @@
|
||||
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)
|
45
houdini/games/four.py
Normal file
45
houdini/games/four.py
Normal file
@ -0,0 +1,45 @@
|
||||
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
|
63
houdini/games/mancala.py
Normal file
63
houdini/games/mancala.py
Normal file
@ -0,0 +1,63 @@
|
||||
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
|
19
houdini/games/sled.py
Normal file
19
houdini/games/sled.py
Normal file
@ -0,0 +1,19 @@
|
||||
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)
|
129
houdini/games/treasure.py
Normal file
129
houdini/games/treasure.py
Normal file
@ -0,0 +1,129 @@
|
||||
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
|
@ -1,7 +1,7 @@
|
||||
from houdini import handlers
|
||||
from houdini.handlers import XTPacket
|
||||
from houdini.handlers.games.table import table_handler
|
||||
from houdini.data.room import ConnectFourLogic
|
||||
from houdini.games.four import ConnectFourLogic
|
||||
|
||||
|
||||
@handlers.handler(XTPacket('gz', ext='z'))
|
||||
@ -37,7 +37,7 @@ async def handle_send_move(p, col: int, row: int):
|
||||
if not p.table.logic.is_valid_move(col, row):
|
||||
return
|
||||
await p.table.send_xt('zm', p.table.logic.current_player - 1, col, row)
|
||||
p.table.logic.place_chip(col, row)
|
||||
p.table.logic.make_move(col, row)
|
||||
opponent = p.table.penguins[1 if p.table.logic.current_player == 1 else 0]
|
||||
if p.table.logic.is_position_win(col, row):
|
||||
await p.add_coins(10)
|
||||
|
@ -1,7 +1,7 @@
|
||||
from houdini import handlers
|
||||
from houdini.handlers import XTPacket
|
||||
from houdini.handlers.games.table import table_handler
|
||||
from houdini.data.room import MancalaLogic
|
||||
from houdini.games.mancala import MancalaLogic
|
||||
|
||||
|
||||
@handlers.handler(XTPacket('gz', ext='z'))
|
||||
@ -39,7 +39,7 @@ async def handle_send_move(p, hollow: int):
|
||||
if not p.table.logic.is_valid_move(hollow):
|
||||
return
|
||||
|
||||
move_result = p.table.logic.place_stone(hollow)
|
||||
move_result = p.table.logic.make_move(hollow)
|
||||
await p.table.send_xt('zm', seat_id, hollow, move_result)
|
||||
opponent = p.table.penguins[1 if p.table.logic.current_player == 1 else 0]
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
from houdini import handlers
|
||||
from houdini.handlers import XTPacket
|
||||
from houdini.handlers.games.table import table_handler
|
||||
from houdini.data.room import TreasureHuntLogic
|
||||
from houdini.games.treasure import TreasureHuntLogic
|
||||
|
||||
|
||||
@handlers.handler(XTPacket('gz', ext='z'))
|
||||
|
Loading…
Reference in New Issue
Block a user