diff options
-rw-r--r-- | CAO_Board.py | 52 | ||||
-rw-r--r-- | CAO_Client.py | 48 | ||||
-rw-r--r-- | CAO_Game.py | 147 | ||||
-rw-r--r-- | CAO_GameManager.py | 18 | ||||
-rw-r--r-- | CAO_Player.py | 23 |
5 files changed, 288 insertions, 0 deletions
diff --git a/CAO_Board.py b/CAO_Board.py new file mode 100644 index 0000000..925b1ee --- /dev/null +++ b/CAO_Board.py @@ -0,0 +1,52 @@ +import random + +class CAO_Board(): + def __init__(self, white_cards, black_cards): + self.white_pick = white_cards + self.black_pick = black_cards + + self.white_recycled = [] + self.black_recycled = [] + + self.current_black_card = None + + # tupple of cards / player currently being played + self.played_cards = [] + + random.shuffle(self.white_pick) + random.shuffle(self.black_pick) + + def reveal_black_card(self): + if not self.black_pick: + self.black_pick = self.black_recycle + + random.shuffle(self.black_pick) + + self.black_recycled = [] + + card = self.black_pick.pop() + + self.current_black_card = card + + def recycle_black_card(self): + self.black_recycled.append(self.current_black_card) + + def pick_white_card(self): + if not self.white_pick: + self.white_pick = self.white_recycled + + random.shuffle(self.white_pick) + + self.white_recycled = [] + + card = self.white_pick.pop() + + return card + + def play_card(self, player, card): + self.played_cards.append((card, player)) + + def recycle_played_cards(self): + self.white_recycled += [i[0] for i in self.played_cards] + + self.played_cards = [] diff --git a/CAO_Client.py b/CAO_Client.py new file mode 100644 index 0000000..daf6f7e --- /dev/null +++ b/CAO_Client.py @@ -0,0 +1,48 @@ +from CAO_Game import CAO_Game + +class CAO_Client(): + def __init__(self, game_manager): + self.game = None + self.game_manager = game_manager + + self.player = None + + def join_game(self, game_name): + if self.game is not None: + return ('ERR', 'You are already in a game') + + self.game = self.game_manager.join_game(game_name) + return self.game.try_join(self) + + def set_player(self, player): + self.player = player + + def play_white_card(self, card_id): + if self.game is None: + return ('ERR', 'You have to join a game first') + return self.game.try_play_card(self.player, card_id) + + def pick_black_card(self): + if self.game is None: + return ('ERR', 'You have to join a game first') + return self.game.try_become_judge(self.player) + + def collect_cards(self): + if self.game is None: + return ('ERR', 'You have to join a game first') + return self.game.try_collect_cards(self.player) + + def designate_card(self, card_id): + if self.game is None: + return ('ERR', 'You have to join a game first') + return self.game.try_designate_card(self.player, card_id) + + def view_player_cards(self): + if self.game is None: + return ('ERR', 'You have to join a game first') + return self.game.try_view_player_cards(self.player) + + def view_played_cards(self): + if self.game is None: + return ('ERR', 'You have to join a game first') + return self.game.try_view_played_cards(self.player) diff --git a/CAO_Game.py b/CAO_Game.py new file mode 100644 index 0000000..dfa7841 --- /dev/null +++ b/CAO_Game.py @@ -0,0 +1,147 @@ +from CAO_Player import CAO_Player +from CAO_Board import CAO_Board + +import json + +class CAO_Game(): + WAITING_NEW_JUDGE = 0, + WAITING_COLLECTION = 1, + WAITING_DESIGNATION = 2, + + + def __init__(self, white_desc, black_desc): + self.white_desc = white_desc + self.black_desc = black_desc + + white_pick = [i for i in range(len(self.white_desc))] + black_pick = [i for i in range(len(self.black_desc))] + + self.state = self.WAITING_NEW_JUDGE + + self.players = [] + + self.judge = None + + self.board = CAO_Board(white_pick, black_pick) + + def try_join(self, client): + if len(self.players) >= 10: + return ('ERR', 'too many players in this game') + + cards = [] + + try: + for i in range(10): + cards.append(self.board.pick_white_card()) + except IndexError: + return ('ERR', 'no enough white cards for player') + + player = CAO_Player(client, cards) + client.set_player(player) + + self.players.append(player) + + return ('OK', '') + + + def try_become_judge(self, player): + if self.state is not self.WAITING_NEW_JUDGE: + # TODO what if the judge has quit ? + return ('ERR', 'Someone is judge already') + + self.judge = player + self.board.reveal_black_card() + + self.state = self.WAITING_COLLECTION + + return ('OK', '') + + + def try_play_card(self, player, card_id): + if self.state is not self.WAITING_COLLECTION: + return ('ERR', 'Who asked you to play now ?!') + + if self.judge is player: + return ('ERR', 'You\'re the judge, you silly') + elif player.get_has_played(): + return ('ERR', 'You already played, you dumb ass') + + try: + card = player.pop_card(card_id) + except IndexError: + return ('ERR', 'Invalid card id') + + player.set_has_played() + + self.board.play_card(player, card) + + return ('OK', '') + + + def try_collect_cards(self, player): + if self.state is not self.WAITING_COLLECTION: + return ('ERR', 'Do you think it\'s the moment for colletion !?') + + if self.judge is not player: + return ('ERR', 'You\'re not the judge, you fool!') + + # we prevent the others to play + self.state = self.WAITING_DESIGNATION + + return ('OK', '') + + + def try_designate_card(self, player, card_id): + if self.state is not self.WAITING_DESIGNATION: + return ('ERR', 'Not now, moron !') + + if self.judge is not player: + return ('ERR', 'Who do you think you are !?') + + if card_id is None and len(self.board.played_cards) > 0: + return ('ERR', 'There are cards on the board, pick one !') + + if card_id is not None or len(self.board.played_cards) > 0: + # if there are cards on the board + # TODO check exception + try: + card, winner = self.board.played_cards[card_id] + except IndexError: + return ('ERR', 'Invalid card') + + winner.inc_score() + + # put the cards back in the deck + self.board.recycle_played_cards() + + # reset the state of the players + for p in self.players: + if p.get_has_played: + p.cards.append(self.board.pick_white_card()) + p.set_has_played(False) + + self.board.recycle_black_card() + self.judge = None # useful or not ... + + self.state = self.WAITING_NEW_JUDGE + + return ('OK', '') + + def try_view_player_cards(self, player): + cards = [] + + for card in player.cards: + cards.append(self.white_desc[card]) + + return ('OK', json.dumps(cards)) + + def try_view_played_cards(self, player): + if self.state is not self.WAITING_DESIGNATION: + return ('ERR', 'Not now, moron !') + + cards = [] + + for card, unused in self.board.played_cards: + cards.append(self.white_desc[card]) + + return ('OK', json.dumps(cards)) diff --git a/CAO_GameManager.py b/CAO_GameManager.py new file mode 100644 index 0000000..afd7f09 --- /dev/null +++ b/CAO_GameManager.py @@ -0,0 +1,18 @@ +from CAO_Game import CAO_Game +from CAO_Cards import CAO_Cards + +class CAO_GameManager(): + def __init__(self): + self.games = {} + + self.black_cards = CAO_Cards.get_black_cards() + self.white_cards = CAO_Cards.get_white_cards() + + def join_game(self, game_name): + game = self.games.get(game_name) + + if game is None: + print('Starting new game') + game = self.games[game_name] = CAO_Game(self.black_cards, self.white_cards) + + return game diff --git a/CAO_Player.py b/CAO_Player.py new file mode 100644 index 0000000..9501a46 --- /dev/null +++ b/CAO_Player.py @@ -0,0 +1,23 @@ +class CAO_Player(): + def __init__(self, client, cards): + self.cards = cards + self.client = client + + self.score = 0 + + self.has_played = False + + self.name = 'default' + + def pop_card(self, card_id): + return self.cards.pop(card_id) + + + def get_has_played(self): + return self.has_played + + def set_has_played(self, has=True): + self.has_played = has + + def inc_score(self): + self.score += 1 |