Rough PGN save support.
[tagua/yd.git] / src / index.cpp
blobb0ccf446890965cba62e14480d2c6798ce3cd2d4
2 /*
3 Copyright (c) 2006 Paolo Capriotti <p.capriotti@gmail.com>
4 (c) 2006 Maurizio Monge <maurizio.monge@kdemail.net>
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
12 #include <iostream>
13 #include <QStringList>
14 #include "index.h"
16 Index::operator QString() const {
17 QString retv = QString::number(num_moves);
19 for(int i = 0; i < (int)nested.size(); i++)
20 retv += QString("_%1.%2").arg( nested[i].variation ).arg( nested[i].num_moves );
22 return retv;
25 Index Index::fromString(const QString& s) {
26 QStringList l = s.split("_");
27 if(l.isEmpty())
28 return Index(-1);
30 Index retv(l[0].toInt());
31 for(int i=1;i<l.size();i++) {
32 QStringList v = l[i].split(".");
33 if(v.size()!=2)
34 return Index(-1);
35 retv.nested.push_back(Ref(v[0].toInt(), v[1].toInt()));
37 return retv;
40 int Index::totalNumMoves() const {
41 int retv = num_moves;
43 for(int i = 0; i < (int)nested.size(); i++)
44 retv += nested[i].num_moves+1;
46 return retv;
49 bool Index::atVariationStart() const {
50 return nested.size() && (nested[nested.size()-1].num_moves == 0);
53 Index Index::flipVariation(const Index& vstart, int v_id) const {
54 int s = vstart.nested.size();
55 if(s) {
56 if( (int)nested.size() < s
57 || vstart.num_moves != num_moves)
58 return *this;
60 for(int i=0;i<s-1;i++)
61 if(vstart.nested[i] != nested[i])
62 return *this;
64 if(vstart.nested[s-1].variation != nested[s-1].variation
65 || vstart.nested[s-1].num_moves > nested[s-1].num_moves)
66 return *this;
68 if(nested[s-1].num_moves > vstart.nested[s-1].num_moves) {
69 Index retv(num_moves);
70 for(int i=0;i<s;i++)
71 retv.nested.push_back(vstart.nested[i]);
72 retv.nested.push_back(Ref(v_id, nested[s-1].num_moves - vstart.nested[s-1].num_moves - 1));
73 for(int i=s;i<(int)nested.size();i++)
74 retv.nested.push_back(nested[i]);
75 return retv;
77 else if(nested[s-1].num_moves == vstart.nested[s-1].num_moves
78 && (int)nested.size() > s && nested[s].variation == v_id) {
79 Index retv(num_moves);
80 for(int i=0;i<s-1;i++)
81 retv.nested.push_back(vstart.nested[i]);
82 retv.nested.push_back(Ref(nested[s-1].variation, nested[s-1].num_moves + nested[s].num_moves + 1));
83 for(int i=s+1;i<(int)nested.size();i++)
84 retv.nested.push_back(nested[i]);
85 return retv;
87 else
88 return *this;
90 else if(num_moves > vstart.num_moves) {
91 Index retv(vstart.num_moves);
92 retv.nested.push_back(Ref(v_id,num_moves - vstart.num_moves - 1));
93 for(int i=0;i<(int)nested.size();i++)
94 retv.nested.push_back(nested[i]);
95 return retv;
97 else if(num_moves == vstart.num_moves
98 && nested.size() > 0 && nested[0].variation == v_id) {
99 Index retv(num_moves + nested[0].num_moves + 1);
100 for(int i=1;i<(int)nested.size();i++)
101 retv.nested.push_back(nested[i]);
102 return retv;
104 else
105 return *this;
108 Index Index::next(int variation_id, int num) const {
109 Index retv = *this;
110 if(variation_id != -1)
111 retv.nested.push_back( Ref(variation_id, num-1) );
112 else if(retv.nested.size() == 0)
113 retv.num_moves += num;
114 else
115 retv.nested.last().num_moves += num;
117 return retv;
120 Index Index::prev(int _num) const {
121 int num = _num;
122 Index retv = *this;
124 while(num) {
125 if(retv.nested.size() == 0) {
126 if(retv.num_moves < num) {
127 ERROR("Cannot rewind index " << *this <<
128 " by " << _num << "!");
129 return Index(-1);
131 retv.num_moves -= num;
132 num = 0;
134 else {
135 if(retv.nested.last().num_moves >= num) {
136 retv.nested.last().num_moves -= num;
137 num = 0;
139 else {
140 num -= retv.nested.last().num_moves+1;
141 retv.nested.pop_back();
146 return retv;
149 Index Index::min(const Index& ix) const {
150 if(ix.num_moves != num_moves)
151 return Index( std::min(ix.num_moves, num_moves) );
153 Index retv(num_moves);
154 for(int i = 0; (i < (int)nested.size()) && (i < (int)ix.nested.size()); i++) {
155 if(nested[i].variation != ix.nested[i].variation)
156 break;
157 retv.nested.push_back(Ref(nested[i].variation,
158 std::min(ix.nested[i].num_moves, nested[i].num_moves) ));
159 if(ix.nested[i].num_moves != nested[i].num_moves)
160 break;
163 return retv;
166 std::pair<int, int> Index::stepsTo(const Index& ix) const {
167 int i;
168 int down = 0, up = 0;
169 bool branch = ix.num_moves != num_moves;
170 if(num_moves>ix.num_moves)
171 down += num_moves-ix.num_moves;
172 if(num_moves<ix.num_moves)
173 up += ix.num_moves-num_moves;
175 for(i = 0; (i < (int)nested.size()) && (i < (int)ix.nested.size()); i++) {
176 if(nested[i].variation != ix.nested[i].variation)
177 branch = true;
178 if(branch) {
179 down += nested[i].num_moves+1;
180 up += ix.nested[i].num_moves+1;
181 continue;
183 if(ix.nested[i].num_moves != nested[i].num_moves)
184 branch = true;
185 if(nested[i].num_moves>ix.nested[i].num_moves)
186 down += nested[i].num_moves-ix.nested[i].num_moves;
187 if(nested[i].num_moves<ix.nested[i].num_moves)
188 up += ix.nested[i].num_moves-nested[i].num_moves;
190 for(; i<(int)nested.size();i++)
191 down += nested[i].num_moves+1;
192 for(; i<(int)ix.nested.size();i++)
193 up += ix.nested[i].num_moves+1;
194 return std::pair<int,int>(down, up);
197 int Index::lastIndex() {
198 return nested.size() ? nested[nested.size()-1].num_moves : num_moves;
201 bool Index::mainLine() const {
202 return nested.empty();