def steal(self, player): stole_resource = False other_player = None res = None strategies = player.strategies if Strategies.Steal_From_Most_Resources in strategies: max_resources = 0 for node in self.board.robber_tile.nodes: if node.player is not None and node.player.total_resources( ) > max_resources and node.player is not player: max_resources = node.player.total_resources() other_player = node.player if other_player is not None: while not stole_resource: res = Resource(random.randint(1, 5)) if other_player.resources[res] > 0: stole_resource = True else: # Default strategy for node in random.sample(self.board.robber_tile.nodes, 6): other_player = node.player if other_player is not None and other_player is not player: res = Resource(random.randint(1, 5)) if other_player.resources[res] > 0: stole_resource = True break if stole_resource: other_player.resources[res] -= 1 player.resources[res] += 1 v_print( "\t\t\tPlayer " + str(player.id) + " stole one " + str(res) + " from Player " + str(other_player.id), 4) else: v_print("\t\t\tNo resource to steal", 4)
def build(self, player): strategies = player.strategies if self.board.turns == 0: buildable_nodes = self.board.buildable_nodes buildable_edges = self.board.buildable_edges node_to_build = None edge_to_build = None while edge_to_build is None: node_to_build = self.find_valid_settlement_or_city_location( player, buildable_nodes) for edge in random.sample(node_to_build.edges, len(node_to_build.edges)): if edge is not None and edge.player is None: edge_to_build = edge break self.board.build_road(player, edge_to_build) self.board.build_settlement(player, node_to_build) else: buildable_nodes = player.buildable_nodes buildable_edges = player.buildable_edges possible_cities = set() possible_settlements = set() if player.can_build_city(): possible_cities = player.settlements if player.can_build_settlement(): possible_settlements = buildable_nodes possible_nodes = possible_cities.union(possible_settlements) if len(possible_nodes) != 0: node = self.find_valid_settlement_or_city_location( player, possible_nodes) if node is not None: if node.player is player: self.board.build_city(player, node) else: self.board.build_settlement(player, node) build_road = player.can_build_road() if Strategies.Prioritize_Settlements in strategies: build_road = build_road and len(player.buildable_nodes) == 0 if Strategies.Road_Settlement_Ratio in strategies: road_settlement_ratio = strategies.get( Strategies.Road_Settlement_Ratio) build_road = build_road and player.cityCount + player.settlementCount > player.roadCount / road_settlement_ratio if build_road: if len(buildable_edges) != 0: rode_edge = self.find_valid_road_location( player, buildable_edges) self.board.build_road(player, rode_edge) else: v_print( "\t\tPlayer " + str(player.id) + " had resources to bulid a road but no valid location was found", 3)
def build_road(self, player, edge): if edge.player is not None: raise Exception('Cannot build road, edge.player was not None') player.build_road() edge.player = player self.buildable_edges.discard(edge) player.edges.add(edge) for player1 in self.players: player1.buildable_edges.discard(edge) for edge1 in itertools.chain(edge.node1.edges, edge.node2.edges): if edge1 is not None and edge1 != edge and edge1 in self.buildable_edges: player.buildable_edges.add(edge1) for node in [edge.node1, edge.node2]: if node in self.buildable_nodes: player.buildable_nodes.add(node) v_print("\t\tPlayer " + str(player.id) + " built a road from " + edge.node1.get_coords() + " to " + edge.node2.get_coords(), 3)
def build_settlement(self, player, node): if node.player is not None: raise Exception('Cannot build settlement, node.player was not None') player.build_settlement() node.type = BuildType.Settlement node.player = player player.nodes.add(node) player.settlements.add(node) nodes = {node} for edge in node.edges: if edge is not None: nodes.add(edge.get_other_node(node)) for node1 in nodes: self.buildable_nodes.discard(node1) for player1 in self.players: player1.buildable_nodes.discard(node1) for tile in node.resources: if tile is not None: player.resource_rates[tile.resource.value] += tile.chance v_print("\t\tPlayer " + str(player.id) + " built a settlement at " + node.get_coords(), 3)
def trade_four_one(self, resource_out, resource_in, in_number): v_print("Player " + str(self.id) + " Before - ", 4) for resource in self.resources: v_print( "\t" + str(resource) + ": " + str(self.resources[resource]), 4) if self.resources[resource_out] < in_number * 4: sys.exit("trade_four_one: not enough resource to trade") self.resources[resource_out] -= in_number * 4 self.resources[resource_in] += in_number v_print( "\t\t\tPlayer " + str(self.id) + " traded " + str(in_number * 4) + " " + str(resource_out) + " for " + str(in_number) + " " + str(resource_in) + " with the Bank", 4) v_print("Player " + str(self.id) + " Before - ", 4) for resource in self.resources: v_print( "\t" + str(resource) + ": " + str(self.resources[resource]), 4)
def distribute(self, roll_value): if self.value == roll_value: if self.disabled: for node in self.nodes: if node.type == BuildType.Settlement: v_print("\t\t\tPlayer " + str(node.player.id) + " would have gotten 1 of resource " + str(self.resource) + " but the robber was placed on the tile", 4) elif node.type == BuildType.City: v_print("\t\t\tPlayer " + str(node.player.id) + " would have gotten 2 of resource " + str(self.resource) + " but the robber was placed on the tile", 4) else: for node in self.nodes: if node.type == BuildType.Settlement: v_print("\t\t\tPlayer " + str(node.player.id) + " got 1 of resource " + str(self.resource), 4) node.player.resources[self.resource] += 1 elif node.type == BuildType.City: v_print("\t\t\tPlayer " + str(node.player.id) + " got 2 of resource " + str(self.resource), 4) node.player.resources[self.resource] += 2
def move_robber(self, new_robber_tile): self.robber_tile.disabled = False self.robber_tile = new_robber_tile self.robber_tile.disabled = True v_print("\t\t\tRobber was moved to tile " + str(self.layout.index(self.robber_tile)), 4)
def dice_roll(self, player): roll = random.randint(1,6) + random.randint(1,6) v_print("\t\tRolled a " + str(roll), 2) return roll
def print_results(self, winner): v_print("Game Ended", 2) v_print("---------------------------------------------", 2) for player in self.board.players: #print every players settlements, roads, and cities v_print("Player " + str(player.id) + ": ", 2) v_print("\tSettlement Locations:", 2) for node in player.nodes: if node.type == BuildType.Settlement: v_print("\t\t" + node.get_coords(), 2) v_print("\tCity Locations:", 2) for node in player.nodes: if node.type == BuildType.City: v_print("\t\t" + node.get_coords(), 2) v_print("\tEdge Between:", 2) for edge in player.edges: v_print( "\t\t" + edge.node1.get_coords() + " to " + edge.node2.get_coords(), 2) if winner is not None: v_print( "Player " + str(winner.id) + " Won After " + str(self.board.turns) + " Turns", 1) else: v_print( "After " + str(max_turns) + " turns, no one has reached 10 points", 1) highest_score = -1 for player in self.board.players: if player.points() >= highest_score: highest_score = player.points() winners = [] for player in self.board.players: if player.points() == highest_score: winners.append(player.id) v_print( "Player(s) " + ", ".join(str(p) for p in winners) + " had the most points, with " + str(highest_score) + " points", 1) v_print("", 1) for player in self.board.players: v_print("Player " + str(player.id), 2) for resource in player.resources: v_print( "\t" + str(resource) + ": " + str(player.resources[resource]), 2)
def game_turn(self): turns = self.board.turns if turns == 0: v_print("", 2) v_print("Players placing initial settlements and roads", 2) v_print("---------------------------------------------", 2) v_print("", 2) for player in self.board.players: self.build(player) # on second placement, players get the resources bordering their settlement for player in reversed(self.board.players): self.build(player) for roll in range(2, 13): if roll != 7: self.board.distribute(roll) v_print("", 2) v_print("Moving on to main game section", 2) v_print("---------------------------------------------", 2) v_print("", 2) else: v_print("Round " + str(self.board.turns), 2) for player in self.board.players: v_print("\tPlayer " + str(player.id) + "'s Turn", 2) roll = self.board.dice_roll(player) if roll == 7: for player1 in self.board.players: resources = player1.total_resources() if player1.total_resources() > 7: self.discard_half(player1) v_print( "\t\t\tPlayer " + str(player1.id) + " had " + str(resources) + " resources and now has " + str(player1.total_resources()), 4) else: v_print( "\t\t\tPlayer " + str(player1.id) + " has " + str(resources) + " resources. No cards are discarded", 4) self.move_robber(player) self.steal(player) else: self.board.distribute(roll) self.trade(player) if Strategies.Build_All in player.strategies: settlementCount = player.settlementCount cityCount = player.cityCount roadCount = player.roadCount count = 0 while (settlementCount != player.settlementCount) \ or (cityCount != player.cityCount) \ or (roadCount != player.roadCount) or count == 0: settlementCount = player.settlementCount cityCount = player.cityCount roadCount = player.roadCount self.build(player) count += 1 else: self.build(player) if player.win(): return player self.board.turns += 1
def trade_with_player(self, other, resource_out, resource_in, out_number, in_number): if self.resources[resource_out] < out_number or other.resources[ resource_in] < in_number: sys.exit( "trade_with_player: not enough resource to trade with player") v_print("Player " + str(self.id) + " Before - ", 4) for resource in self.resources: v_print( "\t" + str(resource) + ": " + str(self.resources[resource]), 4) v_print("Player " + str(other.id) + " Before - ", 4) for resource in other.resources: v_print( "\t" + str(resource) + ": " + str(other.resources[resource]), 4) self.resources[resource_out] -= out_number self.resources[resource_in] += in_number other.resources[resource_out] += out_number other.resources[resource_in] -= in_number v_print( "\t\t\tPlayer " + str(self.id) + " traded " + str(out_number) + " " + str(resource_out) + " for " + str(in_number) + " " + str(resource_in) + " with Player " + str(other.id), 4) v_print("Player " + str(self.id) + " After - ", 4) for resource in self.resources: v_print( "\t" + str(resource) + ": " + str(self.resources[resource]), 4) v_print("Player " + str(other.id) + " After - ", 4) for resource in other.resources: v_print( "\t" + str(resource) + ": " + str(other.resources[resource]), 4)