Hanoi (3d Towers of Hanoi solver)

Help Contents Examples Hanoi (3d Towers of Hanoi solver)
Flying Turtles (3d) Heart

Hanoi (3d Towers of Hanoi solver)

Example:    Hanoi.eli
Modified:   June 2, 2000
Version:    2.0
Author:     Pavel Boychev
E-mail:     pavel@elica.net

Copyright © 2000 Elica Group

This example is a cool 3D towers of Hanoi solver with nice graphics.

It demonstrates recursion and execution of runtime-constructed expressions, combined with lots of 3d graphics.

run "graphix

make "colors 
	(set
		rgb_    1     1    _6
		rgb_  _6   1    _6
		rgb_  _6  _6  1
		rgb_   1    _6  _6
		rgb_  _6  _6  _6
		rgb_  _6   1     1
		rgb_   1    _6   1
	)
make "N 5
make "n 5
make "z 0

to changeview

	make local "zz 45+25*(sin 1.5*:z)
	make "eye vector 15*(cos :zz) 15*(sin :zz) 5
	make "focus vector 0 0 0
	make "forehead vector 0 cos :zz sin :zz

	lookat :eye :focus :forehead
	make "z :z+1
end


to tower :focus :color

	run bf :cone

	make local "center :O
	make local "mode 2
	make local "radiusx 0.2
	make local "radiusy 0.2
	make local "radiusz 3
	make local "light "true
	make local "count 0
	make local "hollow "true
end


to disk :no
	run bf :cylinder

	make local "radius 1-:no/8
	make local "radiusz 0.2
	make local "center point 4 4 4
	make local "color item (:no+1) :colors
	make local "focus vector 1 1 0
	make local "mode 2
	make local "light "true
	make local "smooth "true

	to move_to :aim

		local "dcx "dcy "dcz
		local "drx "dry "drz

		make "dcx (:aim.center.x-:center.x)/:n
		make "dcy (:aim.center.y-:center.y)/:n
		make "dcz (:aim.center.z-:center.z)/:n
		make "drx (:aim.focus.x-:focus.x)/:n
		make "dry (:aim.focus.y-:focus.y)/:n
		make "drz (:aim.focus.z-:focus.z)/:n

		repeat :n
		[
			changeview
			make "center point :center.x+:dcx :center.y+:dcy :center.z+:dcz
			make "focus  point :focus.x+:drx :focus.y+:dry :focus.z+:drz
		]
	end

	to move_put :tower_name

		if :tower_name="C [ make local "MM cube (point 0 0 1.0+:C.count/6) 0 :C.focus ]
		if :tower_name="B [ make local "MM cube (point 0 1.0+:B.count/6 0) 0 :B.focus ]
		if :tower_name="A [ make local "MM cube (point 1.0+:A.count/6 0 0) 0 :A.focus ]

		move_to :MM
	end
end


changeview
make "O vector 0 0 0

make "tex5 texture "marble.bmp
make "tex6 texture "wooddecor.bmp

make "U styled (sphere :O 4) 
	(set
		"color rgb_  _8  _8  _8
		"texture :tex6
		"texture.scale 3
		"texture.spin 90
		"mode 2
		"light "true
		"range range (-90) 259 1
		"rangev range 180 360 1
		"smooth "true
		"normal (-1)
	)
make "W styled (sphere :O 4.05) 
	(set
		"color rgb_  0  0  0.82
		"mode 2
		"texture :tex5
		"texture.spin 90
		"light "true
		"range range (-90) 259 1
		"rangev range 180 360 1
		"smooth "true
		"normal 1
	)
make "arial font "arial 0.3
make "txt1 
	(styled 
		(text "Towers :arial) 
		(set
			"center  point (3) (-1) (1)
			"mode 2
			"light "true
			"color rgb_  1  _6  0
			"spin 180
			"focus point 0 1 0
		)
	)
make "txt2 
	(styled 
		(text "'of Hanoi' :arial) 
		(set
			"center  point (-1) (0) (1)
			"mode 2
			"light "true
			"color rgb_  1  _6  0
			"spin 90
			"focus point 1 0 0
		)
	)
make "A tower (point 1 0 0) (rgb_  1 0 0)
make "B tower (point 0 1 0) (rgb_  0 1 0)
make "C tower (point 0 0 1) (rgb_  0 0 1)

make "J 
	(styled 
		(sphere :O 0.35) 
		(set
			"color rgb 255 205 0
			"mode 2
			"light "true
		)
	)
repeat 90 [ changeview ]

repeat 45
[
	changeview
	make "U.range.toangle :U.range.toangle-2
	make "W.range.toangle :W.range.toangle-2
]
repeat 90 [ changeview ]

make "CC cube point 0 0 3.5 0 :C.focus
make "BB cube point 0 3.5 0 0 :B.focus
make "AA cube point 3.5 0 0 0 :A.focus


to do :from_disk :to_disk :from_stick :to_stick

	if :from_disk=:to_disk
	[
		make local "disk word "D :from_disk 
		make local "stick1 word :from_stick ".count
		make local "stick2 word :to_stick ".count
		make :stick1 :(:stick1)-1

		run (se word :disk ".move_to ": (word :from_stick :from_stick))
		run (se word :disk ".move_to ": (word :to_stick :to_stick))
		make :stick2 :(:stick2)+1
		run (se word :disk ".move_put "" :to_stick)
	]
	[
		make local "third_stick first sminus sminus [A B C] (se :from_stick) (se :to_stick)

		do :from_disk+1 :to_disk :from_stick  :third_stick
		do :from_disk :from_disk :from_stick  :to_stick
		do :from_disk+1 :to_disk :third_stick :to_stick
	]
end


; Creating disks
make "wanted "A
make "notwanted "B
make "N 1

repeat 6
[
	make "i :N-1

	changeview

	make word "D :i disk :i+1
	make (:wanted)("count) :((:wanted)("count))+1

	run (list (word "D :i ".move_to) ": word :wanted :wanted)
	run (list (word "D :i ".move_put) "" :wanted)

	if :N>1
	[
		do 0 :N-1 :wanted :notwanted

		make "zzz :wanted
		make "wanted :notwanted
		make "notwanted :zzz
	]
	make "N :N+1
]

repeat 45
[
	changeview
	make "U.range.toangle :U.range.toangle+2
	make "W.range.toangle :W.range.toangle+2
]

repeat 190 [ changeview ]

Flying Turtles (3d) Heart