15
2024
11

python编程学习-迷宫04

学习python编程,在新东方少儿编程官网的自由创作平台做的一些作品。

可以在线运行,效果如下(在新页面中打开链接):

代码如下(用到平台自定义的xdf库):

from xdf import *
import math
mazeArr = [] # 迷宫数组
visitedArr = [] # 已经访问过的点
visitingArr = [] # 准备访问的点
visitnotArr = [] # 未访问的点
mazeContainer = []
count = 0 # 计数,记录走过多少个格子,当走过的格子数等于格子总数时,停止计算
totalCube = 0 # 记录格子总数,比如10*10的迷宫,格子数为100
directionArr = ["none", "wall", "left", "right", "up", "down"]
M = 2
N = 2
W = 768
H = 1024
CW = int(W / 2)
CH = CW
OX = 0
OY = 0
R = int(CW / 2)
rowArr = []
colArr = []
linePool = []
lineArr = []
level = 1

start = circle(-100, -100, R, "red")
end = circle(-100, -100, R, "green")
tf = text("第1关", 0, 60, 50, "red")
restartTf = text("重新开始", W, 60, 50, "red", "right")

def xy2ij(x, y):
    return [int((x - OX) / CW), int((y - OY) / CH)]

def ij2xy(i, j):
    return [OX + i * CW, OY + j * CH]

def inittMaze():
    global CW,CH,OX,OY,R,totalCube,count
    count = 0
    totalCube = M * N
    R = int(CW / 2)
    moveTo(start, 0, 0)
    moveTo(end, M - 1, N - 1)
    start.size(R * 0.8)
    end.size(R)
    mazeArr.clear()
    for i in range(M+2):
        mazeArr.append([])
        for j in range(N+2):
            if i == 0 or i == M + 1 or j == 0 or j == N + 1:
                mazeArr[i].append(0)
            else:
                mazeArr[i].append(1)
    updateArr(1, 1, 0)
    while 1:
        createRoad()
        if count == totalCube:
            break
    rowArr.clear()
    colArr.clear()
    for i in range(M + 1):
        rowArr.append([])
        for j in range(N):
            rowArr[i].append(1)
    colArr.clear()
    for i in range(M):
        colArr.append([])
        for j in range(N+1):
            colArr[i].append(1)
    updateMap()
    drawMaze()
    #print(mazeArr)
    pass

def updateMap():
    for i in range(1, M + 1):
        for j in range(1, N + 1):
            v = mazeArr[i][j]
            #print(i, j, v)
            if v == 2: # 左
                rowArr[i - 1][j - 1] = 0
            elif v == 3: # 右
                rowArr[i][j - 1] = 0
            elif v == 4: # 上
                colArr[i - 1][j - 1] = 0
            elif v == 5: # 下
                colArr[i - 1][j] = 0
            pass
        pass
    pass
def drawMaze():
    clearLine()
    for i in range(M + 1):
        for j in range(N):
            if rowArr[i][j] != 0:
                drawLine(i, j, i, j + 1)
    for i in range(M):
        for j in range(N + 1):
            if colArr[i][j] != 0:
                drawLine(i, j, i + 1, j)
    pass

def hasNeighbor(i, j):
    arr = [[i+1, j], [i-1, j], [i, j+1], [i, j-1]]
    neighborArr = []
    for a in range(4):
        ii = arr[a][0]
        jj = arr[a][1]
        if mazeArr[ii][jj] == 1:
            neighborArr.append([ii, jj, a + 2])
    return neighborArr

def updateArr(i, j, d):
    global count
    count += 1
    visitedArr.append([i,j])
    mazeArr[i][j] = d
    pass
def createRoad():
    p = visitedArr[-1]
    neighbor = hasNeighbor(p[0], p[1])
    if len(neighbor) == 0:
        visitedArr.pop()
    else:
        a = random(0, len(neighbor) - 1)
        p = neighbor[a]
        updateArr(p[0], p[1], p[2])
    pass

def segment(left, right, top, bottom):
    segI = -1
    segJ = -1
    if left == right - 1:
        for i in range(top + 1, bottom):
            colArr[left][i] = 0
        return
    elif top == bottom - 1:
        for i in range(left + 1, right):
            rowArr[i][top] = 0
        return
    segI = random(left + 1, right - 1)
    segJ = random(top + 1, bottom - 1)
    rand = random(0, 3)
    randIJ = 0
    if rand != 0:
        randIJ = random(top, segJ - 1)
        rowArr[segI][randIJ] = 0
    if rand != 1:
        randIJ = random(segJ, bottom - 1)
        rowArr[segI][randIJ] = 0
    if rand != 2:
        randIJ = random(left, segI - 1)
        colArr[randIJ][segJ] = 0
    if rand != 3:
        randIJ = random(segI, right - 1)
        colArr[randIJ][segJ] = 0
    segment(left, segI, top, segJ)
    segment(segI, right, top, segJ)
    segment(left, segI, segJ, bottom)
    segment(segI, right, segJ, bottom)
    pass

