snake.py 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. import cv2
  2. import numpy as np
  3. from random import randint
  4. from random import choice
  5. class SnakePart:
  6. def __init__(self, front, x, y):
  7. self.front = front
  8. self.x = x
  9. self.y = y
  10. def move(self):
  11. # Moves by following the part in front of it
  12. self.x = self.front.x
  13. self.y = self.front.y
  14. class Head:
  15. def __init__(self, direction, x, y):
  16. self.direction = direction
  17. self.x = x
  18. self.y = y
  19. def move(self):
  20. # Checks what its current direction is and moves accordingly
  21. if self.direction == 0:
  22. self.x += 1
  23. elif self.direction == 1:
  24. self.y += 1
  25. elif self.direction == 2:
  26. self.x -= 1
  27. elif self.direction == 3:
  28. self.y -= 1
  29. def display():
  30. # Create a blank image
  31. board = np.zeros([BOARD_SIZE, BOARD_SIZE, 3])
  32. # Color the snake green
  33. for part in snake:
  34. board[part.y, part.x] = [0, 255, 0]
  35. # Color the apple red
  36. board[appley, applex] = [0, 0, 255]
  37. # Display board
  38. cv2.imshow("Snake Game", np.uint8(board.repeat(CELL_SIZE, 0).repeat(CELL_SIZE, 1)))
  39. key = cv2.waitKey(int(1000/SPEED))
  40. # Return the key pressed. It is -1 if no key is pressed.
  41. return key
  42. def win_focus():
  43. # Ugly trick to get the window in focus.
  44. # Opens an image in fullscreen and then back to normal window
  45. cv2.namedWindow("Snake Game", cv2.WINDOW_AUTOSIZE);
  46. board = np.zeros([BOARD_SIZE * CELL_SIZE, BOARD_SIZE * CELL_SIZE, 3])
  47. cv2.imshow("Snake Game", board);
  48. cv2.setWindowProperty("Snake Game", cv2.WND_PROP_FULLSCREEN, cv2.WINDOW_FULLSCREEN);
  49. cv2.waitKey(2000)
  50. cv2.setWindowProperty("Snake Game", cv2.WND_PROP_FULLSCREEN, cv2.WINDOW_AUTOSIZE)
  51. if __name__ == '__main__' :
  52. # Size of each cell in the board game
  53. CELL_SIZE = 20
  54. # Number of cells along the width in the game
  55. BOARD_SIZE = 45
  56. # Change SPEED to make the game go faster
  57. SPEED = 12
  58. # After eating an apple the snake grows by GROWTH units
  59. GROWTH = 3
  60. # Variable to track if apple is eaten
  61. eaten = True
  62. # Variable to check if the game should quit
  63. quit = False
  64. # Variable to track growth.
  65. grow = 0
  66. # Array for storing snake
  67. snake = []
  68. #snake's head starts at the center of the board.
  69. head = Head(0, int((BOARD_SIZE - 1)/2), int((BOARD_SIZE - 1)/2))
  70. snake.append(head)
  71. # Start the game by printing instructions
  72. print('w = top, a = left, s = down, d = right')
  73. # Ugly trick to bring the window in focus
  74. win_focus()
  75. while True:
  76. # Checks if the apple is eaten and generates a new one
  77. if eaten:
  78. # Create a list of all possible locations
  79. s = list(range(0, BOARD_SIZE ** 2))
  80. # Delete cells that are part of the snake
  81. for part in snake:
  82. s.remove(part.x * BOARD_SIZE + part.y)
  83. # Randomly pick from one of the remaining cells
  84. a = choice(s)
  85. applex = int(a/BOARD_SIZE)
  86. appley = a % BOARD_SIZE
  87. eaten = False
  88. # Makes and displays the board
  89. key = display()
  90. # Gets key presses and moves accordingly
  91. # 8 and 27 are delete and escape keys
  92. # Arrow keys are tricky in OpenCV. So we use
  93. # keys 'w', 'a','s','d' for movement.
  94. # w = top, a = left, s = down, d = right
  95. if key == 8 or key == 27:
  96. break
  97. elif key == ord("d") :
  98. head.direction = 0
  99. elif key == ord("s") :
  100. head.direction = 1
  101. elif key == ord("a") :
  102. head.direction = 2
  103. elif key == ord("w") :
  104. head.direction = 3
  105. # Moving the snake
  106. for part in snake[::-1]:
  107. part.move()
  108. # Collision rules
  109. if head.x < 0 or head.x > BOARD_SIZE - 1 or head.y < 0 or head.y > BOARD_SIZE - 1:
  110. break
  111. for part in snake[1:]:
  112. if head.x == part.x and head.y == part.y:
  113. quit = True
  114. break
  115. if quit:
  116. break
  117. # The snake grows graduallly over multiple frames
  118. if grow > 0:
  119. snake.append(SnakePart(snake[-1], subx, suby))
  120. grow -= 1
  121. # Grows the snake when it eats an apple
  122. if applex == head.x and appley == head.y:
  123. subx = snake[-1].x
  124. suby = snake[-1].y
  125. eaten = True
  126. grow += GROWTH