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

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

上期讲到相同的色块连接,链接见: 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)//2COLOR = []
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, hself.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 = groupdef hide(self):self.box.batch = self.rect.batch = Nonedef on_mouse_over(self, x, y):return self.x<=x<=self.x+self.w and self.y<=y<=self.y+self.hfor 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, cdef __repr__(self):return f'Rc({self.r}, {self.c})'def __and__(self, other):return self.r == other.r and self.c == other.cdef __or__(self, other):return self.r == other.r or self.c == other.cdef __eq__(self, other):return self & otherdef __lt__(self, other):return self.r == other.r and self.c != other.cdef __gt__(self, other):return self.r != other.r and self.c == other.cdef __le__(self, other):return self.r == other.r and self.c - other.cdef __ge__(self, other):return self.c == other.c and self.r - other.rdef __xor__(self, other):return self < other or self > otherdef __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 -1def __add__(self, other):return abs(self<=other)==1 or abs(self>=other)==1def __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 Falseclass Game:def __init__(self):self.array = Arrayself.boxes = Boxesself.rc, self.rc2 = RC(), RC()self.last, self.last2 = None, Noneself.line = shapes.Line(0, 0, 0, 0, width=5, color=Color('light gold').rgba, batch=batch, group=group)self.line.visible = Falsedef on_mouse_click(self, x, y):if self.line.visible or self.success(): returnr, 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').rgbaelif 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').rgbaif self.rc == self.rc2:self.last.box.color = Color('WHITE').rgbaself.last, self.last2 = None, Noneelse: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 = Trueclock.schedule_interval(self.update, 0.3)return (r, c), Color(self.boxes[r][c].rect.color).namedef getxy(self, row, col):return x0+col*(w+space)+w//2, y0+row*(h+space)+h//2def update(self, event):self.line.visible = Falseclock.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] = 0else:self.last.box.color = self.last2.box.color = Color('WHITE').rgbaself.last, self.last2 = None, Noneif 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)//2COLOR = []
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, hself.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 = groupdef hide(self):self.box.batch = self.rect.batch = Nonedef on_mouse_over(self, x, y):return self.x<=x<=self.x+self.w and self.y<=y<=self.y+self.hclass 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, cdef __repr__(self):return f'Rc({self.r}, {self.c})'def __and__(self, other):return self.r == other.r and self.c == other.cdef __or__(self, other):return self.r == other.r or self.c == other.cdef __eq__(self, other):return self & otherdef __lt__(self, other):return self.r == other.r and self.c != other.cdef __gt__(self, other):return self.r != other.r and self.c == other.cdef __le__(self, other):return self.r == other.r and self.c - other.cdef __ge__(self, other):return self.c == other.c and self.r - other.rdef __xor__(self, other):return self < other or self > otherdef __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 -1def __add__(self, other):return abs(self<=other)==1 or abs(self>=other)==1def __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 Falseclass Game:def __init__(self):self.array = Arrayself.boxes = Boxesself.rc, self.rc2 = RC(), RC()self.last, self.last2 = None, Noneself.line = shapes.Line(0, 0, 0, 0, width=5, color=Color('light gold').rgba, batch=batch, group=group)self.line.visible = Falsedef on_mouse_click(self, x, y):if self.line.visible or self.success(): returnr, 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').rgbaelif 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').rgbaif self.rc == self.rc2:self.last.box.color = Color('WHITE').rgbaself.last, self.last2 = None, Noneelse: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 = Trueclock.schedule_interval(self.update, 0.3)return RC(r, c), Color(self.boxes[r][c].rect.color).namedef getxy(self, row, col):return x0+col*(w+space)+w//2, y0+row*(h+space)+h//2def update(self, event):self.line.visible = Falseclock.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] = 0print(matrix)else:self.last.box.color = self.last2.box.color = Color('WHITE').rgbaself.last, self.last2 = None, Noneif 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 keyW, 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)//2sound1, 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, hself.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 = Nonedef show(self):self.box.batch = self.rect.batch = batchdef on_mouse_over(self, x, y):return self.x<=x<=self.x+self.w and self.y<=y<=self.y+self.hclass 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 = Falsedef __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 0def 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 0def adjacent(self, point1, point2):return point1*point2def 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 Truedef 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]) orself.inline(p[i],(p1,p2)[i]))and self.diagonal(p[i], (p2,p1)[i]):self.point.append(p[i])return Truedef connect(self, p1, p2):if (ret := self.connect1(p1, p2) or self.connect2(p1, p2)):self.showlines(p1, p2)return retdef getxy(self, row, col):return x0+col*(w+space)+w//2, y0+row*(h+space)+h//2def 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 = Truedef 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, point2self.drawline(*points)self.point.clear()def hidelines(self):for line in self.lines: line.visible = Falsedef linevisible(self):return self.lines[0].visibledef initMatrix(row, col):global matrix, Array, Boxesmatrix = Matrix(row+2, col+2)Array, Boxes = matrix.array, Matrix().arrayfor i in range(row):for j in range(col):Array[i+1][j+1] = 0COLOR = 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, Boxesself.last1, self.last2, self.lastz = None, None, Noneself.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(): returnif 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').rgbaelif 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').rgbaif self.rc == self.rc2:self.last1.box.color = Color('WHITE').rgbaself.last1, self.last2 = None, Noneelse: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).namedef 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').rgbaself.lastz = self.last1, self.last2self.last1, self.last2 = None, Nonematrix.hidelines()if game.success():window.set_caption('彩色方块连连看——任务完成!')game.label1.batch = game.label2.batch = batch2clock.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] = 1def 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] = 0def success(self):return sum(sum(self.array,[]))==(row+2)*(col+2) def main(event):global gamegame = Game()game.label1.batch = game.label2.batch = Nonewindow.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, batchelif symbol == key.F and modifiers & key.MOD_CTRL:if sum(sum(game.array,[]))%2: returnboxsample = []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.mzph.cn/news/792484.shtml

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

