15
2024
11

python编程学习-汉诺塔

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

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

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

from xdf import *

dizuo = box(1, 1, 1024, 80, '#000')
mc4 = box(1, 1, 40, 200, '#000')
mc5 = box(1, 1, 40, 200, '#000')
mc6 = box(1, 1, 40, 200, '#000')
mc1 = box(1, 1, 240, 40, '#c0c')
mc2 = box(1, 1, 200, 40, '#cc0')
mc3 = box(1, 1, 160, 40, '#0cc')

poles = [mc4, mc5, mc6]
dizuo.move(512, 768 + 40)
mc4.move(128 - 20, 768 - 100)
mc5.move(384 - 20, 768 - 100)
mc6.move(640 - 20, 768 - 100)
stack1 = []
stack2 = []
stack3 = []
stacks = []

mcs = [mc1, mc2, mc3]
dragMc = None
isOver = False
isAutoPlay = False
overTxt = text("点击任意位置开始", 0, 0, 50, 'red', 'center')

def reStart():
    global stack1, stack2, stack3, stacks, mc1, mc2, mc3, overTxt, isOver,isAutoPlay
    isOver = False
    isAutoPlay = False
    overTxt.hide()
    stack1 = [mc1, mc2, mc3]
    stack2 = []
    stack3 = []
    stacks = [stack1, stack2, stack3]
    for i in range(len(stack1)):
        stack1[i].move(128 - 20, 768 - 20 - i * 40)

def tap():
    global isOver
    if isOver:
        reStart()

def loop():
    pass

def win():
    global isOver, overTxt, isAutoPlay
    isOver = True
    isAutoPlay = False
    overTxt.show()

def touch():
    global isOver, dragMc, mcs, isAutoPlay
    if isOver or dragMc != None or isAutoPlay:
        return
    for i in range(len(mcs)):
        mc = mcs[i]
        if mc.hits(x, y) and isTop(mc):
            dragMc = mc
            # print('touch mc', i)
            break;
    #print('touch', x//1, y//1)
    
def isTop(mc):
    global stack1, stack2, stack3
    return isTopS(stack1, mc) or isTopS(stack2, mc)or isTopS(stack3, mc)

def isTopS(stack, mc):
    return len(stack) and stack[len(stack) - 1] == mc

def touching():
    global dragMc
    if dragMc != None:
        dragMc.move(x, y)
        
def untouch():
    global dragMc, poles
    if dragMc != None:
        dragMc.move(x, y)
        for i in range(len(poles)):
            pole = poles[i]
            if canPut(dragMc, pole):
                putTo(dragMc, pole)
                dragMc = None
                return
        putBack(dragMc)
        dragMc = None

def canPut(mc, pole):
    if(mc.hits(pole)):
        global poles, stacks, mcs
        stack = stacks[poles.index(pole)]
        if len(stack) == 0:
            return True
        tmc = stack[len(stack) - 1]
        if tmc == mc or mcs.index(mc) > mcs.index(tmc):
            return True
    return False

def pop(stack):
    if len(stack) > 0:
        return stack.pop()
    return None

def putTo(mc, pole):
    i1 = getMcIndex(mc)
    i2 = getPoleIndex(pole)
    global stacks
    s1 = stacks[i1]
    s2 = stacks[i2]
    s2.append(s1.pop())
    p = getPosI(i2)
    tweenTo(mc, p[0], p[1])

def getPosI(i):
    return [128 - 20 + i * 256, 768 - 20 - (len(stacks[i]) - 1) * 40]

def putBack(mc):
    global stacks
    i = getMcIndex(mc)
    p = getPosI(i)
    tweenTo(mc, p[0], p[1])
    
def tweenTo(mc, tx, ty):
    mc.move(tx, ty, 200)
    checkWin()

def checkWin():
    if isWin():
        win();

def isWin():
    global stack3
    return len(stack3) == 3

def getPoleIndex(pole):
    global poles
    return poles.index(pole)
    
def getMcIndex(mc):
    global stacks
    for i in range(3):
        try:
            stacks[i].index(mc)
            return i
        except:
            pass
    return -1

reStart()

##########################自动求解###############
#算法来源:https://zhuanlan.zhihu.com/p/36090187
btn = text("自动求解", 600, 50, 50, 'red', 'center')
paths = [
            ['BBB', 'BBC', 'BAC', 'BAA', 'CAA', 'CAB', 'CCB', 'CCC'],
            ['AAA', 'AAC', 'ABC', 'ABB', 'CBB', 'CBA', 'CCA', 'CCC'],
            ['BCC', 'BCB', 'BAB', 'BAA', 'CAA', 'CAB', 'CCB', 'CCC'],
            ['ACC', 'ACA', 'ABA', 'ABB', 'CBB', 'CBA', 'CCA', 'CCC'],
            ['CAC', 'CAB', 'CCB', 'CCC'],
            ['CBC', 'CBA', 'CCA', 'CCC'],
            ['BBA', 'BBC', 'BAC', 'BAA', 'CAA', 'CAB', 'CCB', 'CCC'],
            ['BCA', 'BCB', 'BAB', 'BAA', 'CAA', 'CAB', 'CCB', 'CCC'],
            ['ACB', 'ACA', 'ABA', 'ABB', 'CBB', 'CBA', 'CCA', 'CCC'],
            ['AAB', 'AAC', 'ABC', 'ABB', 'CBB', 'CBA', 'CCA', 'CCC']
        ]

def findPath(s):
    for i in range(len(paths)):
        p = paths[i]
        for j in range(len(p)):
            if s == p[j]:
                return p[j:]
    return None

def getCurState():
    global stacks,mcs
    a = []
    for i in range(len(mcs)):
        for j in range(len(stacks)):
            try:
                k = stacks[j].index(mcs[i])
                a.append('ABC'[j])
                break
            except:
                pass
    return ''.join(a)

def getStep(s1, s2):
    for i in range(len(s1)):
        c1 = s1[i]
        c2 = s2[i]
        if c1 != c2:
            return ['ABC'.index(c1), 'ABC'.index(c2)]
    return None

def doStep(a, b):
    global stacks
    pos0 = getPosI(a)
    mc = stacks[a].pop()
    stacks[b].append(mc)
    pos1 = getPosI(b)
    mc.move(pos0[0], 512, 300)
    delay(mc.move, 300, pos1[0], 512, 300)
    delay(mc.move, 600, pos1[0], pos1[1], 300)

def step(p, n):
    if n == len(p) - 1:
        win()
        return
    st = getStep(p[n], p[n + 1])
    # print(st)
    try:
        doStep(st[0], st[1])
    except:
        pass
    delay(step, 1000, p, n+1)
    
def autoPlay():
    global isAutoPlay
    isAutoPlay = True
    s = getCurState()
    #print(s)
    p = findPath(s)
    #print(p)
    step(p, 0)
    
btn.tap = autoPlay


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



« 上一篇下一篇 »

相关文章:

python编程学习-玛丽跳跳跳  (2024-11-15 11:36:43)

python编程学习-模拟键盘按键  (2024-11-15 11:35:50)

python编程学习-显示帧频  (2024-11-15 11:35:26)

python编程学习-收不完的西瓜  (2024-11-15 11:35:0)

python编程学习-推箱子  (2024-11-15 11:34:1)

python编程学习-拼图  (2024-11-15 11:33:25)

python编程学习-扫雷  (2024-11-15 11:32:58)

python编程学习-小学数学加减分解题  (2024-11-15 11:32:29)

python编程学习-对角棋  (2024-11-15 11:32:8)

python编程学习-密室逃生  (2024-11-15 11:31:35)

发表评论:

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