Python 一步一步教你用pyglet制作“彩色方块连连看”游戏(续)

news2025/1/19 2:40:10

“彩色方块连连看”游戏(续)

上期讲到相同的色块连接,链接见: Python 一步一步教你用pyglet制作“彩色方块连连看”游戏-CSDN博客

第八步

续上期,接下来要实现相邻方块的连线:

首先来进一步扩展 行列的类:

class RC:
    def __init__(self, r=0, c=0):
        self.r, self.c = r, c
    def __repr__(self):
        return f'Rc({self.r}, {self.c})'
    def __and__(self, other):
        return self.r == other.r and self.c == other.c
    def __or__(self, other):
        return self.r == other.r or self.c == other.c
    def __eq__(self, other):
        return self & other
    def __lt__(self, other):
        return self.r == other.r and self.c != other.c
    def __gt__(self, other):
        return self.r != other.r and self.c == other.c
    def __le__(self, other):
        return self.r == other.r and self.c - other.c
    def __ge__(self, other):
        return self.c == other.c and self.r - other.r
    def __xor__(self, other):
        return self < other or self > other
    def __mod__(self, other):
        return [RC(self.r, other.c), RC(other.r, self.c)]
    def __truediv__(self, other):
        return 1 if self<other and (self<=other)<0 or self>other and (self>=other)<0 else -1
    def __add__(self, other):
        return abs(self<=other)==1 or abs(self>=other)==1
    def __sub__(self, other):
        if self<other: return [RC(self.r,_) for _ in range(self.c+(self/other),other.c,self/other)]
        if self>other: return [RC(_,self.c) for _ in range(self.r+(self/other),other.r,self/other)]
        return []
    def __mul__(self, other):
        if self<other: return not any(Array[self.r+1][_+1] for _ in range(self.c+(self/other),other.c,self/other))
        if self>other: return not any(Array[_+1][self.c+1] for _ in range(self.r+(self/other),other.r,self/other))
        return False

由上面的类可知,self.rc*self.rc2就表示两点相邻,加时update方法中的if语句,就能实现相邻色块的连线并消去:

    def update(self, event):
        self.line.visible = False
        clock.unschedule(self.update)
        if self.last.rect.color==self.last2.rect.color and self.rc*self.rc2:
            self.last.hide(); self.last2.hide()
            self.array[self.rc.r][self.rc.c] = self.array[self.rc2.r][self.rc2.c] = 0
        else:
            self.last.box.color = self.last2.box.color = Color('WHITE').rgba
        self.last, self.last2 = None, None
        if game.success():
            window.set_caption('彩色色块连连看——任务完成!') 

代码:

from pyglet import *
from colorlib import *

W, H = 800, 600
window = window.Window(W, H, caption='彩色色块连连看')
gl.glClearColor(*Color('lightblue3').decimal)
batch, group = graphics.Batch(),graphics.Group()

row, col, space = 6, 8, 5
w, h = W//(col+2), H//(row+2)
x0, y0 = (W-(w+space)*col)//2, (H-(h+space)*row)//2

COLOR = []
while len(COLOR)<row*col//4:
    if (c:=randcolorTuple()) not in COLOR:
        COLOR.append(c)
COLOR = sample(COLOR*4, row*col)
Array, Boxes = [[[1]*col for _ in range(row)] for _ in range(2)]

class Box:
    def __init__(self, x, y, w, h, color, batch=batch):
        self.x, self.y, self.w, self.h = x, y, w, h
        self.rect = shapes.Rectangle(x, y, w, h, color=color, batch=batch)
        self.box = shapes.Box(x, y, w, h, color=Color('WHITE').rgba, thickness=3, batch=batch)
        self.box.group = group
    def hide(self):
        self.box.batch = self.rect.batch = None
    def on_mouse_over(self, x, y):
        return self.x<=x<=self.x+self.w and self.y<=y<=self.y+self.h

for r,arr in enumerate(Boxes):
    for c,_ in enumerate(arr):
        Boxes[r][c] = Box(x0+c*(w+space), y0+r*(h+space), w, h, COLOR[c+r*len(arr)])