相关文章

VC++建立空文档失败的一种情形

假设现在要在单文档程序的客户区创建控件; 把控件作为视类的成员变量; 先把成员变量定义加到视类头文件; 然后在视类的, BOOL CMyttView::PreCreateWindow(CREATESTRUCT& cs) {....... } 在此成员函数中创建控件; 运行程序,就会出现如下错误, 这就需要在类向导…

gpt4.0中文版

我愿把这个网站成为全球最强AI网站&#xff01;弄100多个AI伺候你&#xff1f;&#xff1f; 家人们&#xff0c;你们猜我发现了什么牛逼的AI网站&#xff1f;&#xff1f; 直接上图&#xff1a; 编辑 这个网站&#xff0c;聚合了国内外100多个顶尖的AI&#xff0c;包括了Op…

Spring Security 实现后台切换用户

Spring Security version 后端代码&#xff1a; /*** author Jerry* date 2024-03-28 17:47* spring security 切换账号*/RestController RequiredArgsConstructor RequestMapping("api/admin") public class AccountSwitchController {private final UserDetailsSe…

【JAVA】JAVA快速入门(长期维护)

下面是java的一些入门基础知识&#xff0c;有需要借鉴即可。 课程&#xff1a;B站黑马程序员&#xff0c;JAVA入门LINK 一、初识JAVA 1.java概述 概念&#xff1a;java是由sun公司研发&#xff0c;在2009年被oracle收购&#xff0c;祖师爷詹姆斯高斯林&#xff0c;是一种高级…

C++核心编程——4.2(2)对象的初始化和清理

4.2.5 深拷贝与浅拷贝 浅拷贝&#xff1a;编译器提供的简单的赋值拷贝操作 深拷贝&#xff1a;在堆区重新申请空间&#xff0c;进行拷贝操作 示例&#xff1a; class Person { public://无参&#xff08;默认&#xff09;构造函数Person() {cout << "无参构造函数…

力扣热题100_链表_2_两数相加

文章目录 题目链接解题思路解题代码 题目链接 2. 两数相加 给你两个 非空 的链表&#xff0c;表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的&#xff0c;并且每个节点只能存储 一位 数字。 请你将两个数相加&#xff0c;并以相同形式返回一个表示和的链表。 …

黑马鸿蒙笔记

目录 25-Stage模型-页面及组件生命周期 26-Stage模型-UIAbility的启动模式 25-Stage模型-页面及组件生命周期 26-Stage模型-UIAbility的启动模式 singleton 只会有一个实例 multiton 会有多个&#xff0c;但是会销毁旧的 standard 会有多个&#xff0c;但是不会销毁

【MATLAB第102期】基于MATLAB的BRT增强回归树多输入单输出回归预测模型

