Python 一步一步教你用pyglet制作汉诺塔游戏(续)

CSDN 2024-06-23 11:35:06 阅读 99

目录

汉诺塔游戏

7. 汉诺塔类

8. 移动圆盘

9. 移动演示

10. 递归问题

11. 任意展示

12. 鼠标操作


汉诺塔游戏

汉诺塔(Tower of Hanoi),是一个源于印度古老传说的益智玩具。这个传说讲述了大梵天创造世界的时候,他做了三根金刚石柱子,并在其中一根柱子上从下往上按照大小顺序摞着64片黄金圆盘。大梵天命令婆罗门将这些圆盘从下面开始按大小顺序重新摆放在另一根柱子上,并规定在小圆盘上不能放大圆盘,同时在三根柱子之间一次只能移动一个圆盘。当盘子的数量增加时,移动步骤的数量会呈指数级增长,圆盘数为n时,总步骤数steps为2^n - 1。

n = 64, steps = 2^64 - 1 = 18446744073709551616 ≈ 1.845 x 10^19

汉诺塔问题是一个递归问题,也可以使用非递归法来解决,例如使用栈来模拟递归过程。这个问题不仅是一个数学和逻辑问题,也是一个很好的教学工具,可以用来教授递归、算法和逻辑思考等概念。同时,汉诺塔游戏也具有一定的娱乐性,人们可以通过解决不同规模的汉诺塔问题来挑战自己的智力和耐心。

本篇接着上期讲下去,这次争取把圆盘移动起来,前篇的链接地址:

Python 一步一步教你用pyglet制作汉诺塔游戏-CSDN博客

7. 汉诺塔类

前篇的最后已经初步把汉诺塔的架子搭好了,可以显示但移动的描述很复杂。所以得改造一下,把三个塔架设计到一个类中,方便圆盘的移动,运行后效果不变:

代码:

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.eventdef on_draw(): window.clear() batch.draw()hann = Hann(window.width/2, 120, 8)pyglet.app.run()

8. 移动圆盘

给圆盘类和汉诺塔类各设计一个.move()方法,主旨思想是圆盘的相对位置移动,不需要在调用时计算各种控件的具体坐标值。

代码:

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 += dyclass 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.s



声明

本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。