[color=#0000ff][u][size=150]課題:geogbraでもライフゲームを作ろう。[br][/size][/u][/color][br]geogebraは行列が得意なので、setValueというスクリプトと行列の積を使って、次の状態を計算しよう。[br][br]#5×5のセルの1つ1つに隣接した位置があります。[br]#そこだけ抜き出すために、[br]#25個のセル1つ1つに対して、どのセルがとなりかの情報が必要です。隣接してれば1をしてなければ0を入れたリストをならべます。[br]#サイズ25のリストが25個格納された隣接行列がAです。[br]#隣接行列 A [br]A = {{0,1,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{1,0,1,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,1,0,1,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,1,0,1,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,1,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{1,1,0,0,0,0,1,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0},{1,1,1,0,0,1,0,1,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0},{0,1,1,1,0,0,1,0,1,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0},{0,0,1,1,1,0,0,1,0,1,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0},{0,0,0,1,1,0,0,0,1,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0},{0,0,0,0,0,1,1,0,0,0,0,1,0,0,0,1,1,0,0,0,0,0,0,0,0},{0,0,0,0,0,1,1,1,0,0,1,0,1,0,0,1,1,1,0,0,0,0,0,0,0},{0,0,0,0,0,0,1,1,1,0,0,1,0,1,0,0,1,1,1,0,0,0,0,0,0},{0,0,0,0,0,0,0,1,1,1,0,0,1,0,1,0,0,1,1,1,0,0,0,0,0},{0,0,0,0,0,0,0,0,1,1,0,0,0,1,0,0,0,0,1,1,0,0,0,0,0},{0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,1,0,0,0,1,1,0,0,0},{0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,1,0,1,0,0,1,1,1,0,0},{0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,1,0,1,0,0,1,1,1,0},{0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,1,0,1,0,0,1,1,1},{0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,1,0,0,0,0,1,1},{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,1,0,0,0},{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,1,0,1,0,0},{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,1,0,1,0},{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,1,0,1},{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,1,0}}[br][br]# 状態ベクトルvの初期値[br]v = {0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}[br][br]# 世代カウンター[br]g = 0[br]count = {0}[br][br]# ツールバーからボタンを選び画面にはりつけます。見出しは「次の世代」[br]# 世代を1つ進め、A.dot(v) を行い結果をvと同サイズのベクトルcountにセットします。[br]# ライフゲームのルール[br]# 生存ルール: 自分が「生(1)」かつ「周囲が2または3」[br]# next_v[(v == 1) & ((neighbor_counts == 2) | (neighbor_counts == 3))] = 1[br]# 誕生ルール: 自分が「死(0)」かつ「周囲が3」[br]# next_v[(v == 0) & (neighbor_counts == 3)] = 1[br]# によって、v状態ベクトルを更新しましょう。次のスクリプトを貼り付けましょう。[br][br]SetValue(g, g + 1)[br]Execute({"count = A * Transpose({v})"})[br]SetValue(v, Sequence(If((Element(v, i) == 1 && (Element(count, i, 1) == 2 || Element(count, i, 1) == 3)) || (Element(v, i) == 0 && Element(count, i, 1) == 3), 1, 0), i, 1, 25))[br][br][br]# ツールバーからボタンを選び画面にはりつけます。見出しは「リセット」、スクリプトは以下の通り[br]SetValue(g, 0)[br]SetValue(v, {0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0})[br][br]#表示用のグリッドを作ります。[br]#不透明度の設定をいじるのではなく、「v の中身が 1 の場所だけに自動で四角形を描画する(0 の場所は描画しない)」にします。[br]# vはr行c列の行列を1次元のベクトルにしているので、読み取った結果をvの(r - 1) * 5 + c番目とします。そこが1のときだけ描画します。 [br][br]Sequence(Sequence(If(Element(v, (r - 1) * 5 + c) == 1, Polygon((c, -r), (c + 1, -r), (c + 1, -r - 1), (c, -r - 1))), c, 1, 5), r, 1, 5)[br][br]# ツールバーからボタンを選び画面にはりつけます。見出しは「ランダムな初期値」、[br]スクリプトは以下の通り[br]SetValue(g, 0)[br]SetValue(v, Sequence(RandomBetween(0,1),k,1,25))[br]#数式に次の行をはりつける。できたテキストラベルを適当に移動してください。[br]""+g +"世代"