class RC:
    def __init__(self, r=0, c=0):
        self.r, self.c = r, c
    def __repr__(self):
        return f'Rc({self.r}, {self.c})'
    def __and__(self, other):
        return self.r == other.r and self.c == other.c
    def __or__(self, other):
        return self.r == other.r or self.c == other.c
    def __eq__(self, other):
        return self & other
    def __lt__(self, other):
        return self.r == other.r and self.c != other.c
    def __gt__(self, other):
        return self.r != other.r and self.c == other.c
    def __le__(self, other):
        return self.r == other.r and self.c - other.c
    def __ge__(self, other):
        return self.c == other.c and self.r - other.r
    def __xor__(self, other):
        return self < other or self > other
    def __mod__(self, other):
        return [RC(self.r, other.c), RC(other.r, self.c)]
    def __truediv__(self, other):
        return 1 if self<other and (self<=other)<0 or self>other and (self>=other)<0 else -1
    def __add__(self, other):
        return abs(self<=other)==1 or abs(self>=other)==1
    def __sub__(self, other):
        if self<other: return [RC(self.r,_) for _ in range(self.c+(self/other),other.c,self/other)]
        if self>other: return [RC(_,self.c) for _ in range(self.r+(self/other),other.r,self/other)]
        return []
    def __mul__(self, other):
        if self<other: return not any(Array[self.r+1][_+1] for _ in range(self.c+(self/other),other.c,self/other))
        if self>other: return not any(Array[_+1][self.c+1] for _ in range(self.r+(self/other),other.r,self/other))
        return False

class Game:
    def __init__(self):
        self.array = Array
        self.boxes = Boxes
        self.rc, self.rc2 = RC(), RC()
        self.last, self.last2 = None, None
        self.line = shapes.Line(0, 0, 0, 0, width=5, color=Color('light gold').rgba, batch=batch, group=group)
        self.line.visible = False
    def on_mouse_click(self, x, y):
        if self.line.visible or self.success(): return
        r, c = (y-y0)//(h+space), (x-x0)//(w+space)
        if r in range(row) and c in range(col) and self.boxes[r][c].on_mouse_over(x, y) and self.array[r][c]:
            if self.last is None and self.last2 is None:
                self.rc, self.last = RC(r, c), self.boxes[r][c]
                self.last.box.color = Color('RED').rgba
            elif self.last is not None and self.last2 is None:
                self.rc2, self.last2 = RC(r, c), self.boxes[r][c]
                self.last2.box.color = Color('RED').rgba
                if self.rc == self.rc2:
                    self.last.box.color = Color('WHITE').rgba
                    self.last, self.last2 = None, None
                else:
                    self.line.x, self.line.y = self.getxy(r, c)
                    self.line.x2, self.line.y2 = self.getxy(self.rc.r, self.rc.c)
                    self.line.visible = True
                    clock.schedule_interval(self.update, 0.3)
            return (r, c), Color(self.boxes[r][c].rect.color).name
    def getxy(self, row, col):
        return x0+col*(w+space)+w//2, y0+row*(h+space)+h//2
    def update(self, event):
        self.line.visible = False
        clock.unschedule(self.update)
        if self.last.rect.color==self.last2.rect.color and self.rc*self.rc2:
            self.last.hide(); self.last2.hide()
            self.array[self.rc.r][self.rc.c] = self.array[self.rc2.r][self.rc2.c] = 0
        else:
            self.last.box.color = self.last2.box.color = Color('WHITE').rgba
        self.last, self.last2 = None, None
        if game.success():
            window.set_caption('彩色色块连连看——任务完成!')         
    def success(self):
        return sum(sum(self.array,[]))==0    

@window.event
def on_draw():
    window.clear()
    batch.draw()

@window.event
def on_mouse_press(x, y, dx, dy):
    ret = game.on_mouse_click(x, y)
    if ret and not game.success():
        window.set_caption(f'彩色色块连连看——坐标:{ret[0]}  颜色:{ret[1]}')

game = Game()
app.run()

第九步

实现同行或同列的连线,self.rc+self.rc2就能实现同行或同列的点连线。

if self.last.rect.color==self.last2.rect.color and ((self.rc*self.rc2) or (self.rc+self.rc2)):

代码

from pyglet import *
from colorlib import *

W, H = 800, 600
window = window.Window(W, H, caption='彩色方块连连看')
gl.glClearColor(*Color('lightblue3').decimal)
batch, group = graphics.Batch(),graphics.Group()

row, col, space = 8, 10, 5
w, h = W//(col+2), H//(row+2)
x0, y0 = (W-(w+space)*col)//2, (H-(h+space)*row)//2

COLOR = []
while len(COLOR)<row*col//8:
    if (c:=randcolorTuple()) not in COLOR:
        COLOR.append(c)
COLOR = sample(COLOR*8, row*col)

class Box:
    def __init__(self, x, y, w, h, color, batch=batch):
        self.x, self.y, self.w, self.h = x, y, w, h
        self.rect = shapes.Rectangle(x, y, w, h, color=color, batch=batch)
        self.box = shapes.Box(x, y, w, h, color=Color('WHITE').rgba, thickness=3, batch=batch)
        self.box.group = group
    def hide(self):
        self.box.batch = self.rect.batch = None
    def on_mouse_over(self, x, y):
        return self.x<=x<=self.x+self.w and self.y<=y<=self.y+self.h

