例題(ハノイの塔)


概要

このサンプルプログラムは、手続き呼び出しのインタフェースを用いたプログラム例です。Java側から、メソッド呼び出しの形でKLICのプログラムを利用しています。
このプログラムは、KLICで書かれたハノイの塔を解くプログラムをJavaから利用します。KLIC側では、サーバプログラムとして動作し、Javaのプログラムと接続するのを待ちます。Java側では、ハノイの塔のGUIがあり、この中で、"solve"のボタンを押すと、KLICのプログラムと接続し、手続き呼び出しのインタフェースを用いて、KLICのプログラムとJavaのプログラムの間で通信を行います。
JavaのGUIは、単独のアプリケーションとして使用するだけでなく、アプレットとしてHTMLの中に貼りつけることも可能です。このことにより、WWWを介してKLICのアプリケーションと接続して利用できるようにすることも出来ます。


コンパイル

他のサンプルプログラム同様に、jkディレクトリにあるソースとsampleディレクトリのファイルを利用するので、トップディレクトリで、makeしてください。これにより、このサンプルプログラムが利用できるようになります。
プログラムの本体は、sample/hanoi/の下にありますので、プログラムの実行は、このディレクトリで行います。


ファイル説明


実行方法

まず、KLIC側のサーバプログラムを起動します。
% ./hanoi &
として実行します。Java側のプログラムは、JDKのjavaで実行します。
% java Hanoi
とすれば、Java側のプログラムが起動し、サンプルプログラムが利用できます。
表示されたウィンドウでハノイの塔が実行することが出来ます。"solve"ボタンを押すとハノイの塔を解くためにKLIC側に接続して、その解を得て、アニメーションで表示します。

Java側のプログラムは、アプレットとしても利用できます。アプレットとして利用する場合は、このプログラムがあるディレクトリをWWWサーバに登録します。そして、このディレクトリ中にあるhanoi.htmlを開くと利用できます。このとき、KLIC側のプログラムは、WWWサーバと同じホストマシン上で既に動いている必要があります。


プログラムの説明

このプログラムは、KLICとJavaのプログラム間で、手続き呼び出しのインタフェースを利用してデータをやり取りするサンプルプログラムです。
KLIC側のプログラムは、サーバプログラムとして動作し、Java側からの接続を待ちます。このプログラムは、ハノイの塔を解くゴールを持っており、このゴールは、Java側からの手続き呼び出しのインタフェースで利用されます。Java側のプログラムは、ハノイの塔のGUIを提供してあり、KLIC側のプログラムへ接続して、ハノイの塔の解法を得て、そのデータをアニメーション表示します。この2つのプログラムをソケットを用いて接続し、手続き呼び出しのインタフェースを利用してデータをやり取りしています。
Java側のプログラムはアプレットとしても動作するようになっています。これにより、JDKがなくても、Javaが動作するWWWブラウザがあれば、どこでも利用することができます。

JavaのGUI
プログラムが実行されると、メインウィンドウが開きます。上部には、左から、ハノイの塔の円盤の枚数、ハノイの塔を解くための"solve"ボタン、円盤の並び方をでたらめにする"shuffle"ボタンがあります。その下の部分にハノイの塔の現在の状況が表示されています。
ハノイの塔の実行画面
円盤の枚数を変更する場合には、変更したい枚数を選びます。"solve"ボタンを押すと、KLIC側のプログラムと接続します。手続き呼び出しのインタフェースを用いて解を取得し、それをアニメーションで表示します。アニメーションをとめたい場合は、キャンバス上をクリックしてください。"shuffle"ボタンを押すと、現在の円盤の並びをでたらめに並べ替えます。
下にあるキャンバスでは、ハノイの塔の現在の状況が表示されています。ユーザは、この円盤を自由に動かすことが出来ます。動かしたい円盤のある棒の近くでマウスボタンをプレスし、移動したい先の棒の近くでボタンを離します。このとき、下の円盤より多きい円盤を移動させることは出来ません。

ハノイの塔を解くプログラム
KLIC側で、ハノイの塔を解くプログラムは、hanoi.kl1にあるhanoi:hanoi/3です。このゴールを用いるとハノイの塔を解く手順を得ることが出来ます。このゴールは、
hanoi -Data -To +Ans
の形をしており、Dataに現在の円盤の状況を各棒ごとにリストにして渡します。例えば、[[4,3,2,1], [], []]であれば、左の棒に下から、4から1の大きさの円盤があり、その他の棒には円盤がないことを示しています。Toには移動先の棒の番号を指定します。左の棒から、0から2の番号が振られています。Ansには、与えられたデータからハノイの塔を解く手順を、move(From, To)の形で、移動する円盤の棒の番号を示したファンクタをリストで返します。例えば、
hanoi([[3,2,1], [], []], 1, Ans)
の呼び出しでは、Ansには、
[move(0,1), move(0,2), move(1,2), move(0,1), move(2,0), move(2,1), move(0,1)]
が設定されます。

Java側のインタフェース利用部分
Java側のプログラムでは、"solve"ボタンが押されると、Hanoi.javaにあるHanoiクラスの
void solveHanoi()
が呼ばれます。このメソッドは、現在の円盤の状態をDataクラスのオブジェクトに変換して、KLICの呼び出しのデータとします。また、移動先の棒の番号として、一番大きい円盤のある棒の次の棒を指定します。そして、KLIC側と接続するソケットを作成し、メッセージインタフェースを作成します。そして、手続き呼び出しのインタフェースを用いて、hanoi:hanoi/3を呼び出します。そして、この戻り値を利用して解のアニメーション表示を行います。