def run(ui, players): #dict_ai=dict_ai_default): time_start = time.time() number_players = len(players) game_state = GameState(number_players) ui.draw_board(game_state) # Check on players (is this useless?)⎈ for player in players: if not player.check(): return False # Initial settlements ui.print("\n" + 5 * "*" + " INITIAL SETTLEMENTS " + 5 * "*" + "\n") beginner = randint(0, game_state.number_players - 1) settlement_order = [] for i in range(number_players): settlement_order.append((beginner + i) % number_players) for i in reversed(range(number_players)): settlement_order.append((beginner + i) % number_players) #print(settlement_order) for i, n in enumerate(settlement_order): # Build initial crossing and road while True: ui.draw_board(game_state) crossing, path = players[n].initial_settlement(game_state) error_code = game_state.build_initial_settlement(n, crossing, path) if error_code == 0: ui.print(f"Player {n} build a settlement at {crossing}.") ui.print(f"Player {n} build a road at {path}.") break else: if error_code == 1: ui.print("That crossing is not available!") elif error_code == 2: ui.print("That is not an adjacent road!") else: ui.print("Something went wrong!") # Distribute initial resources if i >= number_players: for hexcoor in game_state.adjacent_hexcoors(crossing): hexx = game_state.dir_hexes[hexcoor] if not hexx in NO_YIELDS: game_state.dir_resources[n][hexx] += 1 ui.print(f"Player {n} received initial resources.") ui.draw_board(game_state) #for i in range(number_players): #n = (beginner+i)%number_players #crossing, path = players[n].initial_settlement(game_state) #game_state.dir_crossings[crossing] = (1,n) #game_state.dir_paths[path] = n #ui.draw_board(game_state) #ui.print(f"Player {n} build a settlement at {crossing}.") #ui.print(f"Player {n} build a road at {path}.") #for i in reversed(range(number_players)): #n = (beginner+i)%number_players #crossing, path = players[n].initial_settlement(game_state) #game_state.dir_crossings[crossing] = (1,n) #game_state.dir_paths[path] = n #ui.print(f"Player {n} build a settlement at {crossing}.") #ui.print(f"Player {n} build a road at {path}.") #for hexcoor in game_state.adjacent_hexcoors(crossing): #hexx = game_state.dir_hexes[hexcoor] #if not hexx in NO_YIELDS: #game_state.dir_resources[n][hexx] += 1 #ui.draw_board(game_state) ui.print(game_state.dir_resources) # Actual game loops ui.print("\n" + 5 * "*" + " GAME STARTS " + 5 * "*" + "\n") n = beginner turn = 0 running = True winner = None #if input("Pause...") in ("q", "quit"): #running = False while running: turn += 1 roundd = turn // number_players if not DEBUG: ui.draw_board(game_state) if turn % number_players == 0: if roundd == 1000: running = False else: ui.print(f"We're going into round {roundd}!") ui.print("\n" + 5 * "*" + f" ROUND {roundd}, TURN {turn}, PLAYER {n} " + 5 * "*" + "\n") ui.print(f"It's the turn of Player '{players[n].name}'") #ui.print("\n" + 5*"*" + f" TURN {turn}, PLAYER {n} " + 5*"*" + "\n") # Dice roll w = roll_dice() ui.print(f"Player {n} rolled a {w}.") if w == 7: # Robber for m in range(number_players): hand = game_state.number_resources(m) if hand > 7: players[m].get_robbed(game_state) if not game_state.number_resources(m) == (hand - hand // 2): ui.print(f"Player {m} cheated the robber!") else: ui.print(f"Player {m} got robbed!") #input("How about that?") hexcoor, player = players[n].set_robber(game_state) game_state.robber = hexcoor if not player == None: resource = game_state.choose_resource_card(player) if not resource == None: game_state.dir_resources[player][resource] -= 1 game_state.dir_resources[n][resource] += 1 ui.print( f"Player {n} robbed {resource} from player {player}!") ui.draw_board(game_state) else: # Resources for hexcoor in HEXCOORS: resource = game_state.dir_hexes[hexcoor] if (not resource in NO_YIELDS) and (not game_state.robber == hexcoor): if game_state.dir_chips[hexcoor] == w: for direction in DIRECTIONS: crossing = vec_add(hexcoor, direction) piece = game_state.dir_crossings[crossing] if not (piece == None): if piece[0] == 1: game_state.dir_resources[ piece[1]][resource] += 1 if piece[0] == 2: game_state.dir_resources[ piece[1]][resource] += 2 # Turn of player n player = players[n] while True: action = player.get_action(game_state) list_action = action.split(" ") command = list_action[0] # Command pass if command == "pass": if game_state.has_won(n): winner = n running = False break # Command quit elif command in ("q", "quit"): running = False break # Command debug elif command == "debug": #print(game_state.dir_resources) game_state.print_state() # Command trade elif command in ("t", "trade"): try: resource1 = list_action[1] resource2 = list_action[2] cost = {resource: 0 for resource in RESOURCES} price = game_state.price(n, resource1) cost[resource1] += price if game_state.pays(n, cost): game_state.dir_resources[n][resource2] += 1 ui.print( f"Player {n} traded {price} {resource1} for 1 {resource2}" ) #input("How about that?") elif not DEBUG: ui.print("You cannot afford to do that!") except: ui.print("Something failed!") # Command build/buy elif command in ("b", "build", "buy"): arg = list_action[1] try: if arg in ("r", "road"): crossing1 = (int(list_action[2]), int(list_action[3])) crossing2 = (int(list_action[4]), int(list_action[5])) path = frozenset({crossing1, crossing2}) error_code = game_state.build_road(n, path) if error_code == 0: ui.print(f"Player {n} build a road at {path}.") elif arg in ("s", "settlement"): crossing = (int(list_action[2]), int(list_action[3])) error_code = game_state.build_settlement(n, crossing) if error_code == 0: ui.print( f"Player {n} build a settlement at {crossing}." ) elif arg in ("c", "city"): crossing = (int(list_action[2]), int(list_action[3])) error_code = game_state.build_city(n, crossing) if error_code == 0: ui.print(f"Player {n} build a city at {crossing}.") elif arg in ("d", "devcard"): error_code = game_state.buy_devcard(n) if error_code == 0: ui.print(f"Player {n} bought a devcard.") else: error_code = 3 except: ui.print("Something failed. Are the coordinates correct?") ui.print(e) # Error messages if error_code != 0: if error_code == 1: ui.print("You cannot afford to do that!") elif error_code == 2: ui.print("You cannot build there!") elif error_code == 3: ui.print(f"Unknown argument: {arg}") else: ui.print("An unexpected error occured!") # Command play devcard elif command in ("p", "play", "d", "devcard"): if game_state.dir_devcards[n] > 0: game_state.update_armies(n) hexcoor, player2 = players[n].set_robber(game_state) game_state.robber = hexcoor if not player2 == None: resource = game_state.choose_resource_card(player2) if not resource == None: game_state.dir_resources[player2][resource] -= 1 game_state.dir_resources[n][resource] += 1 ui.draw_board(game_state) ui.print( f"Player {n} played a knight and robbed player {player2}." ) if game_state.largest_army[1] == n: ui.print(f"Player {n} has the larges army!") elif not DEBUG: ui.print(f"You do not have a devcard.") else: ui.print(f"Unknown action: {action}") ui.draw_board(game_state) if turn % (10 * number_players) == 0: ui.draw_board(game_state) #game_state.print_state() #if input("Pause...") in ("q", "quit"): #running = False n = (n + 1) % number_players #print(n) vps = {} for n in range(number_players): vps[n] = game_state.victory_points(n) ui.print("The game ends!") for n in range(number_players): ui.print( f"Player {n} ({players[n].name}) has {vps[n]} victory points!") if winner != None: ui.print(f"The winner is player {winner} ({players[winner].name})!") else: ui.print("The game ends without a winner!") total_time = time.time() - time_start return turn, total_time