新しく発言する EXIT インデックスへ
ハノイの塔:以前掲示の改訂版

  ハノイの塔: 以前掲示の改訂版 SECOND 2007/07/28 21:47:59  (修正6回)
  paintで文法エラー 島村1243 2007/07/29 11:31:36 
  │├Windows版のV599では、なんともありませんが... SECOND 2007/07/29 16:34:18  (修正1回)
  ││└各OS版の相違点をまとめたものを作成しまし... 白石 和夫 2007/08/05 21:03:45  (修正1回)
  │└PAINTを使わないように、修正しました。 SECOND 2007/07/29 16:56:50 
  │ └動作確認しました。 島村1243 2007/07/29 18:04:13 
  │  ├すみません。上書き修正は、弊害があります... SECOND 2007/07/29 18:17:43  (修正1回)
  │  │└Win版動作OKでした。 島村1243 2007/07/29 21:21:32  (修正2回)
  │  └ついでに、これは、余計だとは思いますが、 SECOND 2007/07/29 18:52:27 
  │   └いえ、面白さ倍増ですね。 島村1243 2007/07/29 21:35:15 
  修正の経緯 SECOND 2007/07/30 12:42:50  (修正1回)
  !ハノイの塔:コンパクト版 SECOND 2007/08/01 11:10:17 

  ハノイの塔: 以前掲示の改訂版 SECOND 2007/07/28 21:47:59  (修正6回) ツリーへ

ハノイの塔: 以前掲示の改訂版 返事を書く ノートメニュー
SECOND <cszcthjjdj> 2007/07/28 21:47:59 ** この記事は6回修正されてます
!ハノイの塔: 以前掲示の改訂版

!上側が、小さい順で、積まれた円盤の山を、A塔→C塔へ移す問題。
!中継塔を介し、小さい円盤の上に、大きい円盤は積めない規則で1枚づつ運ぶ。
!----------

!円盤は、上から、1,2,3,,,の番号で識別。K に代入して使用。
!A,B,C の塔は、左から、1,2,3 で識別。S,D に代入して使用。
!中継する塔の番号は、(1+2+3)-S-D= 6-S-D で計算される。

!上からK番目の円盤を、Sから、Dへ動かす方法。
!1つ上の、
!(K−1)番目までの全てを、S、D、でない塔(6-S-D)へ移動し、
!K番目を、Sから、Dへ移動する。
!先の(K−1)番目までの全てを、Dの上に積んで終了。
!
!(K−1)番目の上にも、円盤が有るため、
!再帰的に同じ処理をコールし、K=1になる毎に
!再帰が止まって、リターンしてくる。
!1番下の最大の円盤から、最初のコールをする。

!1枚少ない実行回数を N(k-1) とすると、N(k)= N(k-1)+1+N(k-1)
!また、N(1)=1 なので、N(K) は、1,3,7,15,31,,,(2^k)-1 回
!----------

SET WINDOW 0,500,0,500
SET TEXT BACKGROUND "OPAQUE"

LET K=5 !一番下の円盤番号から開始。塔の段数(1~16)、として設定

IF 2<K THEN LET DL=7/(2^K-1) ELSE LET DL=1 ! 速さの調節

PRINT "塔の段数(1~16)=";K
PRINT

DIM X(3),Y(3)

LET X(1)=100 ! A塔の円盤中心のX座標
LET X(2)=250 ! B〜
LET X(3)=400 ! C〜

LET Y(1)=200 ! A塔の円盤上面Y座標。初期値は、台の上面(円盤無し)
LET Y(2)=200 ! B〜
LET Y(3)=200 ! C〜

LET YT=150/K ! 円盤の厚み
LET XT=YT/2 ! 円盤半径の1段毎の差分

!---------
LET S=1
LET D=3
CALL init00
CALL MovK00( K, S, D)

