Skip to content

Commit

Permalink
Made requested changes
Browse files Browse the repository at this point in the history
  • Loading branch information
brandongasser committed Jan 3, 2024
1 parent 897ec85 commit d2cd458
Show file tree
Hide file tree
Showing 7 changed files with 49 additions and 66 deletions.
42 changes: 13 additions & 29 deletions base_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,10 @@ def first_turn_init(self, world, avatar):
self.company = avatar.company
self.my_station_type = ObjectType.TURING_STATION if self.company == Company.TURING else ObjectType.CHURCH_STATION
self.current_state = State.MINING
self.base_position = self.find_all_by_type(world, self.my_station_type)[0]
self.base_position = world.get_objects(self.my_station_type)[0][0]

# This is where your AI will decide what to do
def take_turn(self, turn: int, actions: ActionType, world, avatar):
def take_turn(self, turn, actions, world, avatar):
"""
This is where your AI will decide what to do.
:param turn: The current turn of the game.
Expand All @@ -44,23 +44,30 @@ def take_turn(self, turn: int, actions: ActionType, world, avatar):

current_tile = world.game_map[avatar.position.y][avatar.position.x] # set current tile to the tile that I'm standing on

# If I start the turn on my station, I should start mining
# If I start the turn on my station, I should...
if current_tile.occupied_by.object_type == self.my_station_type:
# buy Improved Mining tech if I can...
if avatar.science_points >= avatar.get_tech_info('Improved Drivetrain').cost and not avatar.is_researched('Improved Drivetrain'):
return [ActionType.BUY_IMPROVED_DRIVETRAIN]
# otherwise set my state to mining
self.current_state = State.MINING

# If I have at least 5 items in my inventory, set my state to selling
if len([item for item in world.inventory_manager.get_inventory(self.company) if item is not None]) >= 5:
self.current_state = State.SELLING

# Make action decision for this turn
if self.current_state == State.SELLING:
# actions = [ActionType.MOVE_LEFT if self.company == Company.TURING else ActionType.MOVE_RIGHT] # If I'm selling, move towards my base
actions = self.generate_moves(avatar.position, self.base_position, turn % 2 == 0)
else:
if current_tile.occupied_by.object_type == ObjectType.ORE_OCCUPIABLE_STATION:
# If I'm mining and I'm standing on an ore, mine it and set my state to selling
# If I'm mining and I'm standing on an ore, mine it
actions = [ActionType.MINE]
self.current_state = State.SELLING
else:
# If I'm mining and I'm not standing on an ore, move randomly
actions = [random.choice([ActionType.MOVE_LEFT, ActionType.MOVE_RIGHT, ActionType.MOVE_UP, ActionType.MOVE_DOWN])]

return actions

def generate_moves(self, start_position, end_position, vertical_first):
Expand All @@ -79,26 +86,3 @@ def generate_moves(self, start_position, end_position, vertical_first):
vertical = [ActionType.MOVE_UP] * -dy if dy < 0 else [ActionType.MOVE_DOWN] * dy

return vertical + horizontal if vertical_first else horizontal + vertical

def find_all_by_type(self, world, object_type):
"""
Finds all tiles on the board with the given object_type
:param world: Generic world information
:param object_type: The desired object type
:return: List of all Vectors for positions with Tiles with the object type
"""
return self.find_all(world, lambda tile: tile.occupied_by is not None and tile.occupied_by.object_type == object_type)

def find_all(self, world, criteria):
"""
Finds all tiles on the board that match the given criteria
:param world: Generic world information
:param criteria: The required criteria as a function that takes a Tile and returns a bool
:return: List of all Vectors for positions with Tiles that meet the criteria
"""
result = []
for y in range(len(world.game_map)):
for x in range(len(world.game_map[y])):
if criteria(world.game_map[y][x]):
result.append(Vector(x=x, y=y))
return result
42 changes: 13 additions & 29 deletions base_client_2.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,10 @@ def first_turn_init(self, world, avatar):
self.company = avatar.company
self.my_station_type = ObjectType.TURING_STATION if self.company == Company.TURING else ObjectType.CHURCH_STATION
self.current_state = State.MINING
self.base_position = self.find_all_by_type(world, self.my_station_type)[0]
self.base_position = world.get_objects(self.my_station_type)[0][0]

# This is where your AI will decide what to do
def take_turn(self, turn: int, actions: ActionType, world, avatar):
def take_turn(self, turn, actions, world, avatar):
"""
This is where your AI will decide what to do.
:param turn: The current turn of the game.
Expand All @@ -44,23 +44,30 @@ def take_turn(self, turn: int, actions: ActionType, world, avatar):