class Matrix:
    def __init__(self, row=row, col=col):
        self.array = [[0]*col for _ in range(row)]
    def __repr__(self):
         return '\n'.join(map(str,self.array))+'\n'

matrix = Matrix(row+2, col+2)
Array, Boxes = matrix.array, Matrix().array
for i in range(row):
    for j in range(col):
        Array[i+1][j+1] = 1
for r,arr in enumerate(Boxes):
    for c,_ in enumerate(arr):
        Boxes[r][c] = Box(x0+c*(w+space), y0+r*(h+space), w, h, COLOR[c+r*len(arr)])

class RC:
    def __init__(self, r=0, c=0):
        self.r, self.c = r, c
    def __repr__(self):
        return f'Rc({self.r}, {self.c})'
    def __and__(self, other):
        return self.r == other.r and self.c == other.c
    def __or__(self, other):
        return self.r == other.r or self.c == other.c
    def __eq__(self, other):
        return self & other
    def __lt__(self, other):
        return self.r == other.r and self.c != other.c
    def __gt__(self, other):
        return self.r != other.r and self.c == other.c
    def __le__(self, other):
        return self.r == other.r and self.c - other.c
    def __ge__(self, other):
        return self.c == other.c and self.r - other.r
    def __xor__(self, other):
        return self < other or self > other
    def __mod__(self, other):
        return [RC(self.r, other.c), RC(other.r, self.c)]
    def __truediv__(self, other):
        return 1 if self<other and (self<=other)<0 or self>other and (self>=other)<0 else -1
    def __add__(self, other):
        return abs(self<=other)==1 or abs(self>=other)==1
    def __sub__(self, other):
        if self<other: return [RC(self.r,_) for _ in range(self.c+(self/other),other.c,self/other)]
        if self>other: return [RC(_,self.c) for _ in range(self.r+(self/other),other.r,self/other)]
        return []
    def __mul__(self, other):
        if self<other: return not any(Array[self.r+1][_+1] for _ in range(self.c+(self/other),other.c,self/other))
        if self>other: return not any(Array[_+1][self.c+1] for _ in range(self.r+(self/other),other.r,self/other))
        return False

class Game:
    def __init__(self):
        self.array = Array
        self.boxes = Boxes
        self.rc, self.rc2 = RC(), RC()
        self.last, self.last2 = None, None
        self.line = shapes.Line(0, 0, 0, 0, width=5, color=Color('light gold').rgba, batch=batch, group=group)
        self.line.visible = False
    def on_mouse_click(self, x, y):
        if self.line.visible or self.success(): return
        r, c = (y-y0)//(h+space), (x-x0)//(w+space)
        if r in range(row) and c in range(col) and self.boxes[r][c].on_mouse_over(x, y) and self.array[r+1][c+1]:
            if self.last is None and self.last2 is None:
                self.rc, self.last = RC(r, c), self.boxes[r][c]
                self.last.box.color = Color('RED').rgba
            elif self.last is not None and self.last2 is None:
                self.rc2, self.last2 = RC(r, c), self.boxes[r][c]
                self.last2.box.color = Color('RED').rgba
                if self.rc == self.rc2:
                    self.last.box.color = Color('WHITE').rgba
                    self.last, self.last2 = None, None
                else:
                    self.line.x, self.line.y = self.getxy(r, c)
                    self.line.x2, self.line.y2 = self.getxy(self.rc.r, self.rc.c)
                    self.line.visible = True
                    clock.schedule_interval(self.update, 0.3)
            return RC(r, c), Color(self.boxes[r][c].rect.color).name
    def getxy(self, row, col):
        return x0+col*(w+space)+w//2, y0+row*(h+space)+h//2
    def update(self, event):
        self.line.visible = False
        clock.unschedule(self.update)
        if self.last.rect.color==self.last2.rect.color and ((self.rc*self.rc2) or (self.rc+self.rc2)):
            self.last.hide(); self.last2.hide()
            self.array[self.rc.r+1][self.rc.c+1] = self.array[self.rc2.r+1][self.rc2.c+1] = 0
            print(matrix)
        else:
            self.last.box.color = self.last2.box.color = Color('WHITE').rgba
        self.last, self.last2 = None, None
        if game.success():
            window.set_caption('彩色色块连连看——任务完成!')         
    def success(self):
        return sum(sum(self.array,[]))==0    

@window.event
def on_draw():
    window.clear()
    batch.draw()