SUB MovK00( K, S, D)
IF 1<K THEN CALL MovK00( K-1, S, 6-S-D) ! 移動要求 K-1,,1層 S→ 中継の塔
CALL movSD( K, S, D) ! 表示 K層 S →D
IF 1<K THEN CALL MovK00( K-1, 6-S-D, D) ! 移動要求 K-1,,1層 中継の塔 →D
END SUB

!--------- 経過の表示
SUB movSD( K, S, D)
SELECT CASE S*10+D
CASE 12
PRINT "A->";K;"->B "
CASE 13
PRINT "A->";K;"--------->C"
CASE 21
PRINT "A<-";K;"<-B "
CASE 23
PRINT TAB(9);"B->";K;"->C"
CASE 31
PRINT "A<---------";K;"<-C"
CASE 32
PRINT TAB(9);"B<-";K;"<-C"
END SELECT
WAIT DELAY DL
!---------
CALL hdisk(K, S, 0) !円盤消去
LET Y(S)=Y(S)-YT
LET Y(D)=Y(D)+YT
CALL hdisk(K, D, K+1) !円盤描画
!-----
LET R9=R9+1
PLOT TEXT,AT 250,110,USING "real times=%%%%%":R9
END SUB

SUB hdisk(k,ABC,col)
SET AREA COLOR col
LET x1=X(ABC)-k*XT
LET x2=X(ABC)+k*XT
LET y1=Y(ABC)
LET y2=Y(ABC)-YT+1
PLOT AREA: x1,y1;x2,y1;x2,y2;x1,y2
END SUB

!--------- 初期画面
SUB init00
PLOT TEXT,AT 210,400:"ハノイの塔"
PLOT LINES:X(1)-80,Y(1)-2; X(3)+80,Y(1)-2
PLOT TEXT,AT X(1),Y(1)-30:"A"
PLOT TEXT,AT X(2),Y(1)-30:"B"
PLOT TEXT,AT X(3),Y(1)-30:"C"
FOR w=K TO 1 STEP -1
LET Y(S)=Y(S)+YT
CALL hdisk(w,S,w+1)
NEXT w
PLOT TEXT,AT 200,110,USING "N=%%":K
PLOT TEXT,AT 250,110,USING "real times=%%%%%":0
PLOT TEXT,AT 244, 90,USING"final times=%%%%%":2^K-1
END SUB

END

  paintで文法エラー 島村1243 2007/07/29 11:31:36  ツリーへ

Re: ハノイの塔: 以前掲示の改訂版 返事を書く ノートメニュー
島村1243 <bjllmpcujp> 2007/07/29 11:31:36
paintで文法エラー

SECONDさん、実行状況を見ているととても面白いプログラムの開示
有難うございます。
ただ、paint (x1+x2)/2,(y1+y2)/2の箇所でエラーしますので
現在は!を付記(コメント)してrunしています。
このpaintはキーワード(命令語)ではなくて、外部関数でしょうか?もしそうでしたら、その内容も開示していただけると有難いです。

  │├Windows版のV599では、なんともありませんが... SECOND 2007/07/29 16:34:18  (修正1回) ツリーへ

Re: paintで文法エラー 返事を書く ノートメニュー
SECOND <cszcthjjdj> 2007/07/29 16:34:18 ** この記事は1回修正されてます
Windows版のV599では、なんともありませんが、
ヘルプファイルには、(独自の拡張)となっているようですので、
Linux版と、共通していないのかも知れませんね。
動作環境がありませんので、白石先生に御願いしないと、
こちらで、分かりません。すみません。

------------------------
塗りつぶし(独自の拡張)

x,yを数値式とする。

FLOOD x,y
 点(x,y)を始点として点(x,y)と同色でつながる領域を現在のarea colorで塗りつぶす。

PAINT x,y
 点(x,y)を始点としてline colorの点を境界とする領域を現在のarea colorで塗りつぶす。

  ││└各OS版の相違点をまとめたものを作成しまし... 白石 和夫 2007/08/05 21:03:45  (修正1回) ツリーへ

