Advertisement
al33kappa

Untitled

Jun 6th, 2018
135
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.08 KB | None | 0 0
  1. from tkinter import*
  2. from random import randint
  3.  
  4. # constants that go in the making of the grid used for the snake's movment
  5. GRADUATION = 40
  6. PIXEL = 10
  7. STEP = 2 * PIXEL
  8. WD = PIXEL * GRADUATION
  9. HT = PIXEL * GRADUATION
  10. # constants that go into specifying the shapes' sizes
  11. OB_SIZE_FACTOR = 1
  12. SN_SIZE_FACTOR = 0.9
  13. OB_SIZE = PIXEL * OB_SIZE_FACTOR
  14. SN_SIZE = PIXEL * SN_SIZE_FACTOR
  15. # color constants
  16. BG_COLOR = 'black'
  17. OB_COLOR = 'red'
  18. SN_COLOR = 'white'
  19. # a dictionary to ease access to a shape's type in the Shape class
  20. SN = 'snake'
  21. OB = 'obstacle'
  22. SIZE = {SN: SN_SIZE, OB: OB_SIZE}
  23. # constants for keyboard input
  24. UP = 'Up'
  25. DOWN = 'Down'
  26. RIGHT = 'Right'
  27. LEFT = 'Left'
  28. # a dictionary to ease access to 'directions'
  29. DIRECTIONS = {UP: [0, -1], DOWN: [0, 1], RIGHT: [1, 0], LEFT: [-1, 0]}
  30. AXES = {UP: 'Vertical', DOWN: 'Vertical', RIGHT: 'Horizontal', LEFT: 'Horizontal'}
  31. # refresh time for the perpetual motion
  32. REFRESH_TIME = 100
  33.  
  34.  
  35. class Master(Canvas):
  36. """create the game canvas, the snake, the obstacle, keep track of the score"""
  37. def __init__(self, boss=None):
  38. super().__init__(boss)
  39. self.configure(width=WD, height=HT, bg=BG_COLOR)
  40. self.running = 0
  41. self.snake = None
  42. self.obstacle = None
  43. self.direction = None
  44. self.current = None
  45. self.score = Scores(boss)
  46.  
  47. def start(self):
  48. """start snake game"""
  49. if self.running == 0:
  50. self.snake = Snake(self)
  51. self.obstacle = Obstacle(self)
  52. self.direction = RIGHT
  53. self.current = Movement(self, RIGHT)
  54. self.current.begin()
  55. self.running = 1
  56.  
  57. def clean(self):
  58. """restarting the game"""
  59. if self.running == 1:
  60. self.score.reset()
  61. self.current.stop()
  62. self.running = 0
  63. self.obstacle.delete()
  64. for block in self.snake.blocks:
  65. block.delete()
  66.  
  67. def redirect(self, event):
  68. """taking keyboard inputs and moving the snake accordingly"""
  69. if 1 == self.running and \
  70. event.keysym in AXES.keys() and\
  71. AXES[event.keysym] != AXES[self.direction]:
  72. self.current.flag = 0
  73. self.direction = event.keysym
  74. self.current = Movement(self, event.keysym) # a new instance at each turn to avoid confusion/tricking
  75. self.current.begin() # program gets tricked if the user presses two arrow keys really quickly
  76.  
  77.  
  78. class Scores:
  79. """Objects that keep track of the score and high score"""
  80. def __init__(self, boss=None):
  81. self.counter = StringVar(boss, '0')
  82. self.maximum = StringVar(boss, '0')
  83.  
  84. def increment(self):
  85. score = int(self.counter.get()) + 1
  86. maximum = max(score, int(self.maximum.get()))
  87. self.counter.set(str(score))
  88. self.maximum.set(str(maximum))
  89.  
  90. def reset(self):
  91. self.counter.set('0')
  92.  
  93.  
  94. class Shape:
  95. """This is a template to make obstacles and snake body parts"""
  96. def __init__(self, can, a, b, kind):
  97. self.can = can
  98. self.x, self.y = a, b
  99. self.kind = kind
  100. if kind == SN:
  101. self.ref = Canvas.create_rectangle(self.can,
  102. a - SN_SIZE, b - SN_SIZE,
  103. a + SN_SIZE, b + SN_SIZE,
  104. fill=SN_COLOR,
  105. width=2)
  106. elif kind == OB:
  107. self.ref = Canvas.create_oval(self.can,
  108. a - OB_SIZE, b - OB_SIZE,
  109. a + SN_SIZE, b + SN_SIZE,
  110. fill=OB_COLOR,
  111. width=2)
  112.  
  113. def modify(self, a, b):
  114. self.x, self.y = a, b
  115. self.can.coords(self.ref,
  116. a - SIZE[self.kind], b - SIZE[self.kind],
  117. a + SIZE[self.kind], b + SIZE[self.kind])
  118.  
  119. def delete(self):
  120. self.can.delete(self.ref)
  121.  
  122.  
  123. class Obstacle(Shape):
  124. """snake food"""
  125. def __init__(self, can):
  126. """only create the obstacles where there is no snake body part"""
  127. self.can = can
  128. p = int(GRADUATION/2 - 1)
  129. n, m = randint(0, p), randint(0, p)
  130. a, b = PIXEL * (2 * n + 1), PIXEL * (2 * m + 1)
  131. while [a, b] in [[block.x, block.y] for block in self.can.snake.blocks]:
  132. n, m = randint(0, p), randint(0, p)
  133. a, b = PIXEL * (2 * n + 1), PIXEL * (2 * m + 1)
  134. super().__init__(can, a, b, OB)
  135.  
  136.  
  137. class Block(Shape):
  138. """snake body part"""
  139. def __init__(self, can, a, y):
  140. super().__init__(can, a, y, SN)
  141.  
  142.  
  143. class Snake:
  144. """a snake keeps track of its body parts"""
  145. def __init__(self, can):
  146. """initial position chosen by me"""
  147. self.can = can
  148. a = PIXEL + 2 * int(GRADUATION/4) * PIXEL
  149. self.blocks = [Block(can, a, a), Block(can, a, a + STEP)]
  150.  
  151. def move(self, path):
  152. """an elementary step consisting of putting the tail of the snake in the first position"""
  153. a = (self.blocks[-1].x + STEP * path[0]) % WD
  154. b = (self.blocks[-1].y + STEP * path[1]) % HT
  155. if a == self.can.obstacle.x and b == self.can.obstacle.y: # check if we find food
  156. self.can.score.increment()
  157. self.can.obstacle.delete()
  158. self.blocks.append(Block(self.can, a, b))
  159. self.can.obstacle = Obstacle(self.can)
  160. elif [a, b] in [[block.x, block.y] for block in self.blocks]: # check if we hit a body part
  161. self.can.clean()
  162. else:
  163. self.blocks[0].modify(a, b)
  164. self.blocks = self.blocks[1:] + [self.blocks[0]]
  165.  
  166.  
  167. class Movement:
  168. """object that enters the snake into a perpetual state of motion in a predefined direction"""
  169. def __init__(self, can, direction):
  170. self.flag = 1
  171. self.can = can
  172. self.direction = direction
  173.  
  174. def begin(self):
  175. """start the perpetual motion"""
  176. if self.flag > 0:
  177. self.can.snake.move(DIRECTIONS[self.direction])
  178. self.can.after(REFRESH_TIME, self.begin)
  179.  
  180. def stop(self):
  181. """stop the perpetual movement"""
  182. self.flag = 0
  183.  
  184.  
  185. if __name__ == "__main__":
  186. root = Tk()
  187. root.title("Snake Game")
  188. game = Master(root)
  189. game.grid(column=1, row=0, rowspan=3)
  190. root.bind("<Key>", game.redirect)
  191. buttons = Frame(root, width=35)
  192. Button(buttons, text='Start', command=game.start).grid()
  193. Button(buttons, text='Stop', command=game.clean).grid()
  194. Button(buttons, text='Quit', command=root.destroy).grid()
  195. buttons.grid(column=0, row=0)
  196. scoreboard = Frame(root, width=35, height=2 * HT / 5)
  197. Label(scoreboard, text='Game Score').grid()
  198. Label(scoreboard, textvariable=game.score.counter).grid()
  199. Label(scoreboard, text='High Score').grid()
  200. Label(scoreboard, textvariable=game.score.maximum).grid()
  201. scoreboard.grid(column=0, row=2)
  202. root.mainloop()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement