Index: main.py
===================================================================
--- main.py	(revision 1)
+++ main.py	(revision 1)
@@ -0,0 +1,162 @@
+from random import shuffle
+
+
+class Player(object):
+
+    def __init__(self, player_count, player_num, role):
+        self.count = player_count
+        self.num = player_num
+        self.role = role
+
+    def reveal_spies(self, spies):
+        pass
+
+    def propose_team(self, count):
+        team = list(range(self.count))
+        shuffle(team)
+        return team[:count]
+
+    def approve_team(self, team):
+        return True
+
+    def observe_team_vote(self, approved, votes):
+        pass
+
+    def perform_mission(self):
+        return False
+
+    def observe_mission(self, success, failures):
+        pass
+
+    def observe_game(self, success):
+        pass
+
+
+class HumanPlayer(Player):
+
+    def __init__(self, player_count, player_num, role):
+        super(HumanPlayer, self).__init__(player_count, player_num, role)
+
+    def reveal_spies(self, spies):
+        print("%s (%s) sees spies: %s" % (self.num, self.role, spies))
+
+    def propose_team(self, count):
+        if count == 2:
+            return [0, 1]
+        else:
+            return [0, 1, 2]
+
+    def approve_team(self, team):
+        return True
+
+    def observe_team_vote(self, approved, votes):
+        pass
+
+    def perform_mission(self):
+        return False
+
+    def observe_mission(self, success, failures):
+        pass
+
+
+
+def spies_for_players(player_count):
+    return {
+        5: 2,
+        6: 2,
+        7: 3,
+        8: 3,
+        9: 3,
+        10: 4
+    }[player_count]
+
+
+def mission_size(player_count, mission_num):
+    return {
+        5: [2, 3, 2, 3, 3],
+        6: [2, 3, 4, 3, 4],
+        7: [2, 3, 3, 4, 4],
+        8: [3, 4, 4, 5, 5],
+        9: [3, 4, 4, 5, 5],
+        10: [3, 4, 4, 5, 5]
+    }[player_count][mission_num - 1]
+
+
+def required_failures(player_count, mission_num):
+    if mission_num == 4 and player_count >= 7:
+        return 2
+    else:
+        return 1
+
+
+def main(player_count):
+    spy_count = spies_for_players(player_count)
+    resistance_count = player_count - spy_count
+    print("Will have {} spies and {} resistance".format(spy_count, resistance_count))
+    role_deck = ["RES"] * resistance_count + ["SPY"] * spy_count
+    shuffle(role_deck)
+    print(role_deck)
+    players = [Player(player_count, i, r) for i, r in enumerate(role_deck)]
+
+    spy_nums = [i for i, r in enumerate(role_deck) if r == "SPY"]
+
+    for i, r in enumerate(role_deck):
+        if r == "SPY":
+            players[i].reveal_spies(spy_nums)
+
+    wins = 0
+    losses = 0
+    captain = 0
+
+    for mission in range(1, 6):
+        team_size = mission_size(player_count, mission)
+        print("Mission {} needs {} members".format(mission, team_size))
+        for attempt in range(5):
+            print("Captain is {}".format(captain))
+            team = players[captain].propose_team(team_size)
+            print("He proposed {}".format(team))
+            votes = [p.approve_team(team) for p in players]
+            approvals = sum(votes)
+            approved = approvals > team_size / 2
+            print("Team {}: {} for, {} against".format(
+                {True: "approved", False: "rejected"}[approved],
+                approvals, player_count - approvals
+            ))
+
+            for p in players:
+                p.observe_team_vote(approved, votes)
+
+            captain = (captain + 1) % player_count
+            if approved:
+                failures = 0
+                for i in team:
+                    if role_deck[i] == "SPY":
+                        if not players[i].perform_mission():
+                            failures = failures + 1
+                success = failures < required_failures(player_count, mission)
+
+                for p in players:
+                    p.observe_mission(success, failures)
+
+                if success:
+                    print("Mission succeeded")
+                    wins += 1
+                    if wins >= 3:
+                        print("The Resistance won!")
+                        for p in players:
+                            p.observe_game(True)
+                        return
+                else:
+                    print("Mission had {} failures".format(failures))
+                    losses += 1
+                    if losses >= 3:
+                        print("The Spies won!")
+                        for p in players:
+                            p.observe_game(False)
+                        return
+
+                break
+            else:
+                pass
+
+main(10)