Re: Windows版のV599では、なんともありませんが... 返事を書く ノートメニュー
白石 和夫 <fbdfvqwhki> 2007/08/05 21:03:45 ** この記事は1回修正されてます
各OS版の相違点をまとめたものを作成しました。参考にしてください。
http://hp.vector.co.jp/authors/VA008683/basi0000.htm

  │└PAINTを使わないように、修正しました。 SECOND 2007/07/29 16:56:50  ツリーへ

Re: paintで文法エラー 返事を書く ノートメニュー
SECOND <cszcthjjdj> 2007/07/29 16:56:50
PAINTを使わないように、修正しました。
かえって、短い文で、無駄がなくなりました。
なんて、バカなことを、していたんでしょうね。
ご指摘、ありがとうございました。これからも、
よろしくお願いします。

  │ └動作確認しました。 島村1243 2007/07/29 18:04:13  ツリーへ

Re: PAINTを使わないように、修正しました。 返事を書く ノートメニュー
島村1243 <bjllmpcujp> 2007/07/29 18:04:13
動作確認しました。

SECONDさん、改訂版有難うございました。
Windowsでは改訂前のプログラムが正常動作するというのは気付きません(Win版は動かさなかったので)でした。
改めてWin版で動作させて見ようとしたのですが、改定前のプログラムコードが存在しないため出来ませんでした。

改訂版のコードはWin版・Liux版の何れでも正常に動作することを確認しました。パズルを解いているようで面白
動きですね。コードのテクニックはこれから読んで勉強させて頂きます。

  │  ├すみません。上書き修正は、弊害があります... SECOND 2007/07/29 18:17:43  (修正1回) ツリーへ

Re: 動作確認しました。 返事を書く ノートメニュー
SECOND <cszcthjjdj> 2007/07/29 18:17:43 ** この記事は1回修正されてます
すみません。上書き修正は、弊害がありますね。この部分が
修正前の文です。

SUB hdisk(k,ABC,col)
SET LINE COLOR col
SET AREA COLOR col
LET x1=X(ABC)-k*XT
LET y1=Y(ABC)
LET x2=X(ABC)+k*XT
LET y2=Y(ABC)+YT-1
SET DRAW mode hidden
PLOT LINES: x1,y1;x2,y1;x2,y2;x1,y2;x1,y1
paint (x1+x2)/2,(y1+y2)/2
SET DRAW mode explicit
END SUB

AREA COLOR まで、セットしておいて
PLOT AREA を使っていない、
すこし、ボケているようです。(笑)

  │  │└Win版動作OKでした。 島村1243 2007/07/29 21:21:32  (修正2回) ツリーへ

Re: すみません。上書き修正は、弊害があります... 返事を書く ノートメニュー
島村1243 <bjllmpcujp> 2007/07/29 21:21:32 ** この記事は2回修正されてます
Win版動作OKでした。

SECONDさん、お手数おかけしました。
再掲示頂いた修正前コードを使ってWin98SE上のBASIC59AでRUNしましたら、確かにエラー無しで動作する事を
確認しました。(念の為Vine4.0とFedora7のLinux版BASICでRUNしましたがやはり、paint文でエラーになりま
した。)

と言うことは、Win版とLinux版でBASICの命令機能が多少異なるという事ですね。
Linux版を使う人が今後増える(と私は思っている)事を考慮すると、Win専用の機能と言うものは明示してお
いた方が良いかも知れませんね。
<追伸>
済みません、「(仮称)十進BASIC バージョン間の相違」にキチンと明示されていました。

  │  └ついでに、これは、余計だとは思いますが、 SECOND 2007/07/29 18:52:27  ツリーへ

Re: 動作確認しました。 返事を書く ノートメニュー
SECOND <cszcthjjdj> 2007/07/29 18:52:27
ついでに、これは、余計だとは思いますが、
以下の様に、メイン部分を替えると、
ぐるぐる回して、おもちゃのように楽しめます。
余計ですね(^-^)