def clearLine():
    linePool.extend(lineArr)
    lineArr.clear()
    pass

def drawLine(i1, j1, i2, j2):
    li = getLine()
    li.p = [i1, j1, i2, j2]
    setLine(li, i1, j1, i2, j2)

def getLine():
    li = None
    if len(linePool):
        li = linePool.pop()
    else:
        li = line(-100, -100, -200, -200, 20, "black")
    lineArr.append(li)
    return li

def rad2ang(rad):
    return 180 * rad / math.pi


def setLine(li, i0, j0, i1, j1):
    p0 = ij2xy(i0, j0)
    p1 = ij2xy(i1, j1)
    x0 = p0[0]
    y0 = p0[1]
    x1 = p1[0]
    y1 = p1[1]
    #
    dx = x1 - x0
    dy = y1 - y0
    sz = math.sqrt(dx * dx + dy * dy)
    rot = math.atan2(dy, dx)
    li.move(x0, y0)
    li.rotate(rad2ang(rot) + 90)
    li.size(sz)
    pass

def reset():
    inittMaze()
    refresh()

def refresh():
    global OX,OY,W,H
    ij = xy2ij(start.x, start.y)
    OX = int(W / 2 - start.x + OX)
    OY = int(H / 2 - start.y + OY)
    moveTo(start, ij[0], ij[1])
    moveTo(end, M - 1, N - 1)
    for li in linePool:
        li.hide()
    for li in lineArr:
        li.show()
        setLine(li, li.p[0], li.p[1], li.p[2], li.p[3])
    end.front()
    start.front()

def nextLevel():
    global level, M, N
    level += 1
    M += 1
    N += 1
    tf.change("第" + str(level) + "关")
    reset()
    pass

def moveTo(c, i, j):
    p = ij2xy(i + 0.5, j + 0.5)
    c.move(p[0], p[1])
    

def move(arr, di, dj):
    ij = xy2ij(start.x, start.y)
    i = ij[0]
    j = ij[1]
    ti = i + di
    tj = j + dj
    ii = i if di <= 0 else ti
    jj = j if dj <= 0 else tj
    if arr[ii][jj] == 0:
        moveTo(start, ti, tj)
        refresh()
        checkOver()
    pass

def checkOver():
    p1 = xy2ij(start.x, start.y)
    p2 = xy2ij(end.x, end.y)
    if p1[0] == p2[0] and p1[1] == p2[1]:
        nextLevel()
    pass

def keyup(key, code):
    if key == 37:
        move(rowArr, -1, 0)
    elif key == 38:
        move(colArr, 0, -1)
    elif key == 39:
        move(rowArr, 1, 0)
    elif key == 40:
        move(colArr, 0, 1)
    elif key == 82 or key == 32:
        reset()
    pass

restartTf.tap = reset
reset()

class MyKeyBoard:
    def __init__(self, x, y, w):
        hw = w / 2
        hhw = w * 0.75
        self.arr = [
            box(x, y - w, w, w, "white", "red"),
            text("↑", x + hw, y - w + hhw, w, "center", "red"),
            box(x, y, w, w, "white", "red"),
            text("↓", x + hw, y + hhw, w, "center", "red"),
            box(x - w, y, w, w, "white", "red"),
            text("←", x - hw, y + hhw, w, "center", "red"),
            box(x + w, y, w, w, "white", "red"),
            text("→", x + w + hw, y + hhw, w, "center", "red"),
        ]
        self.arr[0].tap=self.clickUp
        self.arr[2].tap=self.clickDown
        self.arr[4].tap=self.clickLeft
        self.arr[6].tap=self.clickRight
        delay(self.loop, 100)
        
    def loop(self):
        for i in range(len(self.arr)):
            self.arr[i].front()
        delay(self.loop, 100)
    
    def onKeydown(self, keyCode, key):
        try:
            keyup(keyCode, key)
        except e:
            pass
    def clickUp(self):
        self.onKeydown(38, "ArrowLeft")
    def clickDown(self):
        self.onKeydown(40, "ArrowDown")
    def clickLeft(self):
        self.onKeydown(37, "ArrowLeft")
    def clickRight(self):
        self.onKeydown(39, "ArrowRight")
MyKeyBoard(768-160, 1024-80, 80)

也可以下载代码,本地python环境运行(用pygame封装了xdf库)。



« 上一篇下一篇 »

相关文章:

python编程学习-黑白棋  (2024-11-15 11:43:40)

python编程学习-迷宫03  (2024-11-15 11:42:42)

python编程学习-迷宫02  (2024-11-15 11:42:16)

python编程学习-迷宫01  (2024-11-15 11:41:55)

python编程学习-连连看  (2024-11-15 11:41:16)

python编程学习-进入大圈  (2024-11-15 11:40:57)

python编程学习-跳伞  (2024-11-15 11:40:27)

python编程学习-跑酷01  (2024-11-15 11:40:3)

python编程学习-赛车  (2024-11-15 11:39:38)

python编程学习-贪食蛇  (2024-11-15 11:38:41)

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。