You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

168 lines
4.4 KiB

  1. #!/usr/bin/env python
  2. #
  3. # snake.py
  4. # Playing with ctypes and libcaca
  5. # http://mornie.org/blog/2007/03/25/Playng-with-ctypes-and-libcaca/
  6. #
  7. # Copyright (C) 2007 Daniele Tricoli aka Eriol <eriol@mornie.org>
  8. #
  9. # This program is free software; you can redistribute it and/or
  10. # modify it under the terms of the GNU General Public License
  11. # as published by the Free Software Foundation; either version 2
  12. # of the License, or (at your option) any later version.
  13. #
  14. # This program is distributed in the hope that it will be useful,
  15. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17. # GNU General Public License for more details.
  18. #
  19. # You should have received a copy of the GNU General Public License
  20. # along with this program; if not, write to the Free Software
  21. # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  22. #
  23. # -- Changelog
  24. # * 23/03/07
  25. # Initial release
  26. # * 20/10/07
  27. # Applied patch by Sam Hocevar: check for caca_get_event's return value
  28. # and added caca_event's missing first member
  29. # * 25/10/07
  30. # Updated for newer libcaca API (Sam Hocevar)
  31. import ctypes as C
  32. import random
  33. import sys
  34. import time
  35. CANVAS_WIDTH = 80
  36. CANVAS_HEIGHT = 40
  37. CENTER_X = CANVAS_WIDTH / 2
  38. CENTER_Y = CANVAS_HEIGHT / 2
  39. UP = 273
  40. DOWN = 274
  41. LEFT = 275
  42. RIGHT = 276
  43. class ev(C.Structure):
  44. _fields_ = [('opaque_structure', C.c_char_p * 32)]
  45. class Snake(object):
  46. def __init__(self, center_point, length):
  47. self.head = center_point
  48. self.body = []
  49. for y in xrange(self.head[1] + 1, self.head[1] + length + 1):
  50. self.body.append((self.head[0], y))
  51. def move(self, direction):
  52. phead = tuple(self.head)
  53. if direction == 'UP':
  54. self.head[1] -=1
  55. elif direction == 'DOWN':
  56. self.head[1] +=1
  57. elif direction == 'LEFT':
  58. self.head[0] -=1
  59. elif direction == 'RIGHT':
  60. self.head[0] +=1
  61. self.body = [phead] + self.body[:-1]
  62. def grow(self):
  63. self.body += [tuple(self.head)] * 2
  64. def draw(self):
  65. global cv
  66. lcaca.caca_set_color_ansi(cv, 0x05, 0x00)
  67. for p in self.body:
  68. lcaca.caca_put_char(cv, p[0], p[1], ord('o'))
  69. lcaca.caca_set_color_ansi(cv, 0x02, 0x00)
  70. lcaca.caca_put_char(cv, self.head[0], self.head[1], ord('@'))
  71. lcaca.caca_refresh_display(dp)
  72. class Target(object):
  73. def __init__(self):
  74. self.total = 0
  75. def random(self, width, height):
  76. self.x = int(random.uniform(1, width))
  77. self.y = int(random.uniform(1, height))
  78. self.value = random.choice(range(1,10))
  79. def sum(self):
  80. self.total += self.value
  81. def draw(self):
  82. global cv
  83. lcaca.caca_set_color_ansi(cv, 0x03, 0x00)
  84. lcaca.caca_put_char(cv, self.x, self.y, ord(str(self.value)))
  85. lcaca.caca_refresh_display(dp)
  86. def draw_border():
  87. lcaca.caca_set_color_ansi(cv, 0x04, 0x00)
  88. lcaca.caca_draw_box(cv,
  89. 0,
  90. 0,
  91. CANVAS_WIDTH - 1,
  92. CANVAS_HEIGHT - 1,
  93. ord('#'))
  94. event = ev()
  95. lcaca = C.cdll.LoadLibrary('libcaca.so.0')
  96. cv = lcaca.caca_create_canvas(CANVAS_WIDTH, CANVAS_HEIGHT)
  97. dp = lcaca.caca_create_display(cv)
  98. lcaca.caca_set_display_title(dp, "snake.py - playing with ctypes and libcaca")
  99. s = Snake([CENTER_X, CENTER_Y], 5)
  100. t = Target()
  101. t.random(CANVAS_WIDTH - 2, CANVAS_HEIGHT - 2)
  102. draw_border()
  103. s.draw()
  104. t.draw()
  105. lcaca.caca_get_event(dp, 0x0001, C.byref(event), -1)
  106. while True:
  107. while lcaca.caca_get_event(dp, 0x0001, C.byref(event), 0):
  108. ch = lcaca.caca_get_event_key_ch(C.byref(event))
  109. if ch == 113: # 'q' pressed
  110. sys.exit()
  111. elif ch == UP:
  112. d = 'UP'
  113. elif ch == DOWN:
  114. d = 'DOWN'
  115. elif ch == LEFT:
  116. d = 'LEFT'
  117. elif ch == RIGHT:
  118. d = 'RIGHT'
  119. try:
  120. s.move(d)
  121. except NameError:
  122. pass
  123. if (tuple(s.head) in s.body[1:] or
  124. not 0 < s.head[0] < CANVAS_WIDTH - 1 or
  125. not 0 < s.head[1] < CANVAS_HEIGHT - 1):
  126. print 'Game Over!'
  127. print 'Total score:', t.total
  128. sys.exit()
  129. elif tuple(s.head) == (t.x, t.y):
  130. t.sum()
  131. t.random(CANVAS_WIDTH - 2, CANVAS_HEIGHT - 2)
  132. s.grow()
  133. lcaca.caca_clear_canvas(cv)
  134. draw_border()
  135. s.draw()
  136. t.draw()
  137. time.sleep(0.1)