def main(*flags): """Main game loop and event handling.""" # Initialization pygame.init() #Put window in center of screen os.environ['SDL_VIDEO_WINDOW_POS'] = 'center' screen = pygame.display.set_mode(SCREEN_SIZE, pygame.FULLSCREEN if FULLSCREEN else 0) pygame.display.set_caption('Jeopardy!') # Declarations gameData = GameData() gs = JeopGameState() uicontroller = Controller(screen, gameData, FPS_LIMIT) clock = pygame.time.Clock() # Intro sequence (control passed completely to functions) if SKIP_INTRO_FLAG not in flags: pygame.mouse.set_visible(0) do_intro(screen, clock, uicontroller.audioplayer) do_scroll(screen, clock, gameData.categories) pygame.mouse.set_visible(1) # Prep for primary loop pygame.event.set_allowed(None) pygame.event.set_allowed(EVENTS_ALLOWED) uicontroller.draw(screen) # Primary loop while not gs.state == gs.GAME_END: # Events handle_events(gs, gameData, uicontroller) handle_buzzers(gs, gameData) if gs.state == gs.QUIT: pygame.quit() sys.exit() # Update gameData.update(gs) uicontroller.update(gs, gameData) gs.transition_state_immediate_linear(gameData) transition_state_branching(gs, gameData, uicontroller) # Draw uicontroller.draw(screen) # Cleanup pygame.event.pump() clock.tick_busy_loop(FPS_LIMIT) # Post game: Congratulations screen and credits pygame.mouse.set_visible(0) do_congrats(screen, clock, gameData.winners, uicontroller.audioplayer) do_credits(screen, clock, uicontroller.audioplayer, FPS_LIMIT)
def main(*flags): """Main game loop and event handling.""" # Initialization pygame.init() #Put window in center of screen os.environ ['SDL_VIDEO_WINDOW_POS'] = 'center' screen = pygame.display.set_mode(SCREEN_SIZE, pygame.FULLSCREEN if FULLSCREEN else 0) pygame.display.set_caption('Jeopardy!') # Declarations gameData = GameData() gs = JeopGameState() uicontroller = Controller(screen, gameData, FPS_LIMIT) clock = pygame.time.Clock() # Intro sequence (control passed completely to functions) if SKIP_INTRO_FLAG not in flags: pygame.mouse.set_visible(0) do_intro(screen, clock, uicontroller.audioplayer) do_scroll(screen, clock, gameData.categories) pygame.mouse.set_visible(1) # Prep for primary loop pygame.event.set_allowed(None) pygame.event.set_allowed(EVENTS_ALLOWED) uicontroller.draw(screen) # Primary loop while not gs.state == gs.GAME_END: # Events handle_events(gs, gameData, uicontroller) handle_buzzers(gs, gameData) if gs.state == gs.QUIT: pygame.quit() sys.exit() # Update gameData.update(gs) uicontroller.update(gs, gameData) gs.transition_state_immediate_linear(gameData) transition_state_branching(gs, gameData, uicontroller) # Draw uicontroller.draw(screen) # Cleanup pygame.event.pump() clock.tick_busy_loop(FPS_LIMIT) # Post game: Congratulations screen and credits pygame.mouse.set_visible(0) do_congrats(screen, clock, gameData.winners, uicontroller.audioplayer) do_credits(screen, clock, uicontroller.audioplayer, FPS_LIMIT)
class Brain: """The brain: parses lines, combines data classes to make decisions""" def __init__(self, bot): with Timer() as t: self.bot = bot self.load_realtime_data() self.load_precalc_data() self.iterations = 400 self.bot.log("Brain started up in {t} secs".format(t=t.secs)) def load_realtime_data(self): sharedData = {} self.parser = self.bot.set_up_parser(sharedData, self.do_turn) self.data = GameData(sharedData) self.data.reset() def load_precalc_data(self): """Loads pre-computed hand data""" infile = os.path.join('data', 'preflop_wins_5000.pickle') try: in_stream = open(infile, 'r') try: self.preflop_equity = pickle.load(in_stream) self.bot.log("Loaded preflop equity file") finally: in_stream.close() except IOError: self.bot.log("IO error loading {f}".format(f=infile)) def parse_line(self, line): """Feeds a line to the parsers""" success = self.parser.handle_line(line) if success: self.data.update() else: self.bot.log("didn't handle line: " + line + "\n") def pot_odds(self): """Return the pot odds, or how much we need to gain to call""" to_call = self.data.sidepot pot_total = to_call + self.data.pot return MathUtils.percentage(to_call, pot_total) def do_turn(self, timeLeft_ms): """Wraps internal __do_turn so we can time how long each turn takes""" with Timer() as t: self.__do_turn(timeLeft_ms) self.bot.log("Finished turn in {t}s ({i} sims), had {l}s remaining" .format(t=t.secs, i=self.iterations, l=(timeLeft_ms/1000 - t.secs))) def __do_turn(self, timeLeft_ms): """Callback for when the brain has to make a decision""" if not self.data.hand: self.bot.log("No hand, killing ourselves. Data={d}" .format(d=self.data)) self.bot.fold() return hand = self.data.hand pot_odds = self.pot_odds() equity = 0 if not self.data.table_cards: equity = self.preflop_equity[repr(hand)] else: simulator = HandSimulator(hand, self.data.table_cards) best_hand, score = simulator.best_hand() self.bot.log("best 5: {b} score: {s}" .format(b=str(best_hand), s=score)) equity = simulator.simulate(self.iterations) self.bot.log("{h}, equity: {e}%, pot odds: {p}%" .format(h=hand, e=equity, p=pot_odds)) self.pick_action(equity, pot_odds) def pick_action(self, equity, pot_odds): """Look at our expected return and do something. Will be a semi-random mix of betting, folding, calling""" to_call = self.data.sidepot # action to us: check or bet if to_call == 0: if equity > 0.7 or self.r_test(0.03): self.bot.bet(self.big_raise()) elif equity > 0.5 or self.r_test(0.05): self.bot.minimum_bet() else: # equity <= 0.3: self.bot.check() # use pot odds to call/bet/fold else: return_ratio = equity / pot_odds if return_ratio > 1.5 or self.r_test(0.02): self.bot.bet(self.big_raise()) elif return_ratio > 1: self.bot.call(to_call) else: self.bot.fold() def big_raise(self): """Returns a big raise, 30-50% of the pot""" pot = self.data.pot bet_raise = random.uniform(0.3, 0.5) * pot self.bot.log("big raise of {r}".format(r=bet_raise)) return bet_raise def minimum_bet(self): """Returns a minimum bet, 2.5-4 BB""" bet = self.data.big_blind * random.uniform(2, 4) self.bot.log("min bet of {b}".format(b=bet)) return bet def r_test(self, fraction): """Given a number [0,1], randomly return true / false s.t. r_test(0.5) is true ~50% of the time""" passed = random.uniform(0, 1) < fraction if passed: self.bot.log("r_test() passed for %{f}".format(f=fraction)) return passed
def main(): parse_args() # Sets CONFIG options. # Must be called before UIManager instantiated. pygame.init() pygame.display.set_caption('Flippyflap Wivs') environ['SDL_VIDEO_WINDOW_POS'] = 'center' # Load high score pd = PersistentData(DATA_PATH) if path.exists(DATA_PATH): pd.load() else: pd.high_score = 0 clock = pygame.time.Clock() dt = 1 gdt = 60 / CONFIG.FPS_LIMIT gs = GameState() gd = GameData(pd.high_score) uim = UIManager(gd.n_columns, gdt*gd.scroll_speed) end = False # Prep for game loop pygame.mouse.set_visible(0) pygame.event.set_allowed(None) pygame.event.set_allowed( (pygame.KEYDOWN, pygame.QUIT, pygame.MOUSEBUTTONDOWN) ) # Game loop while not end: # Transition state gs.transition_state() # Handle Events for event in pygame.event.get(): if event.type == pygame.QUIT: end = True elif event.type == pygame.KEYDOWN: handle_event_keydown(gs, event) elif event.type == pygame.MOUSEBUTTONDOWN: handle_event_mousebuttondown(gs, event) if gs.state == gs.QUIT: end = True if gs.state != gs.PAUSE: # Update gd.update(gs, gdt) uim.update(gs, gd, dt) gd.postupdate(gs, gdt) # Draw uim.draw() # Cleanup clock.tick(CONFIG.FPS_LIMIT) fps = clock.get_fps() gdt = 60 / (fps if fps > 15 else CONFIG.FPS_LIMIT) dt = fps / CONFIG.FPS_LIMIT pygame.event.pump() # Save high score pd.high_score = gd.high_score pd.save() pygame.quit()
class Brain(BetSizeCalculator, Fear): """The brain: parses lines, combines data classes to make decisions""" def __init__(self, bot): with Timer() as t: self.bot = bot self.load_realtime_data() self.load_precalc_data() self.iterations = 2000 self.bot.log("Brain started up in {t} secs".format(t=t.secs)) def load_realtime_data(self): sharedData = {} self.parser = self.bot.set_up_parser(sharedData, self.do_turn) self.data = GameData(sharedData) self.data.reset() def load_precalc_data(self): """Loads pre-computed hand data""" preflop = preflop_equity.PreflopEquity(log_func=self.bot.log) self.preflop_equity = preflop.data def parse_line(self, line): """Feeds a line to the parsers""" success = self.parser.handle_line(line) if success: self.data.update() else: self.bot.log("didn't handle line: '{}'".format(line)) def do_turn(self, bot, total_time_left_ms): """Wraps internal __do_turn so we can time how long each turn takes""" time_left = min(total_time_left_ms, self.data.time_per_move) if not bot or bot != self.data.me: return with Timer() as t: self.__do_turn(time_left) if not self.data.table_cards: turn_type = "preflop" else: turn_type = "{} sims".format(self.iterations) left = (time_left / 1000) - t.secs self.bot.log("Finished turn in {t}s ({s}), had {l}s remaining" .format(t=t.secs, s=turn_type, l=left)) def __do_turn(self, time_left_ms): """Callback for when the brain has to make a decision""" if not self.data.hand: self.bot.log("No hand, killing ourselves. Data={d}" .format(d=self.data)) self.bot.fold() return hand = self.data.hand stack = self.our_stack() to_call = self.to_call(silent=False) pot_odds = self.pot_odds() equity = 0 self.update_fear(to_call) preflop_fear = self.data.preflop_fear hand_fear = self.data.hand_fear # preflop, no big raises. safe to use our precalculated win % if not self.data.table_cards and preflop_fear == -1: equity = self.preflop_equity[hand.simple()] source = "preflop" else: simulator = HandSimulator(hand, self.data.table_cards, self.preflop_equity) best_hand, score = simulator.best_hand() equity = self.__run_simulator(simulator, time_left_ms, preflop_fear, hand_fear) source = "sim" self.bot.log(" hand: {h}, table: {t}" .format(h=hand, t=[str(t) for t in self.data.table_cards])) if self.data.table_cards: self.bot.log(" best 5: {b} score: {s}" .format(b=[str(c) for c in best_hand], s=str(score))) self.bot.log(" win: {e:.2f}% ({s}), pot odds: {p:.2f}%, stack={m}" .format(e=equity, s=source, p=pot_odds, m=stack)) self.bot.log(" pre-fear={pf}, hand-fear=({hf})" .format(pf=preflop_fear, hf=hand_fear)) self.pick_action(equity, to_call, pot_odds) def __run_simulator(self, simulator, time_left_ms, hand_filter, hand_fear): results = [] step_size = 100 start_time = time.clock() * 1000 end_time = start_time + time_left_ms - 50 for i in range(0, self.iterations, step_size): now = time.clock() * 1000 if now >= end_time: self.bot.log(" stopping simulation after {} runs".format(i)) break equity = simulator.simulate(step_size, hand_filter, hand_fear) results.append(equity) return sum(results) / len(results) def pick_action(self, equity, to_call, pot_odds): """Look at our expected return and do something. Will be a semi-random mix of betting, folding, calling""" # action to us: check or bet if to_call == 0: # lock hands - 1/3 of the time make a small bet instead of a big one if equity > 90 and self.r_test(0.33, 'lock_trap'): self.make_bet(self.minimum_bet("trap1")) elif equity > 65 or (equity > 40 and self.r_test(0.03, 'c1')): self.make_bet(self.big_raise("R1")) elif equity > 55 or self.r_test(0.02, 'c2'): self.make_bet(self.minimum_bet("R2")) else: self.bot.check() # TODO: combine these and make them aware of button # use pot odds to call/bet/fold else: return_ratio = equity / pot_odds self.bot.log(" return ratio={:.3f}".format(return_ratio)) if equity > 70 or (equity > 40 and self.r_test(0.03, 'po1')): self.make_bet(self.big_raise("R3")) elif to_call < self.data.big_blind and \ (equity > 55 or self.r_test(0.03, 'po2')): # small preflop raise from SB, get more money into the pot self.make_bet(self.minimum_bet("R4")) elif return_ratio > 1.25: self.bot.log(" return ratio > 1.25, calling {}".format(to_call)) self.bot.call(to_call) elif return_ratio > 1 \ and MathUtils.percentage(to_call, self.our_stack()) < 10: self.bot.log(" return ratio > 1 and bet is small, calling {}" .format(to_call)) self.bot.call(to_call) else: self.bot.fold() def make_bet(self, amount): """Make a bet, also update fear assumming the opponent will call.""" self.update_fear(amount) self.bot.bet(amount) def r_test(self, fraction, block=None): """Given a number [0,1], randomly return true / false s.t. r_test(0.5) is true ~50% of the time""" passed = random.uniform(0, 1) < fraction if passed: self.bot.log(" r_test({f}%) passed from {b}" .format(f=100*fraction, b=block)) return passed