@window.event
def on_mouse_press(x, y, dx, dy):
    ret = game.on_mouse_click(x, y)
    if ret and not game.success():
        window.set_caption(f'彩色色块连连看——坐标:{ret[0]}  颜色:{ret[1]}')

game = Game()
app.run()

第十步

改写RC行列类完善更多的功能,见另一篇博文:

Python 妙用运算符重载——玩出“点”花样来-CSDN博客

RC行列改写成整数坐标点的类,完整的 pointlib.py代码如下:

class Point:
    def __init__(self, x=0, y=0):
        self.x, self.y = x, y
    def __repr__(self):
        return f'Point({self.x}, {self.y})'
    def __str__(self):
        return f'({self.x}, {self.y})'
    def __getitem__(self, index):
        if index in range(-2,2):
            return self.y if index in (1,-1) else self.x
        raise IndexError("Index out of range")
    def __setitem__(self, index, value):
        if index in (0, -2):
            self.x = value
        elif index in (1, -1):
            self.y = value
        else:
            raise IndexError("Index out of range.")
    @property
    def value(self):
        return self.x, self.y
    def __len__(self):
        return 2
    def __abs__(self):
        return Point(*map(abs,(self.x, self.y)))
    def __bool__(self):
        return self.x>=0 and self.y>=0
    def __neg__(self):
        return Point(-self.x, -self.y)
    def __pos__(self):
        return self(0, 1), self(0, -1), self(-1), self(1)
    def __call__(self, dx=0, dy=0):
        return Point(self.x + dx, self.y + dy)
    def __eq__(self, other):
        return self.x == other.x and self.y == other.y
    def __ne__(self, other):
        return self.x != other.x or self.y != other.y
    def __gt__(self, other):
        return self.x == other.x and self.y - other.y
    def __lt__(self, other):
        return self.y == other.y and self.x - other.x
    def __ge__(self, other):
        return self.x == other.x and abs(self.y - other.y)==1
    def __le__(self, other):
        return self.y == other.y and abs(self.x - other.x)==1
    def __and__(self, other):
        return self.x != other.x and self.y != other.y
    def __radd__(self, n):
        return self(0, n), self(0, -n), self(-n), self(n)
    def __or__(self, other):
        return self.x == other.x or self.y == other.y
    def __xor__(self, other):
        return self.x == other.x and self.y != other.y or self.x != other.x and self.y == other.y
    def __invert__(self):
        return Point(self.y, self.x)
    def __lshift__(self, other):
        return Point(self.x + other, self.y)
    def __rshift__(self, other):
        return Point(self.x, self.y + other)
    def __add__(self, other):
        return Point(self.x + other.x, self.y + other.y)
    def __sub__(self, other):
        return ((self.x - other.x)**2 + (self.y - other.y)**2)**0.5
    def __mul__(self, other):
        return self >= other or self <= other
    def __truediv__(self, other):
        return (self^other) and (1 if (self<other)<0 or (self>other)<0 else -1)
    def __pow__(self, other):
        if self^other:
            if self<other: return [Point(_, self.y) for _ in range(self.x+(self/other),other.x,self/other)]
            if self>other: return [Point(self.x, _) for _ in range(self.y+(self/other),other.y,self/other)]
    def __mod__(self, other):
        return [Point(self.x, other.y), Point(other.x, self.y)]
    def __floordiv__(self, other):
        if self&other:
            mod1, mod2 = self % other
            return self**mod1 + [mod1] + mod1**other, self**mod2 + [mod2] + mod2**other
    def __rpow__(self, other):
        assert(isinstance(other, (tuple, list)) and len(other)==3)
        x, y, n = other
        return [Point(i, n) for i in range(min(x, self.x), max(x, self.x)+1)]
    def __rfloordiv__(self, other: tuple):
        assert(isinstance(other, (tuple, list)) and len(other)==3)
        x, y, n = other
        return [Point(n, i) for i in range(min(y, self.y), max(y, self.y)+1)]

第十一步

实现一个折角的连线,如下图a点到b点,只要判断a->c->b或者a->d->b是通路即可:

对角连线的核心函数:

    def diagonal(self, point1, point2):
        if point1&point2:
            for point in point1%point2:
                state1 = self.adjacent(point, point1) or self.inline(point, point1)
                state2 = self.adjacent(point, point2) or self.inline(point, point2)
                if self.true(point) and state1 and state2:
                    self.point.append(point)
                    return True

第十二步

实现两个折角的连线,如下图的P点,如它和指点坐标不是相邻也不是同行或同列并且一个折角也不能相连,那么它向上下左右逐点延伸,只要有一个点能与指点坐标一个折角相连就完成了两个折角的相连。

最终实现

