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世界的風采,我也會繼續在這片知識海里學習。