Пример #1
0
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!')
Пример #2
0
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)