Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- from modules.searching_framework import Problem, breadth_first_graph_search, astar_search, uniform_cost_search
- from typing import List, Tuple
- from enum import Enum
- import sys
- import bisect
- class Direction(Enum):
- UP = 1
- RIGHT = 2
- DOWN = 3
- LEFT = 4
- class Snake:
- def __init__(self, s, red: List[Tuple[int, int]], green: List[Tuple[int, int]], direction: Direction, head,
- steps_till_here: int):
- self.snake = s
- self.red = red
- self.green = green
- self.direction = direction
- self.head = head
- self.steps_till_here = steps_till_here
- @classmethod
- def from_self(cls, other: 'Snake'):
- snake_copy = other.snake[:]
- red = other.red[:]
- green = other.green[:]
- return Snake(snake_copy, red, green, other.direction, other.head, other.steps_till_here)
- def change_direction_left(self):
- if self.direction == Direction.UP:
- self.direction = Direction.LEFT
- if self.direction == Direction.LEFT:
- self.direction = Direction.DOWN
- if self.direction == Direction.DOWN:
- self.direction = Direction.RIGHT
- if self.direction == Direction.RIGHT:
- self.direction = Direction.UP
- def change_direction_right(self):
- if self.direction == Direction.UP:
- self.direction = Direction.RIGHT
- if self.direction == Direction.RIGHT:
- self.direction = Direction.DOWN
- if self.direction == Direction.DOWN:
- self.direction = Direction.LEFT
- if self.direction == Direction.LEFT:
- self.direction = Direction.UP
- def check_obstacles_hit(self, prospect_head):
- if not (0, 0) <= prospect_head < (10, 10):
- return True
- if prospect_head in self.snake[:-1]:
- return True
- if prospect_head in self.red:
- return True
- return False
- def peek_straight(self):
- if self.direction == Direction.UP:
- self.head = (self.snake[-1][0] - 1, self.snake[-1][1])
- return self.check_obstacles_hit(self.head)
- if self.direction == Direction.DOWN:
- self.head = (self.snake[-1][0] + 1, self.snake[-1][1])
- return self.check_obstacles_hit(self.head)
- if self.direction == Direction.RIGHT:
- self.head = (self.snake[-1][0], self.snake[-1][1] + 1)
- return self.check_obstacles_hit(self.head)
- if self.direction == Direction.LEFT:
- self.head = (self.snake[-1][0], self.snake[-1][1] - 1)
- return self.check_obstacles_hit(self.head)
- def peek_left(self):
- if self.direction == Direction.UP:
- self.head = (self.snake[-1][0], self.snake[-1][1] - 1)
- return self.check_obstacles_hit(self.head)
- if self.direction == Direction.DOWN:
- self.head = (self.snake[-1][0], self.snake[-1][1] + 1)
- return self.check_obstacles_hit(self.head)
- if self.direction == Direction.RIGHT:
- self.head = (self.snake[-1][0] - 1, self.snake[-1][1])
- return self.check_obstacles_hit(self.head)
- if self.direction == Direction.LEFT:
- self.head = (self.snake[-1][0] + 1, self.snake[-1][1])
- return self.check_obstacles_hit(self.head)
- def peek_right(self):
- if self.direction == Direction.UP:
- self.head = (self.snake[-1][0], self.snake[-1][1] + 1)
- return self.check_obstacles_hit(self.head)
- if self.direction == Direction.DOWN:
- self.head = (self.snake[-1][0], self.snake[-1][1] - 1)
- return self.check_obstacles_hit(self.head)
- if self.direction == Direction.RIGHT:
- self.head = (self.snake[-1][0] + 1, self.snake[-1][1])
- return self.check_obstacles_hit(self.head)
- if self.direction == Direction.LEFT:
- self.head = (self.snake[-1][0] - 1, self.snake[-1][1])
- return self.check_obstacles_hit(self.head)
- def green_eaten(self):
- for g in self.green:
- if g == self.head:
- self.green.remove(g)
- return True
- return False
- def move(self):
- if self.green_eaten():
- new_snake = self.snake[0:]
- else:
- new_snake = self.snake[1:]
- new_snake.append(self.head)
- self.snake = new_snake
- self.steps_till_here += 1
- def all_green_eaten(self):
- return len(self.green) == 2 # 0
- def score(self):
- return self.steps_till_here
- def get_snake_head(self):
- return self.snake[-1]
- def __eq__(self, other):
- return isinstance(other, Snake) and \
- self.snake == other.snake and \
- self.green == other.green and \
- self.direction == other.direction and \
- self.head == other.head and \
- self.steps_till_here == other.steps_till_here
- def __lt__(self, other):
- return self.score() < other.score()
- def __gt__(self, other):
- return self.score() > other.score()
- def __hash__(self):
- return hash(self.score())
- class SnakeProblem(Problem):
- def __init__(self, initial: Snake):
- super().__init__(initial, None)
- def goal_test(self, state):
- return state.all_green_eaten()
- def successor(self, state):
- successors = dict()
- straight = Snake.from_self(state)
- if not straight.peek_straight():
- straight.move()
- successors['ContinueStraight'] = straight
- left = Snake.from_self(state)
- if not left.peek_left():
- left.move()
- left.change_direction_left()
- successors['TurnLeft'] = left
- right = Snake.from_self(state)
- if not right.peek_right():
- right.move()
- right.change_direction_right()
- successors['TurnRight'] = right
- return successors
- def actions(self, state):
- return self.successor(state).keys()
- def result(self, state, action):
- possible = self.successor(state)
- return possible[action]
- def value(self):
- pass
- if __name__ == '__main__':
- n = int(input())
- green_apples = [tuple(map(int, input().split(','))) for _ in range(n)]
- m = int(input())
- red_apples = [tuple(map(int, input().split(','))) for _ in range(m)]
- snake = Snake([(0, 0), (2, 0), (3, 0)], red_apples, green_apples, Direction.DOWN, (3, 0), 0)
- snakeProblem = SnakeProblem(snake)
- answer = breadth_first_graph_search(snakeProblem)
- # answer = uniform_cost_search(snakeProblem)
- print(answer.solution())
- print(answer.solve().get_snake_head())
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement