def on_execute(self): self.on_init() pygame.time.set_timer(EVENT_TICK, 20) running = True playing = False fastest = False while running: self.on_render() if fastest: event = pygame.event.poll() fastest = self.on_loop() else: event = pygame.event.wait() if event.type == QUIT or (event.type == KEYDOWN and event.key == K_ESCAPE): running = False elif event.type == KEYDOWN and event.key == K_SPACE: self.on_loop() elif event.type == EVENT_TICK: self.tick_handler() if playing: playing = self.on_loop() elif event.type == KEYDOWN and event.key == K_p: playing = not playing elif event.type == KEYDOWN and event.key == K_r: self.state = GameState((20, 20)) self.state.apple_pos = (22, 20) elif event.type == KEYDOWN and event.key == K_f: fastest = not fastest playing = False pygame.quit()
def __init__(self, step_handler: Callable[[GameState], int], tick_handler: Callable[[], None] = lambda: None) -> None: self.step_handler = step_handler self.tick_handler = tick_handler self.state = GameState((20, 20)) self.state.apple_pos = (22, 20)
def test_deepcopy(self): slimer = Constants.CARDS[1] scuttler = Constants.CARDS[2] decks = [[slimer], [scuttler]] draft = fix_draft(*decks) state = GameState(draft) state.open_next_turn() copy_state = deepcopy(state) self.assertEqual( copy_state.current_player().get_hand()[0].instance_id(), state.current_player().get_hand()[0].instance_id())
def main(): session = GameState() ui = Ui(session) ui.step() time.sleep(2) while session.step(): ui.step() print(session.get_score()) time.sleep(1) ui.close()
def play_match(self): self._play_draft() draftphase = fix_draft(self._draft_decks[self._ais[0]], self._draft_decks[self._ais[1]]) game = GameState(draftphase) for turn in range(100): for ai in self._ais: game.open_next_turn() actions = ai.play(game) for action in actions: game.perform_action(action) if game.has_winner(): print('Winner!', game.winner()) return game.winner()
def game() -> None: """Represents a single game of craps.""" print("Welcome to craps!") balance = 1000 state = GameState(balance) print(f"You start with ${balance}") print("-" * 32) while True: if state.balance <= 0 and not state.bets: print("You're broke! Game over.") break round(state) print("-" * 32)
def test_summon(self): slimer = Constants.CARDS[1] scuttler = Constants.CARDS[2] decks = [[slimer], [scuttler]] draft = fix_draft(*decks) state = GameState(draft) state.open_next_turn() first_player = state.get_first_player() second_player = state.get_second_player() self.assertEqual(first_player.deck_size(), 0) self.assertEqual(second_player.deck_size(), 0) summon = Summon(first_player.from_hand(slimer)) state.perform_action(summon) self.assertEqual(len(first_player.board()), 1) self.assertEqual(first_player.board()[0].name(), slimer.name()) # rune effect of trying to draw 4, +1 from slimer self.assertEqual(first_player.health(), 11)
def compute_score(step_handler: Callable[[GameState], int]) -> float: state = GameState((20, 20)) step_count = 0 reward = 0 distance_to_apple = state.distance_to_apple() while step_count <= distance_to_apple * 2 * math.sqrt(state.length): state.direction = step_handler(state) step_count += 1 self_intersecting, has_grown = state.move() if not self_intersecting: return reward elif has_grown: reward += distance_to_apple / math.sqrt(step_count) * math.sqrt( state.length) step_count = 0 distance_to_apple = state.distance_to_apple() return reward
def test_charge(self): slimer = Constants.CARDS[1] wings = Constants.CARDS[140] scuttler = Constants.CARDS[2] decks = [[wings] + [slimer] * 6, [scuttler] * 7] draft = fix_draft(*decks) state = GameState(draft) first_player = state.get_first_player() second_player = state.get_second_player() for i in range(5): state.open_next_turn() self.assertEqual(first_player.current_mana(), 3) state.perform_action(Summon(first_player.from_hand(slimer))) slimer_creature = first_player.get_creature_by_index(0) self.assertEqual(first_player.get_creature_by_index(0), slimer_creature) state.perform_action( Use(first_player.from_hand(wings), slimer_creature)) # update as a result of item change slimer_creature = first_player.get_creature_by_index(0) self.assertTrue(slimer_creature.can_attack()) self.assertEqual(first_player.num_board_creatures(), 1) self.assertTrue(slimer_creature.has_abil(Ability.CHARGE)) self.assertEqual( first_player.get_creature_by_index(0).name(), slimer_creature.name()) state.perform_action(Attack(slimer_creature, None)) self.assertEqual(first_player.health(), Constants.INITIAL_HEALTH + 1) self.assertEqual(second_player.health(), Constants.INITIAL_HEALTH - 2)
def test_drain(self): slimer = Constants.CARDS[1] scuttler = Constants.CARDS[2] imp = Constants.CARDS[38] decks = [[slimer] * 8 + [imp], [scuttler] * 9] draft = fix_draft(*decks) state = GameState(draft) first_player = state.get_first_player() second_player = state.get_second_player() for i in range(5): state.open_next_turn() state.perform_action(Summon(first_player.from_hand(imp))) state.open_next_turn() state.open_next_turn() state.perform_action( Attack(first_player.get_creature_by_index(0), None)) self.assertEqual(first_player.health(), Constants.INITIAL_HEALTH + 1)
def round(state: GameState) -> None: """A single round (die roll stage) in a game of craps.""" if state.point is None: print(f"Round {state.round + 1}: Come Out phase") else: print(f"Round {state.round + 1}: Point phase (point: {state.point})") bet_state_message = "Your bets:" if state.bets: for bet_type, amount in state.bets.items(): bet_state_message += f"\n {bet_type.value}: {amount}" else: bet_state_message += "\n None" print(bet_state_message) allowed_bet_types = set() for bet_type in BetType: bet = state.get_bet(bet_type) assert bet.wager >= 0, "Bet wager cannot be negative" if bet.wager and (bet.can_remove() or bet.min_wager() < bet.wager): allowed_bet_types.add(bet_type) elif bet.max_wager() > bet.wager: allowed_bet_types.add(bet_type) assert allowed_bet_types, "You cannot bet on anything! WTF?" while True: bet_types_str = ", ".join(map(attrgetter("value"), allowed_bet_types)) bet_type_str = input(f"Choose bet type ({bet_types_str}): ").strip() if not bet_type_str: print("You decide to skip this round.") else: try: bet_type = BetType(bet_type_str) except ValueError: print(f"{bet_type_str!r} is not a valid bet type.") continue bet_amount_str = input( f"Choose amount to bet (your balance: {state.balance}) : ") try: bet_amount = int(bet_amount_str) except ValueError: print(f"{bet_amount_str!r} is not a valid bet amount.") continue bet = state.get_bet(bet_type) new_wager = bet.wager + bet_amount (fail_reason, ) = state.set_bets([(bet_type, new_wager)]) if fail_reason: if fail_reason == BetFailReason.NEGATIVE_WAGER: print("You can't bet a negative amount!") elif fail_reason == BetFailReason.NOT_ENOUGH_BALANCE: print("You don't have that much money.") elif fail_reason == BetFailReason.CANNOT_ADD_BET: print("You can't make that bet.") elif fail_reason == BetFailReason.CANNOT_REMOVE_BET: print("You can't remove that bet.") elif fail_reason == BetFailReason.WAGER_BELOW_MIN: print(f"You have to bet at least ${bet.min_wager()}") elif fail_reason == BetFailReason.WAGER_ABOVE_MAX: print(f"You cannot bet more than ${bet.max_wager()}") else: raise Exception( f"Unexpected failure: {fail_reason} for {bet_type}") continue try: bet_outcomes = state.shoot_dice() except YouShallNotSkipPassError: print("You can't skip a bet in the Come Out round when you are the" " shooter.") continue break print("You made a bet.") (roll1, roll2) = state.last_roll print(f"You rolled {roll1}, {roll2}") for bet_type, outcome, wager, winnings in bet_outcomes: bet_name = BET_TYPE_NAMES[bet_type] if outcome == BetOutcome.WIN: print(f" You won a {bet_name} bet! (+${winnings})") elif outcome == BetOutcome.LOSE: print(f" You lost a {bet_name} bet... (${wager} gone)") elif outcome == BetOutcome.TIE: print(f" You tied a {bet_name} bet. (+${winnings})") if state.is_finished: print("Round finished.") state.reset() elif state.round == 1: print(f"You established a point: {state.point}") else: # Point phase print("Roll it again, baby.")
def test_guard(self): slimer = Constants.CARDS[1] scuttler = Constants.CARDS[2] prowler = Constants.CARDS[49] decks = [[slimer] * 8 + [prowler], [scuttler] * 9] draft = fix_draft(*decks) state = GameState(draft) first_player = state.get_first_player() second_player = state.get_second_player() for i in range(5): state.open_next_turn() state.perform_action(Summon(first_player.from_hand(prowler))) state.perform_action(Summon(first_player.from_hand(slimer))) state.open_next_turn() state.perform_action(Summon(second_player.from_hand(scuttler))) state.perform_action(Summon(second_player.from_hand(scuttler))) state.open_next_turn() state.open_next_turn() self.assertEqual( first_player.get_creature_by_index(0).name(), prowler.name()) # must attack creature with guard first with self.assertRaises(IllegalAttackException): state.perform_action( Attack(second_player.get_creature_by_index(0), first_player.get_creature_by_index(1))) state.perform_action( Attack(second_player.get_creature_by_index(0), first_player.get_creature_by_index(0))) # now we can attack the other creature without guard state.perform_action( Attack(second_player.get_creature_by_index(0), first_player.get_creature_by_index(0)))
def play(self, state: GameState): # copy to make decisions state = deepcopy(state) my_player = state.current_player() opp_player = state.non_current_player() actions = [] for card in my_player.get_hand(): if my_player.current_mana() >= card.cost(): if card.is_creature() and my_player.num_board_creatures( ) < Constants.MAX_CREATURES_IN_LINE: actions.append(Summon(card)) state.perform_action(actions[-1]) elif card.is_item(): if card.is_green_item(): for target in my_player.board(): actions.append(Use(card, target)) state.perform_action(actions[-1]) break elif card.is_blue_item(): actions.append(Use(card, None)) state.perform_action(actions[-1]) elif card.is_red_item(): for target in opp_player.board(): actions.append(Use(card, target)) state.perform_action(actions[-1]) break for creature in my_player.board(): if creature.can_attack(): targets = opp_player.board() if len(targets) > 0: actions.append(Attack(creature, targets[0])) else: actions.append(Attack(creature, None)) state.perform_action(actions[-1]) return actions
def test_ward(self): slimer = Constants.CARDS[1] scuttler = Constants.CARDS[2] sapling = Constants.CARDS[7] decks = [[slimer] * 8 + [sapling], [scuttler] * 9] draft = fix_draft(*decks) state = GameState(draft) first_player = state.get_first_player() second_player = state.get_second_player() for i in range(5): state.open_next_turn() state.perform_action(Summon(first_player.from_hand(sapling))) state.open_next_turn() state.perform_action(Summon(second_player.from_hand(scuttler))) state.open_next_turn() state.open_next_turn() self.assertEqual(first_player.get_creature_by_index(0).defense(), 2) state.perform_action( Attack(second_player.get_creature_by_index(0), first_player.get_creature_by_index(0))) # check for annulled ward self.assertEqual(first_player.get_creature_by_index(0).defense(), 2)
def test_draw(self): slimer = Constants.CARDS[1] scuttler = Constants.CARDS[2] toad = Constants.CARDS[28] decks = [[slimer] * 8 + [toad], [scuttler] * 9] draft = fix_draft(*decks) state = GameState(draft) first_player = state.get_first_player() second_player = state.get_second_player() for i in range(3): state.open_next_turn() self.assertEqual(first_player.num_hand_cards(), 6) state.perform_action(Summon(first_player.from_hand(toad))) state.open_next_turn() state.open_next_turn() self.assertEqual(first_player.num_hand_cards(), 7) for i in range(5): state.open_next_turn() self.assertEqual(first_player.num_hand_cards(), Constants.MAX_CARDS_IN_HAND) self.assertEqual(second_player.num_hand_cards(), Constants.MAX_CARDS_IN_HAND)
class App: steps = 0 windowWidth = GRID_WIDTH * 10 windowHeight = GRID_HEIGHT * 10 # step handler takes the snake and the apple and returns a new direction def __init__(self, step_handler: Callable[[GameState], int], tick_handler: Callable[[], None] = lambda: None) -> None: self.step_handler = step_handler self.tick_handler = tick_handler self.state = GameState((20, 20)) self.state.apple_pos = (22, 20) def on_init(self): pygame.init() pygame.display.set_caption('EA Snake') self._display_surf = pygame.display.set_mode((self.windowWidth, self.windowHeight), pygame.HWSURFACE) self._image_surf = pygame.Surface((10, 10)) self._image_surf.fill((255, 0, 0)) self._apple_surf = pygame.Surface((10, 10)) self._apple_surf.fill((0, 255, 0)) def on_loop(self) -> bool: self.steps += 1 pygame.display.set_caption('EA Snake - length {} - {} steps'.format(self.state.length, self.steps)) # get new direction self.state.direction = self.step_handler(self.state) # move self_intersection, _ = self.state.move() if not self_intersection: print("self or border intersection") return False return True def on_render(self): self._display_surf.fill((0, 0, 0)) # draw apple self._display_surf.blit(self._apple_surf, (self.state.apple_pos[0] * 10, self.state.apple_pos[1] * 10)) # draw tiles for (x, y) in self.state.positions: self._display_surf.blit(self._image_surf, (x * 10, y * 10)) pygame.display.flip() def on_execute(self): self.on_init() pygame.time.set_timer(EVENT_TICK, 20) running = True playing = False fastest = False while running: self.on_render() if fastest: event = pygame.event.poll() fastest = self.on_loop() else: event = pygame.event.wait() if event.type == QUIT or (event.type == KEYDOWN and event.key == K_ESCAPE): running = False elif event.type == KEYDOWN and event.key == K_SPACE: self.on_loop() elif event.type == EVENT_TICK: self.tick_handler() if playing: playing = self.on_loop() elif event.type == KEYDOWN and event.key == K_p: playing = not playing elif event.type == KEYDOWN and event.key == K_r: self.state = GameState((20, 20)) self.state.apple_pos = (22, 20) elif event.type == KEYDOWN and event.key == K_f: fastest = not fastest playing = False pygame.quit()
def test_breakthrough(self): slimer = Constants.CARDS[1] protein = Constants.CARDS[117] scuttler = Constants.CARDS[2] decks = [[slimer] * 8 + [protein], [scuttler] * 9] draft = fix_draft(*decks) state = GameState(draft) first_player = state.get_first_player() second_player = state.get_second_player() for i in range(5): state.open_next_turn() state.perform_action(Summon(first_player.from_hand(slimer))) state.perform_action( Use(first_player.from_hand(protein), first_player.get_creature_by_index(0))) self.assertTrue( first_player.get_creature_by_index(0).has_abil( Ability.BREAKTHROUGH)) state.open_next_turn() state.perform_action(Summon(second_player.from_hand(scuttler))) state.open_next_turn() state.perform_action( Attack(first_player.get_creature_by_index(0), second_player.get_creature_by_index(0))) self.assertEqual(second_player.health(), Constants.INITIAL_HEALTH - 1)
def test_attack(self): slimer = Constants.CARDS[1] scuttler = Constants.CARDS[2] decks = [[slimer] * 6, [scuttler] * 6] draft = fix_draft(*decks) state = GameState(draft) state.open_next_turn() first_player = state.get_first_player() second_player = state.get_second_player() state.perform_action(Summon(first_player.from_hand(slimer))) with self.assertRaises(IllegalAttackException): state.perform_action( Attack(first_player.get_creature_by_index(0), None)) with self.assertRaises(InsufficientManaException): # not enough mana for this state.perform_action(Summon(first_player.from_hand(slimer))) self.assertEqual(first_player.health(), Constants.INITIAL_HEALTH + 1) # second ai turn state.open_next_turn() for i in range(2): state.perform_action(Summon(second_player.from_hand(scuttler))) # does damage to opp self.assertEqual(first_player.health(), Constants.INITIAL_HEALTH - 1) with self.assertRaises(InsufficientManaException): # not enough mana for this state.perform_action(Summon(second_player.from_hand(scuttler))) state.open_next_turn() a_slimer = first_player.get_creature_by_index(0) a_target = second_player.get_creature_by_index(0) state.perform_action(Attack(a_slimer, a_target)) # they should kill each other self.assertEqual(first_player.num_board_creatures(), 0) self.assertEqual(second_player.num_board_creatures(), 1)