Welcome to pay attention "Python black technology" series , continuously updating
Welcome to pay attention "Python black technology" series , continuously updating
Realization effect
Realization idea
link: https://pan.baidu.com/s/1Q6peGnZe0k0zBalAGaJ8wg?pwd=pdux Extraction code: pdux
Make a bunch of pictures_ 00-----bar_ 09.png
It would be better if we could find gif
imgs = [PhotoImage(file='images\\bar_0' + str(i) + '.png') for i in range(0, 10)] # All icon patterns
Classic continuous view, randomly generate picture elements, and the marks of adjacent picture elements are the same, which can be eliminated.
Implementation code
# @Time : 2022/2/9 20:22 # @Author: Nanli # @FileName: Lianliankan py from tkinter import * from tkinter.messagebox import * from threading import Timer import time import random class Point: # Point class def __init__(self, x, y): self.x = x self.y = y # -------------------------------------- ''' Judge whether the selected two squares can be eliminated ''' def IsLink(p1, p2): if lineCheck(p1, p2): return True if OneCornerLink(p1, p2): # One turn (break point) connection mode return True if TwoCornerLink(p1, p2): # Connection mode of two turns (break points) return True return False # --------------------------- def IsSame(p1, p2): if map[p1.x][p1.y] == map[p2.x][p2.y]: print("clicked at IsSame") return True return False def callback(event): # Left mouse button event code global Select_first, p1, p2 global firstSelectRectId, SecondSelectRectId # print ("clicked at", event.x, event.y,turn) x = (event.x) // 40 # converted chessboard coordinates y = (event.y) // 40 print("clicked at", x, y) if map[x][y] == " ": showinfo(title="Tips", message="There are no squares here") else: if Select_first == False: p1 = Point(x, y) # Draw a border at the selected (x1,y1) firstSelectRectId = cv.create_rectangle(x * 40, y * 40, x * 40 + 40, y * 40 + 40, width=2, outline="blue") Select_first = True else: p2 = Point(x, y) # Judge whether the box clicked for the second time has been selected by the first click. If so, return. if (p1.x == p2.x) and (p1.y == p2.y): return # Draw a border at the selected (x2,y2) print('Second click box', x, y) # SecondSelectRectId=cv.create_rectangle(100,20,x*40+40,y*40+40,width=2,outline="yellow") SecondSelectRectId = cv.create_rectangle(x * 40, y * 40, x * 40 + 40, y * 40 + 40, width=2, outline="yellow") print('Second click box', SecondSelectRectId) cv.pack() # Judge whether it is connected if IsSame(p1, p2) and IsLink(p1, p2): print('connected', x, y) Select_first = False # Draw the connecting line between the selected boxes drawLinkLine(p1, p2) # clearTwoBlock() # time.sleep(0.6) # clearFlag=True t = Timer(timer_interval, delayrun) # Timing function t.start() else: # Reselect the first box # Clear first selected wireframe cv.delete(firstSelectRectId) cv.delete(SecondSelectRectId) # print('clear first selected border ') # firstSelectRectId=SecondSelectRectId # p1=Point(x,y) #Sets the coordinates of the first square to be reselected Select_first = False timer_interval = 0.3 # 0.3 seconds # -------------------------------------- def delayrun(): clearTwoBlock() # Clear lines and blocks def clearTwoBlock(): # Clear lines and blocks # Delay 0.1 second # time.sleep(0.1) # Clears the first selected border cv.delete(firstSelectRectId) # Clears the second selected border cv.delete(SecondSelectRectId) # Clear the value of the record box map[p1.x][p1.y] = " " cv.delete(image_map[p1.x][p1.y]) map[p2.x][p2.y] = " " cv.delete(image_map[p2.x][p2.y]) Select_first = False undrawConnectLine() # Clear the connection line between the selected boxes def drawQiPan(): # Draw a chessboard for i in range(0, 15): cv.create_line(20, 20 + 40 * i, 580, 20 + 40 * i, width=2) for i in range(0, 15): cv.create_line(20 + 40 * i, 20, 20 + 40 * i, 580, width=2) cv.pack() def print_map(): # Output map global image_map for x in range(0, Width): # 0--14 for y in range(0, Height): # 0--14 if (map[x][y] != ' '): img1 = imgs[int(map[x][y])] id = cv.create_image((x * 40 + 20, y * 40 + 20), image=img1) image_map[x][y] = id cv.pack() for y in range(0, Height): # 0--14 for x in range(0, Width): # 0--14 print(map[x][y], end=' ') print(",", y) ''' * Principle of elimination method for the same row and column: if the number of spaces between two identical eliminated elements spaceCount Equal to their (row)/Column difference-1)Then the two can be eliminated * x Representative column, y Representative bank * param p1 The first point object that saves the coordinates of the last selected point * param p2 The second point object that saves the coordinates of the last selected point ''' # Direct connection def lineCheck(p1, p2): absDistance = 0 spaceCount = 0 if (p1.x == p2.x or p1.y == p2.y): # Is it in the same line? print("Same row and same column------") # Same column if (p1.x == p2.x and p1.y != p2.y): print("Same column") # Absolute distance (number of spaces between) absDistance = abs(p1.y - p2.y) - 1 # Positive and negative value if p1.y - p2.y > 0: zf = -1 else: zf = 1 for i in range(1, absDistance + 1): if (map[p1.x][p1.y + i * zf] == " "): # Number of spaces plus 1 spaceCount += 1 else: break; # If you encounter obstacles, you don't have to detect them anymore # Situation of peers elif (p1.y == p2.y and p1.x != p2.x): print(" Situation of peers") absDistance = abs(p1.x - p2.x) - 1 # Positive and negative value if p1.x - p2.x > 0: zf = -1 else: zf = 1 for i in range(1, absDistance + 1): if (map[p1.x + i * zf][p1.y] == " "): # Number of spaces plus 1 spaceCount += 1 else: break; # If you encounter obstacles, you don't have to detect them anymore if (spaceCount == absDistance): # Unicom print(absDistance, spaceCount) print("that 's ok/Columns can be connected directly") return True else: print("that 's ok/Column cannot be eliminated!") return False else: # It is not in the same row and column, so it directly returns false return False; # -------------------------------------- # Second, right angle connection ''' Right angle connection, i.e X,Y If the coordinates are different, you can try to connect with this method param first:First point selected param second:Second point selected ''' def OneCornerLink(p1, p2): # The first right angle checkpoint. If it is empty, the same value will be given for inspection checkP = Point(p1.x, p2.y) # The second right angle checkpoint. If it is empty, the same value will be given for inspection checkP2 = Point(p2.x, p1.y); # First right angle point detection if (map[checkP.x][checkP.y] == " "): if (lineCheck(p1, checkP) and lineCheck(checkP, p2)): linePointStack.append(checkP) print("Right angle elimination ok", checkP.x, checkP.y) return True # Second right angle point detection if (map[checkP2.x][checkP2.y] == " "): if (lineCheck(p1, checkP2) and lineCheck(checkP2, p2)): linePointStack.append(checkP2) print("Right angle elimination ok", checkP2.x, checkP2.y) return True print("Cannot be eliminated at right angles") return False; # ----------------------------------------- ''' #Third, double right angle connection The judgment of double right angle connection can be divided into two steps: 1. stay p1 Look for spaces in 4 directions around the dot checkP 2. call OneCornerLink(checkP, p2) 3. Traversal p1 4 Space in two directions to make it checkP,Then call OneCornerLink(checkP, p2)Determine whether it is true. If it is true, double right angles can be used together. Otherwise, when all spaces are traversed and not found To one checkP send OneCornerLink(checkP, p2)If true, the two points cannot be combined Specific code: Double right angle connection method @param p1 First point @param p2 Second point ''' def TwoCornerLink(p1, p2): checkP = Point(p1.x, p1.y) # Four way detection starts for i in range(0, 4): checkP.x = p1.x checkP.y = p1.y # down if (i == 3): checkP.y += 1 while ((checkP.y < Height) and map[checkP.x][checkP.y] == " "): linePointStack.append(checkP) if (OneCornerLink(checkP, p2)): print("Lower detection OK") return True else: linePointStack.pop() checkP.y += 1 print("ssss", checkP.y, Height - 1) # The two additional break points are outside the bottom side of the game area if checkP.y == Height: # Out of the bottom, we only need to judge whether p2 can also reach the bottom boundary z = Point(p2.x, Height - 1) # Bottom boundary point if lineCheck(z, p2): # The two break points are on the bottom side outside the area linePointStack.append(Point(p1.x, Height)) linePointStack.append(Point(p2.x, Height)) print("The outside of the game area is detected OK") return True # towards the right elif (i == 2): checkP.x += 1 while ((checkP.x < Width) and map[checkP.x][checkP.y] == " "): linePointStack.append(checkP) if (OneCornerLink(checkP, p2)): print("Right detection OK") return True else: linePointStack.pop() checkP.x += 1 # The two additional break points are outside the right side of the game area if checkP.x == Width: # Out of the right side, it is only necessary to judge whether p2 can also reach the right boundary z = Point(Width - 1, p2.y) # Right boundary point if lineCheck(z, p2): # The two break points are on the bottom side outside the area linePointStack.append(Point(Width, p1.y)) linePointStack.append(Point(Width, p2.y)) print("Right detected outside the game area OK") return True # towards the left elif (i == 1): checkP.x -= 1 while ((checkP.x >= 0) and map[checkP.x][checkP.y] == " "): linePointStack.append(checkP) if (OneCornerLink(checkP, p2)): print("Left detection OK") return True else: linePointStack.pop() checkP.x -= 1 # Upward elif (i == 0): checkP.y -= 1 while ((checkP.y >= 0) and map[checkP.x][checkP.y] == " "): linePointStack.append(checkP) if (OneCornerLink(checkP, p2)): print("Upper detection OK") return True else: linePointStack.pop() checkP.y -= 1 # No suitable checkP point was found after searching in all four directions print("Two right angle connections did not find a suitable one checkP spot") return False; # --------------------------- # Draw a connecting line def drawLinkLine(p1, p2): if (len(linePointStack) == 0): Line_id.append(drawLine(p1, p2)) else: print(linePointStack, len(linePointStack)) if (len(linePointStack) == 1): z = linePointStack.pop() print("One break connected point z", z.x, z.y) Line_id.append(drawLine(p1, z)) Line_id.append(drawLine(p2, z)) if (len(linePointStack) == 2): z1 = linePointStack.pop() print("2 Broken connected point z1", z1.x, z1.y) Line_id.append(drawLine(p2, z1)) z2 = linePointStack.pop() print("2 Broken connected point z2", z2.x, z2.y) Line_id.append(drawLine(z1, z2)) Line_id.append(drawLine(p1, z2)) # Delete connector def undrawConnectLine(): while len(Line_id) > 0: idpop = Line_id.pop() cv.delete(idpop) def drawLine(p1, p2): print("drawLine p1,p2", p1.x, p1.y, p2.x, p2.y) # cv.create_line( 40+20, 40+20,200,200,width=5,fill='red') id = cv.create_line(p1.x * 40 + 20, p1.y * 40 + 20, p2.x * 40 + 20, p2.y * 40 + 20, width=5, fill='red') # cv.pack() return id # -------------------------------------- def create_map(): # Generate map map global map # Generate random map # Put all matched pairs of animal species into a temporary map tmpMap = [] m = (Width) * (Height) // 10 print('m=', m) for x in range(0, m): for i in range(0, 10): # There are 10 squares of each type tmpMap.append(x) random.shuffle(tmpMap) for x in range(0, Width): # 0--14 for y in range(0, Height): # 0--14 map[x][y] = tmpMap[x * Height + y] # -------------------------------------- def find2Block(event): # Auto find global firstSelectRectId, SecondSelectRectId m_nRoW = Height m_nCol = Width bFound = False; # The first box starts at position 0 on the map for i in range(0, m_nRoW * m_nCol): # If found, jump out of the loop if (bFound): break # Calculate the corresponding virtual row and column position x1 = i % m_nCol y1 = i // m_nCol p1 = Point(x1, y1) # Non patterned square skip if (map[x1][y1] == ' '): continue # The second box starts from the back of the previous box for j in range(i + 1, m_nRoW * m_nCol): # Calculate the corresponding virtual row and column position x2 = j % m_nCol y2 = j // m_nCol p2 = Point(x2, y2) # The second box is not empty and is the same as the animal in the first box if (map[x2][y2] != ' ' and IsSame(p1, p2)): # Judge whether it can be connected if (IsLink(p1, p2)): bFound = True break # Automatically eliminate after finding if (bFound): # p1 (x1,y1) is connected with p2 (x2,y2) print('After finding', p1.x, p1.y, p2.x, p2.y) # Draw a border at the selected (x1,y1) firstSelectRectId = cv.create_rectangle(x1 * 40, y1 * 40, x1 * 40 + 40, y1 * 40 + 40, width=2, outline="red") # Draw a border at the selected (x2,y2) secondSelectRectId = cv.create_rectangle(x2 * 40, y2 * 40, x2 * 40 + 40, y2 * 40 + 40, width=2, outline="red") # t=Timer(timer_interval,delayrun)#Timing function # t.start() return bFound # Game main logic root = Tk() root.title("Python Look again and again ") imgs = [PhotoImage(file='images\\bar_0' + str(i) + '.png') for i in range(0, 10)] # All icon patterns Select_first = False # Has the first block been selected firstSelectRectId = -1 # The first map object selected SecondSelectRectId = -1 # Selected second map object clearFlag = False linePointStack = [] Line_id = [] Height = 10 Width = 10 map = [[" " for y in range(Height)] for x in range(Width)] image_map = [[" " for y in range(Height)] for x in range(Width)] cv = Canvas(root, bg='green', width=440, height=440) # drawQiPan( ) cv.bind("<Button-1>", callback) # Left mouse button event cv.bind("<Button-3>", find2Block) # Right mouse button event cv.pack() create_map() # Generate map map print_map() # Print map root.mainloop()
summary
If you like, give me a 👍, Pay attention! Share more interesting Python black technology!
Welcome to pay attention "Python black technology" series , continuously updating
Welcome to pay attention "Python black technology" series , continuously updating
[Python black technology] a collection of 7 small projects in tkinter Library (nanny graphics + implementation code)
[Python black technology] tkinter library actually makes a calculator (nanny graphic + implementation code)
[Python black technology] tkinter library actually makes a notepad (nanny graphic + implementation code)
[Python black technology] registration and login of actual users of tkinter Library (nanny graphics + implementation code)
[Python black technology] tkinter library actual combat "2048" game (nanny graphics + implementation code)
[Python black technology] tkinter library actual combat "Tetris" game (nanny graphic + implementation code)
[Python black technology] tkinter library actual combat "greedy snake" game (nanny graphic + implementation code)
[Python black technology] tkinter library actual combat "Lianliankan" game (nanny graphics + implementation code)
[Python installs a third-party library with a one-line command to permanently increase the speed]
[package exe with PyInstaller]
[one click download of Zhihu article pictures without login crawler (nanny graphic + implementation code)]
[lonely programmers chat with AI robot friends to relieve boredom (free interface + nanny level graphics + implementation code comments)]
[draw gif dynamic diagram with a few lines of code (nanny level picture and text + implementation code)]
[several lines of code to realize regular and cyclic screenshots of online class and save important knowledge points (nanny level graphics and text + implementation code)]
[common user_agent browser head crawler simulates users (nanny level graphics + implementation code)]
[more details]