2009年03月07日
15パズルの作り方(その2)
では解説
-----
まず 各ピースの中に入れたスクリプト
-----
これは -1 のコードで送られてきたメッセージからベクトルを取り出し(文字列に変換して渡してる)
-----
それで位置を設定する
-----
子プリムで llSetPos を行うと親プリムに対する相対位置になるのだ...
-----
でもって ルートのプリムに入れたスクリプトの方
-----
この辺は 定数と変数の宣言
-----
なので 飛ばして w
-----
これは ピースのシーケンス位置(左上から右下に向けスキャンするように 0 からつけたシーケンス番号)を 2つ与えてやると そのマンハッタン距離(マンハッタン距離 - Wikipedia)を返す関数
-----
これは ピースのシーケンス位置とスペースのシーケンス位置を与えてやると そのピースを動かすことができるかどうかを返す関数
-----
スペースまでのマンハッタン距離が 1なら動かすことができるってわけ
-----
これは 動かすピースの(盤面の)数字を与えてやると そのピースを動かす関数
-----
といっても cur_state に盤面の状態を保持していて それを変更する
-----
空白は 16 と見なし まず cur_state というリストの中で 空白と与えられた数字の 位置を検出し llListReplaceList で入れ替える
-----
後で使うため 前 空白があった場所を返してます
-----
(続く)
-----
まず 各ピースの中に入れたスクリプト
-----
//-----
// File: 15puzzle_piece.lsl
// Date Author number of nodes
// 2009/2/16 walkinglint 11
//
integer SET_POS = -1;
vector pos;
default {
link_message(integer sender_num, integer num, string str, key id) {
if (num == SET_POS) {
pos = (vector)str;
llSetPos(pos);
}
}
}
これは -1 のコードで送られてきたメッセージからベクトルを取り出し(文字列に変換して渡してる)
-----
それで位置を設定する
-----
子プリムで llSetPos を行うと親プリムに対する相対位置になるのだ...
-----
でもって ルートのプリムに入れたスクリプトの方
-----
//-----
// File: 15puzzle_game.lsl
// Date Author number of nodes
// 2009/3/5 walkinglint 109
//
integer SET_POS = -1;
integer LINK_SHUFFLE = 16;
integer LINK_RESET = 17;
integer SP = 16;
list cur_state;
list goal = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16];
integer sp = -1;
integer count;
integer i;
integer j;
vector pos;
この辺は 定数と変数の宣言
-----
なので 飛ばして w
-----
integer distance(integer from, integer to) {-----
return llAbs((from / 4) - (to / 4)) + llAbs((from % 4) - (to % 4));
}
これは ピースのシーケンス位置(左上から右下に向けスキャンするように 0 からつけたシーケンス番号)を 2つ与えてやると そのマンハッタン距離(マンハッタン距離 - Wikipedia)を返す関数
-----
integer is_movable(integer num, integer sp) {-----
integer idx = llListFindList(cur_state, [num]);
return (distance(idx, sp) <= 1);
}
これは ピースのシーケンス位置とスペースのシーケンス位置を与えてやると そのピースを動かすことができるかどうかを返す関数
-----
スペースまでのマンハッタン距離が 1なら動かすことができるってわけ
-----
integer move_piece(integer num) {-----
integer prev_sp = llListFindList(cur_state, [SP]);
integer idx = llListFindList(cur_state, [num]);
cur_state = llListReplaceList(cur_state, [num], sp, sp);
cur_state = llListReplaceList(cur_state, [SP], idx, idx);
sp = llListFindList(cur_state, [SP]);
return prev_sp;
}
これは 動かすピースの(盤面の)数字を与えてやると そのピースを動かす関数
-----
といっても cur_state に盤面の状態を保持していて それを変更する
-----
空白は 16 と見なし まず cur_state というリストの中で 空白と与えられた数字の 位置を検出し llListReplaceList で入れ替える
-----
後で使うため 前 空白があった場所を返してます
-----
(続く)
Posted by walkinglint at 22:02│Comments(0)
│walking のスクリプティング講座