“Tower of Hanoi” Program

1.ハノイの塔

 N枚のディスクを他の塔に移動する、というパズルゲームがあります。

ハノイの塔と言われるものです。

以前、何かの雑誌のプレゼント企画で、ハノイの塔のパズルをもらったことがありました。

それを機に、ハノイの塔を解くプログラムを作成してみました。

ハノイの塔

2.プログラム

ハノイの塔を解くプログラムは、よく再帰プログラムの例として紹介されたりしています。

以前、別ブログには掲載していたのですが、こちらには未アップでしたので、今回、iPadのプログラムをMacBookへ移植して動作するようにしました。

3.ソースコード

下記に貼り付けましたが、タブとかは正しくコピーできていないかもしれません。

import ui
import time #for sleep()

step = 1     #num. of proc.
lnum = 7     #num. of disk for Left_tower
cnum = rnum = 0   #num. of disk for Center,Right_tower
#Move proc. for each disk
def moveDisk(num_disk, from_twr, to_twr):
  global lnum, cnum, rnum
	if num_disk == 1:                #for disk1
		if to_twr == "Left":
			d1.x = 80 - (num_disk-1) * 10
			d1.y = 280 - lnum * 30
			lnum += 1        #increment Left disk num.
		if to_twr == "Center":
			d1.x = 320 - (num_disk-1) * 10
			d1.y = 280 - cnum * 30
			cnum += 1        #increment Center disk num.
		if to_twr == "Right":
			d1.x = 560 - (num_disk-1) * 10
			d1.y = 280 - rnum * 30
			rnum += 1        #increment Right disk num.
	if num_disk == 2:               #for disk2
		if to_twr == "Left":
			d2.x = 80 - (num_disk-1) * 10
			d2.y = 280 - lnum * 30
			lnum += 1        #increment Left disk num.
		if to_twr == "Center":
			d2.x = 320 - (num_disk-1) * 10
			d2.y = 280 - cnum * 30
			cnum += 1        #increment Center disk num.
		if to_twr == "Right":
			d2.x = 560 - (num_disk-1) * 10
			d2.y = 280 - rnum * 30
			rnum += 1        #increment Right disk num.
	if num_disk == 3:                #for disk3
		if to_twr == "Left":
			d3.x = 80 - (num_disk-1) * 10
			d3.y = 280 - lnum * 30
			lnum += 1 #increment Left disk num.
		if to_twr == "Center":
			d3.x = 320 - (num_disk-1) * 10
			d3.y = 280 - cnum * 30
			cnum += 1        #increment Center disk num.
		if to_twr == "Right":
			d3.x = 560 - (num_disk-1) * 10
			d3.y = 280 - rnum * 30
			rnum += 1        #increment Right disk num.
	if num_disk == 4:                #for disk4
		if to_twr == "Left":
			d4.x = 80 - (num_disk-1) * 10
			d4.y = 280 - lnum * 30
			lnum += 1        #increment Left disk num.
		if to_twr == "Center":
			d4.x = 320 - (num_disk-1) * 10
			d4.y = 280 - cnum * 30
			cnum += 1        #increment Center disk num.
		if to_twr == "Right":
			d4.x = 560 - (num_disk-1) * 10
			d4.y = 280 - rnum * 30
			rnum += 1.       #increment Right disk num.
	if num_disk == 5:                #for disk5
		if to_twr == "Left":
			d5.x = 80 - (num_disk-1) * 10
			d5.y = 280 - lnum * 30
			lnum += 1       #increment Left disk num.
		if to_twr == "Center":
			d5.x = 320 - (num_disk-1) * 10
			d5.y = 280 - cnum * 30
			cnum += 1       #increment Center disk num.
		if to_twr == "Right":
			d5.x = 560 - (num_disk-1) * 10
			d5.y = 280 - rnum * 30
			rnum += 1       #increment Right disk num.
	if num_disk == 6:                 #for disk6
		if to_twr == "Left":
			d6.x = 80 - (num_disk-1) * 10
			d6.y = 280 - lnum * 30
			lnum += 1        #increment Left disk num.
		if to_twr == "Center":
			d6.x = 320 - (num_disk-1) * 10
			d6.y = 280 - cnum * 30
			cnum += 1       #increment Center disk num.
		if to_twr == "Right":
			d6.x = 560 - (num_disk-1) * 10
			d6.y = 280 - rnum * 30
			rnum += 1 #increment Right disk num.
	if num_disk == 7:               #for disk7
		if to_twr == "Left":
			d7.x = 80 - (num_disk-1) * 10
			d7.y = 280 - lnum * 30
			lnum += 1       #increment Left disk num.
		if to_twr == "Center":
			d7.x = 320 - (num_disk-1) * 10
			d7.y = 280 - cnum * 30
			cnum += 1       #increment Center disk num.
		if to_twr == "Right":
			d7.x = 560 - (num_disk-1) * 10
			d7.y = 280 - rnum * 30
			rnum += 1      #increment Right disk num.

	if from_twr == "Left":
		lnum = lnum -1         #decrement Left disk num.
	if from_twr == "Center":
		cnum = cnum - 1        #decrement Center disk num.
	if from_twr == "Right":
		rnum = rnum - 1        #decrement Right disk num.

	time.sleep(0.3)

#Scroll proc. for textview
def scroll():
	tv.content_offset = (0, tv.content_size[1] - tv.height)
	if tv.content_offset[1] < 0:
		#while y_offset is minus, no scroll.
		tv.content_offset = (0,0)

#Main proc. for HANOI, using 'recursion'
def hanois(num_disk, from_twr, to_twr, tmp_twr):
    global step
    #Move disk from 'from_twr' to 'to_twr'. 
    if num_disk == 1:
        #if 1disk, move it finished.
        #print(f"step{step}: No.{num_disk}-disk from {from_twr} to {to_twr}.")
        tv.text += (f"step{step}: No.{num_disk}-disk from {from_twr} to {to_twr}."+"\n")
        scroll()
        moveDisk(num_disk, from_twr, to_twr)
        step = step + 1
        return
    #Move (N-1)th. disk from Left to Center. Right as temporary towerext
    hanois(num_disk-1, from_twr, tmp_twr, to_twr)
    #Move remaining disk from Left to Right
    #print(f"step{step}: No.{num_disk}-disk from {from_twr} to {to_twr}.")
    tv.text += (f"step{step}: No.{num_disk}-disk from {from_twr} to {to_twr}."+"\n")
    scroll()
    moveDisk(num_disk, from_twr, to_twr)
    step = step + 1
    #Move (N-1)th. disk from Center to Right. Left as temporary tower
    hanois(num_disk-1, tmp_twr, to_twr, from_twr)

#Start UI
v = ui.load_view()
v.present('sheet')
tv = v['textview1']         #set textview controll
d1 = v['button1']           #set button_n controll
d2 = v['button2']
d3 = v['button3']
d4 = v['button4']
d5 = v['button5']
d6 = v['button6']
d7 = v['button7']
#start The Hanoi
hanois(7, "Left", "Right", "Center")

4.画面構成

  diskはButtonで構成しています。

 最下部は、テキストビューを使用し、実行中の進捗を表示します。

ハノイの塔pyui
Screenshot

5.実行画面

iPhoneで撮影の動画をアップしようとしましたが、サイズオーバーのためできませんでした。

次の機会にします。

6.ファイル

 ソースと.pyuiファイルをアップしようとしましたが、権限がないと言われ、ファイルをアップできませんでした。

こちらも、後日、調べてからアップします。


コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です