def end_game(game): def sort_players(player_id): return (int(game['players'][player_id]['customers']), sum(game['players'][player_id]['resources'].values())) game['player_order'] = sorted(game['player_order'], key=sort_players, reverse=True) push(game, 'end', {"players": [game['players'][p] for p in game['player_order']]}) for player in game['players'].values(): communication.request(player, "game/%s" % player['id'], method="DELETE")
def end_turn(db, game, player, forced=False): def run_end_turn(): next_turn(db, game) print "Ended turn" game['turn_id'] = None db.save(game) if forced: push(game, 'timeout', {'player': player, 'turn': game['turn'], 'round': game['round']}) communication.request(player, "game/%s/end_turn" % player['id']) thread.start_new_thread(run_end_turn, ()) return {"status": "success"}
def trade(db, game, player, offering, requesting): if not has_enough_resources(player, offering): abort(400, "You don't have enough stuff!") players = [game['players'][p] for p in game['player_order'] if not p == player['id']] random.shuffle(players) # Don't give one person first refusal print "Player ", player['id'], " offering ", offering, " for ", requesting trade_id = uuid4().hex push(game, 'trade', {"round": game['round'], "turn": game['turn'], "player": player, 'offering': offering, 'requesting': requesting, "trade_id": trade_id}) if sum(offering.values()) >= (sum(requesting.values()) * config.BANK_TRADE_RATE): # The bank will take the trade charge_resources(player, offering) for resource in requesting: player['resources'][resource] += requesting[resource] log_action(game, player, 'bank-trade', {"offer": offering, "request": requesting}) push(game, 'trade-bank-accepted', {"trade_id": trade_id}) db.save(game) return {"player": player, 'accepted_by': 'bank'} for p in players: if has_enough_resources(p, requesting): response, data = communication.request(p, "game/%s/trade" % p['id'], {"player": player['id'], "offering": offering, "requesting": requesting}) if response.status == 200: charge_resources(player, offering) charge_resources(p, requesting) for resource in offering: p['resources'][resource] += offering[resource] for resource in requesting: player['resources'][resource] += requesting[resource] log_action(game, player, 'trade', {"offer": offering, "request": requesting, "traded_with": p['id']}) push(game, 'trade-accepted', {"trade_id": trade_id, "player": p}) db.save(game) return {"player": player, 'accepted_by': p['id']} log_action(game, player, 'trade-rejected', {"offer": offering, "request": requesting}) push(game, 'trade-rejected', {"trade_id": trade_id}) abort(500, "No bites")
def next_turn(db, game): turn_taken = False if config.DELAY > 0: time.sleep(config.DELAY) while not turn_taken: # Find the next player ready to make a move game['turn'] = game['turn'] + 1 if game['turn'] >= len(game['player_order']): # Next round game['round'] += 1 game['turn'] = 0 if game_is_over(game): return end_game(game) print "Starting round %i" % game['round'] game['player_order'].reverse() generated = run_generators(game['players']) if len(generated.keys()) > 0: push(game, 'new-round', {'round': game['round'], 'players': copy(game['players']), "generated": generated}) else: push(game, 'new-round', {'round': game['round'], 'players': copy(game['players'])}) player = game['players'][game['player_order'][game['turn']]] # Wow - nice line response, data = communication.request(player, "game/%s/start_turn" % player['id']) if response.status == 200: turn_id = uuid4().hex game['turn_id'] = turn_id player['actions'] = {} db.save(game) turn_taken = True push(game, 'start-turn', {'player': player, 'turn': game['turn'], 'round': game['round']}) def force_turn_end(): g = db.get(game['id']) if g['turn_id'] == turn_id: # The turn hasn't changed print "Out of time" end_turn(db, game, player, forced=True) turn_timeout = Timer(config.TURN_TIMEOUT, force_turn_end) turn_timeout.start() else: db.save(game) log_action(game, player, 'turn-skipped') push(game, 'turn-skipped', {'player': player, 'turn': game['turn'], 'round': game['round']})
def start_game(db, players): print "Starting game" game_id = uuid4().hex game = { "id": game_id, "players": {}, "player_order": [], "turn": len(players), "turn_id": None, "round": 0, "pushes": [] } used_names =[] for player in players: p = setup_player(player) i = 0 while p['name'] in used_names: i += 1 p['name'] = p['player'] + ' %i' % i used_names.append(p['name']) game['players'][p['id']] = p game['player_order'].append(p['id']) generators_to_use = copy(config.GENERATORS.keys()) random.shuffle(generators_to_use) p = 0 max_generators = 0 # First pass out all generators as evenly as possible while (len(generators_to_use) > 0): game['players'][game['player_order'][p]]['generators'][generators_to_use.pop()] += 1 total_generators = sum(game['players'][game['player_order'][p]]['generators'].values()) if total_generators > max_generators: max_generators = total_generators p += 1 if p == len(game['player_order']): p = 0 # Now ensure everyone has an equal amount generators_to_use = copy(config.GENERATORS.keys()) random.shuffle(generators_to_use) for p in game['players']: while sum(game['players'][p]['generators'].values()) < max_generators: game['players'][p]['generators'][generators_to_use.pop()] += 1 started_players = [] for player in game['players'].values(): response, data = communication.request(player, "game/%s" % (player['id']), {"player": player, "endpoint": "http://localhost:8080/game/%s" % game_id}, 'PUT') if response.status != 200: for p in started_players: communication.request(player, "game/%s/cancel" % (player['id']), {"player": player}) return False started_players.append(player) db.save(game) next_turn(db, game) return game_id