summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CAO_Board.py52
-rw-r--r--CAO_Client.py48
-rw-r--r--CAO_Game.py147
-rw-r--r--CAO_GameManager.py18
-rw-r--r--CAO_Player.py23
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