void LeafNode::removeKey(int keyIndex, int childIndex) { for (int i = keyIndex; i < getKeyNum() - 1; ++i) { setKeyValue(i, getKeyValue(i + 1)); setData(i, getData(i + 1)); } setKeyNum(getKeyNum() - 1); }
void CInternalNode::removeKey(int keyIndex, int childIndex) { for (int i=0; i<getKeyNum()-keyIndex-1; ++i) { setKeyValue(keyIndex+i, getKeyValue(keyIndex+i+1)); setChild(childIndex+i, getChild(childIndex+i+1)); } setKeyNum(getKeyNum()-1); }
/*删除内部结点的键值*/ void InternalNode::removeKey(int keyIndex, int childIndex) { for (int i = 0; i < getKeyNum() - childIndex; i++) { setChild(childIndex + i, getChild(childIndex + i + 1)); } for (int i = 0; i < getKeyNum() - keyIndex - 1; ++i) { setKeyValue(keyIndex + i, getKeyValue(keyIndex + i + 1)); }//键值对依次向前移动 setKeyNum(getKeyNum() - 1); }
void Board2048::runGame(){ srand(time(0)); try { /* check board */ if(board.size()==0){ throw exception(); } /* rand a key to put on the board */ randKey(2); /* Show the initial board */ assert(getKeyNum()==2); showBoard('N'); while(1){ /* get input char */ getInput(); if(b_quit == 'q') break; else if(b_quit=='n'){ b_quit = ' '; continue; } moveBoard(); randKey(1); showBoard('N'); checkOver(); if(b_quit == 'q') break; } cout<<endl; }catch(exception e){ cout<<"Board was NOT initialized"<<endl; } }
/*从兄弟结点中借出键值对*/ void InternalNode::borrowFrom(FatherNode* siblingNode, FatherNode* parentNode, int keyIndex, SIBLING_DIRECTION d) { switch (d) { case LEFT: { insert(0, 0, parentNode->getKeyValue(keyIndex), ((InternalNode*)siblingNode)->getChild(siblingNode->getKeyNum())); parentNode->setKeyValue(keyIndex, siblingNode->getKeyValue(siblingNode->getKeyNum() - 1)); siblingNode->removeKey(siblingNode->getKeyNum() - 1, siblingNode->getKeyNum()); } //从左兄弟获得新的键值 break; case RIGHT: { insert(getKeyNum(), getKeyNum() + 1, parentNode->getKeyValue(keyIndex), ((InternalNode*)siblingNode)->getChild(0)); parentNode->setKeyValue(keyIndex, siblingNode->getKeyValue(0)); siblingNode->removeKey(0, 0); } //从右兄弟获得新的键值 break; default: break; } }
//---------------------------------------------------------------------- // ● キーにアクセスする //---------------------------------------------------------------------- Scalar::Key& Scalar::operator [] ( int idx_ ) { if ( idx_ >= getKeyNum() ) { // 警告とか //printf( __FUNCTION__" index error[%d]\n", idx_ ); *reinterpret_cast< int* >( 0 ) = 0; } return mKeyFrameList[ idx_ ]; }
//---------------------------------------------------------------------- // ● 再生が終了しているかを判定する (ループ再生時は常に false) //---------------------------------------------------------------------- bool Scalar::isFinished() const { if ( mEnableLoop ) return false; if ( getKeyNum() == 0 ) { return true; } if ( mCurrentFramePos < mKeyFrameList.back().FramePos ) { return false; } return true; }
/*插入内部结点*/ void InternalNode::insert(int keyIndex, int childIndex, KeyType key, FatherNode* childNode) { int i; for (i = getKeyNum(); i > keyIndex; --i) { setChild(i + 1, m_Childs[i]); setKeyValue(i, m_KeyValues[i - 1]); } //将父节点的childIndex后所有键值对后移一个单位 if (i == childIndex) { setChild(i + 1, m_Childs[i]); } setChild(childIndex, childNode); //插入新结点 setKeyValue(keyIndex, key); setKeyNum(m_KeyNum + 1); }
/* set Num pieces of Keys */ Point Board2048::randPoint(){ int pos = rand()%(b_row*b_col - getKeyNum())+1; int k = 0; for(int i=0;i<b_row;i++){ for(int j=0;j<b_col;j++){ if(!board[i][j]){ if(++k == pos) return Point(i,j); } } } return Point(-1,-1); }
void CInternalNode::insert(int keyIndex, int childIndex, KeyType key, CNode* childNode) { int i; for (i=getKeyNum(); i>keyIndex; --i)//将父节点中的childIndex后的所有关键字的值和子树指针向后移一位 { setChild(i+1,m_Childs[i]); setKeyValue(i,m_KeyValues[i-1]); } if (i==childIndex) { setChild(i+1, m_Childs[i]); } setChild(childIndex, childNode); setKeyValue(keyIndex, key); setKeyNum(m_KeyNum+1); }
/*获得键下标*/ int FatherNode::getKeyIndex(KeyType key) const { int left = 0; int right = getKeyNum() - 1; int current; while (left != right) { current = (left + right) / 2; KeyType currentKey = getKeyValue(current); if (key > currentKey) { left = current + 1; } //折半查找 else { right = current; } } return left; }
//---------------------------------------------------------------------- // ● 時間の設定 //---------------------------------------------------------------------- void Scalar::setTime( double time_ ) { mTime = time_; time_ *= mTimeTick; if ( mEnableLoop ) { // ループ位置未設定 if ( mLoopEndPos == 0.0f && mLoopBeginPos == 0.0f ) { // 終端のキーフレームの時間を使ってループ if ( mKeyFrameList.back().FramePos < time_ ) { time_ = fmod( time_, static_cast< double >( mKeyFrameList.back().FramePos ) ); } } // ループ位置設定済み else { // time_ がループ領域を超えていた場合は開始時間からループ if ( mLoopEndPos < time_ ) { time_ -= mLoopBeginPos; time_ = fmod( time_, ( mLoopEndPos - mLoopBeginPos ) ); time_ = mLoopBeginPos + time_; } } } mCurrentFramePos = time_; if ( getKeyNum() ) { // time_ が最初のフレーム位置より前の場合はデフォルト値 if ( time_ < mKeyFrameList.front().FramePos ) { mValue = mDefaultValue; } // キーがひとつだけの場合はそのキーの値 else if ( getKeyNum() == 1 ) { mValue = mKeyFrameList.front().Value; } // time_ が終端以降の場合は終端の値 else if ( time_ >= mKeyFrameList.back().FramePos ) { mValue = mKeyFrameList.back().Value; } // 以上以外の場合は補間する else { // time_ の型と Key::FramePos の型は同じのにしておかないと正常に検索できない //key = (Key*)bsearch( &time_, mKeyFrames, mSize, sizeof( Key ), _cmpKey ); // キー検索 /* KeyFrameList::iterator itr = std::find_if( mKeyFrameList.begin(), mKeyFrameList.end(), scalarGreaterEqual( mCurrentFramePos ) ); const Key& key0 = *itr; const Key& key1 = *(itr + 1); */ const Key* key0 = (Key*)bsearch( &mCurrentFramePos, &(mKeyFrameList[0]), mKeyFrameList.size(), sizeof( Key ), _cmpKey ); const Key* key1 = key0 + 1; lnFloat p0 = key0->Value; lnFloat p1 = key1->Value; lnFloat t0 = static_cast< lnFloat >( key0->FramePos ); lnFloat t1 = static_cast< lnFloat >( key1->FramePos ); lnFloat t = static_cast< lnFloat >( mCurrentFramePos - t0 ) / ( t1 - t0 ); switch ( key0->InterMode ) { // 補間無し case LN_ANIM_INTER_NONE: { mValue = p0; break; } // 線形 case LN_ANIM_INTER_LINEAR: { mValue = p0 + ( p1 - p0 ) * t; break; } // 等加速度 case LN_ANIM_INTER_ACCEL: { mValue = LMath::QuadAccel( p0, key0->Velocity, key0->Accel, static_cast< lnFloat >( mCurrentFramePos - key0->FramePos ) ); break; } // 三次補間 case LN_ANIM_INTER_CUBIC: { mValue = LMath::Hermite( p0, p1, key0->RightSlope, key1->LeftSlope, t ); break; } // Catmull-Rom case LN_ANIM_INTER_CATMULLROM: { // ループ再生で time が終端を超えている場合、 // この時点でkey の値は ループ開始位置のひとつ前のキーを指している const Key& begin = mKeyFrameList.front(); const Key& end = mKeyFrameList.back(); // この補間には、begin のひとつ前と end のひとつ後の値が必要。 // それぞれが始点、終点の場合はループするように補間する mValue = LMath::CatmullRom( ( ( key0->FramePos == begin.FramePos ) ? end.Value : (key0 - 1)->Value ), p0, p1, ( ( key1->FramePos == end.FramePos ) ? begin.Value : (key0 + 2)->Value ), t ); break; } } #if 0 lnFloat p0 = key0.Value; lnFloat p1 = key1.Value; lnFloat t0 = static_cast< lnFloat >( key0.FramePos ); lnFloat t1 = static_cast< lnFloat >( key1.FramePos ); lnFloat t = static_cast< lnFloat >( time_ - t0 ) / ( t1 - t0 ); switch ( key0.InterMode ) { // 補間無し case LN_ANIM_INTER_NONE: { mValue = p0; break; } // 線形 case LN_ANIM_INTER_LINEAR: { mValue = p0 + ( p1 - p0 ) * t; lnprintf("a %f %f %f %f\n", mValue, p0, p1, t); break; } // 等加速度 case LN_ANIM_INTER_ACCEL: { mValue = LMath::accel( p0, key0.Velocity, key0.Accel, static_cast< lnFloat >( mCurrentFramePos - key0.FramePos ) ); break; } // 三次補間 case LN_ANIM_INTER_CUBIC: { mValue = LMath::cubic( p0, p1, key0.RightSlope, key1.LeftSlope, t ); break; } // Catmull-Rom case LN_ANIM_INTER_CATMULLROM: { // ループ再生で time が終端を超えている場合、 // この時点でkey の値は ループ開始位置のひとつ前のキーを指している const Key& begin = mKeyFrameList.front(); const Key& end = mKeyFrameList.back(); // この補間には、begin のひとつ前と end のひとつ後の値が必要。 // それぞれが始点、終点の場合はループするように補間する mValue = LMath::catmullRom( ( ( key0.FramePos == begin.FramePos ) ? end.Value : (itr - 1)->Value ), p0, p1, ( ( key1.FramePos == end.FramePos ) ? begin.Value : (itr + 2)->Value ), t ); break; } } #endif } } else { mValue = mDefaultValue; } }