用前两步的思路,进一步完善和改写各个类,以完成所有的各种连线情况: 

一、相邻

    def adjacent(self, point1, point2):
        return point1*point2

二、同行列

    def inline(self, point1, point2):
        return point1^point2 and self.alltrue(point1**point2)

三、对角线

    def diagonal(self, point1, point2):
        if point1&point2:
            for point in point1%point2:
                state1 = self.adjacent(point, point1) or self.inline(point, point1)
                state2 = self.adjacent(point, point2) or self.inline(point, point2)
                if self.true(point) and state1 and state2:
                    self.point.append(point)
                    return True

四、以上3种情况

    def connect1(self, p1, p2):
        return self.adjacent(p1, p2) or self.inline(p1, p2) or self.diagonal(p1, p2)

五、二折角连线

    def connect2(self, p1, p2):
        for i in range(1, max(row, col)):
            for p in zip(i+p1, i+p2):
                for i in range(2):
                    if self.true(p[i]) and (self.adjacent(p[i],(p1,p2)[i]) or
                            self.inline(p[i],(p1,p2)[i]))and self.diagonal(p[i], (p2,p1)[i]):
                        self.point.append(p[i])
                        return True

六、可以相连就显示折线

    def connect(self, p1, p2):
        if (ret := self.connect1(p1, p2) or self.connect2(p1, p2)):
            self.showlines(p1, p2)
        return ret

完整代码

再加上键盘事件等功能:

ctrl+Z 恢复一步

ctrl+F 保留剩余方块的随机刷新

ctrl+R 保留所有方块的重新开始 

ctrl+S 全部刷新的重新开始

完整代码: 

from pyglet import *
from colorlib import *
from pointlib import Point
from pyglet.window import key

W, H = 800, 600
window = window.Window(W, H)
gl.glClearColor(*Color('lightblue3').decimal)
batch, batch2, group = graphics.Batch(), graphics.Batch(), graphics.Group()

row, col, space = 8, 10, 5
w, h = W//(col+2), H//(row+2)
x0, y0 = (W-(w+space)*col)//2, (H-(h+space)*row)//2

sound1, sound2 = media.load('box.mp3'), media.load('box2.mp3')

def randColor():
    COLOR = []
    while len(COLOR)<row*col//4:
        if not ((c:=randcolorTuple()) in COLOR or Color(c).name[-1] in '0123456789'):
            COLOR.append(c)
    return sample(COLOR*4, row*col)

class Box:
    def __init__(self, x, y, w, h, color, batch=batch):
        self.x, self.y, self.w, self.h = x, y, w, h
        self.rect = shapes.Rectangle(x, y, w, h, color=color, batch=batch)
        self.box = shapes.Box(x, y, w, h, color=Color('WHITE').rgba, thickness=3, batch=batch)
    def hide(self):
        self.box.batch = self.rect.batch = None
    def show(self):
        self.box.batch = self.rect.batch = batch
    def on_mouse_over(self, x, y):
        return self.x<=x<=self.x+self.w and self.y<=y<=self.y+self.h

class Matrix:
    def __init__(self, r=row, c=col):
        self.array = [[1]*c for _ in range(r)]
        self.point = []
        self.lines = [shapes.Line(*[-3]*4, width=5, color=Color('light gold').rgba,
                            batch=batch2, group=group) for _ in range(5)]
        for line in self.lines: line.visible = False
    def __repr__(self):
        return '\n'.join(map(str,self.array))+'\n'
    def true(self, point):
        try: return self.array[point.x+1][point.y+1]
        except: return 0
    def alltrue(self, points):
        if isinstance(points,(tuple,list)) and all(isinstance(p, Point) for p in points):
            try: return all(self.array[p.x+1][p.y+1] for p in points)
            except: return 0
    def adjacent(self, point1, point2):
        return point1*point2
    def inline(self, point1, point2):
        return point1^point2 and self.alltrue(point1**point2)
    def diagonal(self, point1, point2):
        if point1&point2:
            for point in point1%point2:
                state1 = self.adjacent(point, point1) or self.inline(point, point1)
                state2 = self.adjacent(point, point2) or self.inline(point, point2)
                if self.true(point) and state1 and state2:
                    self.point.append(point)
                    return True
    def connect1(self, p1, p2):
        return self.adjacent(p1, p2) or self.inline(p1, p2) or self.diagonal(p1, p2)
    def connect2(self, p1, p2):
        for i in range(1, max(row, col)):
            for p in zip(i+p1, i+p2):
                for i in range(2):
                    if self.true(p[i]) and (self.adjacent(p[i],(p1,p2)[i]) or
                            self.inline(p[i],(p1,p2)[i]))and self.diagonal(p[i], (p2,p1)[i]):
                        self.point.append(p[i])
                        return True
    def connect(self, p1, p2):
        if (ret := self.connect1(p1, p2) or self.connect2(p1, p2)):
            self.showlines(p1, p2)
        return ret
    def getxy(self, row, col):
        return x0+col*(w+space)+w//2, y0+row*(h+space)+h//2
    def drawline(self, *args):
        for i,p in enumerate(args[:-1]):
            self.lines[i].x, self.lines[i].y = self.getxy(*p)
            self.lines[i].x2, self.lines[i].y2 = self.getxy(*args[i+1])
            self.lines[i].visible = True
    def showlines(self, point1, point2):
        if len(self.point)==3: self.point.pop(0)
        if len(self.point)==2 and not self.point[0]^point1: self.point.reverse()
        points = point1, *self.point, point2
        self.drawline(*points)
        self.point.clear()
    def hidelines(self):
        for line in self.lines: line.visible = False
    def linevisible(self):
        return self.lines[0].visible

