Edit: Just realize this is an old thread.
Maybe this will give you some idea. Haven't done score card yet.
Maybe this will give you some idea. Haven't done score card yet.
import pygame import random from itertools import count from pygame.sprite import Group, Sprite # Interface class State: def __init__(self, engine): self.engine = engine def on_draw(self, surface): pass def on_event(self, event): pass def on_update(self, delta, ticks): pass # Engine class DisplayEngine: def __init__(self, caption, width, height, flags=0): # Basic Pygame Setup pygame.display.set_caption(caption) self.surface = pygame.display.set_mode((width, height), flags) self.rect = self.surface.get_rect() self.clock = pygame.time.Clock() self.running = True self.delta = 0 self.fps = 60 # Handle what state is active. self._state = State(self) self.next_state = None # Main Loop def run(self, state=None): if state: self._state = state while self.running: # State Changer if self.next_state: self._state = self.next_state self.next_state = None # Event Loop for event in pygame.event.get(): # Just send the events to state to handle self._state.on_event(event) ticks = pygame.time.get_ticks() self._state.on_draw(self.surface) self._state.on_update(self.delta, ticks) pygame.display.flip() self.delta = self.clock.tick(self.fps) def quit(self): self.running = False class SimpleSprite(Sprite): def __init__(self, image): super().__init__() self.image = image self.rect = image.get_rect() class Callback: def __init__(self, callback, user_data=None): self.parent = None self.callback = callback self.user_data = user_data def link(self, parent): self.parent = parent return self def call(self): self.callback(self) class Pen: def __init__(self, font, color): self.font = font self.color = color def render(self, text): return self.font.render(text, 1, self.color) def write(self, text): return SimpleSprite(self.render(text)) class ButtonImages: def __init__(self, normal, hover, pushed): self.normal = normal self.hover = hover self.pushed = pushed class ButtonGroup: def __init__(self): self.buttons = Group() self.text = Group() def add(self, button): self.buttons.add(button) self.text.add(button.tsprite) def draw(self, surface): self.buttons.draw(surface) self.text.draw(surface) class Button(Sprite): def __init__(self, images, pen, text, position, callback): super().__init__() self.pen = pen self.images = images self.image = images.normal self.rect = self.images.normal.get_rect(topleft=position) self.is_mouse_over = False self.is_pushed = False self.callback = callback.link(self) self.update_text(text) def mouse_over(self, event): self.is_mouse_over = self.rect.collidepoint(event.pos) self.update_image() def click(self, event): self.mouse_over(event) if self.is_mouse_over: #self.is_pushed = False self.callback.call() def update_image(self): if self.is_pushed: self.image = self.images.pushed elif self.is_mouse_over: self.image = self.images.hover else: self.image = self.images.normal def update_text(self, text): self.tsprite = self.pen.write(text) self.tsprite.rect.center = self.rect.center # Store images. Because you want to create/load, convert, and/or size once. class Images: def __init__(self): self.dice = self.create_dice(40, 'snow', 'black', 3) self.hdice = self.create_dice(40, 'skyblue', 'black', 3) self.sdice = self.create_dice(40, 'lightgreen', 'black', 3) self.button_images = self.create_button((100, 30), 'blue', 'dodgerblue', 'navy') def create_dice(self, size, color, dot_color, dot_size): surface = pygame.Surface((size, size)) surface.fill(color) rect = surface.get_rect() inner = rect.inflate(-rect.centerx, -rect.centery) images = [] for i in range(1, 7): s = surface.copy() if i in [1, 3, 5]: pygame.draw.circle(s, dot_color, rect.center, dot_size) if i != 1: # 2-6 pygame.draw.circle(s, dot_color, inner.topleft, dot_size) pygame.draw.circle(s, dot_color, inner.bottomright, dot_size) if i > 3: pygame.draw.circle(s, dot_color, inner.topright, dot_size) pygame.draw.circle(s, dot_color, inner.bottomleft, dot_size) if i == 6: pygame.draw.circle(s, dot_color, inner.midleft, dot_size) pygame.draw.circle(s, dot_color, inner.midright, dot_size) images.append(s) return images def create_button(self, size, color, hcolor, pcolor): surface = pygame.Surface(size) surface.fill(color) hsurface = surface.copy() hsurface.fill(hcolor) psurface = surface.copy() psurface.fill(pcolor) return ButtonImages(surface, hsurface, psurface) class Die(Sprite): def __init__(self, images, position): super().__init__() # These are just reference self.images = images self.rect = images[0][0].get_rect(topleft=position) self.is_mouse_over = False self.is_selected = False self.roll() def roll(self): self.value = random.randint(1, 6) self.is_selected = False self.update_image() def mouse_over(self, mpos): self.is_mouse_over = self.rect.collidepoint(mpos) self.update_image() def selected(self): if self.is_mouse_over: self.is_selected = not self.is_selected self.update_image() def update_image(self): if self.is_selected: self.image = self.images[2][self.value - 1] elif self.is_mouse_over: self.image = self.images[1][self.value - 1] else: self.image = self.images[0][self.value - 1] class DisplayLines: def __init__(self, pen, position): self.position = position self.lines = [] self.pen = pen def add(self, text): self.lines.append(self.pen.render(text)) def clear(self): self.lines = [] def draw(self, surface): y = count(self.position[1], self.pen.font.get_linesize() + 2) for line in self.lines: surface.blit(line, (self.position[0], next(y))) class GameState(State): def __init__(self, engine): super().__init__(engine) self.dice_space = 50 self.dice_fromedgex = 30 self.dice_fromedgey = 30 self.images = Images() self.roll_button = self.create_roll_button() self.bgroup = ButtonGroup() self.dice = Group() self.set_up() def create_roll_button(self): pen = Pen(pygame.font.Font(None, 28), 'snow') pos = self.dice_space * 5 - 100 + self.dice_fromedgex, 80 callback = Callback(self.push_rolled) return Button(self.images.button_images, pen, "Roll", pos, callback) def set_up(self): images = self.images.dice, self.images.hdice, self.images.sdice for i in range(5): pos = self.dice_space * i + self.dice_fromedgex, self.dice_fromedgey self.dice.add(Die(images, pos)) self.bgroup.add(self.roll_button) pos = self.engine.rect.centerx, 10 pen = Pen(pygame.font.Font(None, 22), 'lawngreen') self.lines = DisplayLines(pen, pos) self.get_data() def push_rolled(self, callback): for d in self.dice: if d.is_selected: d.roll() self.get_data() def get_data(self): self.lines.clear() values = [d.value for d in self.dice] set_v = set(values) if len(set_v) == 1: self.lines.add("Yahtzee") if len(set_v) == 2: for v in set_v: if values.count(v) == 4: self.lines.add("4 of a kind") elif values.count(v) == 3: self.lines.add("Fullhouse") if len(set_v) == 3: data = [values.count(i) for i in set_v] if 3 in data: self.lines.add("3 of a kind") else: self.lines.add("two pair") if len(set_v) == 4: data = list(set_v) data.sort() if [1, 2, 3, 4] == data or [2, 3, 4, 5] == data or [3, 4, 5, 6] == data: self.lines.add("small straight") if len(set_v) == 5: data = list(set_v) data.sort() if [1, 2, 3, 4, 5] == data or [2, 3, 4, 5, 6] == data: self.lines.add("large straight") if ([1, 2, 3, 4] == data[:-1] or [2, 3, 4, 5] == data[:-1] or [2, 3, 4, 5] == data[1:] or [3, 4, 5, 6] == data[1:]): self.lines.add("small straight") # Override. From state interface def on_draw(self, surface): surface.fill('gray10') self.dice.draw(surface) self.bgroup.draw(surface) self.lines.draw(surface) # Override. From state interface def on_event(self, event): if event.type == pygame.QUIT: self.engine.quit() elif event.type == pygame.MOUSEMOTION: for d in self.dice: d.mouse_over(event.pos) for b in self.bgroup.buttons: b.mouse_over(event) elif event.type == pygame.MOUSEBUTTONDOWN: if event.button == 1: self.roll_button.click(event) for d in self.dice: d.selected() if __name__ == '__main__': pygame.init() engine = DisplayEngine("Dice", 800, 600) game = GameState(engine) engine.run(game) pygame.quit()
99 percent of computer problems exists between chair and keyboard.