def move(self, move): ''' Moves according the direction vectors, if it accelerates, returns the position to put a candy on :param move: a (direction, norm) tuple with direction being the tuple encoding the direction and norm being 1 for a normal move and 2 for acceleration :return: None if the snake didn't accelerate, the position to put a candy on, if it did accelerate ''' norm, direction = move.norm(), move.direction() self.on_tail = False if norm == 2: self.pop() before_last_tail = self.pop() self.add(utils.add(self.position[0], direction)) new_head = utils.add(self.position[0], direction) if self.onSnake(new_head): self.on_tail = True self.add(new_head) self.removePoints(CANDY_VAL) return before_last_tail self.pop() head = utils.add(self.head(), direction) if not utils.isOnGrid(head, self.grid_size): print head print self.id print self.position print self.bool_pos print self if self.onSnake(head): self.on_tail = True self.add(head) return None
def simple_actions(self, player): """ List of possible actions for `player`. """ snake = self.snakes.get(player) head = snake.position[0] return [m for m in MOVES if m.norm() == 1 and utils.isOnGrid(m.apply(head), self.grid_size) and snake.authorizedMove(m, possibleNorm=[1])]
def actions(self, player): """ List of possible actions for `player`. """ snake = self.snakes.get(player) head = snake.position[0] return [m for m in MOVES if utils.isOnGrid(m.apply(head), self.grid_size) and snake.authorizedMove(m)]
def onSnakeExceptLastOrNotGrid(self, pos, n): return not utils.isOnGrid(pos, self.grid_size) or \ (self.countSnake(pos) - sum(int(self.position[-i] == pos) for i in xrange(1,n+1)) >= 1)
def onSnakeOrNotGrid(self, pos): return not utils.isOnGrid(pos, self.grid_size) or self.onSnake(pos)
def oneAgentUpdate(self, id, m): #Remember changes snake_who_died = None candies_to_add = [] candies_removed = [] points_won = 0 last_tail = self.snakes[id].last_tail last_pos = [] # update positions accelerated = {} # If the snake couldn't move, then it's dead if m is None: snake_who_died = deepcopy(self.snakes[id]) else: if m.norm() == 2: last_pos.append(self.snakes[id].position[-2]) last_pos.append(self.snakes[id].position[-1]) new_candy_pos = self.snakes[id].move(m) # We remember where to add candies when the snake accelerated if new_candy_pos is not None: candies_to_add.append(new_candy_pos) # We collect candies if head touches a candy head = self.snakes[id].head() if head in self.candies: points_won += self.candies.get(head) candies_removed.append((head, self.candies.get(head))) self.snakes[id].addPoints(self.candies.get(head)) del self.candies[head] # If the snake accelerated, we check if the second part of the body touches a candy if m.norm() == 2: accelerated[id] = True second = self.snakes[id].position[1] if second in self.candies: points_won += self.candies.get(second) candies_removed.append((second, self.candies.get(second))) self.snakes[id].addPoints(self.candies.get(second)) del self.candies[second] else: accelerated[id] = False # add candies created by acceleration for cand_pos in candies_to_add: self.addCandy(cand_pos, CANDY_VAL) # remove snakes which bumped into other snakes # list of (x,y) points occupied by other snakes if snake_who_died is None and (self.onOtherSnakes(self.snakes[id].position[0], id)\ or (accelerated[id] and self.onOtherSnakes(self.snakes[id].position[1], id))\ or not utils.isOnGrid(self.snakes[id].position[0], self.grid_size)): snake_who_died = deepcopy(self.snakes[id]) if snake_who_died is not None: # add candies on the snake position before last move self.snakes[id].popleft() for p in self.snakes[id].position: if self.addCandy(p, CANDY_BONUS, dead_snake=id): candies_to_add.append(p) # print "Snake {} died with {} points".format(id, self.snakes[id].points) del self.snakes[id] return last_pos, id, candies_to_add, candies_removed, points_won, last_tail, snake_who_died
def update(self, moves): """ `moves` is a dict {snake_id => move} Update the positions/points of every snakes and check for collisions. """ self.iter += 1 deads = [] # update positions candies_to_add = [] accelerated = {} for id, m in moves.iteritems(): # If the snake couldn't move, then it's dead if m is None or not self.snakes[id].authorizedMove(m): deads.append(id) continue new_candy_pos = self.snakes[id].move(m) # We remember where to add candies when the snake accelerated if new_candy_pos is not None: candies_to_add.append(new_candy_pos) # We collect candies if head touches a candy head = self.snakes[id].head() if head in self.candies: self.snakes[id].addPoints(self.candies.get(head)) del self.candies[head] # If the snake accelerated, we check if the second part of the body touches a candy if m.norm() == 2: accelerated[id] = True second = self.snakes[id].position[1] if second in self.candies: self.snakes[id].addPoints(self.candies.get(second)) del self.candies[second] else: accelerated[id] = False # add candies created by acceleration for cand_pos in candies_to_add: self.addCandy(cand_pos, CANDY_BONUS) # remove snakes which bumped into other snakes for id in moves.keys(): # list of (x,y) points occupied by other snakes if not id in deads and (self.onOtherSnakes(self.snakes[id].position[0], id)\ or (accelerated[id] and self.onOtherSnakes(self.snakes[id].position[1], id))\ or not utils.isOnGrid(self.snakes[id].position[0], self.grid_size)): deads.append(id) # save scores and add candies rank = len(self.snakes) for id in deads: self.scores[id] = (rank, self.snakes[id].points) # add candies on the snake position before last move for p in self.snakes[id].position: self.addCandy(p, CANDY_BONUS, dead_snake=id) # print "Snake {} died with {} points".format(id, self.snakes[id].points) del self.snakes[id] if len(self.snakes) == 1: winner = self.snakes.keys()[0] self.scores[winner] = (1, self.snakes[winner].points) return self