20212217劉恆謙 2022-2022-2 《Python程式設計》實驗四報告
20212217劉恆謙 2022-2022-2 《Python程式設計》實驗四報告
課程:《Python程式設計》
班級: 2122
姓名: 劉恆謙
學號:20212217
實驗教師:王志強
實驗日期:2022年5月28日
必修/選修: 公選課
1.實驗內容
2. 實驗過程及結果
1.購買雲伺服器
此步比較簡單,完成如圖所示的配置即可。注意的是EularOS和centOS一樣下載外掛用的是yum。
2.下載pygame
wget https://files.pythonhosted.org/packages/1a/04/d6f1159feaccdfc508517dba1929eb93a2854de729fa68da9d5c6b48fa00/setuptools-39.2.0.zip unzip setuptools-39.2.0.zip cd setuptools-39.2.0 python3 setup.py build #以上命令用於下載setuptool wget https://files.pythonhosted.org/packages/ae/e8/2340d46ecadb1692a1e455f13f75e596d4eab3d11a57446f08259dee8f02/pip-10.0.1.tar.gz tar xf pip-10.0.1.tar.gz cd pip-10.0.1 python3 setup.py install #以上下載pip3--10.0.1 pip3 install pygame
3.配置遠端桌面
下載xterm和xauth,EularOS用如下命令
yum install xterm
yum install xauth
用vim編輯器開啟(vi是vim的簡寫)網路設定,注意xming與putty之間是通過ssh協議通訊的
vi /etc/ssh/sshd_config
設定X11Forwarding yes
在vim編輯器中按i進入編輯模式,按Esc退出編輯,按:輸入wq退出vim
完成後退出putty
xming下載並安裝好後,在選單欄找到xlaunch,一直點下一步至完成即可。之後開啟putty輸入xterm即可看見視窗了。
xterm啟動很慢,需要耐心等待5秒左右
4.編寫指令碼上傳執行
貪吃蛇的套路無非是食物在左我向左,食物在上我朝上因此,首先要檢測食物food和蛇頭head的座標大小
蛇頭是一個座標,head = [200, 300]
towards有兩個值0和1,分別用來表示x和y方向,並且只用在head上。
head[0]是x方向,左右方向。head[1]是y方向,上下方向。
want是食物列表中的一個食物,它也是個座標。
head = [200, 300] #蛇頭——一個座標 towards = 0 #蛇的方向 foods = [(690, 400)]#食物列表 want = foods[0] #想要的食物——一個座標 going = True while going: #遊戲迴圈走起——Going SCREEN.fill((255, 255, 255)) for event in pg.event.get([pg.KEYDOWN, pg.QUIT]): if event.type == pg.QUIT: going = False #按XX遊戲退出——QUIT #接近目標 #蛇頭在食物 左 towards = 0 或 上 towards = 1 if head[towards] < want[towards] - R -A: run = V #蛇頭在食物 右 towards = 0 或 下 towards = 1 elif head[towards] > want[towards] + R: run = -V #什麼時候換方向 else: towards = 1 - towards
好了,不過這就大功告成了嗎?還沒呢。要知道蛇吃了食物後,他就該換一個目標了。
#吃到食物
for food in foods:
if food[0] - R - A <= head[0] <= food[0] + R and food[1] - R - A <= head[1] <= food[1] + R:
#刪除食物
foods.remove(food)
#追加食物
foods.append((randint(0, 750), randint(0, 550)))
#蛇身增長
snack.append([head[0] - A, head[1]])
#吃到的就是目標食物
if food == want:
#換一個目標
want = choice(foods)
這就完成了最重要的部分。有了智慧蛇後,實現人機對戰就很簡單了。(長文預警)
下面的智慧蛇叫other,它身體的每一部分叫the,它的蛇頭叫thead,畫出來是綠色的;
而貪吃蛇叫snacks (注意有s),身體的每個方塊叫 snack,頭叫head,畫出來是藍色的。以此區分兩條蛇
原始碼
import pygame as pg
from random import randint, choice
SCREEN = pg.display.set_mode([800, 600])
pg.display.set_caption('貪吃蛇')
V = 21 #蛇速
A = 20 #蛇身方塊
R = 20 #食物半徑
#初始貪吃蛇
direct = "右"
head=[500,500]
snacks = [head]
#初始化食物
foods = [(220, 350), (450, 250), (390, 340), (690, 400)]
#初始智慧蛇
thead = [200, 300]
other = [thead]
which = 0
want = foods[0]
run = V
going = True
while going:
SCREEN.fill((255, 255, 255))
#以下是貪吃蛇的部分_______________________________________________________________________________________
for event in pg.event.get([pg.KEYDOWN, pg.QUIT]):
if event.type == pg.QUIT:
going = False
elif event.key == pg.K_w:
direct = "上"
elif event.key == pg.K_s:
direct = "下"
elif event.key == pg.K_a:
direct = "左"
elif event.key == pg.K_d:
direct = "右"
pg.event.clear()
if direct == '上':
head[1] -= V
if direct == '下':
head[1] += V
if direct == '左':
head[0] -= V
if direct == '右':
head[0] += V
if head[0] < 0:
head[0] = 800
if head[0] > 800:
head[0] = 0
if head[1] < 0:
head[1] = 600
if head[1] > 600:
head[1] = 0
snacks.insert(0, head.copy())
snacks.pop()
#以下是智慧蛇的部分_______________________________________________________________________________________
#接近目標
#蛇頭在食物 左 towards = 0 或 上 towards = 1
if thead[which] < want[which] - R:
run = V
#蛇頭在食物 右 towards = 0 或 下 towards = 1
elif thead[which] > want[which] + R:
run = -V
#什麼時候換方向
else:
which = 1 - which
#蛇的運動
thead[which] += run
other.insert(0, thead.copy())
other.pop()
#吃到食物_______智慧蛇 和 貪吃蛇_____________________________________________________________________________
for food in foods:
#把食物畫出來
pg.draw.circle(SCREEN, (238, 180, 34), (food[0], food[1]), R)
#如果貪吃蛇吃到食物
if food[0] - R - A <= head[0] <= food[0] + R and food[1] - R - A <= head[1] <= food[1] + R:
#刪除食物
foods.remove(food)
#蛇身增長
snacks.append([head[0] - A, head[1]])
#吃到的就是目標食物
if food == want:
#換一個目標
want = choice(foods)
#如果智慧蛇吃到食物
elif food[0] - R - A <= thead[0] <= food[0] + R and food[1] - R - A <= thead[1] <= food[1] + R:
#刪除食物
foods.remove(food)
#追加食物
other.append([thead[0] - A, thead[1]])
#吃到的就是目標食物
if food == want:
#換一個目標
want = choice(foods)
#追加食物
if len(foods) < 4:
foods.append((randint(0, 750), randint(0, 550)))
#安排就緒後繪製
for snack in snacks[1:]:
pg.draw.rect(SCREEN, (100, 200, 200), (snack[0], snack[1], A, A))
pg.draw.rect(SCREEN, (0, 255, 255), (head[0], head[1], A, A))
for the in other[1:]:
pg.draw.rect(SCREEN, (0, 238, 118), (the[0], the[1], A, A))
pg.draw.rect(SCREEN, (0, 139, 69), (thead[0], thead[1], A, A))
pg.display.update()
pg.time.Clock().tick(20)
pg.quit()
3.實驗問題及解決
1.下載pygame報錯
本來以為和windows一樣,沒想到遇到了諸多困難。
首先是EularOS和一般的linux一樣自帶一個Python2.7和python3.7。而它預設的python是python2.7因此很容易搞混。python2.7有諸多語法和python3不同,因此python3指令碼多半是不能被python2執行的。此處很容易弄錯。
用下面這兩個命令檢查一下
whereis python3
whereis pip3
用下面的命令可以檢視python3和pip3的路徑,這個V代表version
python3 -V
pip3 -V
檢查沒問題的話就可以用下面的命令執行檔案
python3 file.py
伺服器裡的pip是系統級的,有很高的許可權,叫pip3.7,但這個pip3.7一下載就報錯
如下載lxml
如下載pygame
要解決這個問題就得自己再下一個pip3
2.執行報錯
pygame和tkinter, turtle一樣,執行時會產生視窗,如果沒有可用的螢幕,就會引發error
在turtle或tkinter中也是一樣的
為解決此問題需要為putty配置xming。
再登入putty
實驗感悟與思考
近些天來學python想動手寫一個貪吃蛇小遊戲,知乎網傳貪吃蛇AI演算法,貪吃蛇自動覓食。如果作為AI練習尚可,要是用來做遊戲未免大材小用了。因此我就想用一種簡單的辦法讓電腦也能控制蛇的覓食。
參考資料