Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #NOTE: every cell is just a list. When empty, that cell-list is [None] (not []). This way we can pass a reference to a cell around and change the cell-list without having to remember co-ordinates, or have a dedicated cell datastructure.
- def _fix_overfull_cell(self, cell_list):
- #-TODO: Docstrings? How are they supposed to be written?
- # takes a reference to a cell's contents list -- so we can change it in this function and grid's referenced version will be changed too
- if length(cell_list) > 1:
- #make a list that contains all bots in cell that moved there this turn
- bots_to_move_back = filter(lambda bot:(bot.has_moved == 1), cell) #-TODO:will throw a AttributeError if there's food/wall in this cell. Might want to raise our own error, and catch the AttributeError if only to have informative crash messages.
- for bot in bots_to_move_back:
- self.grid.move(bot, bot.last_position)
- bot.has_moved = -1
- #-TODO replace with setter, raise actionfailed error with bot when set to -1
- for bot in bots_to_move_back:
- self._fix_overfull_cell(bot.position) #check the cell into which we just moved them
- def _is_stationary(self, cell_element):
- if cell_element == 'WALL':
- return True
- elif cell_element == None:
- return False
- elif cell_element.__class__ == #-TODO fill in ref to Food class
- return True
- elif cell_element.__class__ == #-TODO fill in ref to Bot class
- return (not cell_element.get_action_type() == 'move') or (cell_element.has_moved == -1)
- #other team bots will count as stationary; their action is None
- #truth table -- bots that have been unmoved are stationary (has_moved == -1)
- #has_moved == -1 | action == 'move' | not action == 'move' | desired return value
- # 1 | 1 | 0 | 1
- # 0 | 1 | 0 | 0
- # 0 | 0 | 1 | 1
- else:
- assert False, "World._is_stationary doesn't recognize cell_element: ", cell_element
- def _is_valid_attack_target(self, bot, target):
- """Checks if action 'attack' parameters from brain are acceptable
- Arguments:
- bot -- the bot trying to take the action
- target -- the cell_entity bot is trying to take the action on
- Returns True if target is within range, and is bot
- Returns False otherwise
- """
- try:
- if #-TODO:How to find distance between target and bot?
- #if target is on enemy team and cell_element is within range, return true
- except AttributeError:
- return False
- def _is_valid_move_target(self, #-TODO: check if input gives illegal distance to move
- def _is_valid_harvest_target(self, bot, target):
- #-TODO: decide how mining will work
- pass
- def _is_valid_reproduce_target(self):
- #-TODO: decide how reproduce will work
- pass
- def _is_valid_message(self, action_params):
- #-TODO: write/design message
- pass
- #-TODO make this a public method of grid
- def grid.move(self, bot, destination_cell_list):
- bot.last_position = bot.position
- bot.position = destination_cell_list
- self.add_to_cell(destination_cell_list, bot) #-TODO implement this, remove None when filling empty cell.
- self.remove_from_cell(bot.last_position, bot) #-TODO implement this, add None to empty cells
- # world logic
- # Apply and check action loop
- for bot in self._current_team:
- #-TODO we should do this in start-turn or end-turn cleanup. Just putting it here so we don't forget.
- bot.has_moved = None
- action_type = bot.get_action_type() #-TODO:Change to just get_action, with a tuple
- action_params = bot.get_action_params()
- if action_type == 'move':
- dest_cell_list = action_params
- if filter(self._is_valid_move_target(bot.position, ###dest_cell_list element###), dest_cell_list).length > 0: #-TODO: How to pass functions as arguments, but with one parameter already filled?
- ###The above replaces: if filter(self._is_stationary(), dest_cell_list).length > 0: pass
- #NOTE: Moving into same cell as a bot that has moved or is going to move MUST be allowed, because that bot might have to move forward or backwards. And we don't want the first bot we iterate over to get precedence. We want to disallow either one from moving.
- bot.has_moved = -1
- else:
- self.grid.move(bot, dest_cell_list)
- bot.has_moved = 1
- elif action_type == 'attack':
- pass
- elif action_type == 'harvest':
- pass
- elif action_type == 'reproduce':
- pass
- elif action_type == 'send':
- pass
- else:
- #-TODO: send error to bot brain
- pass
- # Undo illegal moves
- for cell in self.grid:
- self._fix_overfull_cell(cell)
- #-TODO: Cleanup loop. Set lots of bot properties to None. action, has_moved, last_position, any others?
- #-TODO: new public methods/fields:
- #BOT
- #bot.position -- is a reference to bot's current cell-list
- # rename to current_cell
- #bot.last_position -- basically, should just be set to None. We only use it in the apply/check action loop and the undo illegal move loop
- # rename to previous_cell
- #bot.has_moved -- None if action isn't move
- # -1 if bot has been moved back or had move fail
- # 0 if bot hasn't tried to move yet, but intends to
- # 1 if bot has moved, and hasn't been moved back yet
- # should change name to move_state since not boolean; 4 possible values
- #bot.getTeam()
- #mechanism for sending failed action notifications
- # Should maybe replace with getter and setter methods?
- #WORLD
- #world.kill_bot(bot), removes bot from player botlist and grid (using grid.remove_from_cell(cellentity))
- #GRID
- #grid.add_to_cell(cellentity)
- #grid.remove_from_cell(cellentity)
- #make grid an iterable object, returning each cell in no particular order.
- #make each cell a list of its contents. If empty, it should be [None] not []
- #GLOBAL CONSTANTS
- #has_moved: -1 = DEMOVED, 1 = MOVED, 0 = WILLMOVE
- #bot.actions: MOVE, etc...
- #bot move distance (BOT_MOVE_DISTANCE)
- #bot transmit distance (BOT_SEND_DISTANCE)
Add Comment
Please, Sign In to add comment