In [48]:
from random import random, choice
In [49]:
def get_inputs():
    name_a, name_b = input("Enter the two player names (player_a, player_b): ")
    a, b, n = eval(input("Enter prob for player A, B and total games (a, b, n): "))
    return name_a, name_b, a, b, n
In [50]:
def print_intro():
    print("Plays games of racqueteball")
In [61]:
class Player:
    def __init__(self, name, prob):
        self.name = name
        self.prob = prob
        self.score = 0
        
    def get_score(self):
        return self.score
    
    def inc_score(self):
        self.score += 1
        
    def wins_serve(self):
        return random() <= self.prob
    
    def reset_score(self):
        self.score = 0
    
    def get_name(self):
        return self.name
    
    def __repr__(self):
        return "Player({0}, {1})".format(self.name, self.prob)
    
    def __str__(self):
        return self.name
In [62]:
class RBallGame:
    """Represents a single game of racquetball"""
    def __init__(self, player_a, player_b):
        self.player_a = player_a
        self.player_b = player_b
        self.server = choice((self.player_a, self.player_b))
        
        self.player_a.reset_score()
        self.player_b.reset_score()
        #print("The initial server is: {0}".format(self.server))
        
    def play(self):
        while not self.__is_game_over():
            if self.server.wins_serve():
                self.server.inc_score()
            else:
                self.__change_server()
                
    def __is_game_over(self):
        #score = self.server.get_score()
        
        return (self.player_a.get_score() == 15 or 
                self.player_b.get_score() == 15 or 
                (self.player_a.get_score() == 7 and self.player_b.get_score() == 0) or
                (self.player_b.get_score() == 7 and self.player_a.get_score() == 0))
    
    def __change_server(self):
        if self.server is self.player_a:
            self.server = self.player_b
        else:
            self.server = self.player_a
                
    def get_scores(self):
        return self.player_a.get_score(), self.player_b.get_score()
In [63]:
class SimStats:
    """Tracks, and calculates statistics of the games played"""
    def __init__(self, player_a, player_b):
        self.name_a = player_a.get_name()
        self.name_b = player_b.get_name()
        self.wins_a = 0
        self.wins_b = 0
        self.shuts_a = 0
        self.shuts_b = 0
        
    def update(self, a_game):
        if not isinstance(a_game, RBallGame):
            raise TypeError("Object not an RBallGame instance!")

        score_a, score_b = a_game.get_scores()
        
        if score_a > score_b:
            self.wins_a += 1
            if score_b == 0:
                self.shuts_a += 1   
        else:
            self.wins_b += 1
            if score_a == 0:
                self.shuts_b += 1     
    
    def print_summary(self):
        n = self.wins_a + self.wins_b
        print("Summary of", n, "games:\n")
        print("         wins (% total)   shutouts (%wins) ")
        print("-------------------------------------------")
        self.__print_line(self.name_a, self.wins_a, self.shuts_a, n)
        self.__print_line(self.name_b, self.wins_b, self.shuts_b, n)
        
    def __print_line(self, label, wins, shuts, n):
        template = "Player {0}:{1:5}   ({2:5.1%})   {3:11}   ({4})"
        
        if wins == 0:
            shut_str = "-----"
        else:
            shut_str = "{0:4.1%}".format(shuts/wins)
        
        print(template.format(label, wins, wins/n, shuts, shut_str))
In [64]:
def main():
    print_intro()
    #name_a, name_b, prob_a, prob_b, n = get_inputs()
    name_a, name_b, prob_a, prob_b, n = "Denny", "Susan", 0.6, 0.65, 1000
    
    # Create a score tracking instance
    player_a = Player(name_a, prob_a)
    player_b = Player(name_b, prob_b)
    stats = SimStats(player_a, player_b)

    for i in range(n):
        the_game = RBallGame(player_a, player_b)
        the_game.play()
        stats.update(the_game)
    
    stats.print_summary()
In [65]:
main()
Plays games of racqueteball
Summary of 1000 games:

         wins (% total)   shutouts (%wins) 
-------------------------------------------
Player Denny:  363   (36.3%)            54   (14.9%)
Player Susan:  637   (63.7%)            96   (15.1%)