いつかCで書いたスライディングブロックパズルを解くプログ
ラムを Java で書いてみた。
ソースはこちら
といっても、アルゴリズムはできてるから C から Java に翻訳しただけ。
いちおう、各ノード固有の処理(ヒューリスティックメソッドとか、子ノードの展開とか、領域割り当てとか)をカプセル化したり、ルート展開メソッドと一般ノード展開メソッドをオーバーライドしてポリモーフィズムを実装してみたり、オブジェクト指向っぽいことをやってる。
それほど複雑じゃなくてしかも重いアルゴリズムを実装するだけならJavaよりもCで書いたほうが絶対に速い。
でも一度 Java の魅力に取り付かれてしまうと何でもかんでも Java で書いてみたくなってしまうもの。
一般に Java は重いといわれている。
そして、Java の統合開発環境 Eclipse もこれまた重い。
いつまでもコマンドラインベースのコンパイラ使ってるようじゃダメだと思って、最近 Visual C++ とか Eclipse とかに手を出し始めた。
Eclipse とは、Java を作った Sun Microsystems のことを嫌いな某社が「日食」なんていう嫌がらせのような名前でオープンソース界に放流した統合開発環境のこと。
Eclipse の起動中の画面のスクリーンショット↓
「日食」という名の通り、「太陽」をかげらせるイラストが使用されている。
話が飛んでしまった。
Java で書いて Eclipse でビルドしたスライディングブロックプログラムの実行例↓
ソース↓
ラムを Java で書いてみた。
ソースはこちら
といっても、アルゴリズムはできてるから C から Java に翻訳しただけ。
いちおう、各ノード固有の処理(ヒューリスティックメソッドとか、子ノードの展開とか、領域割り当てとか)をカプセル化したり、ルート展開メソッドと一般ノード展開メソッドをオーバーライドしてポリモーフィズムを実装してみたり、オブジェクト指向っぽいことをやってる。
それほど複雑じゃなくてしかも重いアルゴリズムを実装するだけならJavaよりもCで書いたほうが絶対に速い。
でも一度 Java の魅力に取り付かれてしまうと何でもかんでも Java で書いてみたくなってしまうもの。
一般に Java は重いといわれている。
そして、Java の統合開発環境 Eclipse もこれまた重い。
いつまでもコマンドラインベースのコンパイラ使ってるようじゃダメだと思って、最近 Visual C++ とか Eclipse とかに手を出し始めた。
Eclipse とは、Java を作った Sun Microsystems のことを嫌いな某社が「日食」なんていう嫌がらせのような名前でオープンソース界に放流した統合開発環境のこと。
Eclipse の起動中の画面のスクリーンショット↓
「日食」という名の通り、「太陽」をかげらせるイラストが使用されている。
話が飛んでしまった。
Java で書いて Eclipse でビルドしたスライディングブロックプログラムの実行例↓
ソース↓
import java.io.*; import java.lang.*; class Node{ final static byte D = 3; byte block[][] = new byte[D][D]; /*各ノードのブロック状態*/ byte ei; /*空白の場所*/ byte ej; byte nextnum; /*直属の子ノードの数*/ int depth; /*このノードの深さ*/ int exp; /*ヒューリスティック値 + 深さ*/ int h = 0; Node next[]; /*子ノードへのポインタ*/ Node reverse; /*親ノードへのポインタ*/ Node nextleaf; /*リーフだった場合、次のリーフへのポインタ*/ Node reverseleaf; /*前のリーフへのポインタ*/ void heuristic(Node goal) { byte d = D*D, i, j=0, gi, gj=0, b, bj; boolean f; for(byte k=1;k<d;k++){
depth = buf; } this.reverseleaf.nextleaf = this.nextleaf; this.nextleaf.reverseleaf = this.reverseleaf; return depth; } int allocate(Node endleaf, boolean start) { byte k = 0, i; int depth=0, buf; char direction[] = new char[4]; if(this.ei != 0) /*遷移できる状態とその数を調べる*/ direction[k++] = 'u'; if(this.ei != D-1) direction[k++] = 'd'; if(this.ej != 0) direction[k++] = 'l'; if(this.ej != D-1) direction[k++] = 'r'; this.next = new Node[k]; this.nextnum = k; for(i=0;i<k;i++){
depth = buf; } this.reverseleaf.nextleaf = this.nextleaf; this.nextleaf.reverseleaf = this.reverseleaf; return depth; } } class SlidingBlock{ public static void main(String args[]){ Node root = new Node(); Node goal = new Node(); Node startleaf = new Node(); Node endleaf = new Node(); Node cur, next; int depth=0, buf; startleaf.nextleaf = root; root.nextleaf = endleaf; endleaf.reverseleaf = root; root.reverseleaf = startleaf; endleaf.nextleaf = null; SlidingBlock.init(root, goal); root.heuristic(goal); if(depth < (buf = root.allocate(endleaf, true)))
depth = buf; // System.out.println("nn深さ 1 まで展開"); for(byte i=0;i<root.nextnum;i++)
depth = buf; /* for(buf=0;buf<30;buf++)
state[l] = l; */ for(i=0;i<Node.D;i++){
leaf.exp){ nextdev = leaf; min = leaf.exp; } leaf = leaf.nextleaf; } return nextdev; } static void output(Node cur) { int i, j, k=0; do{ cur.reverse.nextleaf = cur; cur = cur.reverse; }while(cur.reverse != null); /*ポインタ再利用*/ System.out.println("nn"); do{ System.out.println(k++ + " 手目"); for(i=0;i<Node.D;i++){
これつくるの何時間くらいかかった?
こんど、ゴロンボーに聞いてみるから。