Ejemplo n.º 1
0
class Game:
	"""The game of Snake."""

	def __init__(self, height, width, speed, placeObstacles=False):
		# Integer height of the plane
		self.height = height
		# Integer width of the plane
		self.width = width
		# Integer delay between frames of the of the game
		self.speed = speed
		# Integer score that is the length of the snake
		self.score = 0
		# The snake, starting on the left side of the plane
		self.snake = Snake(Square(height // 2, width // 2, self.width))
		# Boolean indicating whether to place obstacles or not
		self.placeObstacles = placeObstacles
		# Set of squares representing obstacles
		self.obstacles = set()
		# Square representing the food
		self.food = None

	def play(self):
		"""Play the game."""
		previousDirection = None
		listener = KeyListener()

		# Start the key listener
		listener.start()
		# Get the command for clearing the screen (dependent on OS)
		clearScreen = "cls" if platform.system() == "Windows" else "clear"
		# Place the first food
		self.placeFood()

		# Main game loop
		while not self.gameOver() and not listener.quit:
			# Display the game
			os.system(clearScreen)
			self.display(listener.paused)

			# Delay movement for the specified time
			time.sleep(self.speed)

			# Update the current direction
			currentDirection = listener.direction

			# Snake cannot immediately reverse direction
			if currentDirection == Direction.opposite(previousDirection):
				currentDirection = previousDirection

			# Move the snake if not paused
			if not listener.paused:
				self.move(currentDirection)

			# Store previous direction
			previousDirection = currentDirection

		# End the key listener
		listener.end()

		# Pause for 1 second
		time.sleep(1)

	def move(self, currentDirection):
		"""Move the snake."""
		next = self.nextSquare(currentDirection)

		if next:
			# Snake gets a food and grows by 1 square
			if next == self.food:
				self.snake.grow(next)
				self.placeFood()
				if self.placeObstacles:
					self.placeObstacle()

				self.score += 1
			# Snake moves to next square
			else:
				self.snake.advance(next)

	def display(self, paused):
		"""Display the game.

		paused -- boolean indicating whether the game is paused
		"""
		string = ""

		pausedString = "| PAUSED |"
		pausedString = pausedString if len(pausedString) + 2 <= self.width and paused else ""
		string += "+" + pausedString.center(self.width, "-") + "+\n"

		for row in reversed(range(self.height)):
			string += "|"
			for column in range(self.width):
				# Print the snake
				if Square(row, column, self.width) in self.snake:
					string += "O"
				# Print an obstacle
				elif Square(row, column, self.width) in self.obstacles:
					string += "&"
				# Print the food
				elif Square(row, column, self.width) == self.food:
					string += "+"
				# Print an empty space
				else:
					string += " "
			string += "|\n"

		# Display the score in the bottom border
		scoreString = "| SCORE: " + str(self.score) + " |"
		scoreString = scoreString if len(scoreString) + 2 <= self.width else "| " + str(self.score) + " |"
		string += "+" + scoreString.center(self.width, "-") + "+\n"

		print(string)

	def gameOver(self):
		"""Return whether the game is over."""
		head = self.snake.head()

		# Snake is out of bounds
		if head.x < 0 or head.x >= self.height or head.y < 0 or head.y >= self.width:
			return True
		# Snake has run into itself
		elif head in self.snake.snake[:-1]:
			return True
		# Snake has run into an obstacle
		elif head in self.obstacles:
			return True
		else:
			return False

	def nextSquare(self, currentDirection):
		"""Return the next square based off the snake's direction."""
		head = self.snake.head()

		if currentDirection == Direction.UP:
			return head.up()
		elif currentDirection == Direction.LEFT:
			return head.left()
		elif currentDirection == Direction.DOWN:
			return head.down()
		elif currentDirection == Direction.RIGHT:
			return head.right()

	def placeFood(self):
		"""Place the food on a random square on the plane."""
		x = random.randint(0, self.height - 1)
		y = random.randint(0, self.width - 1)

		food = Square(x, y, self.width)

		# Make sure not to place the food on the snake or an obstacle
		while food in self.snake or food in self.obstacles:
			x = random.randint(0, self.height - 1)
			y = random.randint(0, self.width - 1)

			food = Square(x, y, self.width)

		self.food = food

	def placeObstacle(self):
		"""Place an obstacle on a random square on the plane."""
		x = random.randint(0, self.height - 1)
		y = random.randint(0, self.width - 1)

		obstacle = Square(x, y, self.width)

		# Make sure not to place the obstacle on the snake or food
		while obstacle in self.snake or obstacle == self.food:
			x = random.randint(0, self.height - 1)
			y = random.randint(0, self.width - 1)

			obstacle = Square(x, y, self.width)

		self.obstacles.add(obstacle)