質問 (回答受付中)[artisocモデル] 相続制度の実現に当たって子供リストを取得したかった。 | |
質問者: la manoさん , 質問日時: 2021/01/08 01:38 |
エージェントは家や生産手段(農地等)などの用途として土地を所有するが、エージェントが死亡した際に過去に自らが出産したエージェントのうち、最年長者に所有権を移すという処理を行いたい。その為には子供を纏めたエージェント集合を保持する必要性が出てくる。然しこのエージェント集合が想定しない挙動を見せたため、原因及び解決策を知りたい。
処理の流れとしては、誕生後、(親がいれば)親の座標に移り(親の情報は直前に出産した個体をグローバルなエージェント変数に記録)、親の家に余裕があれば同居、なければ新しく近くに家を建てる。職場として近場の最も栄養価の高い土地に農地を建設する。以上の処理が出来なければ(十分な土地がなければ)自死する。 毎ステップ、家と農地を往復し、農地にいる時土地の栄養価に比例した食料を得て、家にいるとき、手持ちの食料が十分に多ければ余分を家に備蓄する。家の備蓄量が十分に多ければ、備蓄を消費して出産する。
親から子へリンクを結んだものが画像(四角いエージェントは土地エージェントで、青は空き地の栄養価の度合いを示し、緑は農地、桃は家を示している。人エージェントは赤点(数字はID))https://imgur.com/a/SOzsi0T (外部リンク)
明らかに出産したとは言い難い遠方のエージェントと紐づいていることが分かる。また、複数の自称親が特定の子に矢印を伸ばしていることが分かる。
以上の現象に心当たりがあればご教授願いたい。
以下は原因究明に当たって分かったこと。 子から親に向けてリンクを結ぼうとすると親から子と比較すると以上が少ないが時がたつと異常は増すことがある。 周囲の空き地が無くなったタイミングで異常が起きだすようだ。 killagtされたはずのエージェントと同一のIDのエージェントが描画されている。削除から同一IDエージェントが生成された形跡なし。また、kill類似関数に変更しても同様。
以下は人エージェントの全文。デバグの為に余分な文があり見辛いが、参考にされたい。 Agt_Init{ my.食料 = 5 //即餓死を防ぐ。一応2世代目は親から受け取っている。出産にそれ以上の費用なし my.生年 = getcountstep()//産まれたタイミングを記録 dim 親 as agt dim neighbor0 as agtset dim neighbor as agtset dim 親の家 as agt //なぜかuniverse.地域.親.家とかやるとバグるので(数字だから?)クッション ClearAgtSet(my.子) ClearAgtSet(my.親) if universe.地域.親 then//親がいる print("親がいる") 親 = universe.地域.親 addagt(my.親, 親) println("生成された人" & Cstr(my.ID) & "親" & Cstr(親.ID)) 同じ位置にする(my, 親) MakeOneAgtsetAroundOwn(neighbor0, 3, universe.地域.土地, False) //周囲の荒地を探している makecommonagtset(neighbor, neighbor0, universe.荒地) 親の家 = 親.家 if countagtset(親の家.居住者) < 3 then my.家 = 親.家 addagt(my.所有土地, my.家) //相続をさせたいが未実装 同じ位置にする(my, my.家) if countagtset(neighbor) then sortagtset(neighbor, "豊穣", false) //職場 my.職場 = pickupagt(neighbor, 0) //一番豊かな土地を選択 addagt(my.所有土地, my.職場) //未実装 delagtset2(universe.荒地, my.職場) My.職場.色 = COLOR_GREEN //描画の為 my.目的地 = my.職場 //往復の為 addagt(my.家.居住者, my) else//一度産んで殺している print("家飛び出るも行き場なく死") killagt(my) end if elseif countagtset(neighbor) > 1 then //親の家満室 家を出る 家と農地を探す(neighbor) else print("家ない") killagt(My) end if //addagt(親.子, my) else//親がいない つまり第一世代目 場合分けしないと親が0でバグる print("親がいない") my.X = rnd() * getheightspace(universe.地域) //逆だったかもだけど正方形なのでヨシ my.Y = rnd() * getwidthspace(universe.地域) MakeOneAgtsetAroundOwn(neighbor0, 3, universe.地域.土地, False) makecommonagtset(neighbor, neighbor0, universe.荒地) 家と農地を探す(neighbor) end if }
sub 同じ位置にする(対象 as agt, 移動先 as agt){ 対象.X = 移動先.X 対象.Y = 移動先.Y}
sub 家と農地を探す(neighbor as agtset){ if countagtset(neighbor) then //周囲に荒地がある sortagtset(neighbor, "豊穣", false)//周囲で一番豊かな土地を探す my.職場 = pickupagt(neighbor, 0) //集合から除外して家と被らないようにしている addagt(my.所有土地, my.職場)
同じ位置にする(my, my.職場) if countagtset(neighbor) then// my.家= pickupagt(neighbor, Int(Rnd() * CountAgtset(neighbor)))//適当な空き地に家を建てて住む addagt(my.所有土地, my.家) delagtset2(universe.荒地, my.家) My.家.色 = COLOR_MAGENTA delagtset2(universe.荒地, my.職場) My.職場.色 = COLOR_GREEN my.目的地 = my.家 addagt(my.家.居住者, my) else//農地を用意できなければ死 print("農地ない") killagt(my) end if else//家を用意できなければ死 print("家ない") killagt(My) end if}
Agt_Step{ println("step" & Cstr(my.ID)) //家と職場を往復 dim one as agt if My.X == My.家.X and My.Y == My.家.Y then//家に着いたら my.目的地 = My.職場 //目的地のくだりは往復の為 if my.食料 > 10 then //手持ちの食料を10より多く持ってたらその分家に置いておく My.家.備蓄 = my.家.備蓄 + my.食料 - 10 my.食料 = 10 end if if my.家.備蓄 > 10 then//備蓄が十分あれば子を産む universe.地域.親 = my println("creating by " & Cstr(my.ID)) one = createagt(universe.地域.人) if my.X != one.X or my.Y != one.Y then //バグの検知 println(Cstr(my.X) & Cstr(my.Y) & Cstr(one.X) & Cstr(one.Y)) end if my.家.備蓄 = my.家.備蓄 -5
addagt(my.子, one) //なぜかバグり遠方に子供が出来たり複数の人が親権を主張したりする
end if elseif My.X == My.職場.X and My.Y == My.職場.Y then my.目的地 = My.家 my.食料 = my.食料 + my.職場.豊穣 * 10 //農地に着いたら収穫 end if pursue(my.目的地, 1)
my.食料 = my.食料 -1 //食料を消費 if my.食料 < 0 then//餓死と老死 区別するためだけに場合分けている println("餓死削除された人" & Cstr(my.ID)) delagtset2(my.家.居住者, my) if countagtset(my.家.居住者) == 0 then addagt(universe.荒地, my.家) my.家.色 = My.家.豊穣*256 my.家.備蓄 = 0 end if addagt(universe.荒地, my.職場) My.職場.色 = My.職場.豊穣*256 killAgt(my) elseif my.生年 + 50< getcountstep() then println("老死削除された人" & Cstr(my.ID)) //死んだ後も何故か表示され続ける delagtset2(my.家.居住者, my) if countagtset(my.家.居住者) == 0 then //なぜか!=1でも上手くいっていた addagt(universe.荒地, my.家) //誰も住んでいない家を自動で解体する 現実でも出来たらよいが… my.家.色 = My.家.豊穣*256 my.家.備蓄 = 0 end if addagt(universe.荒地, my.職場) //職場は共用じゃないので破壊 My.職場.色 = My.職場.豊穣*256 terminateAgt(my) end if
}
|
|
▼ 全ての回答
|
|