snake.py 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. #!/usr/bin/env python
  2. # -*- coding: utf-8 -*-"
  3. """
  4. PyAISnake - 2018 - by psy (epsylon@riseup.net)
  5. You should have received a copy of the GNU General Public License along
  6. with PyAISnake; if not, write to the Free Software Foundation, Inc., 51
  7. Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  8. """
  9. import curses, random, time
  10. from curses import KEY_RIGHT, KEY_LEFT, KEY_UP, KEY_DOWN
  11. # generate a random AI thought (evading suicidal moves)
  12. def move(prevKey):
  13. if prevKey == KEY_UP:
  14. moves = [KEY_UP, KEY_LEFT, KEY_RIGHT]
  15. elif prevKey == KEY_LEFT:
  16. moves = [KEY_UP, KEY_LEFT, KEY_DOWN]
  17. elif prevKey == KEY_RIGHT:
  18. moves = [KEY_UP, KEY_RIGHT, KEY_DOWN]
  19. elif prevKey == KEY_DOWN:
  20. moves = [KEY_LEFT, KEY_RIGHT, KEY_DOWN]
  21. else:
  22. moves = [KEY_UP, KEY_LEFT, KEY_RIGHT, KEY_DOWN]
  23. key = random.choice(moves)
  24. return key
  25. # translate a thought into a text
  26. def text_to_thought(key):
  27. if key == KEY_UP:
  28. thought = "UP"
  29. elif key == KEY_LEFT:
  30. thought = "LEFT"
  31. elif key == KEY_RIGHT:
  32. thought = "RIGHT"
  33. elif key == KEY_DOWN:
  34. thought = "DOWN"
  35. else:
  36. thought = "LEARNING..."
  37. return thought
  38. # create matrix (with some random init values)
  39. def init(evol, record, max_moves):
  40. curses.initscr()
  41. win = curses.newwin(20, 60, 0, 0)
  42. win.keypad(1)
  43. curses.noecho()
  44. curses.curs_set(0)
  45. win.border(0)
  46. win.nodelay(1)
  47. score = 0
  48. thought = "LEARNING..."
  49. moves = 0
  50. key = move(None)
  51. food = [random.randint(1, 18), random.randint(1, 58)]
  52. snake = [[random.randint(0, 11),random.randint(0, 11)], [random.randint(0, 11),random.randint(0, 11)], [random.randint(0, 11),random.randint(0, 11)]]
  53. win.addch(food[0], food[1], '*')
  54. # build game
  55. while key != 27:
  56. win.border(0)
  57. win.addstr(0, 4, '| Moves: '+str(moves)+' - Max: '+str(max_moves)+' | Score: '+str(score)+' - Record: '+str(record)+' |')
  58. win.addstr(19, 4, '| PyAISnake -> MUTATION: '+str(evol)+' [IDEA: '+str(thought)+'] |')
  59. win.timeout(150 - (len(snake)/5 + len(snake)/10)%120) # if > length: > speed
  60. prevKey = key
  61. event = win.getch()
  62. key = move(prevKey) # AI model reply (Brain -> HERE!)
  63. moves += 1
  64. thought = text_to_thought(key)
  65. key = key if event == -1 else event
  66. if key == ord(' '): # SPACE BAR for pause
  67. key = -1 # pause
  68. paused = ' INFO: GAME PAUSED... '
  69. win.addstr(9, 18, paused)
  70. while key != ord(' '):
  71. paused = ' '
  72. key = win.getch()
  73. win.addstr(9, 18, paused)
  74. win.addch(food[0], food[1], '*')
  75. key = prevKey
  76. continue
  77. if score >= record: # NEW record!
  78. record = score
  79. if moves >= max_moves: # NEW max moves!
  80. max_moves = moves
  81. snake.insert(0, [snake[0][0] + (key == KEY_DOWN and 1) + (key == KEY_UP and -1), snake[0][1] + (key == KEY_LEFT and -1) + (key == KEY_RIGHT and 1)])
  82. if snake[0][0] == 0:
  83. snake[0][0] = 18
  84. if snake[0][1] == 0:
  85. snake[0][1] = 58
  86. if snake[0][0] == 19:
  87. snake[0][0] = 1
  88. if snake[0][1] == 59:
  89. snake[0][1] = 1
  90. if snake[0] in snake[1:]: # GAME LOST ;-(
  91. win.addstr(9, 18, ' SORRY: GAME OVER !!!')
  92. win.addstr(19, 4, '| PyAISnake -> MUTATION: '+str(evol)+' [IDEA: TRYING AGAIN!] |')
  93. if score >= record: # NEW record!
  94. record = score
  95. if moves >= max_moves: # NEW max moves!
  96. max_moves = moves -1
  97. event = win.getch()
  98. time.sleep(2)
  99. evol += 1
  100. init(evol, record, max_moves)
  101. if snake[0] == food:
  102. food = []
  103. score += 1
  104. while food == []:
  105. food = [random.randint(1, 18), random.randint(1, 58)]
  106. if food in snake: food = []
  107. win.addch(food[0], food[1], '*')
  108. else:
  109. last = snake.pop()
  110. try:
  111. win.addch(last[0], last[1], ' ')
  112. except:
  113. pass
  114. try:
  115. win.addch(snake[0][0], snake[0][1], '#')
  116. except:
  117. pass
  118. init(0, 0, 0) # start a new GAME ;-)