ソートされた配列に状態を保存し、再帰的に行う二分探索 (分割統治) アプローチを使用できます。
- 配列を 2 つに分割する
- 配列に項目が 1 つ含まれている場合は、その項目を返します
- どちらの半分が正しい結果を含むかを決定する
- ステップ 1 に進みます
これは、対数時間で結果を見つける必要があります。(なお、log2 ( 1,000)~10、log2 ( 10,000)~13)
以下はドラフト (およびテストされていない) 実装です。
class HistoryEntry
{
public var timestamp:int;
public var state:GameState;
public function HistoryEntry(timestamp:int, state:GameState)
{
this.timestamp = timestamp;
this.state = state;
}
}
class History
{
private var states:Array;
public function History()
{
super();
states = [];
}
public function addState(state:State):void
{
var timestamp:int = getTimer();
var entry:HistoryEntry = new HistoryEntry(timestamp, state);
states.push(entry);
}
public function getStateBefore(timestamp:int):State
{
return doGetStateBefore(timestamp, 0, states.length - 1);
}
// Recursive function
private function doGetStateBefore(timestamp:int, beginIndex:int, endIndex:int):State
{
if (beginIndex == endIndex) {
return states[beginIndex];
}
var beginEntry:HistoryEntry = states[beginIndex];
var endEntry:HistoryEntry = states[endIndex];
if (beginEntry.timestamp == timestamp) {
return beginEntry.state;
}
if (endEntry.timestamp == timestamp) {
return endEntry.state;
}
var middleIndex:int = (beginIndex + endIndex) / 2;
var middleEntry:HistoryEntry = states[middleIndex];
if (midleEntry.timestamp >= timestamp) {
return doGetStateBefore(timestamp, beginIndex, middleIndex);
} else {
return doGetStateBefore(timestamp, middleIndex + 1, endIndex);
}
}
}
HistoryEntry
動的オブジェクトを使用するとパフォーマンスに悪影響を及ぼすため、配列から型指定されたオブジェクトを取得するようにクラスを導入しました。