def main(): while True: game = Engine() user_1 = User(1, AIController(1)) user_2 = User(2, ManualController(2)) game.add_user(user_1) game.add_user(user_2) game.init_game() game.update_users() while not game.is_ended(): game.one_tick() game.outcomes_notify(game.generate_outcomes())
class Game(tk.Frame): # pylint: disable=too-many-ancestors def __init__(self, master): super().__init__(master) self.grid(column=0, row=0, sticky="news") self.rowconfigure(0, weight=1) self.master = master self.engine = None self.users = [] self.user_frames = [] self.active_users_queue = Queue() def turn_callback(self, user_id: int, turn: TURN): self.engine.process_turn(self.users[user_id], turn) if None not in [client_id, turn] and user_id == client_id: resp = requests.post(server_url + '/make_turn', json={ 'id': user_id, 'turn': turn.value }) data = resp.json() if data['status'] == 'FAIL': messagebox.showerror(title='Not your turn', message=data['error_msg']) self.users[user_id].update_table(*self.engine.get_game_table_info()) if self.active_users_queue.empty(): queue_update = self.engine.get_active_users() if queue_update: for user in queue_update: self.active_users_queue.put(user) else: self.engine.outcomes_notify(self.engine.generate_outcomes()) return user = self.active_users_queue.get() self.engine.process_turn( user, user.make_turn(*self.engine.get_game_table_info())) def to_menu_callback(self): global client_id if client_id: requests.post(server_url + '/clear') client_id = None for user_frame in self.user_frames: user_frame.grid_forget() user_frame.destroy() self.user_frames.clear() self.users.clear() self.active_users_queue.queue.clear() self.engine = None self.master.geometry('200x250') self.master.menu.tkraise() def add_player(self, username: str, controller: Controller): frame = tk.Frame(self, bg="white") frame.grid(column=controller.user_id, row=0, sticky="news") self.columnconfigure(controller.user_id, weight=1) self.user_frames.append(frame) frame.rowconfigure(0, weight=0) frame.rowconfigure(1, weight=0) frame.rowconfigure(2, weight=1) frame.columnconfigure(0, weight=1) frame.columnconfigure(1, weight=1) user = GuiUser(frame, username, controller, self.turn_callback, self.to_menu_callback) self.users.append(user) def start_game(self, deck=None): self.master.geometry('1100x250') deck = Deck() if deck is None else deck self.engine = Engine(deck) for user in self.users: self.engine.add_user(user) self.engine.init_game() self.engine.update_users() for user in self.engine.get_active_users(): self.active_users_queue.put(user) user = self.active_users_queue.get() self.engine.process_turn( user, user.make_turn(*self.engine.get_game_table_info())) if self.engine.is_ended(): self.engine.outcomes_notify(self.engine.generate_outcomes())
class TestEngine(TestCase): def setUp(self): self.controller_1 = ManualController(0) self.controller_2 = ManualController(1) self.user_1 = User(0, self.controller_1) self.user_2 = User(1, self.controller_2) self.engine = Engine() self.engine.add_user(self.user_1) self.engine.add_user(self.user_2) self.engine.deck = Deck(shuffle=False, is_small=False) def test_general(self): self.engine.deck.pull_out = Mock(return_value=Card(SUIT.CLUBS, VALUE.SIX)) self.engine.init_game() with self.subTest(): self.assertEqual(len(self.engine.bj_gametable.get_cards(self.user_1)), 2) with self.subTest(): self.assertEqual(len(self.engine.bj_gametable.get_cards(self.user_2)), 2) with self.subTest(): self.assertTrue(self.engine.is_inited) with self.subTest(): self.assertEqual(self.engine.deck.pull_out.call_count, 4) self.controller_1.make_turn = Mock(return_value=TURN.HIT_ME) self.controller_2.make_turn = Mock(return_value=TURN.HIT_ME) self.controller_1.update_table = Mock() self.controller_2.update_table = Mock() self.engine.one_tick() with self.subTest(): self.controller_1.make_turn.assert_called_once() with self.subTest(): self.assertEqual(self.controller_1.update_table.call_count, 2) with self.subTest(): self.controller_2.make_turn.assert_called_once() with self.subTest(): self.assertEqual(self.controller_2.update_table.call_count, 2) with self.subTest(): self.assertEqual(self.engine.deck.pull_out.call_count, 6) with self.subTest(): self.assertFalse(self.engine.is_ended()) self.engine.deck.pull_out.side_effect = [Card(SUIT.CLUBS, VALUE.THREE), Card(SUIT.CLUBS, VALUE.TWO), Card(SUIT.CLUBS, VALUE.ACE)] self.controller_1.make_turn.return_value = TURN.HIT_ME self.controller_2.make_turn.side_effect = [TURN.HIT_ME, TURN.HIT_ME] self.engine.one_tick() with self.subTest(): self.assertEqual(self.engine.bj_gametable.get_status(self.user_1), UserStatus.BLACKJACK) with self.subTest(): self.assertEqual(self.engine.bj_gametable.get_status(self.user_2), UserStatus.IN_GAME) with self.subTest(): self.assertFalse(self.engine.is_ended()) self.controller_1.outcome_notify = Mock() self.controller_2.outcome_notify = Mock() self.engine.one_tick() with self.subTest(): self.assertEqual(self.controller_1.make_turn.call_count + 1, self.controller_2.make_turn.call_count) with self.subTest(): self.assertTrue(self.engine.is_ended()) self.engine.outcomes_notify(self.engine.generate_outcomes()) with self.subTest(): self.controller_1.outcome_notify.assert_called_once_with(21, GameOutcome.DRAW) with self.subTest(): self.controller_2.outcome_notify.assert_called_once_with(21, GameOutcome.DRAW)