Σ(゚д`*;)アッ,アハァ?
修正版 ○配列 (4-698)
こなとけろ むるいのれめ
たて★かは っん★゛しー
すょせきさ くう、。゜・
--★シフト--
ぁねゃほゆ ぬわあにぇ「
ぃおらもふ やつまちえ」
ぅゅそよへ みりひをぉ
修正した評価関数 (key.cpp)
//---------------------------------------------------------------------------
/// キー k の運指にかかる時間を求める
/**
ボトルネックを考えたアルゴリズム。以下のような場合、
t7 1 608
te 1 123
e7 1 421
運指 te7 は、123+421=544msec では打てない。
te で 123msec, e7は421msecだが、t7は608msecと遅い。
最初の t を打った直後に、右中指は t → 7 への移動を開始する。
e を打ったとき、右中指は移動の 123msecぶんを終えた。
t→7 の移動は608msecかかるから、残りは 485msec。
e7 は421msecで打てるはずが、右中指の移動がボトルネックとなり、
結局、123 + (608-123) = 608 になる。
**/
//---------------------------------------------------------------------------
u32 CKey::GetTime(sstr k)
{
if (k.empty()) return 0;
u32 ret=0;
// tPass[i] は、(i+2)個前のキーから何msecが経過したかを記録する
const u32 NPRE=4; // 最速の2キー vs 最遅の2キー がどれくらい違うかによるが4個以上は結果が同じだった
u32 tPass[NPRE];
memset( tPass, 0x00, sizeof(tPass) );
char now=0, next; // 1文字目はnow=0にしてホームからの時間を取る
for (u32 i=0; i<k.length(); i++)
{
next = k[i];
UUMAP::iterator it = mMap.find( KeyType(now, next) );
if ( it!=mMap.end() )
{
u32 dt = (*it).second; // dt は (now, next) の運指にかかる時間
// ボトルネック?
for (u32 j=0; j<NPRE && j+2<=i+1; j++)
{
char c1 = j+2>i ? 0 : k[i-(j+2)]; // j=0なら2文字前、j=1なら3文字前…を取る
u32 bt = mMap[ KeyType(c1, next) ]; // c1 (2,3,4…文字前) からnextまでの時間
if (tPass[j] < bt) // c1の文字→next の運指に十分な時間が経過してない?
{
u32 remain = bt - tPass[j]; // c1→next の運指の残り時間
dt = max(dt, remain); // 残り時間が now→next の運指より長れけばボトルネック
}
}
rTL::shift( tPass, endof(tPass), +1 ); // 経過時間の配列を右にずらす
tPass[0] = dt; // [0]には今やったのを入れて、
for (u32 j=1; j<NPRE; j++) tPass[j]+=dt; // [1]〜は時間を加える
ret += dt;
now = next;
}
else
now = 0; // 0にすることで次はホームからの距離で測る
}
return ret;
}