class Player: def __init__(self,card1,card2): self.hand = Hand() self.hand.deal(card1,card2) self.blackjack = False if self.hand.getValue() == 21: self.blackjack = True def getHand(self): return self.hand def hit(self, card): self.hand.draw(card) def hasBlackjack(self): return self.blackjack def printHand(self): for card in self.hand: print(card) print("Value = %d\n" % self.hand.getValue())
def game(): """ ゲームをコントロールする関数 戻り値 True: 勝ち False: ドローまたは負け """ playerHand = Hand() dealerHand = Hand() # 山札の準備 stock = CardStock() stock.cut() # 最初の2枚とその表示 playerHand.draw(stock).draw(stock).myprint("Player's hand: ") dealerHand.draw(stock).draw(stock).myprint("Dealer's hand: ") # PlayerのHit/Stand while True: if input('もう1枚カードを引く?[y/n]: ') == "y": playerHand.draw(stock).myprint("Player's hand: ") print("合計: ", playerHand.sum()) if playerHand.isBurst() == True: print("Burst! Game over") return False else: break # DealerのHit/Stand while dealerHand.sum() < MAX_DRAW_NUMBER: dealerHand.draw(stock).myprint("Dealer's hand: ") # 勝敗の決定 if dealerHand.isBurst() == True or dealerHand.sum() < playerHand.sum(): print("あなたの勝ちです") return True elif dealerHand.sum() == playerHand.sum(): print("引き分けです") return False else: print("あなたの負けです") return False
class BlackJack(GameGUI): """Implements a simple version of the BlackJack card game and displays the game to the player.""" def __init__(self, window): super().__init__(window) self.player_wins = 0 self.dealer_wins = 0 self.game_status = 'In Progress...' self.in_progress = True self.status_color = 'green' self.text_font = tk.font.Font(family='Helvetica', size=15, weight='bold') Card.load_images() self.deck = Deck() self.player_hand = Hand() self.dealer_hand = Hand() def refresh_canvas(self): """Method which refreshed the canvas (text and player/dealer cards) based on the updated BlackJack attributes. No inputs or outputs.""" self._canvas.delete(tk.ALL) self._canvas.create_text(10, 10, anchor=tk.NW, fill='black', font=self.text_font, text=f'Player Hand Total:' f' {self.player_hand.total}') self._canvas.create_text(10, 150, anchor=tk.NW, font=self.text_font, fill='black', text=f'Dealer Hand Total:' f' {self.dealer_hand.total}') self._canvas.create_text(100, 300, anchor=tk.NW, fill=self.status_color, font=self.text_font, text=f'Game Status: {self.game_status}') self._canvas.create_text(10, 330, anchor=tk.NW, fill='black', font=self.text_font, text=f'Dealer Wins: {self.dealer_wins}') self._canvas.create_text(10, 355, anchor=tk.NW, fill='black', font=self.text_font, text=f'Player Wins: {self.player_wins}') self.player_hand.draw(self._canvas, 10, 35) self.dealer_hand.draw(self._canvas, 10, 175) def reset(self): """Restarts the game (resets player/dealer hands, deals two cards for the player and dealer, and checks for the edge case of two Aces). No inputs or outputs.""" self.player_hand.reset() self.dealer_hand.reset() self.player_hand.add(self.deck.deal()) self.player_hand.add(self.deck.deal()) self.dealer_hand.add(self.deck.deal()) self.dealer_hand.add(self.deck.deal()) # Checking for edge cases where player/dealer (or both) have two aces if self.player_hand.total == 22 and self.dealer_hand.total == 22: self.status_color = 'red' self.game_status = "TIE Game... Press 'r' to start game" self.in_progress = False elif self.player_hand.total == 22: self.status_color = 'red' self.game_status = "Dealer WINS... Press 'r' to start game" self.dealer_wins += 1 self.in_progress = False elif self.dealer_hand.total == 22: self.status_color = 'red' self.game_status = "Player WINS... Press 'r' to start game" self.player_wins += 1 self.in_progress = False else: self.game_status = 'In Progress...' self.status_color = 'green' self.in_progress = True self.refresh_canvas() def player_hit(self): """Functionality for when a player 'hits'. If the player's total score is over 21, the player loses. No inputs or outputs.""" if self.in_progress: self.player_hand.add(self.deck.deal()) if self.player_hand.total > 21: self.status_color = 'red' self.game_status = "Dealer WINS... Press 'r' to start game" self.dealer_wins += 1 self.in_progress = False self.refresh_canvas() def player_stand(self): """Functionality for when a player 'stands'. The dealer automatically draws cards until their total score is 17 or greater. Based on the dealer's score, determines who wins. No inputs or outputs.""" if self.in_progress: while self.dealer_hand.total < 17: self.dealer_hand.add(self.deck.deal()) if self.dealer_hand.total > 21 or self.dealer_hand.total < \ self.player_hand.total: self.status_color = 'red' self.game_status = "Player WINS... Press 'r' to start game" self.player_wins += 1 elif self.player_hand.total == self.dealer_hand.total: self.status_color = 'red' self.game_status = "TIE Game... Press 'r' to start game" else: self.status_color = 'red' self.game_status = "Dealer WINS... Press 'r' to start game" self.dealer_wins += 1 self.in_progress = False self.refresh_canvas()
class War(): """ Class handling the game itself """ def __init__(self): self.player_1 = Hand("Player 1") self.player_2 = Hand("Player 2") self.deck = Deck() self.pile = [] self.menu = """Menu: ======================================= exit, quit: Quit the program menu, help: Show this menu start: Start the game auto: Run game automatically =======================================""" print(self.menu) def run_game(self, auto=False): """ Run the game """ self.start_game() print("Enter for next hand") print('{0:20} {1}'.format("Player one", "Player two")) while len(self.player_1.hand) > 0 and len(self.player_2.hand) > 0: self.next_round(auto) print("============================================================") l_h1 = len(self.player_1.hand) l_h2 = len(self.player_2.hand) if l_h2 < l_h1: print("{0:21}Player one wins!".format(" ")) else: print("{0:21}Player two wins!".format(" ")) print("{0:21}Player one: {1} cards".format(" ", l_h1)) print("{0:21}Player two: {1} cards".format(" ", l_h2)) print("{0:21}In pile: {1}".format(" ", len(self.pile))) def next_round(self, auto): """ Next round """ p1_card = self.player_1.show_card() p2_card = self.player_2.show_card() self.pile.append(p1_card) self.pile.append(p2_card) res = "it's a draw" # large = "" if p1_card.suit == p2_card.suit: if p1_card.value > p2_card.value: res = "player 1 wins" self.player_1.hand += self.pile # large = len(self.player_1.hand) else: res = "player 2 wins" self.player_2.hand += self.pile # large = len(self.player_2.hand) self.pile = [] if auto: (print('{0:20} {1:20} {2}'.format(str(p1_card), str(p2_card), res))) else: (input('{0:20} {1:20} {2}'.format(str(p1_card), str(p2_card), res))) def show_menu(self): """ Print the menu """ # print(chr(27) + "[2J" + chr(27) + "[;H") print(self.menu) def choice(self, inp): """ User request """ inp.lower() if inp in ("menu", "help"): print("Menu requested") self.show_menu() elif inp == "start": print("Start requested") self.run_game() elif inp == "auto": print("Game will run automatically") self.run_game(True) elif inp in ("exit", "quit"): print("Exit program") self.end_game() else: self.show_menu() def start_game(self): """ Set game up """ self.deck.shuffle() # print("Deck shuffled") while len(self.deck.cards) > 0: self.player_1.draw(self.deck) self.player_2.draw(self.deck) # print("Deck has been shuffled and split") @classmethod def end_game(cls): """ End game in graceful manner """ print("Done!") sys.exit()
class Video(AlgoClass): """ Reads frames from a video source and broadcast them to motion and skin Instance Variables: web_cam: bool - True when web camera is the source and is still on False when video file is the source capture: VideoCapture object - use to read frames has_frame: bool - a frame exists (necessary?) current_frame: image - current video frame count_frame: int - total number of frames read from video source """ def __init__(self, source): """ Create a video instance from the given source :param source: either Device ID or video file name """ AlgoClass.__init__(self) self.web_cam, self.capture = self.set_capture(source) self.TOTAL_FRAMES, self.NUM_FRAMES_SKIPPED = self.set_read() # all should be called img self.before_process = None # updated by read(), make sure a frame exists self.has_frame, self.current_frame = False, None self.read() # use to skip frame self.count_frame = 1 self.motion, self.motion_region = self.set_motion_tracker(), None self.skin, self.skin_regions = Skin(), None self.masked_frame = None self.hand_img = None self.hand = None def update(self): """ Video control center. If there is a new non-skipped frame with sufficient changes based on main areas of concern - on motion (including background sub) and - skin color the existing hand is process for gesture recognition :return: bool """ # TODO: rank among multiple hands if self.has_more_frames() and self.is_retrieved( ) and self.motion.detected(): print "frame", self.count_frame self.masked_frame = self.create_masked_frame() hand_silhouette = self.find_hand_silhouette() if hand_silhouette is not None: self.process_hand(hand_silhouette) return True return False def create_masked_frame(self): """ Create and return a masked version of the current frame The mask rejects non-skin colors and static parts by filtering for skin and motion regions :return: image """ self.motion_region = self.motion.get_motion_region() self.skin_regions = self.skin.get_active_regions(self.current_frame) # main area of concern return cv2.bitwise_and(self.skin_regions, self.skin_regions, mask=self.motion_region) def find_hand_silhouette(self, frame=None): """ Return Silhouette of the hand by processing the geometries of all the contours :param frame: image :return: Silhouette """ if frame is None: frame = self.masked_frame contours = Silhouette.get_contours(frame, constants.CONTOURS_MIN_AREA) # onion geometries for all large contours (likely face and hand) silhouettes = Silhouette.create_geometries(frame, contours) if len(silhouettes) > 0: #for idx in range(len(sils)): #sils[idx].draw_all() return Silhouette.select_hand_like(silhouettes) return None def process_hand(self, hand_silhouette): """ Process the hand silhouette to identify the thumb and fingers :param hand_silhouette: Silhouette :return: """ hand_silhouette.log_all() self.hand = Hand(self.current_frame, hand_silhouette.onion_geometry, hand_silhouette.shape_like) # drawn after the Hand constructor call to track the refined poly_curve hand_silhouette.draw_all() self.hand.draw(self.current_frame) def read(self): """ Update current frame with next read and some initial image processing :return: None """ self.has_frame, self.current_frame = self.capture.read() self.before_process = self.current_frame.copy() self.current_frame = Tools.pre_process_image(self.current_frame) def is_running(self): """ Return True if video source has more frames and user has not issued a quit command :return: bool """ if self.has_more_frames() and not self.video_key_interrupt(): return True else: self.capture.release() cv2.destroyAllWindows() return False def is_retrieved(self): """ One frame out of NUM_FRAMES_SKIPPED is to be read For example out with FPS 30 and 3 FRAMES_USED_PER_SEC 1 is read, meaning grabbed and retrieved (latter is a slow op) 9 are skipped, VideoCapture.grab() applied to advance video :return: bool """ self.count_frame += 1 if (self.count_frame % self.NUM_FRAMES_SKIPPED) == 0: self.read() self.motion.update_frame(self.current_frame) return True else: self.has_frame = self.capture.grab() return False def has_more_frames(self): """ Return True if the video source has more frames :return: bool """ return self.web_cam or self.count_frame < self.TOTAL_FRAMES # # constructor helpers def set_capture(self, source): """ :param source: int/str ( live camera index/video file name) :return: VideoCapture """ web_cam = False if source == constants.DEFAULT_DEVICE: self.log_text("Webcam " + source + " in use") web_cam = True capture = cv2.VideoCapture(source) if not capture.isOpened(): self.log_text("Failed to open video source. Exiting...") exit() self.log_text(source) return web_cam, capture def set_read(self): """ Set video statistics Return total number of frames in video source and frames to skip in between two reads :return: int, int """ total_frames = self.capture.get(cv2.CAP_PROP_FRAME_COUNT) num_frames_skipped = int( self.capture.get(cv2.CAP_PROP_FPS) / constants.FRAMES_USED_PER_SEC) self.log_text("total frames %d" % total_frames) self.log_text("used frames %d" % constants.FRAMES_USED_PER_SEC) self.log_text("skip %d" % num_frames_skipped) return total_frames, num_frames_skipped def set_motion_tracker(self): """ :return: Motion object """ width, height = self.get_frame_size() return Motion(height, width, self.current_frame) def get_frame_size(self): """ :return: int, int """ return self.capture.get(cv2.CAP_PROP_FRAME_WIDTH), \ self.capture.get(cv2.CAP_PROP_FRAME_HEIGHT) @staticmethod def video_key_interrupt(): """ Delay for keyboard interrupt callbacks. Return True if the predefined quit key was pressed :return: bool """ """ Note: & 0xff needed for 64-bit machine: see following link http://docs.opencv.org/3.0-beta/doc/py_tutorials/py_gui/py_image_display/ ...py_image_display.html """ k = cv2.waitKey(constants.VIDEO_KEY_EVENT_DELAY) & 0xff return k == ord(constants.PROGRAM_QUIT_KEY.lower())
class BlackJack(GameGUI): '''implements a simple version of the cardgame and displays the game state to the player''' # In pixels, specify the vertical separation between different elements in the canvas. SMALL_VERTICAL_OFFSET= 20 MEDIUM_VERTICAL_OFFSET= 30 # Specify where to put the game status axis GAME_STATUS_TEXT_X_AXIS= Card.IMAGE_WIDTH_IN_PIXELS*3 + 10 def __init__(self, window): ''' Attributes (not already defined in the superclass): numPlayerWins: an int, keep track of times the player has won numDealerWins: an int, keep track of times the dealer has won gameStatusText: a str, game status text indicating the current state of the game gameStatusColor: a str, the color of the game status text playerHand: a Hand object, representing the player's hand dealerHand: a Hand object, representing the dealer's hand deck: a Deck object, representing the current deck of cards ''' super().__init__(window) self.reset() def reset(self): '''Restarts the game. This method is automatically called whenever the user hits the “r” key.''' # Initialize game situation self.numPlayerWins= 0 self.numDealerWins= 0 self.gameStatusText= "In Progress..." self.gameStatusColor= "green" # Initialize (empty) player and dealer hands self.playerHand= Hand() self.dealerHand= Hand() # Initialize deck self.deck= Deck() # Load images Card.load_images() # Draw canvas self.draw_canvas() def player_hit(self): ''' The user is requesting to perform a hit on their hand. This means that the method must draw acard from the deck and add it to the player’s hand. ''' # Is this the first hit in a new game? If so, clear the player and dealer hands, and reset the game status self.new_game_check() # Deal a new card to the player self.playerHand.add(self.deck.deal()) self.reshuffle_check() # Did the player bust? if self.playerHand.total > 21: self.gameStatusColor= "red" self.gameStatusText= "Dealer WINS... Press 'r' to start a new game" self.numDealerWins+= 1 # Update GUI self.draw_canvas() def player_stand(self): ''' The user is requesting to perform a stand on their hand. This means that the method must continuously add cards to the dealer’s hand until their hand is greater than or equal to 17. ''' # Is this the first stand in a new game? If so, clear the player and dealer hands, and reset the game status self.new_game_check() # Add cards to the dealer's hand until the dealer's hand is greater than or equal to 17 while self.dealerHand.total < 17: self.dealerHand.add(self.deck.deal()) self.reshuffle_check() self.gameStatusColor= "red" # Did the dealer bust OR did the player's total exceed the dealer's score? if (self.dealerHand.total > 21) or (self.dealerHand.total < self.playerHand.total): self.gameStatusText= "Player WINS... Press 'r' to start a new game" self.numPlayerWins+= 1 # Was there a tie? elif (self.dealerHand.total == self.playerHand.total): self.gameStatusText= "TIE Game...Press 'r' to start a new game" # Did the dealer win? elif (self.dealerHand.total > self.playerHand.total): self.gameStatusText= "Dealer WINS... Press 'r' to start a new game" self.numDealerWins+= 1 # Update GUI self.draw_canvas() def reshuffle_check(self): '''Check if the deck has 13 cards remaining. If so, reschuffle the deck.''' if self.deck.size <= 13: self.deck.shuffle() def new_game_check(self): ''' If this is a new game, clear the player and dealer hands, and reset the game status ''' if self.gameStatusText != "In Progress...": self.gameStatusText= "In Progress..." self.gameStatusColor= "green" self.playerHand.reset() self.dealerHand.reset() def draw_canvas(self): ''' Update the GUI and redraw everything ''' # Initial coordinates current_x= 10 current_y= 10 # Define the font for everything REGULAR_FONT= font.Font(family='Helvetica', size=10, weight='bold') # Time to update the GUI self._canvas.delete(tk.ALL) # Text with the current player hand total self._canvas.create_text(current_x, current_y, anchor=tk.NW, font=REGULAR_FONT, text=f'Player Hand Total: {self.playerHand.total}') # The images of the player's current hand current_y+= BlackJack.SMALL_VERTICAL_OFFSET self.playerHand.draw(self._canvas, current_x, current_y, None, None) # The text of the dealer's current hand total current_y+= (BlackJack.MEDIUM_VERTICAL_OFFSET + Card.IMAGE_HEIGHT_IN_PIXELS) self._canvas.create_text(current_x, current_y, anchor=tk.NW, font=REGULAR_FONT, text=f'Dealer Hand Total: {self.dealerHand.total}') # The images of the dealer's current hand total current_y+= BlackJack.SMALL_VERTICAL_OFFSET self.dealerHand.draw(self._canvas, current_x, current_y, None, None) # The game status current_y+= (BlackJack.MEDIUM_VERTICAL_OFFSET + Card.IMAGE_HEIGHT_IN_PIXELS) self._canvas.create_text(BlackJack.GAME_STATUS_TEXT_X_AXIS, current_y, anchor=tk.NW, font=REGULAR_FONT, fill= self.gameStatusColor, text=f'Game Status: {self.gameStatusText}') # The text with the dealer wins and the player wins current_y+= BlackJack.SMALL_VERTICAL_OFFSET self._canvas.create_text(current_x, current_y, anchor=tk.NW, font=REGULAR_FONT, text=f'Dealer Wins: {self.numDealerWins}') current_y+= BlackJack.SMALL_VERTICAL_OFFSET self._canvas.create_text(current_x, current_y, anchor=tk.NW, font=REGULAR_FONT, text=f'Player Wins: {self.numPlayerWins}')