20212310刘涵 2021-2022-2 《Python程序设计》实验四报告
课程:《Python程序设计》
班级: 2123
姓名: 刘涵
学号:20212310
实验教师:王志强
实验日期:2022年5月31日
必修/选修: 公选课
一、实验内容
Python综合应用:爬虫、数据处理、可视化、机器学习、神经网络、游戏、网络安全等。
注:在华为ECS服务器(OpenOuler系统)和物理机(Windows/Linux系统)上使用VIM、PDB、IDLE、Pycharm等工具编程实现。
二、实验过程及结果
1.首先要下载有关的模块和库
例如pygame和tkinter。
2.编写连连看程序
编写连连看首先就是要设计好游戏的地图和尺寸,我设计的是一个10X10的,然后要知道连连看的目的是点击两个相同的方块会消除掉
但是我们还需要判断两个点是否可以连接起来如果中间有其他的方块那就是不行的,
然后我们需要将图片到其中,导入的方法是用图片组最方便,所以就用ps将25张图片拼接在一起,从而方便导入。
源代码如下:
`import random
import tkinter as tk
import tkinter.messagebox
from PIL import Image, ImageTk
root = tkinter.Tk()
class MainWindow():
__gameTitle = "lianliankan"
__windowWidth = 700
__windowHeigth = 500
__icons = []
__gameSize = 10
__iconKind = __gameSize * __gameSize / 4
__iconWidth = 40
__iconHeight = 40
__map = []
__delta = 25
__isFirst = True
__isGameStart = False
__formerPoint = None
EMPTY = -1
NONE_LINK = 0
STRAIGHT_LINK = 1
ONE_CORNER_LINK = 2
TWO_CORNER_LINK = 3
def __init__(self):
root.title(self.__gameTitle)
self.centerWindow(self.__windowWidth, self.__windowHeigth)
root.minsize(460, 460)
self.__addComponets()
self.extractSmallIconList()
def __addComponets(self):
self.menubar = tk.Menu(root, bg="lightgrey", fg="black")
self.file_menu = tk.Menu(self.menubar, tearoff=0, bg="lightgrey", fg="black")
self.file_menu.add_command(label="newgame", command=self.file_new, accelerator="Ctrl+N")
self.menubar.add_cascade(label="game", menu=self.file_menu)
root.configure(menu=self.menubar)
self.canvas = tk.Canvas(root, bg = 'white', width = 450, height = 450)
self.canvas.pack(side=tk.TOP, pady = 5)
self.canvas.bind('<Button-1>', self.clickCanvas)
def centerWindow(self, width, height):
screenwidth = root.winfo_screenwidth()
screenheight = root.winfo_screenheight()
size = '%dx%d+%d+%d' % (width, height, (screenwidth - width)/2, (screenheight - height)/2)
root.geometry(size)
def file_new(self, event=None):
self.iniMap()
self.drawMap()
self.__isGameStart = True
def clickCanvas(self, event):
if self.__isGameStart:
point = self.getInnerPoint(Point(event.x, event.y))
if point.isUserful() and not self.isEmptyInMap(point):
if self.__isFirst:
self.drawSelectedArea(point)
self.__isFirst= False
self.__formerPoint = point
else:
if self.__formerPoint.isEqual(point):
self.__isFirst = True
self.canvas.delete("rectRedOne")
else:
linkType = self.getLinkType(self.__formerPoint, point)
if linkType['type'] != self.NONE_LINK:
self.ClearLinkedBlocks(self.__formerPoint, point)
self.canvas.delete("rectRedOne")
self.__isFirst = True
if self.isGameEnd():
tk.messagebox.showinfo("You Win!", "Tip")
self.__isGameStart = False
else:
self.__formerPoint = point
self.canvas.delete("rectRedOne")
self.drawSelectedArea(point)
def isGameEnd(self):
for y in range(0, self.__gameSize):
for x in range(0, self.__gameSize):
if self.__map[y][x] != self.EMPTY:
return False
return True
def extractSmallIconList(self):
imageSouce = Image.open('tupian/1.png')
for index in range(0, int(self.__iconKind)):
region = imageSouce.crop((self.__iconWidth * index, 0,
self.__iconWidth * index + self.__iconWidth - 1, self.__iconHeight - 1))
self.__icons.append(ImageTk.PhotoImage(region))
def iniMap(self):
self.__map = []
tmpRecords = []
records = []
for i in range(0, int(self.__iconKind)):
for j in range(0, 4):
tmpRecords.append(i)
total = self.__gameSize * self.__gameSize
for x in range(0, total):
index = random.randint(0, total - x - 1)
records.append(tmpRecords[index])
del tmpRecords[index]
for y in range(0, self.__gameSize):
for x in range(0, self.__gameSize):
if x == 0:
self.__map.append([])
self.__map[y].append(records[x + y * self.__gameSize])
def drawMap(self):
self.canvas.delete("all")
for y in range(0, self.__gameSize):
for x in range(0, self.__gameSize):
point = self.getOuterLeftTopPoint(Point(x, y))
im = self.canvas.create_image((point.x, point.y),
image=self.__icons[self.__map[y][x]], anchor='nw', tags = 'im%d%d' % (x, y))
def getOuterLeftTopPoint(self, point):
return Point(self.getX(point.x), self.getY(point.y))
def getOuterCenterPoint(self, point):
return Point(self.getX(point.x) + int(self.__iconWidth / 2),
self.getY(point.y) + int(self.__iconHeight / 2))
def getX(self, x):
return x * self.__iconWidth + self.__delta
def getY(self, y):
return y * self.__iconHeight + self.__delta
def getInnerPoint(self, point):
x = -1
y = -1
for i in range(0, self.__gameSize):
x1 = self.getX(i)
x2 = self.getX(i + 1)
if point.x >= x1 and point.x < x2:
x = i
for j in range(0, self.__gameSize):
j1 = self.getY(j)
j2 = self.getY(j + 1)
if point.y >= j1 and point.y < j2:
y = j
return Point(x, y)
def drawSelectedArea(self, point):
pointLT = self.getOuterLeftTopPoint(point)
pointRB = self.getOuterLeftTopPoint(Point(point.x + 1, point.y + 1))
self.canvas.create_rectangle(pointLT.x, pointLT.y,
pointRB.x - 1, pointRB.y - 1, outline = 'red', tags = "rectRedOne")
def ClearLinkedBlocks(self, p1, p2):
self.__map[p1.y][p1.x] = self.EMPTY
self.__map[p2.y][p2.x] = self.EMPTY
self.canvas.delete('im%d%d' % (p1.x, p1.y))
self.canvas.delete('im%d%d' % (p2.x, p2.y))
def isEmptyInMap(self, point):
if self.__map[point.y][point.x] == self.EMPTY:
return True
else:
return False
def getLinkType(self, p1, p2):
if self.__map[p1.y][p1.x] != self.__map[p2.y][p2.x]:
return { 'type': self.NONE_LINK }
if self.isStraightLink(p1, p2):
return {
'type': self.STRAIGHT_LINK
}
res = self.isOneCornerLink(p1, p2)
if res:
return {
'type': self.ONE_CORNER_LINK,
'p1': res
}
res = self.isTwoCornerLink(p1, p2)
if res:
return {
'type': self.TWO_CORNER_LINK,
'p1': res['p1'],
'p2': res['p2']
}
return {
'type': self.NONE_LINK
}
def isStraightLink(self, p1, p2):
start = -1
end = -1
if p1.y == p2.y:
if p2.x < p1.x:
start = p2.x
end = p1.x
else:
start = p1.x
end = p2.x
for x in range(start + 1, end):
if self.__map[p1.y][x] != self.EMPTY:
return False
return True
elif p1.x == p2.x:
if p1.y > p2.y:
start = p2.y
end = p1.y
else:
start = p1.y
end = p2.y
for y in range(start + 1, end):
if self.__map[y][p1.x] != self.EMPTY:
return False
return True
return False
def isOneCornerLink(self, p1, p2):
pointCorner = Point(p1.x, p2.y)
if self.isStraightLink(p1, pointCorner) and self.isStraightLink(pointCorner, p2) and self.isEmptyInMap(pointCorner):
return pointCorner
pointCorner = Point(p2.x, p1.y)
if self.isStraightLink(p1, pointCorner) and self.isStraightLink(pointCorner, p2) and self.isEmptyInMap(pointCorner):
return pointCorner
def isTwoCornerLink(self, p1, p2):
for y in range(-1, self.__gameSize + 1):
pointCorner1 = Point(p1.x, y)
pointCorner2 = Point(p2.x, y)
if y == p1.y or y == p2.y:
continue
if y == -1 or y == self.__gameSize:
if self.isStraightLink(p1, pointCorner1) and self.isStraightLink(pointCorner2, p2):
return {'p1': pointCorner1, 'p2': pointCorner2}
else:
if self.isStraightLink(p1, pointCorner1) and self.isStraightLink(pointCorner1, pointCorner2) and self.isStraightLink(pointCorner2, p2) and self.isEmptyInMap(pointCorner1) and self.isEmptyInMap(pointCorner2):
return {'p1': pointCorner1, 'p2': pointCorner2}
for x in range(-1, self.__gameSize + 1):
pointCorner1 = Point(x, p1.y)
pointCorner2 = Point(x, p2.y)
if x == p1.x or x == p2.x:
continue
if x == -1 or x == self.__gameSize:
if self.isStraightLink(p1, pointCorner1) and self.isStraightLink(pointCorner2, p2):
return {'p1': pointCorner1, 'p2': pointCorner2}
else:
if self.isStraightLink(p1, pointCorner1) and self.isStraightLink(pointCorner1, pointCorner2) and self.isStraightLink(pointCorner2, p2) and self.isEmptyInMap(pointCorner1) and self.isEmptyInMap(pointCorner2):
return {'p1': pointCorner1, 'p2': pointCorner2}
class Point():
def init(self, x, y):
self.x = x
self.y = y
def isUserful(self):
if self.x >= 0 and self.y >= 0:
return True
else:
return False
def isEqual(self, point):
if self.x == point.x and self.y == point.y:
return True
else:
return False
def clone(self):
return Point(self.x, self.y)
def changeTo(self, point):
self.x = point.x
self.y = point.y
m = MainWindow()
root.mainloop()`
3.将代码上传到云服务器上面,进行运行
这里发现云服务器上的python的版本不同,需要自己下载,然后各种的库也需要自己重新下,而且云服务器下的好慢!!(不知道是它本来就卡还是我网卡)下完之后就发现没有屏幕,所以求助了同学才知道需要xming,下完xming之后的调试又是一大挫折,最后求助了万能的b站才调试完成,因为不知道怎么让云服务器里面可以读取中文,所以把所有的输入都改成了拼音。
三、实验问题及解决
1.一开始不知道要在云服务器上重新安装各个模块,导致代码一直报错
最后查找云班课资料进行升级安装
2.不知道xming如何与putty联动
参考b站,安装xterm和xauth后进入vim编辑器修改x11的参数,退出后将本机ip地址加入到源文件x0.host的白名单中,重启之后完成xlaunch的设置,最后打开putty中x11的设置
3.云服务器无法读取中文
让步了,将中文改成英文或拼音
四、结课感想与体会
高中的时候一直很羡慕黑客可以一下子入侵别人的网站,现在学习爬虫了之后,自己也有了一些雏形,而用python写了一个小时候特别经典的游戏,带给我了很大的成就感。学习python也从一开始的复习上个学期学过的一点知识到了全新的没有接触过的领域,总之非常的新奇,从一个编程小白变成了一个初学者。python是我第一个掌握的编程语言,学完之后也有了可以拿出手的一点东西了,虽然已经结课,但是时不时还想去写写他,毕竟是第一个,每次写都会有不一样的感觉,偶尔也会有忘记之前的知识还要再次去查的情况,但一次一次的查总归最后会记住。
总之,感谢老师带着我领略了python世界的风采,我也会继续在这片知识海里学习。