class TextYahtzee(object): def __init__(self): self._yahtzee = Yahtzee() self._running = False self._pristine = True ## properies @property def dice_str(self): s = '' for d in self._yahtzee.dice: s += ('{%s}' if d.held else '[%s]') % d.value return s ## private def _main_game_loop(self): print() rolls = self._yahtzee.cur_rolls if rolls > 0: print(self.dice_str) if self._yahtzee.is_game_over(): print('GAME OVER!') else: print('%s rolls remain.' % (3 - rolls)) print('Score: %s' % self._yahtzee.score) actions = self._yahtzee.available_actions print('What would you like to do?') for i, a in enumerate(actions): print(' %s: %s' % (i + 1, title_caps(a))) print(' ---') print(' 9: Show Scorecard') print(' 0: Quit') print() user_in = input() int_in = None # validate input is int try: int_in = int(user_in) except Exception: print('"%s" is not a valid option.' % user_in) return if int_in == 0: self.quit() elif int_in == 9: self._print_score() elif (int_in - 1) in range(len(actions)): self._do_action(actions[int_in - 1]) else: print('"%s" is not one of the options.' % int_in) def _do_action(self, action): if action is GA.ROLL: self._roll() elif action is GA.HOLD: self._hold() elif action is GA.SCORE: self._score() elif action is GA.RESTART: self._restart() else: raise ('Error: no such action') def _roll(self): self._pristine = False self._yahtzee.roll() def _hold(self): didxs = input('Which dice should hold? (ex. 145): ') dice = [] for c in didxs.strip(): if c in '12345' and c not in dice: dice += [int(c)] self._yahtzee.toggle_hold(*[i - 1 for i in dice]) def _score(self): sc = self._yahtzee.scorecard open_cats = sc.get_open_categories() dice = self._yahtzee.dice idx = 0 cats = [] print('- Top Categories') for cat in SC.top_categories(): if cat in open_cats: potential = sc.get_potential_score_for(dice, cat) print(' %s: %s (%s)' % (idx + 1, title_caps(cat), potential)) cats += [cat] idx += 1 print('- Bottom Categories') for cat in SC.bottom_categories(): if cat in open_cats: potential = sc.get_potential_score_for(dice, cat) print(' %s: %s (%s)' % (idx + 1, title_caps(cat), potential)) cats += [cat] idx += 1 print('\n 0: Cancel') while True: i = input('\nScore your dice in which category?: ') try: cidx = int(i) if cidx == 0: # cancel break elif (cidx - 1) in range(len(cats)): c = cats[cidx - 1] p = self._yahtzee.score_dice_as(c) print('Scored %s points as %s!' % (p, title_caps(c))) break else: raise Exception() except Exception: print('"%s" is not one of the options' % i) def _restart(self): if self._yahtzee.is_game_over() or self._pristine: self._yahtzee.restart() else: yn = input( 'Are you sure you want to restart? Your score will not be saved. (y/N): ' ) if yn.lower() == 'y': print('Restarted!') self._yahtzee.restart() def _print_score(self): sc = self._yahtzee.scorecard print('=== Yahtzee Scorecard ===') print(' -- Top Categories --') for cat in SC.top_categories(): s = sc.get_score_for(cat) print(' %s: %s' % (title_caps(cat), self._get_score_string(s))) print(' Top Bonus: %s' % sc.top_bonus) print(' - Top Total: %s' % sc.top_score) print(' -- Bottom Categories --') for cat in SC.bottom_categories(): s = sc.get_score_for(cat) print(' %s: %s' % (title_caps(cat), self._get_score_string(s))) print(' - Bottom Total: %s' % sc.bottom_score) print('== Total: %s' % sc.score) def _get_score_string(self, score): return '-' if score is None else str(score) ## public def start(self): console.clear() self._running = True print('Welcome to Yahtzee!') while (self._running): self._main_game_loop() def quit(self): q = False if self._pristine: q = True else: ans = input('Are you sure you want to quit? (y/N): ') if ans.lower() == 'y': q = True if q: self._running = False print('Seeya!')
class YahtzeeView (ui.View): def __init__(self): self._yahtzee = Yahtzee() def did_load(self): self.right_button_items = [ui.ButtonItem(image=ui.Image('iob:ios7_reload_32'), action=lambda s: self.restart(prompt=True))] self._highscore = highscore.get() self._update_title() self._dice_view = self['dice'] self._dice_view.onrollfinished = self._handle_roll_finished self._dice_view.onholdchange = self._handle_hold_changed self._rolling = False self._roll_btn = self['roll_btn'] self._roll_btn.action = lambda s: self._roll() self._score_lbl = self['score'] self._sv = self['categories'] self._top_bonus_lbl = self._sv['top_bonus_slbl'] self._top_total_lbl = self._sv['top_total_slbl'] self._bonus_yahtzee_lbl = self._sv['bonus_yahtzee_slbl'] self._bonus_yahtzee_ticks = self._sv['bonus_yahtzee_ticks'] self._bot_total_lbl = self._sv['bot_total_slbl'] self._category_buttons = {} self._init_score_buttons() self._update_views() def layout(self): x,y,w,h = self.frame dx,dy,dw,dh = self._dice_view.frame bx,by,bw,bh = self._roll_btn.frame sx,sy,sw,sh = self._sv.frame lx,ly,lw,lh = self._score_lbl.frame nby = dy + dh + 8 self._roll_btn.frame = (bx,nby,bw,bh) self._score_lbl.frame = (lx,nby,lw,lh) nsy = nby + bh + 8 nsh = h - 6 - dh - 8 - bh - 8 self._sv.frame = (sx,nsy,sw,nsh) def _update_title(self): hs = self._highscore msg = '' if hs['score']: if hs['name'] != '': msg = ' (High Score: %s - %s)' % (hs['name'][:4], hs['score']) else: msg = ' (High Score: %s)' % hs['score'] self.name = 'Yahtzee!%s' % msg def _make_category_dict(self, lst): d = {} for cat in lst: n,c = cat d[c] = self._make_category_btn(n, c) return d def _make_category_btn(self, name, category): btn = self._sv[name] btn.background_color = '#64c800' btn.tint_color = '#000' def press_action(sender): self._dice_view.release_all() score = self._yahtzee.score_dice_as(category) self._update_views() if self._yahtzee.is_game_over(): self._game_over() btn.action = press_action return btn def _init_score_buttons(self): self._category_buttons = self._make_category_dict([ ('ones_sbtn', SC.ONES), ('twos_sbtn', SC.TWOS), ('threes_sbtn', SC.THREES), ('fours_sbtn', SC.FOURS), ('fives_sbtn', SC.FIVES), ('sixes_sbtn', SC.SIXES), ('toak_sbtn', SC.THREE_OF_A_KIND), ('foak_sbtn', SC.FOUR_OF_A_KIND), ('full_house_sbtn', SC.FULL_HOUSE), ('smstr_sbtn', SC.SM_STRAIGHT), ('lgstr_sbtn', SC.LG_STRAIGHT), ('chance_sbtn', SC.CHANCE), ('yahtzee_sbtn', SC.YAHTZEE)]) def _update_views(self): actions = self._yahtzee.available_actions self._dice_view.enabled = GA.HOLD in actions self._roll_btn.enabled = not self._rolling and GA.ROLL in actions self._roll_btn.title = 'Roll (%s left)' % str(3 - self._yahtzee.cur_rolls) scorecard = self._yahtzee.scorecard self._score_lbl.text = 'Score\n%s' % scorecard.score self._top_bonus_lbl.text = str(scorecard.top_bonus) self._top_total_lbl.text = str(scorecard.top_score) self._bonus_yahtzee_ticks.text = '/'*scorecard.num_bonus_yahtzees self._bonus_yahtzee_lbl.text = str(scorecard.bonus_yahtzees) self._bot_total_lbl.text = str(scorecard.bottom_score) for cat in SC: btn = self._category_buttons[cat] score = self._yahtzee.scorecard.get_score_for(cat) btn.enabled = False if score is not None: btn.enabled = True btn.action = lambda s: None btn.title = str(score) btn.background_color = '#fff' btn.tint_color = '#000' else: if GA.SCORE in actions and not self._rolling: btn.enabled = True btn.title = '(%s)' % self._yahtzee.get_potential_score_for(cat) else: btn.title = '' def _roll(self): self._rolling = True self._yahtzee.roll() self._dice_view.roll_to(self._yahtzee.dice) self._update_views() @ui.in_background def _game_over(self): score = self._yahtzee.score msg = 'Your score is: %s' % score if score > self._highscore['score']: name = console.input_alert('High Score! Enter your name:') highscore.set(name, score) self._highscore = highscore.get() msg += '\nNew High Score!' self._update_title() result = dialogs.alert('GAME OVER!', msg, 'Restart', 'Quit', hide_cancel_button=True) if result == 1: self.restart() @ui.in_background def restart(self, prompt=False): result = 1 if not self._yahtzee.is_game_over() and prompt: result = dialogs.alert('Start Over?', 'Progress will be lost.', 'Restart', 'Nevermind', hide_cancel_button=True) if result == 1: self._dice_view.reset() self._yahtzee.restart() self._init_score_buttons() self._update_views() def _handle_roll_finished(self): self._rolling = False self._update_views() def _handle_hold_changed(self, idx, val): if val: self._yahtzee.hold(idx) else: self._yahtzee.release(idx)