def trade_menu(player,app): """Runs trading screen for player""" from catan_logic import perform_trade, evaluate_port_trade app.pieces.turn_phase = "trade" app.button_chosen.set(-1) while app.button_chosen.get()!=0: clear_resource_panel(app) draw_resource_panel(player,app) app.board_canvas.wait_variable(app.button_chosen) if app.button_chosen.get()==1: given_resource = app.displays.port_give_text.get() gotten_resource = app.displays.port_get_text.get() sell_resource_type = given_resource.split()[1] sell_resource_copies = int(given_resource.split()[0]) buy_resource_type = gotten_resource.split()[1] buy_resource_copies = int(gotten_resource.split()[0]) trade_successful, mul, trade_ratio = evaluate_port_trade(player,sell_resource_copies, sell_resource_type,buy_resource_copies,buy_resource_type) if trade_successful: perform_trade(player,sell_resource_type,buy_resource_type, app,mul,False,trade_ratio) app.button_chosen.set(-1)
def player_discard(player,app): """Prompts player for how many of each resource they would like to discard. They need to get down to new_resource_count""" starting_resource_count = player.resource_count() clear_resource_panel(app) draw_resource_panel(player,app) app.button_chosen.set(-1) while app.button_chosen.get()!=0: total_discard_count = app.displays.get_wood_discard() + \ app.displays.get_brick_discard() + app.displays.get_sheep_discard() + \ app.displays.get_wheat_discard() + app.displays.get_stone_discard() total_string = "Total: " + str(total_discard_count) if total_discard_count>player.rob_count(): total_string_color = "red" elif total_discard_count==player.rob_count(): total_string_color = "#309540" #green else: total_string_color = "black" app.board_canvas.itemconfig(app.displays.total_text, text=total_string, fill=total_string_color) app.board_canvas.wait_variable(app.button_chosen) app.button_chosen.set(-1) player.wood -= app.displays.get_wood_discard() player.brick -= app.displays.get_brick_discard() player.sheep -= app.displays.get_sheep_discard() player.wheat -= app.displays.get_wheat_discard() player.stone -= app.displays.get_stone_discard() discard_count = starting_resource_count - player.resource_count() return discard_count
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 player_place_robber(player,app): """Gets click of where player would like to place the robber""" clear_resource_panel(app) draw_resource_panel(player,app) app.click_x.set(int(app.style.hex_x_off-app.style.water_width)+1) app.click_y.set(int(app.style.hex_y_off-app.style.water_width)+1) available_tiles = [] for tile in app.pieces.tiles: if tile.visible and not(tile.has_robber): available_tiles.append(tile) robber_tile = Tile(0) # Wait for the player to click a valid tile for the robber while(not(robber_tile in available_tiles)): # coordinate = 0 # Draw the circles for the valid plays # (after clearing any existing circles) app.board_canvas.delete("circle") # Draw circles on available tiles for tile in available_tiles: # Get position of center of tile pos_x = (tile.vertices[0]+tile.vertices[6])/2 pos_y = (tile.vertices[1]+tile.vertices[7])/2 # Set the radius of the circle based on a third the side length r = (tile.vertices[3]-tile.vertices[1])/3 # Draw the circle app.board_canvas.create_oval(pos_x-r,pos_y-r, pos_x+r,pos_y+r, width=3, tags="circle") # Find which tile was clicked for tile in available_tiles: # Get position of center of tile pos_x = (tile.vertices[0]+tile.vertices[6])/2 pos_y = (tile.vertices[1]+tile.vertices[7])/2 # Set the radius of the circle based on a third the side length r = (tile.vertices[3]-tile.vertices[1])/3 if app.click_x.get()>pos_x-r and app.click_x.get()<pos_x+r and \ app.click_y.get()>pos_y-r and app.click_y.get()<pos_y+r: robber_tile = tile break # If the point clicked is not a legal vertex, try again if not(robber_tile in available_tiles): app.board_canvas.wait_variable(app.click_x) app.board_canvas.delete("circle") return robber_tile
def player_choose_city(player,available_points,app): """Asks player to click hex point on board to place city. Returns tuple of the placed settlement""" clear_resource_panel(app) draw_resource_panel(player,app) coordinate = placement_loop(player,available_points,app) # If the placement loop was exited early, exit this loop early too if not(coordinate): return False # Get rid of all circles app.board_canvas.delete("circle") return Point(coordinate[0],coordinate[1],coordinate[2])
def turn_loop(player,app): from catan_logic import build_settlement, build_road, build_city from catan_logic import buy_development_card from catan_logic import legal_settlement_placements, legal_road_placements from catan_AI import computer_take_turn app.pieces.turn_phase = "make decisions" draw_stats(app) clear_resource_panel(app) draw_resource_panel(app.pieces.players[app.pieces.turn_index],app) # For human players, draw buttons and get button clicks if player.AI_code<0: app.button_chosen.set(-1) while app.button_chosen.get()!=0: app.pieces.turn_phase = "make decisions" draw_stats(app) clear_resource_panel(app) draw_resource_panel(app.pieces.players[app.pieces.turn_index],app) app.board_canvas.wait_variable(app.button_chosen) if app.button_chosen.get()==1: build_settlement(player,app) elif app.button_chosen.get()==2: build_road(player,app) elif app.button_chosen.get()==3: build_city(player,app) elif app.button_chosen.get()==4: buy_development_card(player,app) elif app.button_chosen.get()==5: trade_menu(player,app) elif app.button_chosen.get()==6: development_menu(player,app) # For computer players, reference AI file else: computer_action = "none" while not(computer_action=="ended turn"): available_settlement_points = legal_settlement_placements(player, app.pieces.players,app.pieces.all_points) available_roads = legal_road_placements(player,app.pieces.players, app.pieces.all_roads) computer_action = computer_take_turn(player, available_settlement_points,available_roads,app)
def development_menu(player,app): """Runs development card screen for player""" from catan_logic import move_robber, build_road, largest_army app.button_chosen.set(-1) while app.button_chosen.get()!=0: app.pieces.turn_phase = "development" clear_resource_panel(app) draw_resource_panel(player,app) app.board_canvas.wait_variable(app.button_chosen) # Implement use of development cards here if app.button_chosen.get()==1 and player.development_cards["victory point"]!=0: player.revealed_vp += player.development_cards["victory point"] player.development_cards["victory point"] = 0 elif app.button_chosen.get()==2 and player.development_cards["knight"]!=0: move_robber(player,app) player.development_cards["knight"]-=1 player.knight_count += 1 for guy in app.pieces.players: largest_army(guy,app) elif app.button_chosen.get()==3 and player.development_cards["road building"]!=0: build_road(player,app) build_road(player,app) player.development_cards["road building"]-=1 elif app.button_chosen.get()==4 and player.development_cards["year of plenty"]!=0: player.development_cards["year of plenty"]-=1 pass elif app.button_chosen.get()==5 and player.development_cards["monopoly"]!=0: player.development_cards["monopoly"]-=1 pass for guy in app.pieces.players: guy.calculate_score() draw_stats(app) app.button_chosen.set(-1)
def player_choose_road(player,available_roads,app): """Asks player to click two hex points on board to place road between them. Returns tuples of the placed road""" clear_resource_panel(app) draw_resource_panel(player,app) road_coordinates = [] valid_road = False # Loop until player picks a valid road pair while(not(valid_road)): # Determine the places a player can legally play available_points = [] for road in available_roads: available_points.append(road.point1) available_points.append(road.point2) # Just draw points where player can connect to first point in the second # loop. Let player click on the initial point to cancel if len(road_coordinates)==1: points_to_remove = [] for point in available_points: if road_coordinates[0].adjacent_point(point) or \ road_coordinates[0]==point: continue else: points_to_remove.append(point) for point in points_to_remove: while point in available_points: available_points.remove(point) points_to_remove = [] for point in available_points: for guy in app.pieces.players: if Road(road_coordinates[0],point) in guy.roads: points_to_remove.append(point) for point in points_to_remove: available_points.remove(point) # Wait for the player to click a valid vertex coordinate = placement_loop(player,available_points,app) # If the placement loop was exited early, exit this loop early too if not(coordinate): return False # Add selected vertex to the road coordinates road_coordinates.append(Point(coordinate[0],coordinate[1], coordinate[2])) # Set variables to loop again app.click_x.set(0) app.click_y.set(0) # If there are two road coordinates, check if they make a valid road if len(road_coordinates)==2: road = Road(road_coordinates[0],road_coordinates[1]) if road.valid: for match in available_roads: if road==match: valid_road = True # If the road is not legal after all, try two new vertices if not(valid_road): road_coordinates = [] # Get rid of all circles app.board_canvas.delete("circle") 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)