前提:本文实现AI贪吃蛇自行对战,加上人机对战,读者可再次基础上自行添加电脑VS电脑和玩家VS玩家(其实把人机对战写完,这2个都没什么了,思路都一样)
实现效果:
具体功能:
1.智能模式:电脑自己玩(自己吃食物)
2.人机对战:电脑和人操作(在上步的基础上加一个键盘控制的贪吃蛇即可)
实现环境:
Pycharm + Python3.6 + Curses + Win10
具体过程:
一:配置环境:
Curses: 参考链接 (Cp后面代表本地Python环境,别下错了) ( Stackoverflow 真的是个非常好的地方)
二:
1.灵感来源+参考链接:
http://www.hawstein.com/posts/snake-ai.html (Chrome有时候打不开,Firefox可以打开)
2.算法思路:
AI算法:https://www.cnblogs.com/21207-iHome/p/6048969.html (本人之前接触过,当时讲课老师说是自动寻路算法,我感觉和BFS+DFS一样,结果没想到居然是AI算法)
BFS+DFS(略)
第一步是能制作一个 基本的贪吃蛇 ,熟悉Curses的相关环境(最好别对蛇和食物使用特殊字符,在windows环境下会导致像素延迟,非常丑)
#curses官方手册:
https://docs.python.org/3.5/library/curses.html#module-curses
#curses参考手册:
https://blog.csdn.net/chenxiaohua/article/details/2099304
具体思路:
熟悉Curses中相关指令后基本就没什么了, 保证按的下一个键不导致蛇死亡,保证蛇吃食物后食物不在蛇身上,保证蛇碰到自己和边框就死亡,如果按其他键,会导致头被插入2次,从而让蛇死亡。(具体见代码分析)
1 #!/usr/bin/env python
2 # -*- coding: utf-8 -*-
3 # @Time : 2018/11/5 17:08
4 # @Author : Empirefree
5 # @File : 贪吃蛇-01.py
6 # @Software: PyCharm Community Edition
7
8 #curses官方手册:https://docs.python.org/3.5/library/curses.html#module-curses
9 #curses参考手册:https://blog.csdn.net/chenxiaohua/article/details/2099304
10
11 # 基本思路:while循环,让蛇一直右走(直到按键,如果按了其他键就会导致蛇头被重复插入1次到snake中,
12 # 继而第二次循环就会退出),蛇是每次自动增长,但是每次没吃到食物就会pop尾部(snake放在dict中,类似链表),按键检查就是只能按方向键
13 # 按方向键也存在判别是否出错(按了up后又按down),然后对于死亡情况就是碰到周围和自己
14
15 # 1.蛇的移动和吃食物后的变化
16 # 2.按键:按其他键和方向键
17 # 3.死亡判断
18
19 import curses
20 import random
21
22 # 开启curses
23 def Init_Curse():
24 global s
25 s = curses.initscr()
26 curses.curs_set(0) #能见度光标,写错了哇
27 curses.noecho()
28 curses.cbreak() #立即得到响应
29 s.keypad(True) #特殊处理键位,返回KEY_LEFT
30
31 #关闭并回到终端
32 def Exit_Curse():
33 curses.echo()
34 curses.nocbreak()
35 s.keypad(False)
36 curses.endwin()
37
38 def Start_Game():
39 # 窗口化操作
40 y, x = s.getmaxyx() # curses中是y,x
41 w = curses.newwin(y, x, 0, 0)
42 w.keypad(1)
43 w.timeout(100)
44
45 # 初始化蛇的位置,并用dict存储
46 snake_x = int(x / 4)
47 snake_y = int(y / 2)
48 snake = [[snake_y, snake_x], [snake_y, snake_x - 1], [snake_y, snake_x - 2]]
49
50 # 初始化食物
51 food_pos = [int(y / 2), int(x / 2)]
52 w.addch(food_pos[0], food_pos[1], '@') # 用@显示食物字元
53
54 key = curses.KEY_RIGHT # 得到右方向键
55
56 # 开始,为什么我感觉True比1看的爽一些
57 while True:
58 next_key = w.getch() # 等待输入,传回整数
59 print(next_key, 'QAQ')
60 # 防止Error
61 if next_key != -1:
62 if key == curses.KEY_RIGHT and next_key != curses.KEY_LEFT
63 or key == curses.KEY_LEFT and next_key != curses.KEY_RIGHT
64 or key == curses.KEY_DOWN and next_key != curses.KEY_UP
65 or key == curses.KEY_UP and next_key != curses.KEY_DOWN: