摘要:很早之前用也是寫過一個,但是寫的不好,這次用寫,看看自己有木有提升。
UI 代碼
#!/usr/bin/env python # -*- coding: utf-8 -*- # @Date : 2017-10-02 15:19:24 # @Author : Salamander (*********@qq.com) # @Link : http://51lucy.com import os, random import tkinter as tk import tkinter.messagebox from PIL import Image, ImageTk class MainWindow(): __gameTitle = "連連看游戲" __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): self.root = tk.Tk() self.root.title(self.__gameTitle) self.centerWindow(self.__windowWidth, self.__windowHeigth) self.root.minsize(460, 460) self.__addComponets() self.extractSmallIconList() self.root.mainloop() def __addComponets(self): self.menubar = tk.Menu(self.root, bg="lightgrey", fg="black") self.file_menu = tk.Menu(self.menubar, tearoff=0, bg="lightgrey", fg="black") self.file_menu.add_command(label="新游戲", command=self.file_new, accelerator="Ctrl+N") self.menubar.add_cascade(label="游戲", menu=self.file_menu) self.root.configure(menu=self.menubar) self.canvas = tk.Canvas(self.root, bg = "white", width = 450, height = 450) self.canvas.pack(side=tk.TOP, pady = 5) self.canvas.bind("使用", self.clickCanvas) def centerWindow(self, width, height): screenwidth = self.root.winfo_screenwidth() screenheight = self.root.winfo_screenheight() size = "%dx%d+%d+%d" % (width, height, (screenwidth - width)/2, (screenheight - height)/2) self.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: # TODO Animation 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(r"imagesNARUTO.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)) """ 初始化地圖 存值為0-24 """ 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] # 一維數組轉為二維,y為高維度 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) """ 選擇的區域變紅,point為內部坐標 """ 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 MainWindow()
完整源碼在GitHub上,主要就是三種連通情況的判斷。
很早之前用C#也是寫過一個,但是寫的不好,這次用python寫,看看自己有木有提升。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/40897.html
摘要:是一個基于與的高性能平臺,其內部集成了大量精良的庫第三方模塊以及大多數的依賴項。用于方便地搭建能夠處理超高并發擴展性極高的動態應用服務和動態網關。,,,階段處理,比如記錄訪問量統計平均響應時間 Lua lua的特點 小巧:一個完整的Lua解釋器不過200k 可擴展性:Lua的解釋器是100%的ANSI編寫的,它提供了非常易于使用的擴展接口和機制,所以Lua的腳本很容易的被C/C++ ...
摘要:輸入框和標簽都帶了一個神秘的參數。我們可以在之前調用的時候做這些事,但上面這樣做也是個不錯的選擇第二行告訴讓我們的輸入框獲取到焦點。 原文http://www.tkdocs.com/tutorial/firstexample.html 第一個實用的簡易案例 A First (Real) ExampleWith that out of the way, lets try a slight...
? ? ? ? 國慶假期快到了,想查查還有幾天幾小時到假期,這對程序員小菜一碟,輕輕松松用python寫個倒計時程序(天、時、分、秒),助你熬到假期! 一、先看效果: ?二、安裝python: 1、下載安裝python 下載安裝python3.9.6,進入python官方網站://www.python.org/ ?點擊Python 3.9.6 直接安裝即可。 2、驗證安裝成功。 按win+R...
摘要:代碼需要的字段模仿獲取西部數碼信息域名代理模擬執行代碼解析出錯添加代理解析出錯查詢西部數碼失敗請求西部數碼失敗生成失敗提取西部數碼數據使用結果另外這個域名是我的,有意出售。 目標對象和過程 爬取的網站是西部數碼,該網站在https://www.west.cn/web/whois...可以查詢whois信息,通過chrome調試知道,數據是從接口:https://www.west.cn/...
摘要:先來看下效果實際使用不需要打開手機,此處為演示需要實現代碼主要有兩個部分接收紅包消息直接從手機端微信獲取數據比較麻煩,主流的方法都是通過微信網頁版來獲取。這里我用的是,通過即可安裝,之前我也寫過文章介紹微信機器人進化指南。 又到了辭舊迎新的時候,群里的紅包也多起來了。然而大佬們總是喜歡趁我不在的時候發紅包,經常打開手機,發現紅包已被搶完,感覺錯過了一個億。 安卓上有不少紅包助手工具,但...
閱讀 2516·2021-09-26 10:18
閱讀 3394·2021-09-22 10:02
閱讀 3190·2019-08-30 15:44
閱讀 3329·2019-08-30 15:44
閱讀 1836·2019-08-29 15:25
閱讀 2580·2019-08-26 14:04
閱讀 2042·2019-08-26 12:15
閱讀 2442·2019-08-26 11:43