예제 #1
0
// State save
int BurnStateSave(TCHAR* szName, int bAll)
{
	const char szHeader[] = "FB1 ";						// File identifier
	int nLen = 0, nVer = 0;
	int nRet = 0;

	if (bAll) {											// Get amount of data
		StateInfo(&nLen, &nVer, 1);
	} else {
		StateInfo(&nLen, &nVer, 0);
	}
	if (nLen <= 0) {									// No data, so exit without creating a savestate
		return 0;										// Don't return an error code
	}

	FILE* fp = _tfopen(szName, _T("wb"));
	if (fp == NULL) {
		return 1;
	}

	fwrite(&szHeader, 1, 4, fp);
	nRet = BurnStateSaveEmbed(fp, -1, bAll);
    fclose(fp);

	if (nRet < 0) {
		return 1;
	} else {
		return 0;
	}
}
예제 #2
0
int iCmpExt::NObjCmpConnection::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
{
    typedef Domain::NamedObject QMocSuperClass;
    _id = QMocSuperClass::qt_metacall(_c, _id, _a);
    if (_id < 0)
        return _id;
    if (_c == QMetaObject::InvokeMetaMethod) {
        switch (_id) {
        case 0: StateInfo((*reinterpret_cast< DRI::IAsyncCmd*(*)>(_a[1]))); break;
        case 1: TdmInfo((*reinterpret_cast< DRI::IAsyncCmd*(*)>(_a[1]))); break;
        case 2: ChannelInfo((*reinterpret_cast< DRI::IAsyncCmd*(*)>(_a[1])),(*reinterpret_cast< int(*)>(_a[2])),(*reinterpret_cast< bool(*)>(_a[3]))); break;
        case 3: ConferenceInfo((*reinterpret_cast< DRI::IAsyncCmd*(*)>(_a[1])),(*reinterpret_cast< int(*)>(_a[2]))); break;
        default: ;
        }
        _id -= 4;
    }
#ifndef QT_NO_PROPERTIES
      else if (_c == QMetaObject::ReadProperty) {
        void *_v = _a[0];
        switch (_id) {
        case 0: *reinterpret_cast< QString*>(_v) = DriNameBoard(); break;
        case 1: *reinterpret_cast< QString*>(_v) = GetState(); break;
        case 2: *reinterpret_cast< int*>(_v) = m_countActivation; break;
        case 3: *reinterpret_cast< QString*>(_v) = LastActivation(); break;
        case 4: *reinterpret_cast< QString*>(_v) = LastDeactivation(); break;
        case 5: *reinterpret_cast< QString*>(_v) = m_lastBoardError; break;
        case 6: *reinterpret_cast< iCmpExt::ChDataCaptureMode::Value*>(_v) = m_dataCaptureMode; break;
        case 7: *reinterpret_cast< int*>(_v) = m_maxDataCaptureCount; break;
        case 8: *reinterpret_cast< int*>(_v) = m_currDataCaptureCount; break;
        }
        _id -= 9;
    } else if (_c == QMetaObject::WriteProperty) {
        void *_v = _a[0];
        switch (_id) {
        case 6: m_dataCaptureMode = *reinterpret_cast< iCmpExt::ChDataCaptureMode::Value*>(_v); break;
        case 7: m_maxDataCaptureCount = *reinterpret_cast< int*>(_v); break;
        case 8: m_currDataCaptureCount = *reinterpret_cast< int*>(_v); break;
        }
        _id -= 9;
    } else if (_c == QMetaObject::ResetProperty) {
        _id -= 9;
    } else if (_c == QMetaObject::QueryPropertyDesignable) {
        _id -= 9;
    } else if (_c == QMetaObject::QueryPropertyScriptable) {
        _id -= 9;
    } else if (_c == QMetaObject::QueryPropertyStored) {
        _id -= 9;
    } else if (_c == QMetaObject::QueryPropertyEditable) {
        _id -= 9;
    } else if (_c == QMetaObject::QueryPropertyUser) {
        _id -= 9;
    }
#endif // QT_NO_PROPERTIES
    return _id;
}
예제 #3
0
void SpinBlock::transform_operators(std::vector<Matrix>& rotateMatrix)
{
  StateInfo oldStateInfo = stateInfo;
  std::vector<SpinQuantum> newQuanta;
  std::vector<int> newQuantaStates;
  std::vector<int> newQuantaMap;
  for (int Q = 0; Q < rotateMatrix.size (); ++Q)
    {
      if (rotateMatrix [Q].Ncols () != 0)
        {
          newQuanta.push_back (stateInfo.quanta [Q]);
          newQuantaStates.push_back (rotateMatrix [Q].Ncols ());
          newQuantaMap.push_back (Q);
        }
    }
  StateInfo newStateInfo = StateInfo (newQuanta, newQuantaStates, newQuantaMap);

  for (std::map<opTypes, boost::shared_ptr< Op_component_base> >::iterator it = ops.begin(); it != ops.end(); ++it)
    if (! it->second->is_core())
      for_all_operators_multithread(*it->second, bind(&SparseMatrix::build_and_renormalise_transform, _1, this, it->first, 
						       ref(rotateMatrix) , &newStateInfo));
  stateInfo = newStateInfo;
  stateInfo.AllocatePreviousStateInfo ();
  *stateInfo.previousStateInfo = oldStateInfo;

  for (int i = 0; i < newQuantaMap.size (); ++i)
    assert (stateInfo.quanta [i] == oldStateInfo.quanta [newQuantaMap [i]]);

  if (dmrginp.outputlevel() > 0) {
    pout << "\t\t\t total elapsed time " << globaltimer.totalwalltime() << " " << globaltimer.totalcputime() << " ... " 
	 << globaltimer.elapsedwalltime() << " " << globaltimer.elapsedcputime() << endl;
    pout << "\t\t\t Transforming to new basis " << endl;
  }
  Timer transformtimer;

  for (std::map<opTypes, boost::shared_ptr< Op_component_base> >::iterator it = ops.begin(); it != ops.end(); ++it)
    if ( it->second->is_core())
      for_all_operators_multithread(*it->second, bind(&SparseMatrix::renormalise_transform, _1, ref(rotateMatrix), (&this->stateInfo)));


  for (std::map<opTypes, boost::shared_ptr< Op_component_base> >::iterator it = ops.begin(); it != ops.end(); ++it)
    if (! it->second->is_core())
      ops[it->first]->set_core(true);

  this->direct = false;
  if (dmrginp.outputlevel() > 0)
    pout << "\t\t\t transform time " << transformtimer.elapsedwalltime() << " " << transformtimer.elapsedcputime() << endl;

  if (leftBlock)
    leftBlock->clear();
  if (rightBlock)
    rightBlock->clear();


}
예제 #4
0
static
vector<StateInfo> makeInfoTable(const NGHolder &g) {
    vector<StateInfo> info(num_vertices(g));
    for (auto v : vertices_range(g)) {
        u32 idx = g[v].index;
        const CharReach &cr = g[v].char_reach;
        assert(idx < info.size());
        info[idx] = StateInfo(v, cr);
    }
    return info;
}
예제 #5
0
void SpinBlock::transform_operators(std::vector<Matrix>& rotateMatrix)
{

  StateInfo oldStateInfo = braStateInfo;
  std::vector<SpinQuantum> newQuanta;
  std::vector<int> newQuantaStates;
  std::vector<int> newQuantaMap;
  for (int Q = 0; Q < rotateMatrix.size (); ++Q)
  {
    if (rotateMatrix [Q].Ncols () != 0)
      {
	newQuanta.push_back (braStateInfo.quanta [Q]);
	newQuantaStates.push_back (rotateMatrix [Q].Ncols ());
	newQuantaMap.push_back (Q);
      }
  }
  StateInfo newStateInfo = StateInfo (newQuanta, newQuantaStates, newQuantaMap);

  build_and_renormalise_operators( rotateMatrix, &newStateInfo );

  braStateInfo = newStateInfo;
  braStateInfo.AllocatePreviousStateInfo ();
  *braStateInfo.previousStateInfo = oldStateInfo;
  ketStateInfo = braStateInfo;

  for (int i = 0; i < newQuantaMap.size (); ++i) {
    assert (braStateInfo.quanta [i] == oldStateInfo.quanta [newQuantaMap [i]]);
    assert (ketStateInfo.quanta [i] == oldStateInfo.quanta [newQuantaMap [i]]);
  }

  tcpu = globaltimer.totalcputime(); twall= globaltimer.totalwalltime();
  ecpu = globaltimer.elapsedcputime(); ewall= globaltimer.elapsedwalltime();
  p3out << "\t\t\t total elapsed time " <<  twall << " " << tcpu << " ... " << ewall << " " << ecpu << endl;
  p1out << "\t\t\t Transforming to new basis " << endl;
  Timer transformtimer;

  renormalise_transform( rotateMatrix, &this->braStateInfo );

  for (std::map<opTypes, boost::shared_ptr< Op_component_base> >::iterator it = ops.begin(); it != ops.end(); ++it)
    if (! it->second->is_core())
      ops[it->first]->set_core(true);

  this->direct = false;
  ecpu = transformtimer.elapsedcputime();ewall= transformtimer.elapsedwalltime();
  p3out << "\t\t\t transform time " << ewall << " " << ecpu << endl;

  if (leftBlock)
    leftBlock->clear();
  if (rightBlock)
    rightBlock->clear();


}
StateInfo NFA::match_first(const string & text)
{
    _matchStates.push({_start, text.begin()});

    while (can_match())
    {
        if (unguarded_match(text))
        {
            break;
        }
    }

    if (_results.size())
    {
        return _results.front();
    }
    return StateInfo();
}
예제 #7
0
string analyze_game(string moves)
{
   SetupStates = Search::StateStackPtr(new std::stack<StateInfo>);

    istringstream is(moves);


    std::stringstream ss;
    ss << centipawn_evaluate(pos);

    // Parse move list (if any)
    while (is >> token && (m = UCI::to_move(pos, token)) != MOVE_NONE)
    {
        SetupStates->push(StateInfo());
        pos.do_move(m, SetupStates->top(), pos.gives_check(m, CheckInfo(pos)));        
        ss << "," << centipawn_evaluate(pos);
    }
    return ss.str();
}
예제 #8
0
int iCmpExt::NObjWatchdogTest::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
{
    typedef Domain::NamedObject QMocSuperClass;
    _id = QMocSuperClass::qt_metacall(_c, _id, _a);
    if (_id < 0)
        return _id;
    if (_c == QMetaObject::InvokeMetaMethod) {
        switch (_id) {
        case 0: SmallWatchdogTest((*reinterpret_cast< DRI::IAsyncCmd*(*)>(_a[1])),(*reinterpret_cast< const QString(*)>(_a[2]))); break;
        case 1: HugeWatchdogTest((*reinterpret_cast< DRI::IAsyncCmd*(*)>(_a[1])),(*reinterpret_cast< const QString(*)>(_a[2]))); break;
        case 2: LoopForeverTest((*reinterpret_cast< DRI::IAsyncCmd*(*)>(_a[1])),(*reinterpret_cast< const QString(*)>(_a[2]))); break;
        case 3: AssertTest((*reinterpret_cast< DRI::IAsyncCmd*(*)>(_a[1])),(*reinterpret_cast< const QString(*)>(_a[2]))); break;
        case 4: OutOfMemoryTest((*reinterpret_cast< DRI::IAsyncCmd*(*)>(_a[1])),(*reinterpret_cast< const QString(*)>(_a[2]))); break;
        case 5: EchoHaltTest((*reinterpret_cast< DRI::IAsyncCmd*(*)>(_a[1])),(*reinterpret_cast< const QString(*)>(_a[2]))); break;
        case 6: StateInfo((*reinterpret_cast< DRI::IAsyncCmd*(*)>(_a[1])),(*reinterpret_cast< const QString(*)>(_a[2]))); break;
        case 7: RunWatchdogLoop((*reinterpret_cast< DRI::IAsyncCmd*(*)>(_a[1])),(*reinterpret_cast< const QString(*)>(_a[2])),(*reinterpret_cast< int(*)>(_a[3]))); break;
        default: ;
        }
        _id -= 8;
    }
    return _id;
}
예제 #9
0
// State load
int BurnStateLoadEmbed(FILE* fp, int nOffset, int bAll, int (*pLoadGame)())
{
	const char* szHeader = "FS1 ";						// Chunk identifier

	int nLen = 0;
	int nMin = 0, nFileVer = 0, nFileMin = 0;
	int t1 = 0, t2 = 0;
	char ReadHeader[4];
	char szForName[33];
	int nChunkSize = 0;
	unsigned char *Def = NULL;
	int nDefLen = 0;									// Deflated version
	int nRet = 0;

	if (nOffset >= 0) {
		fseek(fp, nOffset, SEEK_SET);
	} else {
		if (nOffset == -2) {
			fseek(fp, 0, SEEK_END);
		} else {
			fseek(fp, 0, SEEK_CUR);
		}
	}

	memset(ReadHeader, 0, 4);
	fread(ReadHeader, 1, 4, fp);						// Read identifier
	if (memcmp(ReadHeader, szHeader, 4)) {				// Not the right file type
		return -2;
	}

	fread(&nChunkSize, 1, 4, fp);
	if (nChunkSize <= 0x40) {							// Not big enough
		return -1;
	}

	int nChunkData = ftell(fp);

	fread(&nFileVer, 1, 4, fp);							// Version of FB that this file was saved from

	fread(&t1, 1, 4, fp);								// Min version of FB that NV  data will work with
	fread(&t2, 1, 4, fp);								// Min version of FB that All data will work with

	if (bAll) {											// Get the min version number which applies to us
		nFileMin = t2;
	} else {
		nFileMin = t1;
	}

	fread(&nDefLen, 1, 4, fp);							// Get the size of the compressed data block

	memset(szForName, 0, sizeof(szForName));
	fread(szForName, 1, 32, fp);

	if (nBurnVer < nFileMin) {							// Error - emulator is too old to load this state
		return -5;
	}

	// Check the game the savestate is for, and load it if needed.
	{
		bool bLoadGame = false;

		if (nBurnDrvActive < nBurnDrvCount) {
			if (strcmp(szForName, BurnDrvGetTextA(DRV_NAME))) {	// The save state is for the wrong game
				bLoadGame = true;
			}
		} else {										// No game loaded
			bLoadGame = true;
		}

		if (bLoadGame) {
			unsigned int nCurrentGame = nBurnDrvActive;
			unsigned int i;
			for (i = 0; i < nBurnDrvCount; i++) {
				nBurnDrvActive = i;
				if (strcmp(szForName, BurnDrvGetTextA(DRV_NAME)) == 0) {
					break;
				}
			}
			if (i == nBurnDrvCount) {
				nBurnDrvActive = nCurrentGame;
				return -3;
			} else {
				if (pLoadGame == NULL) {
					return -1;
				}
				if (pLoadGame()) {
					return -1;
				}
			}
		}
	}

	StateInfo(&nLen, &nMin, bAll);
	if (nLen <= 0) {									// No memory to load
		return -1;
	}

	// Check if the save state is okay
	if (nFileVer < nMin) {								// Error - this state is too old and cannot be loaded.
		return -4;
	}

	fseek(fp, nChunkData + 0x30, SEEK_SET);				// Read current frame
	fread(&nCurrentFrame, 1, 4, fp);					//

	fseek(fp, 0x0C, SEEK_CUR);							// Move file pointer to the start of the compressed block
	Def = (unsigned char*)malloc(nDefLen);
	if (Def == NULL) {
		return -1;
	}
	memset(Def, 0, nDefLen);
	fread(Def, 1, nDefLen, fp);							// Read in deflated block

	nRet = BurnStateDecompress(Def, nDefLen, bAll);		// Decompress block into driver
	if (Def) {
		free(Def);											// free deflated block
		Def = NULL;
	}

	fseek(fp, nChunkData + nChunkSize, SEEK_SET);

	if (nRet) {
		return -1;
	} else {
		return 0;
	}
}
예제 #10
0
// Write a savestate as a chunk of an "FB1 " file
// nOffset is the absolute offset from the beginning of the file
// -1: Append at current position
// -2: Append at EOF
int BurnStateSaveEmbed(FILE* fp, int nOffset, int bAll)
{
	const char* szHeader = "FS1 ";						// Chunk identifier

	int nLen = 0;
	int nNvMin = 0, nAMin = 0;
	int nZero = 0;
	char szGame[33];
	unsigned char *Def = NULL;
	int nDefLen = 0;									// Deflated version
	int nRet = 0;

	if (fp == NULL) {
		return -1;
	}

	StateInfo(&nLen, &nNvMin, 0);						// Get minimum version for NV part
	nAMin = nNvMin;
	if (bAll) {											// Get minimum version for All data
		StateInfo(&nLen, &nAMin, 1);
	}

	if (nLen <= 0) {									// No memory to save
		return -1;
	}

	if (nOffset >= 0) {
		fseek(fp, nOffset, SEEK_SET);
	} else {
		if (nOffset == -2) {
			fseek(fp, 0, SEEK_END);
		} else {
			fseek(fp, 0, SEEK_CUR);
		}
	}

	fwrite(szHeader, 1, 4, fp);							// Chunk identifier
	int nSizeOffset = ftell(fp);						// Reserve space to write the size of this chunk
	fwrite(&nZero, 1, 4, fp);							//

	fwrite(&nBurnVer, 1, 4, fp);						// Version of FB this was saved from
	fwrite(&nNvMin, 1, 4, fp);							// Min version of FB NV  data will work with
	fwrite(&nAMin, 1, 4, fp);							// Min version of FB All data will work with

	fwrite(&nZero, 1, 4, fp);							// Reserve space to write the compressed data size

	memset(szGame, 0, sizeof(szGame));					// Game name
	sprintf(szGame, "%.32s", BurnDrvGetTextA(DRV_NAME));			//
	fwrite(szGame, 1, 32, fp);							//

	fwrite(&nCurrentFrame, 1, 4, fp);					// Current frame

	fwrite(&nZero, 1, 4, fp);							// Reserved
	fwrite(&nZero, 1, 4, fp);							//
	fwrite(&nZero, 1, 4, fp);							//

	nRet = BurnStateCompress(&Def, &nDefLen, bAll);		// Compress block from driver and return deflated buffer
	if (Def == NULL) {
		return -1;
	}

	nRet = fwrite(Def, 1, nDefLen, fp);					// Write block to disk
	if (Def) {
		free(Def);											// free deflated block and close file
		Def = NULL;
	}

	if (nRet != nDefLen) {								// error writing block to disk
		return -1;
	}

	if (nDefLen & 3) {									// Chunk size must be a multiple of 4
		fwrite(&nZero, 1, 4 - (nDefLen & 3), fp);		// Pad chunk if needed
	}

	fseek(fp, nSizeOffset + 0x10, SEEK_SET);			// Write size of the compressed data
	fwrite(&nDefLen, 1, 4, fp);							//

	nDefLen = (nDefLen + 0x43) & ~3;					// Add for header size and align

	fseek(fp, nSizeOffset, SEEK_SET);					// Write size of the chunk
	fwrite(&nDefLen, 1, 4, fp);							//

	fseek (fp, 0, SEEK_END);							// Set file pointer to the end of the chunk

	return nDefLen;
}
예제 #11
0
// 自己対局を行い局面を生成する
// 生成した局面はposition_listに追加する
void
play_game(std::vector<PositionData> &position_list, std::vector<std::vector<std::string>> &book)
{
  std::random_device rnd;
  std::mt19937 mt(rnd());
  std::unordered_map<Key, bool> hash_map;
  Search::StateStackPtr state = Search::StateStackPtr(new std::stack<StateInfo>());
  Position pos;
  pos.set("lnsgkgsnl/1r5b1/ppppppppp/9/9/9/PPPPPPPPP/1B5R1/LNSGKGSNL b - 1", Threads[0]);
  hash_map[pos.key()] = true;
  Thread *thread = pos.this_thread();

  if (book.empty())
  {
    std::uniform_real_distribution<> select_prob(0.0, 1.0);
    std::uniform_int_distribution<> move_prob(kMinBookMove, kMaxBookMove);
    std::uniform_int_distribution<> search_prob(kMultiPvDepthMin, kMultiPvDepthMax);
    int book_end = move_prob(mt);
    for (int k = 0; k < book_end; ++k)
    {
      size_t multipv_max = (pos.game_ply() <= 20) ? kMultiPv20 : kMultiPvOver;

      if (!search(pos, multipv_max, static_cast<Depth>(search_prob(mt))))
        return;
      double prob[kMultiPv20] = {0.0};
      double total = 0.0;
      int pv_end = static_cast<int>(std::min(multipv_max, thread->root_moves_.size()));
      for (int i = 0; i < pv_end; ++i)
      {
        prob[i] = win_rate(thread->root_moves_[i].score);
        total += prob[i];
      }
      for (int i = 0; i < pv_end; ++i)
        prob[i] = prob[i] / total;
      double t = select_prob(mt);
      int index;
      total = 0.0;
      for (index = 0; index < pv_end - 1; ++index)
      {
        total += prob[index];
        if (total > t)
          break;
      }
      state->push(StateInfo());
      pos.do_move(thread->root_moves_[index].pv[0], state->top());
      hash_map[pos.key()] = true;
    }
  }
  else
  {
    std::uniform_int_distribution<> book_index(0, static_cast<int>(book.size() - 1));
    std::vector<std::string> &moves = book[book_index(mt)];
    std::uniform_int_distribution<> move_index(kMinBookMove, static_cast<int>(moves.size()));
    int book_end = move_index(mt);
    for (int i = 0; i < book_end; ++i)
    {
      Move m = USI::to_move(pos, moves[i]);
      if (m == kMoveNone)
        return;
      state->push(StateInfo());
      pos.do_move(m, state->top());
      hash_map[pos.key()] = true;
    }

    int randam_end = 1;
    if (moves.size() > 30)
    {
      std::uniform_int_distribution<> g(0, 1);
      randam_end = g(mt);
    }

    for (int i = 0; i < randam_end; ++i)
    {
      Move m = pick_randam_move(pos, mt);
      if (m == kMoveNone)
        return;

      state->push(StateInfo());
      pos.do_move(m, state->top());
      hash_map[pos.key()] = true;
    }
  }

  Search::clear();

  Search::Limits.infinite = 1;
  Search::Signals.stop_on_ponder_hit = false;
  Search::Signals.stop = false;

  thread->pv_index_ = 0;
  thread->calls_count_ = 0;
  thread->max_ply_ = 0;
  thread->root_depth_ = kDepthZero;

  std::vector<PositionData> game;
  if (!search(pos, 1, kSearchDepth))
    return;
  Value initial_value = thread->root_moves_[0].score;
  if (initial_value < -kWinValue || initial_value > kWinValue)
    return;
  PositionData d;
  d.sfen = USI::to_sfen(pos);
  d.value = initial_value;
  d.next_move = USI::format_move(thread->root_moves_[0].pv[0]);
  game.push_back(d);
  state->push(StateInfo());
  pos.do_move(thread->root_moves_[0].pv[0], state->top());
  hash_map[pos.key()] = true;

  Color win = kNoColor;
  while (true)
  {
    TT.new_search();
    if (!search(pos, 1, kSearchDepth))
    {
      win = ~pos.side_to_move();
      break;
    }
    Value v = thread->root_moves_[0].score;

    if (pos.game_ply() > 1000)
    {
      if (v > 0)
        win = pos.side_to_move();
      else if (v < 0)
        win = ~pos.side_to_move();
      else
        win = kNoColor;
      break;
    }

    PositionData data;
    data.value = v;
    data.sfen = USI::to_sfen(pos);
    data.next_move = USI::format_move(thread->root_moves_[0].pv[0]);
    game.push_back(data);
    state->push(StateInfo());
    pos.do_move(thread->root_moves_[0].pv[0], state->top());
    if (hash_map[pos.key()])
      break;

    hash_map[pos.key()] = true;
  }

  if (win != kNoColor)
  {
    for (auto &g : game)
    {
      g.win = win;
      position_list.push_back(g);
    }
  }
}
예제 #12
0
// 以下のようなフォーマットが入力される。
// <棋譜番号> <日付> <先手名> <後手名> <0:引き分け, 1:先手勝ち, 2:後手勝ち> <総手数> <棋戦名前> <戦形>
// <CSA1行形式の指し手>
//
// (例)
// 1 2003/09/08 羽生善治 谷川浩司 2 126 王位戦 その他の戦型
// 7776FU3334FU2726FU4132KI
//
// 勝った方の手だけを定跡として使うこととする。
// 出現回数がそのまま定跡として使う確率となる。
// 基本的には棋譜を丁寧に選別した上で定跡を作る必要がある。
// MAKE_SEARCHED_BOOK を on にしていると、定跡生成に非常に時間が掛かる。
void MakeBook(Position& pos, std::istringstream& ssCmd) {
	std::string fileName;
	ssCmd >> fileName;
	std::ifstream ifs(fileName.c_str(), std::ios::binary);
	if (!ifs) {
		std::cout << "I cannot open " << fileName << std::endl;
		return;
	}
	std::string line;
	std::map<Key, std::vector<BookEntry> > bookMap;

	while (std::getline(ifs, line)) {
		std::string elem;
		std::stringstream ss(line);
		ss >> elem; // 棋譜番号を飛ばす。
		ss >> elem; // 対局日を飛ばす。
		ss >> elem; // 先手
		const std::string sente = elem;
		ss >> elem; // 後手
		const std::string gote = elem;
		ss >> elem; // (0:引き分け,1:先手の勝ち,2:後手の勝ち)
		const Color winner = (elem == "1" ? Black : elem == "2" ? White : Color::Null);
		// 勝った方の指し手を記録していく。
		// 又は稲庭戦法側を記録していく。
		const Color saveColor = winner;

		if (!std::getline(ifs, line)) {
			std::cout << "!!! header only !!!" << std::endl;
			return;
		}
		pos.Set(g_DefaultStartPositionSFEN, pos.GetRucksack()->m_ownerHerosPub.GetFirstCaptain());
		StateStackPtr SetUpStates = StateStackPtr(new std::stack<StateInfo>());
		UsiOperation usiOperation;
		while (!line.empty()) {
			const std::string moveStrCSA = line.substr(0, 6);
			const Move move = usiOperation.CsaToMove(pos, moveStrCSA);
			if (move.IsNone()) {
				pos.Print();
				std::cout << "!!! Illegal move = " << moveStrCSA << " !!!" << std::endl;
				break;
			}
			line.erase(0, 6); // 先頭から6文字削除
			if (pos.GetTurn() == saveColor) {
				// 先手、後手の内、片方だけを記録する。
				const Key key = Book::GetBookKey(pos);
				bool isFind = false;
				if (bookMap.find(key) != bookMap.end()) {
					for (std::vector<BookEntry>::iterator it = bookMap[key].begin();
						 it != bookMap[key].end();
						 ++it)
					{
						if (it->m_fromToPro == move.ProFromAndTo()) {
							++it->m_count;
							if (it->m_count < 1) {
								// 数えられる数の上限を超えたので元に戻す。
								--it->m_count;
							}
							isFind = true;
						}
					}
				}
				if (isFind == false) {
#if defined MAKE_SEARCHED_BOOK
					SetUpStates->push(StateInfo());
					pos.GetTurn()==Color::Black
						?
						pos.DoMove<Color::Black,Color::White>(move, SetUpStates->top())
						:
						pos.DoMove<Color::White,Color::Black>(move, SetUpStates->top())
						;

					std::istringstream ssCmd("byoyomi 1000");
					UsiOperation usiOperation;
					usiOperation.Go(pos, ssCmd);
					pos.GetRucksack()->m_ownerHerosPub.WaitForThinkFinished();

					pos.UndoMove(move);
					SetUpStates->pop();

					// doMove してから search してるので点数が反転しているので直す。
					const ScoreIndex score = -pos.GetConstRucksack()->m_rootMoves[0].m_score_;
#else
					const ScoreIndex GetScore = ScoreZero;
#endif
					// 未登録の手
					BookEntry be;
					be.m_score = score;
					be.m_key = key;
					be.m_fromToPro = static_cast<u16>(move.ProFromAndTo());
					be.m_count = 1;
					bookMap[key].push_back(be);
				}
			}
			SetUpStates->push(StateInfo());

			pos.GetTurn() == Color::Black
				?
				pos.DoMove<Color::Black,Color::White>(move, SetUpStates->top())
				:
				pos.DoMove<Color::White,Color::Black>(move, SetUpStates->top())
				;
			

		}
	}

	// BookEntry::count の値で降順にソート
	for (auto& elem : bookMap) {
		std::sort(elem.second.rbegin(), elem.second.rend(), countCompare);
	}

#if 0
	// 2 回以上棋譜に出現していない手は削除する。
	for (auto& elem : bookMap) {
		auto& second = elem.second;
		auto erase_it = std::find_if(second.begin(), second.IsEnd(), [](decltype(*second.begin())& second_elem) { return second_elem.m_count < 2; });
		second.erase(erase_it, second.IsEnd());
	}
#endif

#if 0
	// narrow book
	for (auto& elem : bookMap) {
		auto& second = elem.second;
		auto erase_it = std::find_if(second.begin(), second.IsEnd(), [&](decltype(*second.begin())& second_elem) { return second_elem.m_count < second[0].m_count / 2; });
		second.erase(erase_it, second.IsEnd());
	}
#endif

	std::ofstream ofs("book.bin", std::ios::binary);
	for (auto& elem : bookMap) {
		for (auto& elel : elem.second) {
			ofs.write(reinterpret_cast<char*>(&(elel)), sizeof(BookEntry));
		}
	}

	std::cout << "book making was done" << std::endl;
}