ソラマメブログ

2008年07月04日

ライフゲーム作ってみようかな(その5) - ビット演算

結構またなんだかんだで嵌ってしまったけど できた ^^
-----
最初リストで作ってたんだが なんとなく 体感 遅い というわけで ビット版で簡単に作り直してみたら 普通に動いたので そっちからのせときます
-----

-----

-----
のようになります
-----
HUD でと考えたのはプリムの制約があると考えたからなのでした
-----
というわけで HUD でも動きます(というか上の写真は HUD で動かしているわけですが...)
-----
最初あまり考えなかったのですが 適当に作っていたら 上下左右 で繋がっているようになりました ^^
-----
というわけでリストもあげておきます
-----
通常のボタン側は Walking Jun:ライフゲーム作ってみようかな(その4) - メッセージ から変更なし
-----
赤いボタンは 今の所 光らせていないので(動作状態を示すため光らせてもよいような気はするが...)
//
// File: start_button.lsl
// Date Author number of nodes
// 2008/7/4 walkinglint 5
//
default {
touch_start(integer total_number) {
llMessageLinked(LINK_ROOT, 0, "", NULL_KEY);
}
}
本体側は
//
// File: LifeGame2.lsl
// Date Author number of nodes
// 2008/7/4 walkinglint 98
// 2008/7/4 walkinglint 98 (LifeGame->LifeGame2)
// 2008/7/4 walkinglint 98
//
integer START_BUTTON = 2;
integer min_link_num = 3;
integer num_of_buttons = 64;
integer i;
integer gen_word1;
integer gen_word2;
integer next_gen_word1;
integer next_gen_word2;
integer is_generating = FALSE;
float time_interval = 1.0;
string line;
init() {
gen_word1 = 0;
gen_word2 = 0;
}
integer get(integer i) {
if (i >= 32) {
return gen_word2 & (1 << (i - 32));
} else {
return gen_word1 & (1 << i);
}
}
set(integer i) {
if (i >= 32) {
gen_word2 = gen_word2 | (1 << (i - 32));
} else {
gen_word1 = gen_word1 | (1 << i);
}
}
set_next(integer i) {
if (i >= 32) {
next_gen_word2 = next_gen_word2 | (1 << (i - 32));
} else {
next_gen_word1 = next_gen_word1 | (1 << i);
}
}
unset(integer i) {
if (i >= 32) {
gen_word2 = gen_word2 & ~(1 << (i - 32));
} else {
gen_word1 = gen_word1& ~(1 << i);
}
}
unset_next(integer i) {
if (i >= 32) {
next_gen_word2 = next_gen_word2 & ~(1 << (i - 32));
} else {
next_gen_word1 = next_gen_word1 & ~(1 << i);
}
}
integer range_check_and_test(integer i) {
if (i < 0) {
i += num_of_buttons;
} else if (num_of_buttons <= i) {
i -= num_of_buttons;
}
return get(i);
}
string show(integer word) {
line = "";
for (i = 0; i < 32; i++) {
if (word & (1 << i)) {
line = "1" + line;
} else {
line = "0" + line;
}
}
return line;
}
gen_next() {
for (i = 0; i < num_of_buttons; i++) {
integer cnt = 0;
if (range_check_and_test(i - 8 - 1)) {
cnt++;
}
if (range_check_and_test(i - 8)) {
cnt++;
}
if (range_check_and_test(i - 8 + 1)) {
cnt++;
}
if (range_check_and_test(i - 1)) {
cnt++;
}
if (range_check_and_test(i + 1)) {
cnt++;
}
if (range_check_and_test(i + 8 - 1)) {
cnt++;
}
if (range_check_and_test(i + 8)) {
cnt++;
}
if (range_check_and_test(i + 8 + 1)) {
cnt++;
}
if ((get(i) == 0) && (cnt == 3)) {
set_next(i);
} else if (get(i) && ((cnt == 2) || (cnt == 3))) {
set_next(i);
} else {
unset_next(i);
}
}
gen_word1 = next_gen_word1;
gen_word2 = next_gen_word2;
}
disp() {
for (i = 0; i < num_of_buttons; i++) {
if (get(i)) {
llMessageLinked(min_link_num + i, TRUE, "", NULL_KEY);
} else {
llMessageLinked(min_link_num + i, FALSE, "", NULL_KEY);
}
}
}
default {
state_entry() {
init();
disp();
llSetTimerEvent(0.0);
}
on_rez(integer param) {
llResetScript();
}
link_message(integer sender_num, integer num, string str, key id) {
if (sender_num == START_BUTTON) {
is_generating = !is_generating;
if (is_generating) {
llSetTimerEvent(time_interval);
llOwnerSay("start gen");
} else {
llSetTimerEvent(0.0);
llOwnerSay("stop gen");
}
} else {
integer i = sender_num - min_link_num;
if (num == TRUE) {
set(i);
} else {
unset(i);
}
}
}
timer() {
gen_next();
disp();
}
}
64ビットあればいいというわけで べたに 2ワード使っています
-----
で 一つ やられた~ というのがあって |= とか &= がなかった事
-----
後 1 をシフトして ~(反転)して アンドをとる というのをとっさに思い付かず 変なことをしてしまってバグらせていました ^^
-----
ライフゲームに関しては ライフゲーム - Wikipedia とか参照しました...

同じカテゴリー(walking のスクリプティング講座)の記事
 プロフィール写真の表示に問題 (2009-11-30 20:55)
 ミニ太陽系 (2009-03-21 06:03)
 関数から文字列を返したら何か問題になる? (2009-03-18 18:02)
 llListFindList って型って関係ないんだったっけ (2009-03-18 14:02)
 夏時間(PDT)の実験 (2009-03-08 22:04)
 15パズルの作り方(その3) (2009-03-08 06:03)
上の画像に書かれている文字を入力して下さい
 
<ご注意>
書き込まれた内容は公開され、ブログの持ち主だけが削除できます。