current_tile = world.game_map[avatar.position.y][avatar.position.x] # set current tile to the tile that I'm standing on

# If I start the turn on my station, I should start mining
# If I start the turn on my station, I should...
if current_tile.occupied_by.object_type == self.my_station_type:
# buy Improved Mining tech if I can...
if avatar.science_points >= avatar.get_tech_info('Improved Drivetrain').cost and not avatar.is_researched('Improved Drivetrain'):
return [ActionType.BUY_IMPROVED_DRIVETRAIN]
# otherwise set my state to mining
self.current_state = State.MINING

# If I have at least 5 items in my inventory, set my state to selling
if len([item for item in world.inventory_manager.get_inventory(self.company) if item is not None]) >= 5:
self.current_state = State.SELLING

# Make action decision for this turn
if self.current_state == State.SELLING:
# actions = [ActionType.MOVE_LEFT if self.company == Company.TURING else ActionType.MOVE_RIGHT] # If I'm selling, move towards my base
actions = self.generate_moves(avatar.position, self.base_position, turn % 2 == 0)
else:
if current_tile.occupied_by.object_type == ObjectType.ORE_OCCUPIABLE_STATION:
# If I'm mining and I'm standing on an ore, mine it and set my state to selling
# If I'm mining and I'm standing on an ore, mine it
actions = [ActionType.MINE]
self.current_state = State.SELLING
else:
# If I'm mining and I'm not standing on an ore, move randomly
actions = [random.choice([ActionType.MOVE_LEFT, ActionType.MOVE_RIGHT, ActionType.MOVE_UP, ActionType.MOVE_DOWN])]

return actions

def generate_moves(self, start_position, end_position, vertical_first):
Expand All @@ -79,26 +86,3 @@ def generate_moves(self, start_position, end_position, vertical_first):
vertical = [ActionType.MOVE_UP] * -dy if dy < 0 else [ActionType.MOVE_DOWN] * dy

return vertical + horizontal if vertical_first else horizontal + vertical

def find_all_by_type(self, world, object_type):
"""
Finds all tiles on the board with the given object_type
:param world: Generic world information
:param object_type: The desired object type
:return: List of all Vectors for positions with Tiles with the object type
"""
return self.find_all(world, lambda tile: tile.occupied_by is not None and tile.occupied_by.object_type == object_type)

def find_all(self, world, criteria):
"""
Finds all tiles on the board that match the given criteria
:param world: Generic world information
:param criteria: The required criteria as a function that takes a Tile and returns a bool
:return: List of all Vectors for positions with Tiles that meet the criteria
"""
result = []
for y in range(len(world.game_map)):
for x in range(len(world.game_map[y])):
if criteria(world.game_map[y][x]):
result.append(Vector(x=x, y=y))
return result
16 changes: 11 additions & 5 deletions game/common/avatar.py
Original file line number Diff line number Diff line change
Expand Up @@ -301,7 +301,8 @@ def __unlock_trap_defusal(self) -> None:

