diff --git a/AllPlayAll.py b/AllPlayAll.py index 04a030e..ea13ceb 100644 --- a/AllPlayAll.py +++ b/AllPlayAll.py @@ -1,49 +1,31 @@ __author__ = "Paul Council & William Ezekiel" -__date__ = "November 19 2014" -__version__ = "1.0" +__date__ = "November 24 2014" +__version__ = "1.0.1" -from Game import * -from Registration import * -""" AllPlayAll Tournament Type, every player plays every other player in - 1 match""" -class AllPlayAll(Tournament): - def __init__(self,game,registration,rounds=1000): - """ Initialize AllPlayAll class. Requires Game, Registration - and Rounds. Rounds is optional and will be 1000 by default. - """ - if(rounds>0): - self.rounds = rounds - else: - self.rounds = 1000 - self.game = game - self.registration = registration - - - def set_players(self): - """ Place all active players into tournament bracket.""" - self.bracket = self.registration.get_players() +#imports +import Tournament - def create_next_match(self,i,j): - """Create a match consisting of two players. Players - are determined by positions i and j in bracket""" - #i == j will never happen - return [bracket[i],bracket[j]] - - def play_match(self,match): - """ play match: play a game a certain number of rounds""" - self.game.connect() - for i in range(0,rounds): - self.game.play(match[0],match[1]) - # assuming games updates scoreboard on winner. - - +""" AllPlayAll Tournament Type, every player is in a match with every other player """ +class AllPlayAll(Tournament.Tournament): - def run(self): - """ Run the All-Play-All Tournament. - Each player plays all other players in one match. + def __init__(self,rounds = 100): + """ Initialize AllPlayAll + :param rounds the number of rounds per match, 100 by default """ - for i in range(0,len(self.bracket)): - for j in range(i+1,len(self.bracket)): - match = create_next_match(i,j) - play_match(match) - + Tournament.Tournament.__init__(self) + # variables to help us pick players 1 and 2. + self.p = 0 # player 1 index + self.q = 1 # player 2 index + self.rounds = rounds + + def create_next_match(self): + """ Create the next match """ + self.playerList = self.get_players() + if self.q >= len(self.playerList): # Gone through all possible matchups. + return None + match = ((self.playerList[self.p],self.playerList[self.q]), self.rounds) + self.q = self.q+1 + if self.q >= len(self.playerList): # if index out of bounds + self.p = self.p+1 + self.q = self.p+1 + return match diff --git a/GSACPlayer.py b/GSACPlayer.py new file mode 100644 index 0000000..4b25ff6 --- /dev/null +++ b/GSACPlayer.py @@ -0,0 +1,104 @@ + # Greg Suner and Alex Ciarmella + # Concrete Player Class + +import Player +import Message + +class GSACPlayer(Player.Player): + + def __init__(self): + # Call super class constructor + Player.Player.__init__(self) + self.reset() + self.name = "Alex and Greg" + + def play(self): + return RpsPlayingStrategy.play(self.opponents_moves) + + def reset(self): + self.opponents_moves = [] + + def get_name(self): + return self.name + + def set_name (self, playername): + self.name = playername + + def notify(self, msg): + + # We use notifications to store opponent's moves in past rounds + # Process match-start and round-end messages + # At the start of the match, clear opponent moves history since a new match has started + # At the end of a round, append move to opponent's move history. Move history is used + # to compute the next move played. + if msg.is_match_start_message(): + players = msg.get_players() + if players[0] == self or players[1] == self: + self.reset() + elif msg.is_round_end_message(): + players = msg.get_players() + # Check if this message is for me and only then proceed + if (players[0] == self) or (players[1] == self): + # In this case, (by convention) the info is a tuple of the moves made and result e.g. ((1, 0), 1) which + # means player 1 played paper (1), the player 2 played rock(0) and the result was that + # player 1 won + + moves, result = msg.get_info() + + # RPS is a two person game; figure out which of the players is me + # and which one is the opponent + if players[0] == self: + opponent = 1 + else: + opponent = 0 + + # Update opponent's past moves history + self.opponents_moves.append(moves[opponent]) + +class RpsPlayingStrategy(object): + + #Decides next move based on opponents past moves + #Looks for what opponent throws the most and tries to counter it. 0-rock, 1-paper, 2-scissors + #Takes list of opponents past moves + def play(pastmoves): + rock, paper, scissors = 0, 0, 0 + + for index, move in enumerate(pastmoves): + + if move == 0: + rock += 1 + elif move == 1: + paper += 1 + else: + scissors += 1 + else: + return 0 + + #Look for most thrown move and throw counter + if rock > paper and rock > scissors: + return 0 + elif paper > rock and paper > scissors: + return 2 + elif scissors > rock and scissors > paper: + return 1 + else: #Arbitrary throw if 2 or 3 are thrown evenly + return 0 + + + +# Test driver +# Run by typing "python3 GSACPlayer.py" + +if __name__ == "__main__": + player = GSACPlayer() + opponent = GSACPlayer() + players = [opponent,player] + fakeinfo = ((0,1),1) + fakeresult = 1 + fakemoves = (1,2) + + player.notify(Message.Message.get_match_start_message(players)) + player.notify(Message.Message.get_round_start_message(players)) + move = player.play() + print ("Move played: ", move) + player.notify(Message.Message.get_round_end_message(players,fakemoves,fakeresult)) \ No newline at end of file diff --git a/RPSGame.py b/RPSGame.py new file mode 100644 index 0000000..240ecd7 --- /dev/null +++ b/RPSGame.py @@ -0,0 +1,36 @@ +__author__ = 'Greg Richards' + +import Game + + +class RPSGame(Game): + # # this class simulates two players playing a game of rock, paper, scissors + def __init__(self): + super(RPSGame, self).__init__() + + def get_result(self, moves): + # unpack the tuple that was passed as a parameter + move1, move2 = moves + x = self.is_legal(move1) + y = self.is_legal(move2) + + if x and y: + if move1 == move2: + result = (0, 0) + elif (move1 == 0 and move2 != 1) \ + or (move1 == 1 and move2 != 2) \ + or (move1 == 2 and move2 != 0): + # result is tuple with points each player has earned respectively + result = (1, 0) + else: + result = (0, 1) + elif x and not y: + result = (1, 0) + elif not x and y: + result = (0, 1) + else: + result = (0, 0) + return result + + def is_legal(self, move): + return isinstance(move,int) and (move in (0, 1, 2)) diff --git a/RPSPlayerExample.py b/RPSPlayerExample.py index 3d19c97..fd0b834 100644 --- a/RPSPlayerExample.py +++ b/RPSPlayerExample.py @@ -36,9 +36,9 @@ def notify(self, msg): players = msg.get_players() # Check if this message is for me and only then proceed if (players[0] == self) or (players[1] == self): - # In this case, (by convention) the info is a tuple of the moves made and result e.g. ((1, 0), 1) which + # In this case, (by convention) the info is a tuple of the moves made and result e.g. ((1, 0), (1,0)) which # means player 1 played paper (1), the player 2 played rock(0) and the result was that - # player 1 won + # player 1 won (got 1 point) and player 2 lost (got 0 point) moves, result = msg.get_info() @@ -88,9 +88,8 @@ def play(opponents_moves): player = RPSPlayerExample() opponent = RPSPlayerExample() players = [opponent,player] - fakeinfo = ((0,1),1) - fakeresult = 1 fakemoves = (1,2) + fakeresult = (0,1) player.notify(Message.Message.get_match_start_message(players)) player.notify(Message.Message.get_round_start_message(players)) diff --git a/Tournament.py b/Tournament.py index 5c18662..72a6dfb 100644 --- a/Tournament.py +++ b/Tournament.py @@ -1,77 +1,96 @@ # Alex Ciaramella and Greg Suner # Abstract Tournament Class -#Tournament is observable while players are observers +# Tournament is observable while players are observers import Message +import Observable -class Tournament(Observable): +class Tournament(Observable.Observable): # set up a list of players when tournament is initialized def __init__(self): + Observable.Observable.__init__(self) self.playerList = [] - self.game + self.game = None + + # Returns the players in the tournament + def get_players(self): + return self.playerList # run the tournament - def run(self): + def run(self): self.begin_tournament() - while(True): - match = self.create_next_match() - if match == None: - break - self.play_match(match) + while (True): + match = self.create_next_match() + if match == None: + break + self.play_match(match) self.end_tournament() - - + + # get a reference to the next game to be played def create_next_match(self): pass - # register a player for the tournament by adding them to # the list of current players + # register a player for the tournament by adding them to + # the list of current players def register_player(self, player): self.playerList.append(player) + self.add_observer(player) # stores a reference to the type of game we will be playing def set_game(self, game): self.game = game + + # Computes the result of a round based on the moves made by the players + def get_result(self, moves): + return self.game.get_result(moves) + # play the next match and return the results def play_match(self, match): - self.start_match(match[0]) - result = self.play_game(match) - self.end_match(match[0], result) + players = match[0] + self.start_match(players) + result = self.play_rounds(match) + self.end_match(players, result) # plays each indvidual game in the match - def play_round(self, match): - for i in range(0, match[1]): - self.start_round(match[0]) - result = match.get_results(match[0]) - # need to find out definite structure of results!! - self.end_round(result[0], result[1], result[2]) - - # notifies players tournament has begun + def play_rounds(self, match): + players = match[0] + rounds = match[1] + for i in range(rounds): + self.start_round(players) + moves = [] + for p in players: + moves.append(p.play()) + result = self.get_result(moves) + self.end_round(players, moves, result) + + + # notifies players tournament has begun def begin_tournament(self): - pass - - # Announces results of tournament to all players + pass + + # Announces results of tournament to all players def end_tournament(self): pass # send a message containing a list of all the players in the current match def start_match(self, players): - message = Message.get_match_start_message(players) + message = Message.Message.get_match_start_message(players) self.notify_all(message) # send a message containing the result of the match - def end_match(self,players, result): - message = Message.get_match_end_message(players, result) + def end_match(self, players, result): + message = Message.Message.get_match_end_message(players, result) self.notify_all(message) # send a message containing the players in the next game def start_round(self, players): - message = Message.get_round_start_message(players) + message = Message.Message.get_round_start_message(players) self.notify_all(message) # send a message containing the players, moves, and result of the last game - def end_round(players, moves, result): - message = Message.get_round_end_message(players, moves, result) + def end_round(self, players, moves, result): + message = Message.Message.get_round_end_message(players, moves, result) self.notify_all(message) diff --git a/TournamentService.py b/TournamentService.py new file mode 100644 index 0000000..f254706 --- /dev/null +++ b/TournamentService.py @@ -0,0 +1,44 @@ +__author__ = "Joe Kvedaras and Collin Day" +#Set up a tournament with a game and register players +from Tournament.py import * +from AllPlayAll.py import * + +class TournamentService: + + def __init__(self): + #Is tournament service the one to create a new tournament? + self.tournament + self.game + + + def register_player(self, player): + """register a player in the current tournament""" + if self.tournament is None: + print("Can not add player. Tournament is null") + else: + self.tournament.register_player(player) + + + + def set_game(self, game): + """set the game of the current tournament""" + #Tournament initializes with a game and you can not change + #game type afterwards + self.game = game + + def set_tournament(self, tournament_type = None): + """Allow client to set the tournament type. Defaults to + AllPlayAll tournament type""" + if tournament_type is None: + #AllPlayAll takes registration as a parameter. I don't think they + #need that there + self.tournament = AllPlayAll(self.game, None, 1000) + else: + self.tournament = tournament_type(self.game, None, 1000) + + def run(self): + """Set the game and run the tournament""" + if self.tournament is None: + print("Can not run tournament. Tournament is null") + else: + self.tournament.run() diff --git a/feature_Tournament.py b/feature_Tournament.py deleted file mode 100644 index 18c7d76..0000000 --- a/feature_Tournament.py +++ /dev/null @@ -1,77 +0,0 @@ -# Alex Ciaramella and Greg Suner -# Abstract Tournament Class - -#Tournament is observable while players are observers - -import Message - -class Tournament(Observable): - # set up a list of players when tournament is initialized - def __init__(self): - self.playerList = [] - self.game - - # run the tournament - def run(self): - self.begin_tournament() - while(True): - match = self.create_next_match() - if match == None: - break - self.play_match(match) - self.end_tournament() - - - # get a reference to the next game to be played - def create_next_match(self): - pass - - # register a player for the tournament by adding them to # the list of current players - def register_player(self, player): - self.playerList.append(player) - - # stores a reference to the type of game we will be playing - def set_game(self, game): - self.game = game - - # play the next match and return the results - def play_match(self, match): - self.start_match(match[0]) - result = self.play_game(match) - self.end_match(match[0], result) - - # plays each indvidual game in the match - def play_game(self, match): - for i in range(0, match[1]): - self.start_game(match[0]) - result = match.get_results(match[0]) - # need to find out definite structure of results!! - self.end_game(result[0], result[1], result[2]) - - # notifies players tournament has begun - def begin_tournament(self): - pass - - # Announces results of tournament to all players - def end_tournament(self): - pass - - # send a message containing a list of all the players in the current match - def start_match(self, players): - message = Message.get_match_start_message(players) - self.notify_all(message) - - # send a message containing the result of the match - def end_match(self,players, result): - message = Message.get_match_end_message(players, result) - self.notify_all(message) - - # send a message containing the players in the next game - def start_game(self, players): - message = Message.get_round_start_message(players) - self.notify_all(message) - - # send a message containing the players, moves, and result of the last game - def end_game(players, moves, result): - message = Message.get_round_end_message(players, moves, result) - self.notify_all(message) diff --git a/feature_Tournament.pyc b/feature_Tournament.pyc deleted file mode 100644 index 958797b..0000000 Binary files a/feature_Tournament.pyc and /dev/null differ