!---------
LET S=1
LET D=3
CALL init00
DO
PRINT "tower";CHR$(64+S);" -->tower";CHR$(64+D)
CALL MovK00( K, S, D)
PRINT
WAIT DELAY 1
LET R9=0 ! clear real times
LET S=D
LET D=D-1
IF D<1 THEN LET D=3 ! この行を除けば1往復で止め。
LOOP UNTIL D<1

SUB MovK00( K, S, D)
IF 1<K THEN CALL MovK00( K-1, S, 6-S-D) ! 移動要求 K-1,,1層 S→ 中継の塔
CALL movSD( K, S, D) ! 表示 K層 S →D
IF 1<K THEN CALL MovK00( K-1, 6-S-D, D) ! 移動要求 K-1,,1層 中継の塔 →D
END SUB

  │   └いえ、面白さ倍増ですね。 島村1243 2007/07/29 21:35:15  ツリーへ

Re: ついでに、これは、余計だとは思いますが、 返事を書く ノートメニュー
島村1243 <bjllmpcujp> 2007/07/29 21:35:15
いえ、面白さ倍増ですね。

DO LOOPをうまく組み入れる事で動きが更に面白くなりましたね。非常に参考になります、有難う御座いました。

  修正の経緯 SECOND 2007/07/30 12:42:50  (修正1回) ツリーへ

Re: ハノイの塔: 以前掲示の改訂版 返事を書く ノートメニュー
SECOND <cszcthjjdj> 2007/07/30 12:42:50 ** この記事は1回修正されてます
修正の経緯

!-----修正6、(前)
座標X左から 0~639
座標Y下から 479~0

!-----修正6、(後)
座標X左から 0~500( 501pixel)
座標Y下から 0~500( 501pixel)

注釈の追加。
------------

  (
(  )
 )
!-----修正1〜2、(前) すみません、記録がありません。
テキスト・サイズ上限は、3072バイトとなっていますが、
2797バイトでも、入らなかったため、いたる所、注釈を削ってしまっていた。

!-----修正1〜2、(後) 記録がありません。
一部の無駄命令を、取り除いた。
注釈を、短い文に替え、欠落の過ぎる分を、補てんした。


!-----修正3〜4、(前) :島村氏のご指摘で、悪い文が見つかりました。
SUB hdisk(k,ABC,col)
SET LINE COLOR col
SET AREA COLOR col
LET x1=X(ABC)-k*XT
LET y1=Y(ABC)
LET x2=X(ABC)+k*XT
LET y2=Y(ABC)+YT-1
SET DRAW mode hidden
PLOT LINES: x1,y1;x2,y1;x2,y2;x1,y2;x1,y1
paint (x1+x2)/2,(y1+y2)/2
SET DRAW mode explicit
END SUB

!-----修正3〜4、(後)
SUB hdisk(k,ABC,col)
SET AREA COLOR col
LET x1=X(ABC)-k*XT
LET y1=Y(ABC)
LET x2=X(ABC)+k*XT
LET y2=Y(ABC)+YT-1
SET DRAW mode hidden
PLOT AREA: x1,y1;x2,y1;x2,y2;x1,y2
SET DRAW mode explicit
END SUB


!-----修正5、(前)
SUB movSD( K, S, D)

 )
PLOT TEXT,AT 36*8,23*16,USING "real times=%%%%%":R9
LET R9=R9+1
END SUB


SUB init00

 )
LET R9=1
END SUB

!-----修正5、(後) :real times R9=0 で、開始するように変更した。
SUB movSD( K, S, D)

 )
LET R9=R9+1
PLOT TEXT,AT 36*8,23*16,USING "real times=%%%%%":R9
END SUB


SUB init00

 )
!LET R9=0 ←消した。有った方が良かったか、メインでセットすべきかも知れない。
END SUB