# Helper method to create a dictionary that stores bool values for which abilities the player unlocked
def __create_abilities_dict(self) -> dict:
abilities = {'Improved Drivetrain': False,
abilities = {'Mining Robotics': True,
'Improved Drivetrain': False,
'Superior Drivetrain': False,
'Overdrive Drivetrain': False,
'Improved Mining': False,
Expand Down Expand Up @@ -336,9 +337,6 @@ def buy_new_tech(self, tech_name: str) -> bool:

return successful

def get_tech_tree(self) -> TechTree:
return self.__tech_tree

def is_researched(self, tech_name: str) -> bool:
"""Returns if the given tech was researched."""
return self.__tech_tree.is_researched(tech_name)
Expand All @@ -350,6 +348,13 @@ def get_researched_techs(self) -> list[str]:
def get_all_tech_names(self) -> list[str]:
"""Returns a list of all possible tech names in a Tech Tree."""
return self.__tech_tree.tech_names()

def get_tech_info(self, tech_name: str) -> TechInfo | None:
"""
Returns a TechInfo object about the tech with the given name if the tech is found in the tree.
Returns None if the tech isn't found
"""
return self.__tech_tree.tech_info(tech_name)

# Dynamite placing functionality ----------------------------------------------------------------------------------
# if avatar calls place dynamite, set to true, i.e. they want to place dynamite
Expand Down Expand Up @@ -393,7 +398,8 @@ def from_json(self, data: dict) -> Self:
self.movement_speed = data['movement_speed']
self.drop_rate = data['drop_rate']
self.abilities = data['tech_tree']
self.__tech_tree = data['tech_tree']
self.__tech_tree = self.__create_tech_tree()
self.__tech_tree.from_json(data['tech_tree'])
self.dynamite_active_ability = DynamiteActiveAbility().from_json(data['dynamite_active_ability'])
self.landmine_active_ability = LandmineActiveAbility().from_json(data['landmine_active_ability'])
self.emp_active_ability = EMPActiveAbility().from_json(data['emp_active_ability'])
Expand Down
2 changes: 1 addition & 1 deletion game/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@

MAX_SECONDS_PER_TURN = 0.1 # max number of basic operations clients have for their turns

MAX_NUMBER_OF_ACTIONS_PER_TURN = 1000 # master_controller will be handling max actions enforcement for Byte-le 2024 "Quarry Rush"
MAX_NUMBER_OF_ACTIONS_PER_TURN = 5 # master_controller will be handling max actions enforcement for Byte-le 2024 "Quarry Rush"

MIN_CLIENTS_START = None # minimum number of clients required to start running the game; should be None when SET_NUMBER_OF_CLIENTS is used
MAX_CLIENTS_START = None # maximum number of clients required to start running the game; should be None when SET_NUMBER_OF_CLIENTS is used
Expand Down
3 changes: 2 additions & 1 deletion game/controllers/buy_tech_controller.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,8 @@ def handle_actions(self, action: ActionType, client: Player, world: GameBoard):
case ActionType.BUY_TRAP_DEFUSAL:
tech_name = 'Trap Defusal'

client.avatar.buy_new_tech(tech_name) # buy the tech specified
if tech_name != '':
client.avatar.buy_new_tech(tech_name) # buy the tech specified

def __is_on_home_base(self, client: Player, world: GameBoard):
avatar_pos: Vector = client.avatar.position # get the position of the avatar
Expand Down
8 changes: 8 additions & 0 deletions game/controllers/master_controller.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
from game.controllers.controller import Controller
from game.controllers.interact_controller import InteractController
from game.controllers.mine_controller import MineController
from game.controllers.buy_tech_controller import BuyTechController
from game.controllers.place_controller import PlaceController
from game.common.map.game_board import GameBoard
from game.config import MAX_NUMBER_OF_ACTIONS_PER_TURN
from game.utils.vector import Vector
Expand Down Expand Up @@ -63,6 +65,8 @@ def __init__(self):
self.dynamite_controller: DynamiteController = DynamiteController()
self.defuse_controller: DefuseController = DefuseController()
self.mine_controller: MineController = MineController()
self.buy_tech_controller: BuyTechController = BuyTechController()
self.place_controller: PlaceController = PlaceController()

# Receives all clients for the purpose of giving them the objects they will control
def give_clients_objects(self, clients: list[Player], world: dict):
Expand Down Expand Up @@ -139,6 +143,10 @@ def turn_logic(self, clients: list[Player], turn):
'game_board'])
self.defuse_controller.handle_actions(client.actions[i], client, self.current_world_data[
'game_board'])
self.buy_tech_controller.handle_actions(client.actions[i], client, self.current_world_data[
'game_board'])
self.place_controller.handle_actions(client.actions[i], client, self.current_world_data[
'game_board'])
except IndexError:
pass

Expand Down
2 changes: 1 addition & 1 deletion game/quarry_rush/entity/ancient_tech.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,6 @@ class AncientTech(Item):
"""
Class for generic Ancient Tech item
"""
def __init__(self, science_point_value: int = 1, quantity: int = 1, stack_size: int = 1, durability: int | None = None, position: Vector | None = None, name: str | None = None):
def __init__(self, science_point_value: int = 10, quantity: int = 1, stack_size: int = 1, durability: int | None = None, position: Vector | None = None, name: str | None = None):
super().__init__(0, science_point_value, quantity, stack_size, durability, position, name)
self.object_type = ObjectType.ANCIENT_TECH

0 comments on commit d2cd458

Please sign in to comment.