学习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库)。
发表评论:
◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。