2015-10-27 34 views
1

我是OOP的新手,正在練習使用各種類和實現像繼承原則的一些更復雜的程序。我創建了一個包含Player類的乒乓模擬,其中包含玩家贏得發球的概率。然後我有一個PingPong類,它是超類RacquetSports的子類。每個實例都是一個單一的遊戲,具有更改服務器的能力,記錄誰贏了,以及是否是關閉。最後,我有一個SimStats類,其目的是在「n」個遊戲中記錄統計數據。乒乓球模擬不正確觸發功能

我的問題是,它似乎像我的play_game函數不正確觸發,當我把打印語句放在那裏它從來沒有觸發。我運行整個程序的當前結果是Player1有10次沒有關閉,而且Player2的兩次都沒有。

最後,任何關於更好的面向對象實踐的建議也將不勝感激。這裏是我的播放器類:

from random import random 


class Player(object): 

    def __init__(self, prob_win): 
     self.prob = prob_win 
     self.points = 0 

    def wins_serve(self): 
     return self.prob >= random() 

    def add_point(self): 
     self.points += 1 

    def get_score(self): 
     return self.points 

我RacquetSports類:

from abc import ABCMeta, abstractmethod 
from player import Player 


class RacquetSport(object): 

    __metaclass__ = ABCMeta 

    def __init__(self, prob1, prob2): 
     self.player1 = Player(prob1) 
     self.player2 = Player(prob2) 
     self.server = self.player1 

    def play_game(self): 
     while not self.game_over(): 
      self.sim_point() 

    @abstractmethod 
    def type(self): 
     pass 

    def chg_server(self): 
     if self.server == self.player1: 
      self.server = self.player2 
     else: 
      self.server = self.player1 

    def sim_point(self): 
     if self.server.wins_serve(): 
      self.server.add_point() 
     else: 
      self.chg_server() 

    @abstractmethod 
    def game_over(self): 
     pass 

    def get_scores(self): 
     return self.player1.get_score(), \ 
       self.player2.get_score() 

    def return_stats(self): 
     p1_score, p2_score = self.get_scores() 
     print(p1_score, p2_score) 
     won = 'p1' 
     if p2_score > p1_score: 
      won = 'p2' 
     return won, self.__shutout(p1_score, p2_score) 

    @staticmethod 
    @abstractmethod 
    def __shutout(score1, score2): 
     pass 

我的乒乓和SimStats類,以及我的調用代碼:

from racquet import RacquetSport 


class PingPong(RacquetSport): 

    def type(self): 
     return 'Ping Pong' 

    def game_over(self): 
     return self.player1.get_score == 11 or \ 
       self.player2.get_score == 11 

    @staticmethod 
    def __shutout(score1, score2): 
     return abs(score1 - score2) == 11 


class SimStats(object): 

    def __init__(self): 
     # First field is games won, second is shutouts. 
     self.gms_won_p1 = [0] * 2 
     self.gms_won_p2 = [0] * 2 

    def update(self, game): 
     won, shutout = game.return_stats() 
     if won == 'p1': 
      self.gms_won_p1[0] += 1 
      if shutout: 
       self.gms_won_p1[1] += 1 
     else: 
      self.gms_won_p2[0] += 1 
      if shutout: 
       self.gms_won_p2[1] += 1 

    def print_results(self): 
     tot_games = self.gms_won_p1 + self.gms_won_p2 
     print('Wins for Player 1 = {} Shutouts = {}\n' 
       'Wins for Player 2 = {} Shutouts = {}'.format(*tot_games)) 


if __name__ == '__main__': 
    stats = SimStats() 
    for x in range(1, 11): 
     game = PingPong(.5, .5) 
     stats.update(game) 
    stats.print_results() 
+1

記:你的問題是'標記的python-3.x'但你使用metaclasses'python-2.x'-style。 new是:'class RacquetSport(object,metaclass = ABCMeta):'(你可以省略'object' ...)。 –

+0

謝謝!我會做出改變。 – flybonzai

+3

你寫道:「我的問題是,它似乎像我的play_game函數不正確觸發」,但你的代碼中沒有任何地方叫'play_game'。你爲什麼認爲它被稱爲? –

回答

1

你的第一個問題是你永遠不要致電play_game。我的猜測是,你打算這樣工作:

if __name__ == '__main__': 
    stats = SimStats() 
    for x in range(1, 11): 
     game = PingPong(.5, .5) 
     game.play_game() 
     stats.update(game) 
    stats.print_results() 

接下來,你有一個錯誤,將導致整個遊戲永遠持續下去。看看這些行:

def game_over(self): 
    return self.player1.get_score == 11 or \ 
      self.player2.get_score == 11 

get_score是一個函數,所以你需要呼叫它:

def game_over(self): 
    return self.player1.get_score() == 11 or \ 
      self.player2.get_score() == 11 
+0

修復了這個問題,謝謝! – flybonzai