格ゲーコマンド定義をぶち込むコンテナ part2

良く考えて見たら、タメの概念はどれだけボタンが押されているか?だと思う。
なので右タメボタンが1だとしたら定義はuint8 def[]={1,1,1,1,1,1}(とりあえず6フレームほど)みたいな感じで定義できるんじゃないですかな?と感じた。
タメ判定が他のボタンによって阻害されるという条件を付ければこれでも十分に使用は可能だと感じた。続く・・・http://d.hatena.ne.jp/studiokingyo/20051129#p3

licence:NYSL


#include <iostream>

#include <dkutil_c/dkc.h>
//#include <dkutil/macro.hpp>


#include <vector>

template<class T>
struct default_offset_calc_functor{
 size_t operator()(const T &x){
  return x;
 }
};
template<class T,size_t __N_,class A=std::allocator<T>,class FUNCTOR=default_offset_calc_functor<T> >
class dictionary{
public:
 typedef typename A allocator;
 //BOOST_STATIC_CONSTANT(size_t,node_num = __N_);
 ///sizeof -> 4 * __N_ + sizeof(bool) + alpha
 struct node_type{
  T data;
  bool data_stop;
  node_type *next[__N_];
  node_type(){
   data_stop = false;
   for(size_t i=0;i<__N_;i++)
    next[i] = NULL;
  }
 };
 typedef typename std::vector<node_type **> free_node_vector;
 //node_type *root[__N_];
 typedef node_type *root_type[__N_];
 root_type root;

 dictionary(){
  for(size_t i=0;i<__N_;i++)
   root[i] = NULL;
 }
 ~dictionary(){
  clear();
 }
 bool reset(){
  clear();
  
 }
 void clear_reflective(free_node_vector &v,node_type *pt[__N_]){
  
  for(size_t i=0;i<__N_;i++)
  {
   if(NULL != pt[i])
   {
    v.push_back(&pt[i]);
    
    //if(pt[i]->next[j])
    clear_reflective(v,&(pt[i]->next[0]));
   }
  }

 }
 void node_free(node_type *p){
  delete p;
 }
 node_type *node_alloc(){
  return new node_type;
 }
 void clear()
 {
  //stack
  free_node_vector v;
  clear_reflective(v,&root[0]);
  
  free_node_vector::reverse_iterator it = v.rbegin();
  for(;it != v.rend();it++)
  {
   node_type **tpp = (*it);
   node_free(*tpp);
   tpp = NULL;
  }
  v.clear();
 }
 
 bool insert(T *pobj,size_t num){
  node_type **pt = root;
  size_t offset = 0;
  FUNCTOR calc;
  size_t nt = calc(pobj[offset]);
  if(NULL==pt[nt]){
   pt[nt] = node_alloc();
  }
  pt[nt]->data = pobj[offset];
  offset++;
  if(offset == num){
   pt[nt]->data_stop = true;
   return true;
  }
  return insert_reflective(pt[nt]->next,offset,pobj,num);
 }
 
 bool insert_reflective(node_type **pt,size_t offset,T *pobj,size_t num)
 {
  FUNCTOR calc;
  size_t nt = calc(pobj[offset]);
  if(NULL==pt[nt]){
   pt[nt] = node_alloc();
  }
  offset++;
  if(offset == num){
   pt[nt]->data_stop = true;
   return true;
  }
  return insert_reflective(pt[nt]->next,offset,pobj,num);
 }

 
 bool find(T *pobj,size_t num)
 {
  FUNCTOR calc;
  node_type **pt = root;
  size_t offset = 0;
  size_t nt = calc(pobj[offset]);
  if(NULL==pt[nt]){
   return false;
  }
  offset++;
  if(offset == num){
   return true;
  }
  return find_reflective(pt[nt]->next,offset,pobj,num);
 }
 
 bool find_reflective(root_type pt,size_t offset,T *pobj,size_t num)
 {
  FUNCTOR calc;
  size_t nt = calc(pobj[offset]);
  if(NULL==pt[nt]){
   return false;
  }
  offset++;
  if(offset == num){
   if(true==pt[nt]->data_stop)
   {
    return true;
   }
   return false;
  }
  return find_reflective(pt[nt]->next,offset,pobj,num);
 }

 /**
 abcdとabcという定義がこのコンテナ内に存在したら
 abcが見つかり次第trueを返す
 */
 
 bool find_front(T *pobj,size_t num)
 {
  FUNCTOR calc;
  node_type **pt = root;
  size_t nt;
  size_t i = 0;
  for(;i<num;i++){
   nt  = calc(pobj[i]);
   if(NULL==pt[nt]){
    return false;
   }
   if(pt[nt]->data_stop) return true;
   //offset++;
   //if(offset == num){ return true;}
   pt = pt[nt]->next;

  }
  return false;
 }

};



int main(){

 dkcCheckMemoryLeak(TRUE);
 typedef dictionary<uint8,256> dic_t;
 dic_t dic;
 uint8 data[]={4,2,6,4,9,2};
 uint8 data2[]={4,2,6,4};

 bool r = dic.insert(data,sizeof(data));
 if(dic.find(data,sizeof(data)))
  std::cout << "find ok" << std::endl;
 dic.insert(data2,sizeof(data2));
 if(dic.find_front(data,sizeof(data)))
  std::cout << "find front ok" << std::endl;
 return 0;
}