【MATLAB第102期】基于MATLAB的BRT增强回归树多输入单输出回归预测模型 BRT&#xff0c;即Boosted Regression Trees&#xff08;增强回归树&#xff09;&#xff0c;是一种用于回归问题的集成学习方法。它结合了多个决策树模型&#xff0c;通过逐步改进的方式来提高整体模型的…

GDAL源码剖析(九)之GDAL体系架构

GDAL源码剖析&#xff08;九&#xff09;之GDAL体系架构_gdal 源码-CSDN博客 在GDAL库中包含栅格数据的读写&#xff0c;矢量数据的读写&#xff0c;以及栅格和矢量数据的相关算法。下面主要对GDAL中栅格数据和矢量数据的体系架构做一个简单的说明。本人英文很烂&#xff0c;有…

Linux 多线程与线程控制(程序均有详细注释)

多线程与线程控制 线程的基本概念线程的特点页表多线程 线程控制线程的创建线程传参线程id资源回收---线程等待线程id和LWP 封装一个线程库线程互斥和线程同步线程互斥基本原理线程安全VS线程不安全锁的诞生可重入VS线程安全 死锁死锁的定义 线程同步条件变量接口 生成消费者模…

使用Python获取红某书笔记详情并批量无水印下载

根据红某手最新版 请求接口必须要携带x-s x-s-c x-t,而调用官方接口又必须携带cookie,缺一不可,获取笔记详情可以通过爬取网页的形式获取&#xff0c;虽然也是无水印&#xff0c;但是一些详情信息只能获取大概&#xff0c;并不是详细的数值&#xff0c;因此既不想自己破解x-s x…

清明时节雨纷纷,AI达人用Bedrock(第一季)

今天是清明小长假第一天&#xff0c;没有外出踏青&#xff0c;在家体验Amazon Bedrock的强大能力。Amazon Bedrock是专门为创新者量身打造的平台&#xff0c;它提供了构建生成式人工智能应用程序所需的一切。 这次我主要尝试的是通过 Amazon Bedrock 里的 Stability AI SDXL 1…

C++理解std::move和转发(std::forward)

理解 std::move 标准库move函数是使用右值引用的模板的一个很好的例子。 幸运的是&#xff0c;我们不必理解move所使用的模板机制也可以直接使用它。 但是&#xff0c;研究move是如何工作的可以帮助我们巩固对模板的理解和使用。 我们注意到&#xff0c;虽然不能直接将一个…

提升工作效率:B端工作台设计基础详解

随着互联网和信息技术的快速发展&#xff0c;越来越多的企业开始以数字化、智能化的方式管理和运营自己的业务。B端工作台设计作为企业应用的重要组成部分&#xff0c;越来越受到重视。本文将从三个方面对B端工作台设计进行全面分析。让我们看看。 1. B端工作台设计原则 B端工…

攻防世界 wife_wife

在这个 JavaScript 示例中&#xff0c;有两个对象&#xff1a;baseUser 和 user。 baseUser 对象定义如下&#xff1a; baseUser { a: 1 } 这个对象有一个属性 a&#xff0c;其值为 1&#xff0c;没有显式指定原型对象&#xff0c;因此它将默认继承 Object.prototype。 …

不堪大用的pow

【题目描述】 输出100&#xff5e;999中的所有水仙花数。若3位数ABC满足&#xff0c;则称其为水仙花 数。例如&#xff0c;所以153是水仙花数。 【题目来源】 刘汝佳《算法竞赛入门经典 第2版》习题2-1 水仙花数&#xff08;daffodil&#xff09; 题目很简单&#xff0c;…

配置vite配置文件更改项目端口、使用@别名

一、配置vite配置文件更改项目端口 vite官方文档地址&#xff1a;开发服务器选项 | Vite 官方中文文档 (vitejs.dev) 使用&#xff1a; 二、使用别名 1. 安装 types/node types/node 包允许您在TypeScript项目中使用Node.js的核心模块和API&#xff0c;并提供了对它们的类型…

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

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

每日面经分享(python part1)

Python中的深拷贝和浅拷贝的区别是什么&#xff1f; a. 浅拷贝创建一个新的对象&#xff0c;但其中的可变元素仍然共享引用。只有对象的第一层被复制&#xff0c;而更深层次的嵌套对象仍然是引用。更改其中一个对象的属性会影响到其他对象。 b. 深拷贝创建一个完全独立的新对象…

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

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