欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Python使用pyglet庫完整實(shí)現(xiàn)漢諾塔游戲流程詳解

 更新時間:2024年04月01日 16:55:19   作者:Hann Yang  
這篇文章主要介紹了Python使用pyglet庫完整實(shí)現(xiàn)漢諾塔游戲流程,漢諾塔問題是一個遞歸問題,也可以使用非遞歸法來解決,這個問題不僅是一個數(shù)學(xué)和邏輯問題,也是一個很好的教學(xué)工具,可以用來教授遞歸、算法和邏輯思考等概念,需要的朋友可以參考下

前言

漢諾塔(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庫制作這個小游戲,首先在上圖中抓取出需要用到的顏色RGB值,每種顏色畫一個矩形塊:

Rectangle(x, y, width, height, color=color)

代碼:

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 Rect:
    def __init__(self, x, y, color=(0,0,0), width=180, height=60):
        self.rect = pyglet.shapes.Rectangle(x, y, width, height, color=color, batch=batch)
@window.event
def on_draw():
    window.clear()
    batch.draw()
rectangle = [None]*9
for i,color in enumerate(Color):
    rectangle[i] = Rect(110+i//3*200, 120+i%3*100, color)
pyglet.app.run()

繪制圓盤

圓盤用矩形加2個半圓表示,半圓用扇形控件繪制:

Sector(x,y, radius=R, angle=pi, start_angle=-pi/2, color=color)

注意圓盤類中的矩形的寬度和坐標(biāo)需要調(diào)整,整個圓盤類的寬度是矩形寬度加2倍扇形半徑,圓盤的中心是矩形的中心而不是矩形左下角。

import pyglet
window = pyglet.window.Window(800, 500, caption='漢諾塔')
pyglet.gl.glClearColor(1, 1, 1, 1)
batch = pyglet.graphics.Batch()
pi = 3.141592653589793
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 Bead:
    def __init__(self, x, y, width=180, height=60):
        self.sec1 = pyglet.shapes.Sector(x+width/2-height/2, y, radius=height/2, angle=pi, start_angle=-pi/2, color=Color[5], batch=batch)
        self.sec2 = pyglet.shapes.Sector(x-width/2+height/2, y, radius=height/2, angle=pi, start_angle=pi/2, color=Color[5], batch=batch)
        self.rect = pyglet.shapes.Rectangle(x-width/2+height/2, y-height/2, width-height, height, color=Color[1], batch=batch)
@window.event
def on_draw():
    window.clear()
    batch.draw()
ead1 = Bead(window.width/2, window.height/2)
pyglet.app.run()

九層漢塔

疊加多個圓盤,繪制出漢諾塔的樣子:

代碼:

import pyglet
window = pyglet.window.Window(800, 500, caption='漢諾塔')
pyglet.gl.glClearColor(1, 1, 1, 1)
batch = pyglet.graphics.Batch()
pi = 3.141592653589793
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.sec1 = pyglet.shapes.Sector(x+width/2-height/2, y, radius=height/2, angle=pi, start_angle=-pi/2, color=color, batch=batch)
        self.sec2 = pyglet.shapes.Sector(x-width/2+height/2, y, radius=height/2, angle=pi, start_angle=pi/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)
        assert(width>height and x-width/2+height/2>0)
@window.event
def on_draw():
    window.clear()
    batch.draw()
x, y = window.width/2, window.height/2
width, height = 200, 40
disk = []
for i in range(9):
    disk.append(Disk(x, y+height*(i-4), Color[i], width=width-20*(i-1), height=height))
pyglet.app.run()

繪制塔架

把圓盤變簿(高度換成厚度),再加一條粗直線(直線的寬度等于圓盤的厚度)表示出“豎桿”,就畫出疊放的架子來:

self.pole = pyglet.shapes.Line(x, y, x, y+height, width=thickness, color=color)

self.disk = Disk(x, y, color=color, width=width, height=thickness)

代碼:

import pyglet
window = pyglet.window.Window(800, 500, caption='漢諾塔')
pyglet.gl.glClearColor(1, 1, 1, 1)
batch = pyglet.graphics.Batch()
pi = 3.141592653589793
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.sec1 = pyglet.shapes.Sector(x+width/2-height/2, y, radius=height/2, angle=pi, start_angle=-pi/2, color=color, batch=batch)
        self.sec2 = pyglet.shapes.Sector(x-width/2+height/2, y, radius=height/2, angle=pi, start_angle=pi/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)
        assert(width>height and x-width/2+height/2>0)
class Hann:
    def __init__(self, x, y, color=(0,0,0), width=220, height=300, thickness=20):
        self.pole = pyglet.shapes.Line(x, y, x, y+height, width=thickness, color=color, batch=batch)
        self.disk = Disk(x, y, color=color, width=width, height=thickness)
@window.event
def on_draw():
    window.clear()
    batch.draw()
pole1 = Hann(window.width/2-250, 100)
pole2 = Hann(window.width/2, 100, color=Color[0])
pole3 = Hann(window.width/2+250, 100, color=Color[1])
pyglet.app.run()

疊加圓盤

把多個圓盤疊加磊在塔架上,圓盤數(shù)至少為2。 注意Color顏色列表共有9種顏色,Color[i%8+1]只取后8種顏色,Color[0]僅用于塔架的涂色。

Hann類中各控件的坐標(biāo)計(jì)算有點(diǎn)復(fù)雜,以下方案可以解決問題但未必是最佳方案:

self.x, self.y = x, y
self.width = width
self.height = (height-thickness*2)/order
self.step = (width-thickness)/(order+1)
self.beads = []
self.coordinates = []
for i in range(order):
    self.coordinates.append([self.x, self.y+(i+1)*self.height-(self.height-thickness)/2])

代碼:

import pyglet
window = pyglet.window.Window(800, 500, caption='漢諾塔')
pyglet.gl.glClearColor(1, 1, 1, 1)
batch = pyglet.graphics.Batch()
pi = 3.141592653589793
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.sec1 = pyglet.shapes.Sector(x+width/2-height/2, y, radius=height/2, angle=pi, start_angle=-pi/2, color=color, batch=batch)
        self.sec2 = pyglet.shapes.Sector(x-width/2+height/2, y, radius=height/2, angle=pi, start_angle=pi/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)
        assert(width>height and x-width/2+height/2>0)
class Hann:
    def __init__(self, x, y, order=2, thickness=20, width=220, height=300):
        assert(order>1)
        self.pole = pyglet.shapes.Line(x, y, x, y+height, width=thickness, color=Color[0], batch=batch)
        self.disk = Disk(x, y, color=Color[0], width=width+thickness, height=thickness)
        self.x, self.y = x, y
        self.width = width
        self.height = (height-thickness*2)/order
        self.step = (width-thickness)/(order+1)
        self.beads = []
        self.coordinates = []
        for i in range(order):
            self.coordinates.append([self.x, self.y+(i+1)*self.height-(self.height-thickness)/2])
        self.fillup()
    def fillup(self):
        for i,xy in enumerate(self.coordinates):
            self.beads.append(Disk(*xy, Color[i%8+1], width=self.width-i*self.step, height=self.height))
@window.event
def on_draw():
    window.clear()
    batch.draw()
hann1 = Hann(window.width/2-260, 100, 2)
hann2 = Hann(window.width/2-22, 180, 5, 25)
hann3 = Hann(window.width/2+230, 80, 10, 15, 300, 380)
pyglet.app.run()

游戲框架

畫三個相同的塔架,左邊的磊放好圓盤。另外用兩個圓代替兩個扇形,效果一樣卻省了pi常量。

Circle(x+width/2-height/2, y, radius=height/2, color=color)

代碼:

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)
        assert(width>height and x-width/2+height/2>0)
class Hann:
    def __init__(self, x, y, order=2, thickness=20, width=200, height=300):
        assert(order>1)
        self.pole = pyglet.shapes.Line(x, y, x, y+height, width=thickness, color=Color[0], batch=batch)
        self.disk = Disk(x, y, color=Color[0], width=width+thickness, height=thickness)
        self.x, self.y = x, y
        self.width = width
        self.height = (height-thickness*2)/order
        self.step = (width-thickness)/(order+1)
        self.beads = []
        self.coordinates = []
        for i in range(order):
            self.coordinates.append([self.x, self.y+(i+1)*self.height-(self.height-thickness)/2])
    def fillup(self):
        for i,xy in enumerate(self.coordinates):
            self.beads.append(Disk(*xy, Color[i%8+1], width=self.width-i*self.step, height=self.height))
class Game:
    def __init__(self, x, y, order=2, space=250):
        self.x, self.y = x, y
        self.space = space
        self.order = order
        self.hanns = Hann(x-space, y, order), Hann(x, y, order), Hann(x+space, y, order)
        self.hanns[0].fillup()
@window.event
def on_draw():
    window.clear()
    batch.draw()
hann = Game(window.width/2, 100, 8)
pyglet.app.run()

接下來就要添加鼠標(biāo)和鍵盤事件,用于操作在塔架上移動圓盤。

以上就是Python使用pyglet庫完整實(shí)現(xiàn)漢諾塔游戲流程詳解的詳細(xì)內(nèi)容,更多關(guān)于Python pyglet漢諾塔的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • pygame游戲之旅 添加icon和bgm音效的方法

    pygame游戲之旅 添加icon和bgm音效的方法

    這篇文章主要為大家詳細(xì)介紹了pygame游戲之旅的第14篇,教大家如何添加icon和bgm音效,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-11-11
  • Python中BeautifulSoup通過查找Id獲取元素信息

    Python中BeautifulSoup通過查找Id獲取元素信息

    這篇文章主要介紹了Python中BeautifulSoup通過查找Id獲取元素信息,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-12-12
  • 對Python 字典元素進(jìn)行刪除的方法

    對Python 字典元素進(jìn)行刪除的方法

    這篇文章主要介紹了對Python 字典元素進(jìn)行刪除的方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-07-07
  • Python 中包/模塊的 `import` 操作代碼

    Python 中包/模塊的 `import` 操作代碼

    這篇文章主要介紹了Python 中包/模塊的 `import` 操作代碼,非常不錯,具有一定的參考借鑒價值 ,需要的朋友可以參考下
    2019-04-04
  • pandas刪除行刪除列增加行增加列的實(shí)現(xiàn)

    pandas刪除行刪除列增加行增加列的實(shí)現(xiàn)

    這篇文章主要介紹了pandas刪除行刪除列增加行增加列的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-07-07
  • python之multimethod包多分派解讀

    python之multimethod包多分派解讀

    這篇文章主要介紹了python之multimethod包多分派問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-08-08
  • pycharm安裝漢化包失敗的問題及解決

    pycharm安裝漢化包失敗的問題及解決

    這篇文章主要介紹了pycharm安裝漢化包失敗的問題及解決方案,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-11-11
  • Python基礎(chǔ)之循環(huán)語句相關(guān)知識總結(jié)

    Python基礎(chǔ)之循環(huán)語句相關(guān)知識總結(jié)

    今天給大家?guī)淼氖顷P(guān)于Python基礎(chǔ)的相關(guān)知識,文章圍繞著Python循環(huán)語句展開,文中有非常詳細(xì)的介紹及代碼示例,需要的朋友可以參考下
    2021-06-06
  • python使用 zip 同時迭代多個序列示例

    python使用 zip 同時迭代多個序列示例

    這篇文章主要介紹了python使用 zip 同時迭代多個序列,結(jié)合實(shí)例形式分析了Python使用zip遍歷迭代長度相等與不等的序列相關(guān)操作技巧,需要的朋友可以參考下
    2019-07-07
  • pandas DataFrame rsub的實(shí)現(xiàn)示例

    pandas DataFrame rsub的實(shí)現(xiàn)示例

    本文主要介紹了pandas DataFrame rsub的實(shí)現(xiàn)示例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2025-04-04

最新評論