Logo Search packages:      
Sourcecode: tagua version File versions  Download package

void Game::load ( PositionPtr  pos,
const PGN &  pgn 
)

loads a pgn in the current game

Definition at line 839 of file game.cpp.

References GamePrivate::Entry::comment, GamePrivate::Entry::last_var_id, Index::next(), position(), Index::prev(), Index::totalNumMoves(), GamePrivate::Entry::variations, and GamePrivate::Entry::vcomments.

Referenced by load().

                                               {
  current = Index(0);
  undo_history.clear();
  undo_pos = 0;

  // setup an empty history, clear as needed

  if(history.size()) {
    Entry* fe = &history[0];
    int old_history_size = history.size();
    std::vector<int> v_ids;

    while(history.size()>1)
      history.pop_back();
    for(Variations::const_iterator it = fe->variations.begin();
            it != fe->variations.end(); ++it)
      v_ids.push_back(it->first);
    fe->variations.clear();
    fe->vcomments.clear();

    for(int i=0;i<(int)v_ids.size();i++)
      onRemoved(Index(0).next(v_ids[i]));
    if(old_history_size>1)
      onRemoved(Index(1));
    v_ids.clear();
    history[0].position = pos;
  }
  else
    history.push_back( Entry(MovePtr(), pos) );

  // apply moves from PGN, one by one

  QString vcomment;
  std::vector<Index> var_stack;
  bool var_start = false;

  for (uint i = 0; i < pgn.m_entries.size(); i++) {
    if(boost::get<QString>(pgn[i])) {
      if(var_start)
        vcomment += *boost::get<QString>(pgn[i]);
      else {
        Entry *e = fetch(current);
        Q_ASSERT(e);

        e->comment += *boost::get<QString>(pgn[i]);
      }
    }
    else if(boost::get<PGN::BeginVariation>(pgn[i])) {
      var_stack.push_back(current);
      var_start = true;
    }
    else if(boost::get<PGN::EndVariation>(pgn[i])) {
      if(var_stack.size() == 0) {
        kError() << "Unexpected end variation";
        break;
      }
      current = var_stack.back();
      var_stack.pop_back();
    }
    else if(boost::get<PGN::Move>(pgn[i])) {
      const PGN::Move *pm = boost::get<PGN::Move>(pgn[i]);

      int n = current.totalNumMoves()+1;
      if(var_start) {
        if(!pm->m_number) // not all moves get numbered in PGN, usually only 1st player ones
          current = current.prev();
        else if(pm->m_number>n+1)
          kError() << "Too far variation";
        else {
          if(pm->m_number<n)
            kError() << "Too close variation";
          current = current.prev(n + 1 - pm->m_number);
        }
      }
      else if(pm->m_number && pm->m_number!=n+1)
        kError() << "Move number mismatch";

      PositionPtr pos = position();
      MovePtr m = pos->getMove(pm->m_move);

      if(!m || !pos->testMove(m))
        break;

      PositionPtr newPos = pos->clone();
      newPos->move(m);

      int at;
      History *vec = fetchRef(current, &at);
      Q_ASSERT(vec);

      if(var_start) {
        Entry *e = &(*vec)[at];
        int var_id = e->last_var_id++;
        e->variations[var_id].push_back(Entry(m, newPos));
        if(!vcomment.isEmpty()) {
          e->vcomments[var_id] = vcomment;
          vcomment = QString();
        }
        /* this is a hack, but the mainline should NEVER
            be empty if there is a variation*/
        if((int)vec->size() - 1 == at)
          vec->push_back(Entry(m, newPos));

        current = current.next(var_id);
      }
      else {
        if((int)vec->size() - 1 == at)
          vec->push_back(Entry(m, newPos));
        else
          (*vec)[at] = Entry(m, newPos);

        current = current.next();
      }

      var_start = false;
    }
    else
      kError() << "Unexpected type in boost::variant";
  }

  if(history.size()>1)
    onAdded(Index(1));
  Entry* e = fetch(Index(0));
  for(Variations::const_iterator it = e->variations.begin();
          it != e->variations.end(); ++it)
    onAdded(Index(0).next(it->first));
  for(VComments::const_iterator it = e->vcomments.begin();
          it != e->vcomments.end(); ++it)
    onSetVComment(Index(0), it->first, it->second);

  current = Index(0);
  onCurrentIndexChanged();
}


Generated by  Doxygen 1.6.0   Back to index