def move_robber(player,app): """Depending on human or computer, should move robber to new space and steal random card from player on that space""" app.pieces.turn_phase = "place robber" # Get the tile for the robber to be placed if player.AI_code<0: robber_tile = player_place_robber(player,app) else: robber_tile = computer_place_robber(player,app) for tile in app.pieces.tiles: if tile.has_robber: tile.has_robber = False break for tile in app.pieces.tiles: if tile==robber_tile: tile.has_robber = True # Write to log where player put the robber write_log(app,player.name,"placed the robber",vague_location(robber_tile)) # Redraw the robber on the board redraw_robber(app) app.pieces.turn_phase = "steal resource" # Take a resource from a player on the tile where the robber was placed if player.AI_code<0: player_steal_resource(player,robber_tile,app) else: computer_steal_resource(player,robber_tile,app)
def roll_dice(app): """Rolls two six sided dice and returns their values.""" die_values = [1,2,3,4,5,6] die_1 = choice(die_values) die_2 = choice(die_values) # while die_1+die_2 == 7: # die_1 = choice(die_values) # die_2 = choice(die_values) write_log(app,"Rolled",die_1,"+",die_2,"=",die_1+die_2) return die_1, die_2
def player_steal_resource(player,robber_tile,app): """Prompts player for which player they would like to steal from""" from catan_logic import get_stealable_players clear_resource_panel(app) draw_resource_panel(player,app) # Skip this step if there is nobody to steal from stealable_players = get_stealable_players(player,robber_tile,app) if len(stealable_players)==0: return app.button_chosen.set(-1) while app.button_chosen.get()!=0 or \ app.displays.steal_choice.get()=="Choose a player to steal from": app.board_canvas.wait_variable(app.button_chosen) app.button_chosen.set(-1) target_player_name = app.displays.steal_choice.get() for guy in app.pieces.players: if guy.name==target_player_name: target_player = guy break target_resources = [] for i in range(target_player.wood): target_resources.append("wood") for i in range(target_player.brick): target_resources.append("brick") for i in range(target_player.sheep): target_resources.append("sheep") for i in range(target_player.wheat): target_resources.append("wheat") for i in range(target_player.stone): target_resources.append("stone") stolen_resource = choice(target_resources) if stolen_resource=="wood": target_player.wood -= 1 player.wood += 1 if stolen_resource=="brick": target_player.brick -= 1 player.brick += 1 if stolen_resource=="sheep": target_player.sheep -= 1 player.sheep += 1 if stolen_resource=="wheat": target_player.wheat -= 1 player.wheat += 1 if stolen_resource=="stone": target_player.stone -= 1 player.stone += 1 write_log(app,player.name,"stole a resource from",target_player.name)
def perform_trade(player,give_resource,get_resource,app,mul = 1,AI=True,ratio=4): """For player, trades the necessary number of give_resource for get_resource""" if AI: #AI always uses the "optimal" trade ratio whereas humans can use any if "any" in player.ports or "?" in player.ports: trade_ratio = 3 else: trade_ratio = 4 if give_resource in player.ports: trade_ratio = 2 else: trade_ratio = ratio trade_allowed = False if give_resource=="wood" and player.wood>=mul: trade_allowed = True player.wood -= mul*trade_ratio elif give_resource=="brick" and player.brick>=mul: trade_allowed = True player.brick -= mul*trade_ratio elif give_resource=="sheep" and player.sheep>=mul: trade_allowed = True player.sheep -= mul*trade_ratio elif give_resource=="wheat" and player.wheat>=mul: trade_allowed = True player.wheat -= mul*trade_ratio elif give_resource=="stone" and player.stone>=mul: trade_allowed = True player.stone -= mul*trade_ratio if trade_allowed: if get_resource=="wood": player.wood += mul elif get_resource=="brick": player.brick += mul elif get_resource=="sheep": player.sheep += mul elif get_resource=="wheat": player.wheat += mul elif get_resource=="stone": player.stone += mul write_log(app,player.name,"traded",trade_ratio*mul,give_resource,"for ",mul, get_resource)
def build_settlement(player,app): # If the player can't build a settlement, exit without building anything available_points = legal_settlement_placements(player,app.pieces.players, app.pieces.all_points) if len(available_points)==0: print("Nowhere to build a new settlement!") return if len(player.settlements)>=player.settlement_max: print("Already built maximum number of settlements!") return # Unless it's the first round of placements, take resources away if len(player.roads)>1: # Make sure the player has the necessary resources first if player.wood<1 or player.brick<1 or player.sheep<1 or player.wheat<1: print("Not enough resources to build a settlement!") return player.wood -= 1 player.brick -= 1 player.wheat -= 1 player.sheep -= 1 app.pieces.turn_phase = "build settlement" # Get the point for the settlement to be built if player.AI_code<0: settlement = player_choose_settlement(player,available_points,app) else: settlement = computer_choose_settlement(player,available_points,app) # If the player didn't choose a settlement, refund resources and exit if not(settlement): player.wood += 1 player.brick += 1 player.wheat += 1 player.sheep += 1 return # Update the player's building list player_building_update(settlement,1,player,app.pieces.all_points) # Draw the settlement on the board draw_settlement(settlement,player,app) # Write to log where player built settlement write_log(app,player.name,"built a settlement",vague_location(settlement)) # Recalculate the player's score player.calculate_score() return settlement
def build_city(player,app): app.pieces.turn_phase = "build city" # If the player can't build a city, exit without building anything available_points = player.settlements if len(available_points)==0: print("Nowhere to build a new city!") return if len(player.cities)>=player.city_max: print("Already built maximum number of cities!") return if player.wheat<2 or player.stone<3: print("Not enough resources to build a city!") return # Take resources away player.stone -= 3 player.wheat -= 2 # Get the point for the city to be built if player.AI_code<0: city = player_choose_city(player,available_points,app) else: city = computer_choose_city(player,available_points,app) # If the player didn't choose a city, refund resources and exit if not(city): player.stone += 3 player.wheat += 2 return # Update the player's building list player_building_update(city,2,player,app.pieces.all_points) # Draw the city on the board draw_city(city,player,app) # Write to log where player built city write_log(app,player.name,"built a city",vague_location(city)) # Recalculate the player's score player.calculate_score() return city
def build_road(player,app): # If the player can't build a road, exit without building anything available_roads = legal_road_placements(player,app.pieces.players, app.pieces.all_roads) if len(available_roads)==0: print("Nowhere to build a new road!") return if len(player.roads)>=player.road_max: print("Already built maximum number of roads!") return # Unless it's the first round of placements, take resources away if len(player.roads)>1: # Make sure the player has the necessary resources first if player.wood<1 or player.brick<1: print("Not enough resources to build a road!") return player.wood -= 1 player.brick -= 1 app.pieces.turn_phase = "build road" # Get the points for the road to be built if player.AI_code<0: road = player_choose_road(player,available_roads,app) else: road = computer_choose_road(player,available_roads,app) # If the player didn't choose a road, refund resources and exit if not(road): player.wood += 1 player.brick += 1 return # Update the player's road and point lists player_road_update(road,player,app.pieces.all_points) # Draw the road on the board draw_road(road,player,app) # Write to log where player built road write_log(app,player.name,"built a road",vague_location(road)) # Recalculate the player's score player.calculate_score() player.road_length = check_road_length(player.roads) for guy in app.pieces.players: if guy.has_longest_road: break if player.road_length>guy.road_length and player.road_length>=5: player.has_longest_road = True guy.has_longest_road = False if player.road_length==5: write_log(app,player.name,"got the longest road bonus") elif player.road_length>5: write_log(app,player.name,"took longest road from",guy.name) player.calculate_score() guy.calculate_score() return road
def new_game(app): from random import shuffle from player import Player from tiles import Tile from os.path import isfile from catan_logic import set_tiles, roll_dice, check_winner from catan_logic import point_resources, distribute_resources from catan_logic import build_settlement, build_road, build_city from catan_logic import move_robber, discard_resources from graphics_controller import open_board_window, close_board_window from graphics_controller import close_all, redraw_board, set_players from draw_elements import draw_tiles, draw_dice from draw_menus import draw_stats, draw_log, write_log, draw_status_box from draw_menus import draw_resource_panel, clear_resource_panel from draw_menus import draw_intermediate_screen, draw_winning_screen from turn_manager import turn_loop # Set log file name and delete it if it already exists log_file_exists = False try: log_file_exists = isfile(app.pieces.log_file_name) except: pass if log_file_exists: from os import remove remove(app.pieces.log_file_name) print("Deleted old log file",app.pieces.log_file_name) # Start drawing log file to the board window draw_log(app) write_log(app,"*****New game started*****") # Set the number of players, their names, and levels of AI set_players(app) # Randomize player order shuffle(app.pieces.players) # Check to see if all players are computers for guy in app.pieces.players: if guy.AI_code<0: app.pieces.all_computers = False # Arange the tiles, then draw them to the board window app.pieces.tiles = set_tiles(app.pieces) draw_tiles(app) # Draw player stats on board window playnum = len(app.pieces.players) draw_stats(app) draw_status_box(app) # Place two settlements per player for the first turn app.pieces.turn_phase = "first placements" app.pieces.active_index = 0 for player in app.pieces.players: draw_status_box(app) # write_log(app,player.name,"build first settlement") build_settlement(player,app) # write_log(app,player.name,"build first road") build_road(player,app) app.pieces.active_index += 1 draw_stats(app) app.pieces.turn_phase = "second placements" for player in reversed(app.pieces.players): # first_round = False app.pieces.active_index -= 1 draw_stats(app) draw_status_box(app) # write_log(app,player.name,"build second settlement") point = build_settlement(player,app) # write_log(app,player.name,"build second road") build_road(player,app) resources = point_resources(point,app.pieces.tiles) for resource in resources: player.give_resource(resource) # Loop through player turns until someone wins! # Additional condition that players can only win on their turn while not(app.pieces.players[app.pieces.turn_index].index \ in check_winner(app.pieces.players)): app.pieces.loop_index += 1 app.pieces.turn_index = app.pieces.loop_index%playnum app.pieces.active_index = app.pieces.turn_index app.pieces.turn_phase = "change turns" draw_stats(app) draw_status_box(app) write_log(app,"---",app.pieces.players[app.pieces.turn_index].name, "'s turn---", sep='') # Wait screen for human players, or if all computer players if app.pieces.players[app.pieces.turn_index].AI_code<0 or \ app.pieces.all_computers: clear_resource_panel(app) draw_intermediate_screen(app.pieces.players[app.pieces.turn_index], app) app.pieces.turn_phase = "roll dice" app.pieces.dice = roll_dice(app) draw_dice(app) if sum(app.pieces.dice)!=7: distribute_resources(sum(app.pieces.dice), app.pieces.tiles,app.pieces.players) else: # Robber sequence. Start with the next player, and loop through app.pieces.turn_phase = "discard" draw_status_box(app) for player in app.pieces.players[app.pieces.turn_index+1:]: app.pieces.active_index += 1 draw_stats(app) draw_status_box(app) if player.rob_count()>0: if player.AI_code<0: clear_resource_panel(app) draw_intermediate_screen(player,app,"discard") discard_count = discard_resources(player,app) write_log(app,player.name,"was robbed of",discard_count, "resources.") app.pieces.active_index = -1 for player in app.pieces.players[:app.pieces.turn_index+1]: app.pieces.active_index += 1 draw_stats(app) draw_status_box(app) if player.rob_count()>0: if player.AI_code<0: clear_resource_panel(app) draw_intermediate_screen(player,app,"discard") discard_count = discard_resources(player,app) write_log(app,player.name,"was robbed of",discard_count, "resources.") clear_resource_panel(app) draw_stats(app) draw_status_box(app) move_robber(app.pieces.players[app.pieces.turn_index],app) app.pieces.turn_phase = "make decisions" draw_status_box(app) turn_loop(app.pieces.players[app.pieces.turn_index],app) app.pieces.turn_phase = "end game" draw_status_box(app) winner = app.pieces.turn_index write_log(app,"*****Congratulations ",app.pieces.players[winner].name, "!*****", sep='') clear_resource_panel(app) draw_stats(app) draw_winning_screen(app.pieces.players[winner],app) close_all(app)