目錄
漢諾塔游戲
7. 漢諾塔類
8. 移動圓盤
9. 移動演示
10. 遞歸問題
11. 任意展示
12. 鼠標(biāo)操作
漢諾塔游戲
漢諾塔(Tower of Hanoi),是一個源于印度古老傳說的益智玩具。這個傳說講述了大梵天創(chuàng)造世界的時候,他做了三根金剛石柱子,并在其中一根柱子上從下往上按照大小順序摞著64片黃金圓盤。大梵天命令婆羅門將這些圓盤從下面開始按大小順序重新擺放在另一根柱子上,并規(guī)定在小圓盤上不能放大圓盤,同時在三根柱子之間一次只能移動一個圓盤。當(dāng)盤子的數(shù)量增加時,移動步驟的數(shù)量會呈指數(shù)級增長,圓盤數(shù)為n時,總步驟數(shù)steps為2^n - 1。
n = 64, steps = 2^64 - 1 = 18446744073709551616 ≈ 1.845 x 10^19
漢諾塔問題是一個遞歸問題,也可以使用非遞歸法來解決,例如使用棧來模擬遞歸過程。這個問題不僅是一個數(shù)學(xué)和邏輯問題,也是一個很好的教學(xué)工具,可以用來教授遞歸、算法和邏輯思考等概念。同時,漢諾塔游戲也具有一定的娛樂性,人們可以通過解決不同規(guī)模的漢諾塔問題來挑戰(zhàn)自己的智力和耐心。
本篇接著上期講下去,這次爭取把圓盤移動起來,前篇的鏈接地址:
Python 一步一步教你用pyglet制作漢諾塔游戲-CSDN博客
7. 漢諾塔類
前篇的最后已經(jīng)初步把漢諾塔的架子搭好了,可以顯示但移動的描述很復(fù)雜。所以得改造一下,把三個塔架設(shè)計到一個類中,方便圓盤的移動,運(yùn)行后效果不變:
代碼:
import pyglet
window = pyglet.window.Window(800, 500, caption='漢諾塔')
pyglet.gl.glClearColor(1, 1, 1, 1)
batch = pyglet.graphics.Batch()
Color = (182,128,18),(25,65,160),(56,170,210),(16,188,78),(20,240,20),(240,240,20),(255,128,20),(240,20,20),(245,60,138)
class Disk:
def __init__(self, x, y, color=(0,0,0), width=200, height=20):
self.cir1 = pyglet.shapes.Circle(x+width/2-height/2, y, radius=height/2, color=color, batch=batch)
self.cir2 = pyglet.shapes.Circle(x-width/2+height/2, y, radius=height/2, color=color, batch=batch)
self.rect = pyglet.shapes.Rectangle(x-width/2+height/2, y-height/2, width-height, height, color=color, batch=batch)
class Hann:
def __init__(self, x, y, order=2, space=250, thickness=20, width=200, height=300):
assert(order>1)
self.pole = [pyglet.shapes.Line(x-i*space, y, x-i*space, y+height, width=thickness, color=Color[0], batch=batch) for i in range(-1,2)]
self.disk = [Disk(x+i*space, y, color=Color[0], width=width+thickness, height=thickness) for i in range(-1,2)]
self.x, self.y = x, y
self.order = order
self.space = space
self.thickness = thickness
self.width = width
self.height = (height-thickness*2)/order
self.step = (width-thickness)/(order+1)
coordinates = [(self.x-space, self.y+(i+1)*self.height-(self.height-thickness)/2) for i in range(order)]
self.beads = [Disk(*xy, Color[i%8+1], width=self.width-i*self.step, height=self.height) for i,xy in enumerate(coordinates)]
@window.event
def on_draw():
window.clear()
batch.draw()
hann = Hann(window.width/2, 120, 8)
pyglet.app.run()
8. 移動圓盤
給圓盤類和漢諾塔類各設(shè)計一個.move()方法,主旨思想是圓盤的相對位置移動,不需要在調(diào)用時計算各種控件的具體坐標(biāo)值。
代碼:
import pyglet
window = pyglet.window.Window(800, 500, caption='漢諾塔')
pyglet.gl.glClearColor(1, 1, 1, 1)
batch = pyglet.graphics.Batch()
Color = (182,128,18),(25,65,160),(56,170,210),(16,188,78),(20,240,20),(240,240,20),(255,128,20),(240,20,20),(245,60,138)
class Disk:
def __init__(self, x, y, color=(0,0,0), width=200, height=20):
self.cir1 = pyglet.shapes.Circle(x+width/2-height/2, y, radius=height/2, color=color, batch=batch)
self.cir2 = pyglet.shapes.Circle(x-width/2+height/2, y, radius=height/2, color=color, batch=batch)
self.rect = pyglet.shapes.Rectangle(x-width/2+height/2, y-height/2, width-height, height, color=color, batch=batch)
def move(self, dx, dy):
self.cir1.x += dx; self.cir1.y += dy
self.cir2.x += dx; self.cir2.y += dy
self.rect.x += dx; self.rect.y += dy
class Hann:
def __init__(self, x, y, order=2, space=250, thickness=20, width=200, height=300):
assert(order>1)
self.pole = [pyglet.shapes.Line(x-i*space, y, x-i*space, y+height, width=thickness, color=Color[0], batch=batch) for i in range(-1,2)]
self.disk = [Disk(x+i*space, y, color=Color[0], width=width+thickness, height=thickness) for i in range(-1,2)]
self.x, self.y = x, y
self.order = order
self.space = space
self.thickness = thickness
self.width = width
self.height = (height-thickness*2)/order
self.step = (width-thickness)/(order+1)
coordinates = [(self.x-space, self.y+(i+1)*self.height-(self.height-thickness)/2) for i in range(order)]
self.beads = [Disk(*xy, Color[i%8+1], width=self.width-i*self.step, height=self.height) for i,xy in enumerate(coordinates)]
self.array = [[*range(order)], [], []]
def move(self, pole1, pole2):
if self.array[pole1]:
bead = self.array[pole1].pop()
if self.array[pole2] and bead<self.array[pole2][-1]:
print('大盤不能搬到小盤上')
return False
else:
print('所選擇的塔架為空!')
return None
self.beads[bead].move((pole2-pole1)*self.space, (len(self.array[pole2])-len(self.array[pole1]))*self.height)
self.array[pole2].append(bead)
return True
@window.event
def on_draw():
window.clear()
batch.draw()
hann = Hann(window.width/2, 100, 7)
hann.move(0,1)
hann.move(0,2)
hann.move(1,2)
hann.move(0,1)
hann.move(2,0)
hann.move(2,1)
hann.move(0,1)
hann.move(0,2)
pyglet.app.run()
9. 移動演示
pyglet.clock.schedule_interval(function,? seconds) 是 Pyglet 庫中的一個函數(shù)調(diào)用,用于定期調(diào)度另一個函數(shù)function在指定的時間間隔seconds內(nèi)執(zhí)行。
pyglet.clock.unschedule(function) 任務(wù)完成后使用此函數(shù)來取消調(diào)度,以避免不必要的資源消耗。
以下展示一個四層漢諾塔的移動演示:
代碼:?
import pyglet
window = pyglet.window.Window(800, 500, caption='漢諾塔')
pyglet.gl.glClearColor(1, 1, 1, 1)
batch = pyglet.graphics.Batch()
Color = (182,128,18),(25,65,160),(56,170,210),(16,188,78),(20,240,20),(240,240,20),(255,128,20),(240,20,20),(245,60,138)
class Disk:
def __init__(self, x, y, color=(0,0,0), width=200, height=20):
self.cir1 = pyglet.shapes.Circle(x+width/2-height/2, y, radius=height/2, color=color, batch=batch)
self.cir2 = pyglet.shapes.Circle(x-width/2+height/2, y, radius=height/2, color=color, batch=batch)
self.rect = pyglet.shapes.Rectangle(x-width/2+height/2, y-height/2, width-height, height, color=color, batch=batch)
def move(self, dx, dy):
self.cir1.x += dx; self.cir1.y += dy
self.cir2.x += dx; self.cir2.y += dy
self.rect.x += dx; self.rect.y += dy
class Hann:
def __init__(self, x, y, order=2, space=250, thickness=20, width=200, height=300):
assert(order>1)
self.pole = [pyglet.shapes.Line(x-i*space, y, x-i*space, y+height, width=thickness, color=Color[0], batch=batch) for i in range(-1,2)]
self.disk = [Disk(x+i*space, y, color=Color[0], width=width+thickness, height=thickness) for i in range(-1,2)]
self.x, self.y = x, y
self.order = order
self.space = space
self.thickness = thickness
self.width = width
self.height = (height-thickness*2)/order
self.step = (width-thickness)/(order+1)
coordinates = [(self.x-space, self.y+(i+1)*self.height-(self.height-thickness)/2) for i in range(order)]
self.beads = [Disk(*xy, Color[i%8+1], width=self.width-i*self.step, height=self.height) for i,xy in enumerate(coordinates)]
self.array = [[*range(order)], [], []]
def move(self, pole1, pole2):
if self.array[pole1]:
bead = self.array[pole1].pop()
if self.array[pole2] and bead<self.array[pole2][-1]:
print('大盤不能搬到小盤上')
return False
else:
print('所選擇的塔架為空!')
return None
self.beads[bead].move((pole2-pole1)*self.space, (len(self.array[pole2])-len(self.array[pole1]))*self.height)
self.array[pole2].append(bead)
return True
@window.event
def on_draw():
window.clear()
batch.draw()
def on_move(event):
global moves
if moves:
x, y = moves.pop(0)
hann.move(x, y)
label.text = f'盤架{x+1}的圓盤移到盤架{y+1}上'
else:
label.text = '演示完畢!'
pyglet.clock.unschedule(on_move)
hann = Hann(window.width/2, 120, 4)
moves = [(0,1), (0,2), (1,2), (0,1), (2,0), (2,1), (0,1), (0,2), (1,2), (1,0), (2,0), (1,2), (0,1), (0,2), (1,2)]
label = pyglet.text.Label('漢諾塔圓盤自動移動演示', font_size=24, color=(0,0,0,255), x=window.width/2, y=50, anchor_x='center', batch=batch)
pyglet.clock.schedule_interval(on_move, 1)
pyglet.app.run()
10. 遞歸問題
雖然解決了自動演示的功能,但繼續(xù)增加層數(shù)怎么辦?還是要自己解決這個問題,本篇前言里就說了漢諾塔問題就是一個遞歸問題,所以就用遞歸函數(shù)來解決,通常寫法:
def hanoi(n, start, mid, end):
if n == 1:
print('Move disk 1 from', start, 'to', end)
else:
hanoi(n-1, start, end, mid)
print('Move disk', n, 'from', start, 'to', end)
hanoi(n-1, mid, start, end)
hanoi(4, 0, 1, 2)
運(yùn)行的打印結(jié)果為:?
Move disk 1 from 0 to 1
Move disk 2 from 0 to 2
Move disk 1 from 1 to 2
Move disk 3 from 0 to 1
Move disk 1 from 2 to 0
Move disk 2 from 2 to 1
Move disk 1 from 0 to 1
Move disk 4 from 0 to 2
Move disk 1 from 1 to 2
Move disk 2 from 1 to 0
Move disk 1 from 2 to 0
Move disk 3 from 1 to 2
Move disk 1 from 0 to 1
Move disk 2 from 0 to 2
Move disk 1 from 1 to 2
移動的坐標(biāo)剛好與上一步指定的相同,但要改造這個函數(shù),我們需要的是坐標(biāo)返回值不是打印信息,所以指定一列表用于存放這些坐標(biāo),改造后的函數(shù):
def hanoi(n, start, mid, end, moves=None):
if moves is None:
moves = []
if n == 1:
moves.append((start, end))
else:
hanoi(n-1, start, end, mid, moves)
moves.append((start, end))
hanoi(n-1, mid, start, end, moves)
return moves
for order in (4,7,8):
moves = hanoi(order, 0, 1, 2)
print(len(moves)==2**order-1)
print(moves)
運(yùn)行結(jié)果:
True
[(0, 1), (0, 2), (1, 2), (0, 1), (2, 0), (2, 1), (0, 1), (0, 2), (1, 2), (1, 0), (2, 0), (1, 2), (0, 1), (0, 2), (1, 2)]
True
[(0, 2), (0, 1), (2, 1), (0, 2), (1, 0), (1, 2), (0, 2), (0, 1), (2, 1), (2, 0), (1, 0), (2, 1), (0, 2), (0, 1), (2, 1), (0, 2), (1, 0), (1, 2), (0, 2), (1, 0), (2, 1), (2, 0), (1, 0), (1, 2), (0, 2), (0, 1), (2, 1), (0, 2), (1, 0), (1, 2), (0, 2), (0, 1), (2, 1), (2, 0), (1, 0), (2, 1), (0, 2), (0, 1), (2, 1), (2, 0), (1, 0), (1, 2), (0, 2), (1, 0), (2, 1), (2, 0), (1, 0), (2, 1), (0, 2), (0, 1), (2, 1), (0, 2), (1, 0), (1, 2), (0, 2), (0, 1), (2, 1), (2, 0), (1, 0), (2, 1), (0, 2), (0, 1), (2, 1), (0, 2), (1, 0), (1, 2), (0, 2), (1, 0), (2, 1), (2, 0), (1, 0), (1, 2), (0, 2), (0, 1), (2, 1), (0, 2), (1, 0), (1, 2), (0, 2), (1, 0), (2, 1), (2, 0), (1, 0), (2, 1), (0, 2), (0, 1), (2, 1), (2, 0), (1, 0), (1, 2), (0, 2), (1, 0), (2, 1), (2, 0), (1, 0), (1, 2), (0, 2), (0, 1), (2, 1), (0, 2), (1, 0), (1, 2), (0, 2), (0, 1), (2, 1), (2, 0), (1, 0), (2, 1), (0, 2), (0, 1), (2, 1), (0, 2), (1, 0), (1, 2), (0, 2), (1, 0), (2, 1), (2, 0), (1, 0), (1, 2), (0, 2), (0, 1), (2, 1), (0, 2), (1, 0), (1, 2), (0, 2)]
True
[(0, 1), (0, 2), (1, 2), (0, 1), (2, 0), (2, 1), (0, 1), (0, 2), (1, 2), (1, 0), (2, 0), (1, 2), (0, 1), (0, 2), (1, 2), (0, 1), (2, 0), (2, 1), (0, 1), (2, 0), (1, 2), (1, 0), (2, 0), (2, 1), (0, 1), (0, 2), (1, 2), (0, 1), (2, 0), (2, 1), (0, 1), (0, 2), (1, 2), (1, 0), (2, 0), (1, 2), (0, 1), (0, 2), (1, 2), (1, 0), (2, 0), (2, 1), (0, 1), (2, 0), (1, 2), (1, 0), (2, 0), (1, 2), (0, 1), (0, 2), (1, 2), (0, 1), (2, 0), (2, 1), (0, 1), (0, 2), (1, 2), (1, 0), (2, 0), (1, 2), (0, 1), (0, 2), (1, 2), (0, 1), (2, 0), (2, 1), (0, 1), (2, 0), (1, 2), (1, 0), (2, 0), (2, 1), (0, 1), (0, 2), (1, 2), (0, 1), (2, 0), (2, 1), (0, 1), (2, 0), (1, 2), (1, 0), (2, 0), (1, 2), (0, 1), (0, 2), (1, 2), (1, 0), (2, 0), (2, 1), (0, 1), (2, 0), (1, 2), (1, 0), (2, 0), (2, 1), (0, 1), (0, 2), (1, 2), (0, 1), (2, 0), (2, 1), (0, 1), (0, 2), (1, 2), (1, 0), (2, 0), (1, 2), (0, 1), (0, 2), (1, 2), (0, 1), (2, 0), (2, 1), (0, 1), (2, 0), (1, 2), (1, 0), (2, 0), (2, 1), (0, 1), (0, 2), (1, 2), (0, 1), (2, 0), (2, 1), (0, 1), (0, 2), (1, 2), (1, 0), (2, 0), (1, 2), (0, 1), (0, 2), (1, 2), (1, 0), (2, 0), (2, 1), (0, 1), (2, 0), (1, 2), (1, 0), (2, 0), (1, 2), (0, 1), (0, 2), (1, 2), (0, 1), (2, 0), (2, 1), (0, 1), (0, 2), (1, 2), (1, 0), (2, 0), (1, 2), (0, 1), (0, 2), (1, 2), (1, 0), (2, 0), (2, 1), (0, 1), (2, 0), (1, 2), (1, 0), (2, 0), (2, 1), (0, 1), (0, 2), (1, 2), (0, 1), (2, 0), (2, 1), (0, 1), (2, 0), (1, 2), (1, 0), (2, 0), (1, 2), (0, 1), (0, 2), (1, 2), (1, 0), (2, 0), (2, 1), (0, 1), (2, 0), (1, 2), (1, 0), (2, 0), (1, 2), (0, 1), (0, 2), (1, 2), (0, 1), (2, 0), (2, 1), (0, 1), (0, 2), (1, 2), (1, 0), (2, 0), (1, 2), (0, 1), (0, 2), (1, 2), (0, 1), (2, 0), (2, 1), (0, 1), (2, 0), (1, 2), (1, 0), (2, 0), (2, 1), (0, 1), (0, 2), (1, 2), (0, 1), (2, 0), (2, 1), (0, 1), (0, 2), (1, 2), (1, 0), (2, 0), (1, 2), (0, 1), (0, 2), (1, 2), (1, 0), (2, 0), (2, 1), (0, 1), (2, 0), (1, 2), (1, 0), (2, 0), (1, 2), (0, 1), (0, 2), (1, 2), (0, 1), (2, 0), (2, 1), (0, 1), (0, 2), (1, 2), (1, 0), (2, 0), (1, 2), (0, 1), (0, 2), (1, 2)]
由此,也驗證了總步驟數(shù) steps = 2^n?- 1,n為層數(shù)。
11. 任意展示
解決遞歸問題后,就可以展示任意層數(shù)的移動演示了,就用上一步得到的7層漢諾塔的移動坐標(biāo)來展示一下它的移動過程:
完整代碼:
import pyglet
window = pyglet.window.Window(800, 500, caption='漢諾塔')
pyglet.gl.glClearColor(1, 1, 1, 1)
batch = pyglet.graphics.Batch()
Color = (182,128,18),(25,65,160),(56,170,210),(16,188,78),(20,240,20),(240,240,20),(255,128,20),(240,20,20),(245,60,138)
class Disk:
def __init__(self, x, y, color=(0,0,0), width=200, height=20):
self.cir1 = pyglet.shapes.Circle(x+width/2-height/2, y, radius=height/2, color=color, batch=batch)
self.cir2 = pyglet.shapes.Circle(x-width/2+height/2, y, radius=height/2, color=color, batch=batch)
self.rect = pyglet.shapes.Rectangle(x-width/2+height/2, y-height/2, width-height, height, color=color, batch=batch)
def move(self, dx, dy):
self.cir1.x += dx; self.cir1.y += dy
self.cir2.x += dx; self.cir2.y += dy
self.rect.x += dx; self.rect.y += dy
class Hann:
def __init__(self, x, y, order=2, space=250, thickness=20, width=200, height=300):
assert(order>1)
self.pole = [pyglet.shapes.Line(x-i*space, y, x-i*space, y+height, width=thickness, color=Color[0], batch=batch) for i in range(-1,2)]
self.disk = [Disk(x+i*space, y, color=Color[0], width=width+thickness, height=thickness) for i in range(-1,2)]
self.x, self.y = x, y
self.order = order
self.space = space
self.thickness = thickness
self.width = width
self.height = (height-thickness*2)/order
self.step = (width-thickness)/(order+1)
coordinates = [(self.x-space, self.y+(i+1)*self.height-(self.height-thickness)/2) for i in range(order)]
self.beads = [Disk(*xy, Color[i%8+1], width=self.width-i*self.step, height=self.height) for i,xy in enumerate(coordinates)]
self.array = [[*range(order)], [], []]
def move(self, pole1, pole2):
if self.array[pole1]:
bead = self.array[pole1].pop()
if self.array[pole2] and bead<self.array[pole2][-1]:
self.array[pole1].append(bead)
print('大盤不能搬到小盤上')
return False
else:
print('所選擇的塔架為空!')
return None
self.beads[bead].move((pole2-pole1)*self.space, (len(self.array[pole2])-len(self.array[pole1]))*self.height)
self.array[pole2].append(bead)
return True
@window.event
def on_draw():
window.clear()
batch.draw()
@window.event
def on_key_press(symbol, modifiers):
global start
if not start:
start = True
pyglet.clock.schedule_interval(on_move, 0.3)
@window.event
def on_mouse_press(x, y, button, modifier):
global start
if not start:
start = True
pyglet.clock.schedule_interval(on_move, 0.3)
def hanoi(n, start, mid, end, moves=None):
if moves is None:
moves = []
if n == 1:
moves.append((start, end))
else:
hanoi(n-1, start, end, mid, moves)
moves.append((start, end))
hanoi(n-1, mid, start, end, moves)
return moves
def on_move(event):
global moves,steps
if moves:
x, y = moves.pop(0)
hanns.move(x, y)
label.text = f'盤架{x+1}的圓盤移到盤架{y+1}上'
message.text = f'總步驟數(shù):{steps}\t當(dāng)前步數(shù):{steps-len(moves)}'
else:
label.text = '演示完畢!'
pyglet.clock.unschedule(on_move)
order = 7
start = False
hanns = Hann(window.width/2, 120, order)
label = pyglet.text.Label('漢諾塔圓盤自動移動演示,任意按鍵開始......', font_size=24, color=(0,0,0,255), x=window.width/2, y=50, anchor_x='center', batch=batch)
moves = hanoi(order, 0, 1, 2)
steps = len(moves)
message = pyglet.text.Label(f'總步驟數(shù):{steps}\t當(dāng)前步數(shù):{steps-len(moves)}', font_size=24, color=(0,0,0,255), x=100, y=450, batch=batch)
pyglet.app.run()
12. 鼠標(biāo)操作
增加一個新的屬性.poleheight,把原來的.height屬性改為.beadheight以示區(qū)別;再給塔類增加兩個方法判斷鼠標(biāo)點擊和是否成功:
? ? def on_mouse_over(self, x, y):
? ? ? ? for i in range(-1,2):
? ? ? ? ? ? if hanns.x-hanns.width/2 < x-i*hanns.space < hanns.x+hanns.width/2 and hanns.y-hanns.thickness/2 < y < hanns.y+hanns.poleheight:
? ? ? ? ? ? ? ? return i+1
? ? def success(self):
? ? ? ? return len(self.array[2]) == self.order
最后配合鼠標(biāo)點擊事件,就能開始玩游戲了!
@window.event
def on_mouse_press(x, y, dx, dy):
? ? global moves
? ? if not hanns.success():
? ? ? ? pole = hanns.on_mouse_over(x, y)
? ? ? ? if pole is not None:
? ? ? ? ? ? print(pole)
? ? ? ? ? ? moves.append(pole)
? ? ? ? if len(moves)==2:
? ? ? ? ? ? hanns.move(*moves)
? ? ? ? ? ? moves.clear()
? ? ? ? if hanns.success():
? ? ? ? ? ? print('Success!')
完整代碼:?文章來源:http://www.zghlxwxcb.cn/news/detail-839246.html
import pyglet
window = pyglet.window.Window(800, 500, caption='漢諾塔')
pyglet.gl.glClearColor(1, 1, 1, 1)
batch = pyglet.graphics.Batch()
Color = (182,128,18),(25,65,160),(56,170,210),(16,188,78),(20,240,20),(240,240,20),(255,128,20),(240,20,20),(245,60,138)
class Disk:
def __init__(self, x, y, color=(0,0,0), width=200, height=20):
self.cir1 = pyglet.shapes.Circle(x+width/2-height/2, y, radius=height/2, color=color, batch=batch)
self.cir2 = pyglet.shapes.Circle(x-width/2+height/2, y, radius=height/2, color=color, batch=batch)
self.rect = pyglet.shapes.Rectangle(x-width/2+height/2, y-height/2, width-height, height, color=color, batch=batch)
def move(self, dx, dy):
self.cir1.x += dx; self.cir1.y += dy
self.cir2.x += dx; self.cir2.y += dy
self.rect.x += dx; self.rect.y += dy
class Hann:
def __init__(self, x, y, order=2, space=250, thickness=20, width=200, height=300):
assert(order>1)
self.pole = [pyglet.shapes.Line(x-i*space, y, x-i*space, y+height, width=thickness, color=Color[0], batch=batch) for i in range(-1,2)]
self.disk = [Disk(x+i*space, y, color=Color[0], width=width+thickness, height=thickness) for i in range(-1,2)]
self.x, self.y = x, y
self.order = order
self.space = space
self.thickness = thickness
self.width = width
self.poleheight = height
self.beadheight = (height-thickness*2)/order
self.step = (width-thickness)/(order+1)
coordinates = [(self.x-space, self.y+(i+1)*self.beadheight-(self.beadheight-thickness)/2) for i in range(order)]
self.beads = [Disk(*xy, Color[i%8+1], width=self.width-i*self.step, height=self.beadheight) for i,xy in enumerate(coordinates)]
self.array = [[*range(order)], [], []]
def move(self, pole1, pole2):
if self.array[pole1]:
bead = self.array[pole1].pop()
if self.array[pole2] and bead<self.array[pole2][-1]:
self.array[pole1].append(bead)
print('大盤不能搬到小盤上')
return False
else:
print('所選擇的塔架為空!')
return None
self.beads[bead].move((pole2-pole1)*self.space, (len(self.array[pole2])-len(self.array[pole1]))*self.beadheight)
self.array[pole2].append(bead)
return True
def on_mouse_over(self, x, y):
for i in range(-1,2):
if hanns.x-hanns.width/2 < x-i*hanns.space < hanns.x+hanns.width/2 and hanns.y-hanns.thickness/2 < y < hanns.y+hanns.poleheight:
return i+1
def success(self):
return len(self.array[2]) == self.order
@window.event
def on_draw():
window.clear()
batch.draw()
@window.event
def on_mouse_press(x, y, dx, dy):
global moves
if not hanns.success():
pole = hanns.on_mouse_over(x, y)
if pole is not None:
print(pole)
moves.append(pole)
if len(moves)==2:
hanns.move(*moves)
moves.clear()
if hanns.success():
print('Success!')
moves = []
hanns = Hann(window.width/2, 120, 4)
pyglet.app.run()
本篇至此暫時告一段落,下期會繼續(xù)給游戲增加信息提示等等功能,敬請期待......文章來源地址http://www.zghlxwxcb.cn/news/detail-839246.html
到了這里,關(guān)于Python 一步一步教你用pyglet制作漢諾塔游戲(續(xù))的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!