def initMatrix(row, col):
    global matrix, Array, Boxes
    matrix = Matrix(row+2, col+2)
    Array, Boxes = matrix.array, Matrix().array
    for i in range(row):
        for j in range(col):
            Array[i+1][j+1] = 0
    COLOR = randColor()
    for r,arr in enumerate(Boxes):
        for c,_ in enumerate(arr):
            Boxes[r][c] = Box(x0+c*(w+space), y0+r*(h+space), w, h, COLOR[c+r*len(arr)])

class Game:
    def __init__(self):
        initMatrix(row, col)
        self.rc, self.rc2 = Point(), Point()
        self.array, self.boxes = Array, Boxes
        self.last1, self.last2, self.lastz = None, None, None
        self.label1 = text.Label('Congratulations!', color=Color().randcolor().rgba, font_size=50,
                                    x=W//2, y=H//2+80, anchor_x='center', anchor_y='center', bold=True, batch=batch)
        self.label2 = text.Label('Any key to restart...', color=Color().randcolor().rgba, font_size=36,
                                    x=W//2, y=H//2-50, anchor_x='center', anchor_y='center', bold=True, batch=batch)
    def on_mouse_click(self, x, y):
        if matrix.linevisible(): return
        if self.success(): main(event)
        r, c = (y-y0)//(h+space), (x-x0)//(w+space)
        if r in range(row) and c in range(col) and self.boxes[r][c].on_mouse_over(x, y) and not self.array[r+1][c+1]:
            if self.last1 is None and self.last2 is None:
                self.rc, self.last1 = Point(r, c), self.boxes[r][c]
                self.last1.box.color = Color('RED').rgba
            elif self.last1 is not None and self.last2 is None:
                self.rc2, self.last2 = Point(r, c), self.boxes[r][c]
                self.last2.box.color = Color('RED').rgba
                if self.rc == self.rc2:
                    self.last1.box.color = Color('WHITE').rgba
                    self.last1, self.last2 = None, None
                else:
                    if self.last1.rect.color==self.last2.rect.color:
                        matrix.connect(self.rc, self.rc2)
                    clock.schedule_interval(self.update, 0.5)
            return (r, c), Color(self.boxes[r][c].rect.color).name
    def update(self, event):
        clock.unschedule(self.update)
        if self.last1.rect.color==self.last2.rect.color and matrix.connect(self.rc, self.rc2):
            self.hide()
            sound1.play()
        else:
            sound2.play()
        self.last1.box.color = self.last2.box.color = Color('WHITE').rgba
        self.lastz = self.last1, self.last2
        self.last1, self.last2 = None, None
        matrix.hidelines()
        if game.success():
            window.set_caption('彩色方块连连看——任务完成!')
            game.label1.batch = game.label2.batch = batch2
            clock.schedule_interval(main, 5) # 5秒后自动开始
    def hide(self):
        self.last1.hide(); self.last2.hide()
        self.array[self.rc.x+1][self.rc.y+1] = self.array[self.rc2.x+1][self.rc2.y+1] = 1
    def unhide(self):
        self.lastz[0].show(); self.lastz[1].show()
        self.array[self.rc.x+1][self.rc.y+1] = self.array[self.rc2.x+1][self.rc2.y+1] = 0
    def success(self):
        return sum(sum(self.array,[]))==(row+2)*(col+2) 

def main(event):
    global game
    game = Game()
    game.label1.batch = game.label2.batch = None
    window.set_caption('彩色方块连连看')
    clock.unschedule(main)

@window.event
def on_draw():
    window.clear()
    batch.draw()
    batch2.draw()

@window.event
def on_mouse_press(x, y, dx, dy):
    if (ret := game.on_mouse_click(x, y)):
        window.set_caption(f'彩色方块连连看——坐标:{ret[0]}  颜色:{ret[1]}')

@window.event
def on_key_press(symbol, modifiers):
    if game.success(): main(event)
    if symbol == key.S and modifiers & key.MOD_CTRL:
        main(event)
    elif symbol == key.Z and modifiers & key.MOD_CTRL:
        game.unhide()
    elif symbol == key.R and modifiers & key.MOD_CTRL:
        for i in range(row):
            for j in range(col):
                Array[i+1][j+1], Boxes[i][j].box.batch, Boxes[i][j].rect.batch = 0, batch, batch
    elif symbol == key.F and modifiers & key.MOD_CTRL:
        if sum(sum(game.array,[]))%2: return
        boxsample = []
        for i,arr in enumerate(Array[1:-1]):
            for j,n in enumerate(arr[1:-1]):
                if n==0: boxsample.append(Boxes[i][j].rect.color)
        boxsample = sample(boxsample,len(boxsample))
        for i,arr in enumerate(Array[1:-1]):
            for j,n in enumerate(arr[1:-1]):
                if n==0: Boxes[i][j].rect.color = boxsample.pop()

main(event)
app.run()

运行效果

目录

“彩色方块连连看”游戏(续)

第八步

第九步

第十步

第十一步

第十二步

最终实现

完整代码

运行效果


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1568965.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

STM32 can通信部分函数注释

-----CAN1_Mode_Init CAN模式初始化函数:u8 CAN1_Mode_Init(u8 tsjw,u8 tbs2,u8 tbs1,u16 brp,u8 mode) //CAN初始化 //tsjw:重新同步跳跃时间单元.范围:CAN_SJW_1tq~ CAN_SJW_4tq //tbs2:时间段2的时间单元. 范围:CAN_BS2_1tq~CAN_BS2_8tq; //tbs1:时间段1的时间单元. 范…

day63 单调栈part02

503. 下一个更大元素 II 中等 给定一个循环数组 nums &#xff08; nums[nums.length - 1] 的下一个元素是 nums[0] &#xff09;&#xff0c;返回 nums 中每个元素的 下一个更大元素 。 数字 x 的 下一个更大的元素 是按数组遍历顺序&#xff0c;这个数字之后的第一个比它更…

vue快速入门(六)v-else和v-else-if

注释很详细&#xff0c;直接上代码 上一篇 新增内容 v-else-if用法v-else用法 源码 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-s…

docker部署nacos,单例模式(standalone),使用内置的derby数据库,简易安装

文章目录 前言安装创建文件夹docker指令安装docker指令安装-瘦身版 制作docker-compose.yaml文件查看页面 前言 nacos作为主流的服务发现中心和配置中心&#xff0c;广泛应用于springcloud框架中&#xff0c;现在就让我们一起简易的部署一个单例模式的nacos&#xff0c;版本可…

算法学习系列(四十六):迭代加深、双向DFS

目录 引言概念一、加成序列二、送礼物 引言 本文主要讲了&#xff0c; D F S DFS DFS 的另外两种优化&#xff0c;分别是迭代加深和双向 D F S DFS DFS &#xff0c;思路还是非常清晰明了的&#xff0c;只要会写 D F S DFS DFS 那么这些剪枝和优化其实还是非常的容易的&…

Vue监听器watch的基本用法

文章目录 1. 作用2. 格式3. 示例3.1 value 值为字符串3.2 value 值为函数3.3 value 值为对象 4. 与计算属性对比 1. 作用 监视数据变化&#xff0c;执行一些业务逻辑或异步操作。 2. 格式 监听器 watch 内部以 key &#xff1a;value 的形式定义&#xff0c;key 是 data 中的…

用html写一个爱心

<!DOCTYPE html> <html lang"zh-CN"><head><meta http-equiv"Content-Type" content"text/html; charsetUTF-8" /><title>爱您</title><style>* {padding: 0;margin: 0;}body {background-color: pin…

C语言笔试题之求解X的平方根

求解X的平方根 一、实例要求 1、给定一个非负整数 x &#xff0c;计算并返回 x 的算术平方根 &#xff1b;2、由于返回类型是整数&#xff0c;结果只保留整数部分 &#xff0c;小数部分将被舍去&#xff1b;3、不允许使用任何内置指数函数、运算符&#xff1b; 二、实例分析…

图DP

目录 有向无环图DP 力扣 329. 矩阵中的最长递增路径 力扣 2192. 有向无环图中一个节点的所有祖先 有向有环图DP 力扣 1306. 跳跃游戏 III 有向无环图DP 力扣 329. 矩阵中的最长递增路径 给定一个 m x n 整数矩阵 matrix &#xff0c;找出其中 最长递增路径 的长度。 对…

C语言:文件操作(二)

目录 前言 4、文件的顺序读写 4.1fputc 4.2 fgetc 4.3 fputs 4.4 fgets 4.5 fprintf 4.6 fscanf 4.7 fread和fwrite 结&#xff08;二&#xff09; 前言 接者“C语言&#xff1a;文件操作&#xff08;一&#xff09;”往下讲。 本篇文章将介绍C语言的文件操作&#xf…

【数字图像处理matlab系列】空间域处理之亮度变换(imadjust函数使用)

【数字图像处理matlab系列】空间域处理之亮度变换(imadjust函数使用) 在空间域中&#xff0c;图像处理就是直接对图像的像素进行操作 imadjust 是 MATLAB 中用于调整图像强度值或颜色图的函数。它可以改变图像的对比度&#xff0c;使得图像更清晰或更易于分析。以下是 imadju…

【MATLAB源码-第178期】基于matlab的8PSK调制解调系统频偏估计及补偿算法仿真,对比补偿前后的星座图误码率。

操作环境&#xff1a; MATLAB 2022a 1、算法描述 在通信系统中&#xff0c;频率偏移是一种常见的问题&#xff0c;它会导致接收到的信号频率与发送信号的频率不完全匹配&#xff0c;进而影响通信质量。在调制技术中&#xff0c;QPSK&#xff08;Quadrature Phase Shift Keyi…

4.2总结

了解了部分Api的使用并学习了接口的API API API包含了较多种类&#xff08;System,Runtime等&#xff09; System其实就是一个工具类&#xff0c;提供了一些与系统相关的方法 下面有一些常间的System方法 方法名说明public static void exit (int status)终止当前运行的ja…

Android JNI 调用第三方SO

最近一个项目使用了Go 编译了一个so库&#xff0c;但是这个so里面还需要使用第三方so库pdfium, 首先在Android工程把2个so库都放好 在jni中只能使用dlopen方式&#xff0c;其他的使用函数指针的方式来调用&#xff0c;和windows dll类似&#xff0c;不然虽然编译过了但是会崩溃…

picGo图床搭建gitee和smms(建议使用)

picGoGitee 这个需要下载gitee插件, 因为官方频繁的检索文件类型, 有时候也会失效 如果没有特殊要求平时存个学习的要看图中文字的重要的图片建议就是smms, 免费也够用! 图片存本地不方便, 各种APP中来回传还会失帧损失画质, 所以你值得往下看 picGosmms 建议使用这个, sm…

为移动云数据实现基于可撤销属性组的加密:多代理辅助方法

参考文献为2023年发表的Achieving Revocable Attribute Group-Based Encryption for Mobile Cloud Data: A Multi-Proxy Assisted Approach 动机 对于目前的代理辅助的可撤销基于属性加密来说&#xff0c;外包解密存一些缺点。当多个具有相同属性的用户请求外包转换时&#x…

非写代码无以致远

标题党一下&#xff0c;本篇文章主要汇总了一些代码题&#xff0c;让大家写一些代码练习一下吧&#xff01; 变种水仙花_牛客题霸_牛客网 (nowcoder.com) #include<stdio.h> int main() {for (int i 10000; i < 99999; i) {int sum 0;for (int j 10; j < 1000…

业务网关的设计与实践

在过去的两年里&#xff0c;主要在做业务网关的开发。今年春节后选择转岗去做更偏近业务的开发。公司的业务是金融相关&#xff0c;一直觉得金融相关的业务是有一定门槛并且是对职业生涯有帮助的&#xff0c;所以趁这个机会来深入了解这块业务。 仔细回想&#xff0c;在做业务…

数据结构和算法:十大排序

排序算法 排序算法用于对一组数据按照特定顺序进行排列。排序算法有着广泛的应用&#xff0c;因为有序数据通常能够被更高效地查找、分析和处理。 排序算法中的数据类型可以是整数、浮点数、字符或字符串等。排序的判断规则可根据需求设定&#xff0c;如数字大小、字符 ASCII…

【算法】单单单单单调栈,接接接接接雨水

【算法】单单单单单调栈&#xff0c;接接接接接雨水 今天没有小故事。 参考以及题单来源&#xff1a; 代码随想录 (programmercarl.com) Part 1 啥是单调栈&#xff1f; 1.啥啥啥是单调栈&#xff1f; 栈的特性想必各位再熟悉不过了&#xff1a;先进后出。栈仅仅有一个出口&a…