データの持ち方

今日は電車のトラブルでぼけーっとしてる時間が出来て、そのときにこんなことを考えてました。


データの持ち方について。
以前、魔法学校でシューティングゲームを作っていたんですが、そのとき、弾のデータを構造体の配列で持ってました。
構造体の中に使用中かどうかのフラグを用意して、新しく弾を出したいときは0から順にフラグを調べて未使用の場所に当たったら初期化して使用中にします。
画面外に行ったり消滅したりと、未使用になる場合はフラグを戻します。
なので、そのうち歯抜けになっていきます。
フレーム毎の処理(移動やあたり判定など)は、forループで0から最後まで使用中のフラグを調べて使用中なら処理を行います。
今思うとそりゃ無いだろうって思いますが、当時はこれしか方法を思いつかなかった(考えなかった)わけです。
データの持ち方の知識なんて無きに等しかったし(今でもあまり変わらないけど)動的生成とか知ってはいたけど、実装出来るスキルなんてなかったですし。


魔法学校を卒業後、ちょっと弾幕っぽいのを作ってみようと思い、ちまちまと作業を始めました。
弾が何個出るか分からないから必要になったらその都度メモリを確保しようということになり、今度は構造体を双方向リストで持つことにしました。
弾が必要になったらnewで生成してリストの最後にくっつけ、要らなくなったらdeleteで消してリンクを繋ぎ直します。
これなら弾がいくら出ても大丈夫。
弾がいくら出るか分からない時点でダメ仕様だと思いますが……リストを使えるようになったときには、こんな便利なモノがあるのかと思ったものです。
でも、さすがにnewやdeleteをその都度やるのは負荷がかかりそうです。


今ならどうやるだろうと考えると、どれくらい弾が出るかわからないなんてことはないはずなので、まず必要分だけメモリを確保します。
とりあえず双方向リスト方式はそのままで、使用中のリストと未使用分リストの二つで管理するのがいいんじゃなかろうかと。
必要になったら未使用分の最後を使用中リストにくっつけて未使用分は一つ前を最後にし、不要になったらそれを未使用の最後にくっつけ使用中リストを繋ぎ直します。
魔法学校時代の配列方式は、作っている最中ずっと歯抜けになることと追加時の無駄が気になっていました。
これなら配列方式の歯抜けと追加の無駄がなくなります。
電車が止まったせいで数年来のもやもやが晴れました。


でもまだまだ無駄が多いような。
一般的にはどうやって持つんだろ?
仕事でやってるプログラムは実行効率とかそんなのはまったく関係なく動くかどうかしか求められないから、たまには意識して効率の良いプログラムにしようとか考えないとなあ。