!--------------------------------------------------------
修正5は、以下の様に改造して、1往復させる際、
real times 表示に、異常が出るため行なった。
LET R9=1 ! clear real times
として、修正しないのも、一考ですが、clear は、0の方が・・
!--------------------------------------------------------
LET S=1
LET D=3
CALL init00
DO
PRINT "tower";CHR$(64+S);" -->tower";CHR$(64+D)
CALL MovK00( K, S, D)
PRINT
WAIT DELAY 1
LET R9=0 ! clear real times
LET S=D
LET D=D-1
!IF D<1 THEN LET D=3 ! この行を除けば1往復で止め。
LOOP UNTIL D<1

SUB MovK00( K, S, D)
IF 1<K THEN CALL MovK00( K-1, S, 6-S-D) ! 移動要求 K-1,,1層 S→ 中継の塔
CALL movSD( K, S, D) ! 表示 K層 S →D
IF 1<K THEN CALL MovK00( K-1, 6-S-D, D) ! 移動要求 K-1,,1層 中継の塔 →D
END SUB

  !ハノイの塔:コンパクト版 SECOND 2007/08/01 11:10:17  ツリーへ

Re: ハノイの塔: 以前掲示の改訂版 返事を書く ノートメニュー
SECOND <cszcthjjdj> 2007/08/01 11:10:17
!ハノイの塔: コンパクト版
!----------

SET WINDOW 0,500,0,500

LET K=5 !一番下の円盤番号から開始。塔の段数(1~16)、として設定

DIM X(3),Y(3)
LET X(1)=100 ! A塔の円盤中心のX座標
LET X(2)=250 ! B〜
LET X(3)=400 ! C〜
LET Y(1)=200 ! A塔の円盤上面Y座標。初期値は、台の上面(円盤無し)
LET Y(2)=200 ! B〜
LET Y(3)=200 ! C〜

LET YT=150/K ! 円盤の厚み
LET XT=YT/2 ! 円盤半径の1段毎の差分

!----------移動の開始
LET S=1
LET D=3
CALL init00
CALL MovK00( K, S, D)

SUB MovK00( K, S, D)
IF 1<K THEN CALL MovK00( K-1, S, 6-S-D) ! 移動要求 K-1,,1層 S→ 中継の塔
!----------
! K層 S →D  移動の実行(表示のみで、K,S,D, 何れも変化させない)
WAIT DELAY 0.2 ! 速さの調節
CALL hdisk(K, S, 0) ! Source 円盤 消去
LET Y(S)=Y(S)-YT !  1段下げ
LET Y(D)=Y(D)+YT !  1段上げ
CALL hdisk(K, D, K+1) ! Destination 円盤 追加
!----------
IF 1<K THEN CALL MovK00( K-1, 6-S-D, D) ! 移動要求 K-1,,1層 中継の塔 →D
END SUB

SUB hdisk(k,ABC,col)
SET AREA COLOR col
LET x1=X(ABC)-k*XT ! 円盤の左端
LET x2=X(ABC)+k*XT !   〜右端
LET y1=Y(ABC) !    〜上面
LET y2=Y(ABC)-YT+1 ! 〜下面、+1 は、画素の重なり防止
PLOT AREA: x1,y1;x2,y1;x2,y2;x1,y2
END SUB

!----------初期画面
SUB init00
PLOT TEXT,AT 210,400:"ハノイの塔"
PLOT LINES:X(1)-80,Y(1)-2; X(3)+80,Y(1)-2
PLOT TEXT,AT X(1),Y(1)-30:"A"
PLOT TEXT,AT X(2),Y(2)-30:"B"
PLOT TEXT,AT X(3),Y(3)-30:"C"
FOR w=K TO 1 STEP -1
LET Y(S)=Y(S)+YT
CALL hdisk(w,S,w+1) ! S(=1 =A塔)、下から順に、K 枚の円盤を描画。
NEXT w
END SUB

END


インデックスへ EXIT
新規発言を反映させるにはブラウザの更新ボタンを押してください。