91 WhiteID = BlackID = 0;
92 WhiteElo = BlackElo = 0;
100 NoteNumber = NoteMoveNum = 0;
110 uint maxExtraMoves,
uint maxThemeMoveNumber)
118 GameNumber = gameNum;
133 NoteNumber = NoteMoveNum = 0;
142 while (i < columnMoves) {
158 while (i < maxLineMoves) {
175 uint maxThemePly = maxThemeMoveNumber * 2;
178 for (i=0; i < maxThemePly; i++) {
188 OpLine::Destroy (
void)
215 if ((wBPair && !bBPair) || (!wBPair && bBPair)) {
248 OpLine * subsub = subline->Next;
249 subline->Next = Next;
250 if (subsub != NULL) {
251 OpLine * subtail = subsub;
252 while (subtail->Next != NULL) {
253 subtail = subtail->Next;
255 subtail->Next = subline;
267 if (!
strEqual (Move[length], line->Move[length])) {
break; }
268 if (
strEqual (Move[length],
"")) {
break; }
276 char tempTrans[5000];
279 strcpy(tempTrans, move);
281 char *ptr = tempTrans;
284 if (ch !=
'+' && ch !=
'x') {
294 strcpy(tempTrans, move);
304 case 'K':
case 'Q':
case 'R':
case 'B':
case 'N':
322 const char * preFirstMove =
"";
323 const char * postFirstMove =
"";
325 preFirstMove =
"\\textbf{";
328 preFirstMove =
"<b>";
329 postFirstMove =
"</b>";
331 for (
uint i=0; i < Length; i++) {
336 dstr->
Append (preFirstMove, movenum, wtm ?
"." :
"...");
338 dstr->
Append (
" ", movenum,
".");
344 dstr->
Append (postFirstMove);
368 dstr->
Append (
"<g_", GameNumber,
">");
377 default: resultStr =
"*";
break;
381 if (nmoves || !ShortGame) {
382 dstr->
Append (
"(", NumMoves,
")");
384 const char * preName =
"";
385 const char * postName =
"";
387 preName =
"<darkblue>";
388 postName =
"</darkblue>";
390 preName =
"<span class=\"player\">";
391 postName =
"</span>";
394 dstr->
Append (
" ", preName);
395 const char * s = White;
396 while (*s != 0 && *s !=
',') {
398 if (*s ==
'_' || *s ==
'$' || *s ==
'%') {
407 const char * preElo =
" ";
408 const char * postElo =
"";
409 const char * sep =
" - ";
411 preElo =
" \\emph{"; postElo =
"}"; sep =
" -- ";
413 preElo =
" <span class=\"elo\">"; postElo =
"</span>";
416 preElo =
" <green>"; postElo =
"</green>";
419 if (WhiteElo > 0) { dstr->
Append (preElo, WhiteElo, postElo); }
420 dstr->
Append (sep, preName);
423 while (*s != 0 && *s !=
',') {
439 if (BlackElo > 0) { dstr->
Append (preElo, BlackElo, postElo); }
440 dstr->
Append (
", ", Site,
" ");
446 if (s != NULL) { s--; *s = 0; }
468 NumLines = NumTableLines = 0;
469 SetMaxExtraMoves (1);
470 FilterCount = TheoryCount = 0;
497 if (ebook != NULL && ECOstr_.empty()) {
500 ECOstr_.append(eco.first, eco.second);
504 if (sm == NULL) {
break; }
519 for (i=0; i < NumLines; i++) {
522 for (i=0; i < NumMoveOrders; i++) {
524 my_Tcl_Free((
char*) MoveOrder[i].moves);
526 delete MoveOrder[i].moves;
529 NumLines = NumTableLines = 0;
531 FilterCount = TheoryCount = 0;
543 for (
uint i=0; i < NumTableLines; i++) {
547 Line[i]->Next = NULL;
548 Line[i]->NoteMoveNum = 0;
549 Line[i]->NoteNumber = 0;
577 Format = FormatFromStr (str);
591 percent = percent * 500;
594 if (total > 0) { percent = percent / total; }
606 percent = percent * 500;
609 if (total > 0) { percent = percent / total; }
631 uint percent = Results[result] * 1000;
634 if (total > 0) { percent = percent / total; }
649 strCopy (line->Move[0], StartLine[0]);
656 Results[line->Result]++;
660 if (WTM &&
strEqual (line->Move[0], ExcludeMove)) {
return false; }
661 if (!WTM &&
strEqual (line->Move[1], ExcludeMove)) {
return false; }
664 TheoryResults[line->Result]++;
666 Line[NumLines] = line;
668 if (NumTableLines < MaxTableLines) { NumTableLines++; }
675 eloT evictElo = line->AvgElo;
677 for (
uint i=0; i < NumLines; i++) {
678 eloT elo = Line[i]->AvgElo;
679 if (elo < evictElo) {
684 if (evictIndex < 0) {
687 delete Line[evictIndex];
688 Line[evictIndex] = line;
700 for (bit = 1 << 15; bit != 0; bit >>= 1) {
703 if (guess * guess > val) {
718 SetNumRows (int_sqrt((NumTableLines * 3) / 4) + 3);
728 for (
uint i=0; i < NumRows; i++) {
732 while (line != NULL) {
738 sprintf (buf,
"ROW %u[%u]: ", i+1, NLines[i]);
739 my_Tcl_Write(fp,buf,strlen(buf));
742 sprintf (buf,
" %u-NOTE: ", i+1);
743 my_Tcl_Write(fp,buf,strlen(buf));
744 line->
PrintNote (dstr, (StartLength + 2) / 2,
748 sprintf (buf,
"%s\n", dstr->
Data());
749 my_Tcl_Write(fp,buf,strlen(buf));
763 for (
uint i=0; i < NumRows; i++) {
767 while (line != NULL) {
772 fprintf (fp,
"ROW %u[%u]: ", i+1, NLines[i]);
774 fprintf (fp,
" %u-NOTE: ", i+1);
775 line->
PrintNote (dstr, (StartLength + 2) / 2,
778 fprintf (fp,
"%s\n", dstr->
Data());
788 OpTable::IsRowMergable (
uint rownum)
790 ASSERT (rownum > 0 && rownum < NumRows-1);
791 uint prevLength = Row[rownum]->CommonLength (Row[rownum-1]);
792 uint nextLength = Row[rownum]->CommonLength (Row[rownum+1]);
793 return (nextLength > prevLength);
797 OpTable::MergeRow (
uint rownum)
799 ASSERT (rownum < NumRows-1);
800 Row[rownum+1]->Insert (Row[rownum]);
801 NLines[rownum+1] += NLines[rownum];
802 RowScore[rownum+1] += RowScore[rownum];
803 for (
uint i=rownum; i < NumRows-1; i++) {
804 NLines[i] = NLines[i+1];
806 RowScore[i] = RowScore[i+1];
816 OpTable::SelectTableLines (
void)
819 if (NumLines == NumTableLines) {
return; }
820 ASSERT (NumTableLines < NumLines);
821 for (i=0; i < NumTableLines; i++) {
823 uint bestAvgElo = Line[i]->AvgElo;
824 for (j = i+1; j < NumLines; j++) {
825 if (Line[j]->AvgElo >= bestAvgElo) {
827 bestAvgElo = Line[j]->AvgElo;
830 if (bestIndex != i) {
832 Line[i] = Line[bestIndex];
833 Line[bestIndex] = temp;
842 if (NumLines == 0) {
return; }
848 SortTableLines (Line, NumTableLines, 0);
853 NumRows = NumTableLines;
862 for (i=0; i < NumRows-1;) {
863 uint clength = Row[i]->CommonLength (Row[i+1]);
866 }
else if (clength == Row[i]->Length) {
876 while (NumRows > TargetRows) {
883 uint bestcost = NLines[0] + NLines[1];
885 for (i=1; i < NumRows-1; i++) {
886 if (IsRowMergable (i)) {
887 uint cost = NLines[i] + NLines[i+1];
888 if (cost < bestcost) {
900 for (i=0; i < NumRows; i++) {
901 OpLine * rowline = Row[i];
902 OpLine * subline = Row[i]->Next;
903 while (subline != NULL) {
905 subline = subline->Next;
922 OpTable::SortTableLines (
OpLine ** lines,
uint nlines,
uint depth)
924 uint i, j, nUnique = 0;
925 if (nlines < 2) {
return; }
934 for (i=0; i < nlines; i++) {
936 for (j=0; j < nUnique; j++) {
945 moves[nUnique].
count = 1;
947 lines[i]->Next = NULL;
955 for (i=0; i < nUnique-1; i++) {
956 for (j=i+1; j < nUnique; j++) {
959 if (result == 0 && moves[i].count == 1) {
968 if (
strEqual (moves[j].move,
"")) { result = 1; }
980 for (i=0; i < nUnique; i++) {
982 while (line != NULL) {
991 for (i=0; i < nUnique; i++) {
992 SortTableLines (lines, moves[i].count, depth+1);
993 lines += moves[i].
count;
998 my_Tcl_Free((
char*)moves);
1007 for (
uint i=0; i < StartLength; i++) {
1009 if (i % 2 == 0) { dstr->
Append ((i+2)/2,
"."); }
1012 if (exclude && ExcludeMove[0] != 0) {
1014 dstr->
Append ((StartLength+2)/2, StartLength % 2 == 0 ?
"." :
"...");
1023 ASSERT (title != NULL && comment != NULL);
1026 PrintLaTeX (dstr, title, comment);
1029 PrintHTML (dstr, title, comment);
1032 PrintText (dstr, title, comment,
false);
1035 PrintText (dstr, title, comment,
true);
1049 dstr->
Append (
"\\renewcommand{\\arraystretch}{1.15}\n");
1050 dstr->
Append (
"\\twocolumn[\n");
1052 dstr->
Append (
"\\begin{center}\n");
1054 dstr->
Append (
"}{p{1.15cm}}r@{: }l}\n\\hline\n");
1055 dstr->
Append (
"\\multicolumn{11}{p{13cm}}{\\textbf{");
1057 dstr->
Append (
"}: \\mbox{");
1061 uint score = TheoryScore();
1062 dstr->
Append (
" (", score/2);
1063 if (score % 2) { dstr->
AddChar (DecimalChar); dstr->
AddChar (
'5'); }
1064 dstr->
Append (
"/", TheoryCount,
": ");
1065 dstr->
Append ((TheoryPercent() + 5) / 10,
"\\%)}");
1066 dstr->
Append (
"} \\\\\n\\hline\n");
1068 dstr->
Append (
" & ", i + ((StartLength + 2) / 2));
1070 dstr->
Append (
" & \\multicolumn{2}{c}{} \\\\\n");
1074 for (
uint row=0; row < NumRows; row++) {
1075 dstr->
Append (
"\\textbf{", row+1,
"}");
1076 uint nSameMoves = 0;
1077 if (row > 0) { nSameMoves = Row[row]->CommonLength(Row[row-1]); }
1082 }
else if (*(Row[row]->Move[j-1]) !=
'\0') {
1083 dstr->
Append (
" \\newline ");
1085 if (j < nSameMoves) {
1092 if (HasNotes (Row[row], j)) {
1093 dstr->
Append (
"$^{", NumNotes,
"}");
1097 uint ncount = NoteCount(NumNotes);
1098 uint nscore = NoteScore(NumNotes);
1099 dstr->
Append (
"_{\\mbox{\\tiny ", ncount,
":");
1102 case 100: dstr->
Append (
"+");
break;
1103 case 50: dstr->
Append (
"=");
break;
1104 case 0: dstr->
Append (
"--");
break;
1107 dstr->
Append (nscore,
"\\%");
1116 dstr->
Append (
" & ", NLines[row],
" & ");
1118 if (NLines[row] > 0) {
1119 score = (RowScore[row] * 50 + (NLines[row]/2)) / NLines[row];
1121 dstr->
Append (score,
"\\% \\\\\n");
1124 dstr->
Append (
"\\hline\n");
1126 dstr->
Append (
"\\multicolumn{11}{r}{\\em ", comment,
"}\n");
1128 dstr->
Append (
"\\end{tabular}\n\\end{center}\n]\n");
1139 dstr->
Append (
"<center>");
1145 uint score = TheoryScore();
1146 dstr->
Append (
" (", score/2);
1147 if (score % 2) { dstr->
AddChar (DecimalChar); dstr->
AddChar (
'5'); }
1148 dstr->
Append (
"/", TheoryCount,
": ");
1149 dstr->
Append ((TheoryPercent() + 5) / 10,
"%)\n");
1150 dstr->
Append (
"<table border=0 cellspacing=0 cellpadding=4>\n");
1151 dstr->
Append (
"<tr><th></th>");
1153 dstr->
Append (
"<th align=\"left\">", i + ((StartLength + 2) / 2),
"</th>");
1155 dstr->
Append (
"</tr>\n");
1158 for (
uint row=0; row < NumRows; row++) {
1159 dstr->
Append (
"<tr><th>", row+1,
"</th>\n");
1160 uint nSameMoves = 0;
1161 if (row > 0) { nSameMoves = Row[row]->CommonLength(Row[row-1]); }
1163 dstr->
Append (j % 2 == 0 ?
" <td> " :
" <br> ");
1164 if (j < nSameMoves) {
1171 if (HasNotes (Row[row], j)) {
1172 dstr->
Append (
"<sup><a href=\"#note", NumNotes);
1173 dstr->
Append (
"\">", NumNotes,
"</a></sup>");
1175 if (j % 2 != 0) { dstr->
Append (
" </td>\n"); }
1178 dstr->
Append (
" <td>", NLines[row],
": ");
1180 if (NLines[row] > 0) {
1181 score = (RowScore[row] * 50 + (NLines[row]/2)) / NLines[row];
1183 dstr->
Append (score,
"% </td> ");
1184 dstr->
Append (
"</tr>\n");
1186 dstr->
Append (
"</table>");
1188 dstr->
Append (
"</center>");
1199 const uint cellBytes = 9;
1201 const char * hrule =
"-------------------------------------------------------------------------------\n";
1203 dstr->
Append (title,
"\n");
1204 if (ctext) { dstr->
Append (
"<tt>"); }
1205 dstr->
Append (hrule,
" ");
1206 if (StartLength > 0) {
1208 dstr->
Append (
"<darkblue><run importMoveListTrans {");
1213 if (ctext) { dstr->
Append (
"</run></darkblue>"); }
1219 uint score = TheoryScore();
1220 dstr->
Append (
" (", score/2);
1221 if (score % 2) { dstr->
AddChar (DecimalChar); dstr->
AddChar (
'5'); }
1222 dstr->
Append (
"/", TheoryCount,
": ");
1223 dstr->
Append ((TheoryPercent() + 5) / 10,
"%)\n");
1224 dstr->
Append (hrule,
" ");
1226 sprintf (cell,
" %3u ", i + ((StartLength + 2) / 2));
1229 dstr->
Append (
"\n", hrule);
1237 for (
uint row=0; row < NumRows; row++) {
1242 sprintf (tempStr,
"%2u ", row+1);
1245 uint nSameMoves = 0;
1246 if (row > 0) { nSameMoves = Row[row]->CommonLength(Row[row-1]); }
1250 if (j < nSameMoves) {
1254 if (ctext && j >= nSameMoves) {
1255 dtemp->
Append (
"<darkblue><run importMoveListTrans {");
1258 if (! WTM) { x = 1; }
1259 for (; x <= j; x++) {
1266 size_t oldwidth = dtemp->
Length();
1268 width += dtemp->
Length() - oldwidth;
1269 if (ctext && j >= nSameMoves) {
1270 dtemp->
Append (
"</run></darkblue>");
1275 if (HasNotes (Row[row], j)) {
1277 dtemp->
Append (
"<red><go n", NumNotes,
">");
1278 dtemp->
Append (
"<N", NumNotes,
">");
1280 size_t oldwidth = dtemp->
Length();
1281 dtemp->
Append (
"[", NumNotes,
"]");
1282 width += dtemp->
Length() - oldwidth;
1283 if (ctext) { dtemp->
Append (
"</N", NumNotes,
"></go></red>"); }
1286 while (width < cellBytes) {
1301 sprintf (cell,
"%2u:", NLines[row]);
1304 if (NLines[row] > 0) {
1305 score = (RowScore[row] * 50 + (NLines[row]/2)) / NLines[row];
1307 sprintf (cell,
"%2u%%", score);
1314 if (ctext) { dstr->
Append (
"</tt>"); }
1325 OpTable::HasNotes (
OpLine * line,
uint movenum)
1331 OpLine * subline = line->Next;
1332 bool noteSeen =
false;
1333 bool lastMoveInRow =
false;
1334 if (movenum == line->Length-1) { lastMoveInRow =
true; }
1336 lastMoveInRow =
true;
1338 if (lastMoveInRow) {
1341 line->NoteMoveNum = movenum+1;
1342 line->NoteNumber = NumNotes;
1344 while (subline != NULL) {
1345 if (subline->NoteMoveNum == movenum) {
1350 subline->NoteNumber = NumNotes;
1352 if (subline->NoteNumber == 0 && lastMoveInRow) {
1353 subline->NoteNumber = NumNotes;
1354 subline->NoteMoveNum = movenum+1;
1356 subline = subline->Next;
1362 OpTable::NoteCount (
uint note)
1365 for (
uint n = 0; n < NumTableLines; n++) {
1366 if (Line[n]->NoteNumber == note) { count++; }
1372 OpTable::NoteScore (
uint note)
1376 for (
uint n = 0; n < NumTableLines; n++) {
1377 if (Line[n]->NoteNumber == note) {
1383 score = (score * 50 + (count/2)) / count;
1391 if (NumNotes == 0) {
return; }
1393 const char * preNotesList =
"\n";
1394 const char * postNotesList =
"\n";
1395 const char * para =
"\n ";
1396 const char * endNote =
"\n\n";
1397 const char * nextGame =
";\n ";
1403 preNotesList =
"\n\n<ol>\n";
1404 postNotesList =
"</ol>\n";
1405 para =
"<br>\n"; nextGame =
";\n";
1406 endNote =
"</a><p>\n";
1409 endNote =
"</tab>\n\n";
1412 dstr->
Append (preNotesList);
1414 for (
uint note=1; note <= NumNotes; note++) {
1416 dstr->
Append (
"\\notenum{", note,
"}\n");
1419 dstr->
Append (
"<li><a name=\"note", note,
"\"></a> ");
1421 dstr->
Append (
"<tab><red><go N", note,
">");
1422 dstr->
Append (
"<n", note,
">");
1423 dstr->
Append (
"[", note,
"]");
1424 dstr->
Append (
"</n", note,
"></go></red> ");
1426 dstr->
Append (
"[*", note,
"*] ");
1428 OpLine * prevLine = NULL;
1429 for (
int n = NumTableLines-1; n >= 0; n--) {
1430 if (Line[n]->NoteNumber == note) {
1431 uint mnum = Line[n]->NoteMoveNum;
1432 if (prevLine != NULL) {
1433 mnum = Line[n]->CommonLength(prevLine);
1434 if (mnum <= Line[n]->NoteMoveNum &&
1435 prevLine->Length > mnum) {
1436 dstr->
Append (
".", para);
1441 Line[n]->PrintNote (dstr, (StartLength+2) / 2, mnum, format);
1445 dstr->
Append (
".", endNote);
1447 dstr->
Append (postNotesList);
1454 BEST_White, BEST_Black, BEST_AvgElo, BEST_Oldest, BEST_Newest
1456 int rt = BEST_AvgElo;
1460 rt = BEST_White;
break;
1463 rt = BEST_Black;
break;
1466 rt = BEST_AvgElo;
break;
1469 rt = BEST_Oldest;
break;
1472 rt = BEST_Newest;
break;
1477 const char * preNum =
" ";
1478 const char * postNum =
": ";
1479 const char * endLine =
"\n";
1480 const char * preList =
"";
1481 const char * postList =
"";
1484 preNum =
"\\textbf{";
1494 for (i=0; i < NumLines; i++) {
1495 Line[i]->Selected =
false;
1499 bool printFullDate = (rt == BEST_Oldest || rt == BEST_Newest);
1501 for (
uint c=1; c <= count; c++) {
1504 for (i=0; i < NumLines; i++) {
1505 if (Line[i]->Selected) {
continue; }
1510 v = 1000 - Line[i]->NumMoves;
1511 v = (v << 12) + Line[i]->AvgElo;
1515 v = 1000 - Line[i]->NumMoves;
1516 v = (v << 12) + Line[i]->AvgElo;
1519 v = Line[i]->AvgElo;
1523 if (Line[i]->Date ==
ZERO_DATE) { v = 0; }
1532 if (v >= bestValue) {
1537 if (bestIndex < 0) {
break; }
1539 sprintf (tempStr,
"%2u", c);
1540 dstr->
Append (preNum, tempStr, postNum);
1541 Line[bestIndex]->PrintSummary (dstr, Format, printFullDate,
true);
1542 if (Line[bestIndex]->NoteNumber != 0) {
1544 dstr->
Append (
" $^{", Line[bestIndex]->NoteNumber,
"}$");
1546 dstr->
Append (
" [<a href=\"#note", Line[bestIndex]->NoteNumber);
1547 dstr->
Append (
"\">", Line[bestIndex]->NoteNumber,
"</a>]");
1549 dstr->
Append (
" <red><go n", Line[bestIndex]->NoteNumber);
1550 dstr->
Append (
">[", Line[bestIndex]->NoteNumber,
1553 dstr->
Append (
" [", Line[bestIndex]->NoteNumber,
"]");
1557 Line[bestIndex]->Selected =
true;
1567 #define PLAYERFREQ_MAXNOTES 8 1592 uint largestPlayerID = 0;
1593 for (i=0; i < NumLines; i++) {
1594 uint id = (c ==
WHITE ? Line[i]->WhiteID : Line[i]->BlackID);
1595 if (
id > largestPlayerID) { largestPlayerID = id; }
1602 for (i=0; i <= largestPlayerID; i++) {
1615 for (i=0; i < NumLines; i++) {
1619 const char *
name = NULL;
1625 elo = line->WhiteElo;
1626 oppElo = line->BlackElo;
1631 elo = line->BlackElo;
1632 oppElo = line->WhiteElo;
1636 ASSERT (
id <= largestPlayerID);
1639 pf[id].
score += score;
1641 if (pf[
id].minElo == 0) { pf[id].
minElo = elo; }
1642 if (elo < pf[
id].minElo) { pf[id].
minElo = elo; }
1643 if (elo > pf[
id].maxElo) { pf[id].
maxElo = elo; }
1651 if (pf[
id].minYear == 0) { pf[id].
minYear = year; }
1652 if (year < pf[
id].minYear) { pf[id].
minYear = year; }
1653 if (year > pf[
id].maxYear) { pf[id].
maxYear = year; }
1655 if (Line[i]->NoteNumber != 0) {
1657 if (pf[
id].noteNumber[n] == Line[i]->NoteNumber) {
break; }
1658 if (pf[
id].noteNumber[n] == 0) {
1666 const char * preNum =
" ";
1667 const char * postNum =
":";
1668 const char * preElo =
"";
1669 const char * postElo =
"";
1670 const char * inRange =
"-";
1671 const char * percentStr =
"%";
1672 const char * startTable =
"";
1673 const char * endTable =
"";
1674 const char * startRow =
"";
1675 const char * endRow =
"\n";
1676 const char * startName =
"";
1677 const char * endName =
"";
1678 const char * nextCell =
" ";
1679 const char * startNotes =
" [";
1680 const char * endNotes =
"]";
1683 startTable =
"<table border=0 cellspacing=0 cellpadding=4>\n";
1684 endTable =
"</table>\n";
1685 startRow =
"<tr><td align=\"right\">"; endRow =
"</td></tr>\n";
1686 nextCell =
"</td><td>";
1690 startRow =
"<tt>"; startName =
"</tt>";
1691 startNotes =
" <red>["; endNotes =
"]</red>";
1694 startTable =
"\n\\begin{tabular}{rrrrrl}\n";
1695 endTable =
"\\end{tabular}\n";
1696 startRow =
" "; endRow =
" \\\\ \n";
1697 nextCell =
" & "; percentStr =
"\\%";
1698 preNum =
"\\textbf{"; postNum =
":}";
1699 preElo =
" \\emph{"; postElo =
"}"; inRange =
"--";
1700 startNotes =
" $^{"; endNotes =
"}$";
1703 dstr->
Append (startTable);
1706 for (
uint n=1; n <= count; n++) {
1711 for (
uint id=0;
id <= largestPlayerID;
id++) {
1714 if (freq == 0) {
continue; }
1715 if ((freq > maxFreq) || (freq == maxFreq && elo > maxElo)) {
1725 sprintf (tempStr,
"%2u", n);
1726 dstr->
Append (startRow, preNum, tempStr, postNum);
1730 sprintf (tempStr,
"%3u", freq);
1731 dstr->
Append (nextCell, tempStr);
1738 }
else if (minYear == maxYear) {
1739 sprintf (tempStr,
" %4u", minYear);
1741 sprintf (tempStr,
"%4u%s%4u",
1742 minYear, inRange, maxYear);
1744 dstr->
Append (nextCell,
" ", tempStr);
1747 uint score = (50 * pf[index].
score + (freq / 2)) / freq;
1748 sprintf (tempStr,
"%3u%s", score, percentStr);
1749 dstr->
Append (nextCell, tempStr);
1754 sprintf (tempStr,
"%s %s", preElo, postElo);
1756 sprintf (tempStr,
"%s%4u%s", preElo, maxElo, postElo);
1758 dstr->
Append (nextCell,
" ", tempStr);
1759 dstr->
Append (nextCell,
" ", startName);
1768 if (pf[index].noteNumber[0] != 0) {
1769 dstr->
Append (startNotes);
1771 if (pf[index].noteNumber[n] == 0) {
break; }
1772 if (n > 0) { dstr->
Append (
","); }
1774 dstr->
Append (
"<go n", pf[index].noteNumber[n]);
1775 dstr->
Append (
">", pf[index].noteNumber[n],
"</go>");
1778 dstr->
Append (pf[index].noteNumber[n]);
1781 if (pf[index].noteNumber[PLAYERFREQ_MAXNOTES] != 0) {
1794 my_Tcl_Free((
char*)pf);
1810 uint ecoSubCount[50][10];
1812 for (
uint ecoGroup=0; ecoGroup < 50; ecoGroup++) {
1813 ecoCount[ecoGroup] = 0;
1814 ecoScore[ecoGroup] = 0;
1815 for (
uint subCode = 0; subCode < 10; subCode++) {
1816 ecoSubCount[ecoGroup][subCode] = 0;
1821 for (
uint i=0; i < NumLines; i++) {
1823 int ecoSubCode = -1;
1824 ecoT ecoCode = Line[i]->EcoCode;
1828 if (ecoStr[0] != 0) {
1829 ecoClass = ((ecoStr[0] -
'A') * 10) + (ecoStr[1] -
'0');
1830 if (ecoClass < 0 || ecoClass >= 50) { ecoClass = -1; }
1831 ecoSubCode = (ecoStr[2] -
'0');
1834 if (ecoClass >= 0) {
1835 ecoCount[ecoClass]++;
1837 ecoSubCount[ecoClass][ecoSubCode]++;
1841 const char * preNum =
" ";
1842 const char * postNum =
":";
1843 const char * inRange =
"-";
1844 const char * percentStr =
"%";
1845 const char * startTable =
"";
1846 const char * endTable =
"";
1847 const char * startRow =
"";
1848 const char * endRow =
"\n";
1849 const char * nextCell =
" ";
1852 startTable =
"<table border=0 cellspacing=0 cellpadding=4>\n";
1853 endTable =
"</table>\n";
1854 startRow =
"<tr><td align=\"right\">"; endRow =
"</td></tr>\n";
1855 nextCell =
"</td><td align=\"right\">";
1859 startTable =
"<tt>"; endTable =
"</tt>";
1862 startTable =
"\n\\begin{tabular}{rlrr}\n";
1863 endTable =
"\\end{tabular}\n";
1864 startRow =
" "; endRow =
" \\\\ \n";
1865 nextCell =
" & "; percentStr =
"\\%";
1866 preNum =
"\\textbf{"; postNum =
":}";
1870 dstr->
Append (startTable);
1873 for (
uint n=1; n <= count; n++) {
1876 for (
uint i=0; i < 50; i++) {
1877 if (ecoCount[i] > maxFreq) {
1879 maxFreq = ecoCount[i];
1885 ecoStr[0] = (ecoClass / 10) +
'A';
1886 ecoStr[1] = (ecoClass % 10) +
'0';
1891 sprintf (tempStr,
"%2u", n);
1892 dstr->
Append (startRow, preNum, tempStr, postNum);
1893 dstr->
Append (nextCell, ecoStr);
1895 dstr->
Append (inRange, ecoStr);
1896 sprintf (tempStr,
"%3u", maxFreq);
1897 dstr->
Append (nextCell, tempStr);
1899 uint score = (50 * ecoScore[ecoClass] + (maxFreq / 2)) / maxFreq;
1900 sprintf (tempStr,
"%3u%s", score, percentStr);
1901 dstr->
Append (nextCell, tempStr);
1903 ecoCount[ecoClass] = 0;
1914 for (
uint i=0; i < NumLines; i++) {
1915 if (Line[i]->Result == result) {
1917 sum += Line[i]->NumMoves;
1920 if (n == 0) {
return 0; }
1930 for (
uint i=0; i < NumLines; i++) {
1931 eloT elo = (color ==
WHITE ? Line[i]->WhiteElo : Line[i]->BlackElo);
1936 if (color ==
WHITE) {
1946 if (count != NULL) { *count = n; }
1948 if (oppScore != NULL) { *oppScore = 0; }
1949 if (oppPerf != NULL) { *oppPerf = 0; }
1952 uint avgElo = (sum + (n/2)) / n;
1953 uint percent = ((score * 50) + (n/2)) / n;
1954 if (percent > 100) { percent = 100; }
1955 if (oppScore != NULL) { *oppScore = percent; }
1956 if (oppPerf != NULL) {
1974 for (
uint i=0; i < NumMoveOrders; i++) {
1977 MoveOrder[i].count++;
1978 id = MoveOrder[i].id;
1987 MoveOrder[NumMoveOrders].count = 1;
1989 MoveOrder[NumMoveOrders].id = NumMoveOrders + 1;
1990 id = MoveOrder[NumMoveOrders].id;
1991 index = NumMoveOrders;
2001 if (index <= 0) {
break; }
2002 if (MoveOrder[index].count < MoveOrder[index-1].count) {
break; }
2003 if (MoveOrder[index].count == MoveOrder[index-1].count &&
2004 strCompare(MoveOrder[index].moves, MoveOrder[index-1].moves) > 0) {
2009 char * tempMoves = MoveOrder[index].moves;
2010 MoveOrder[index].moves = MoveOrder[index-1].moves;
2011 MoveOrder[index-1].moves = tempMoves;
2012 uint tempCount = MoveOrder[index].count;
2013 MoveOrder[index].count = MoveOrder[index-1].count;
2014 MoveOrder[index-1].count = tempCount;
2015 uint tempID = MoveOrder[index].id;
2016 MoveOrder[index].id = MoveOrder[index-1].id;
2017 MoveOrder[index-1].id = tempID;
2028 const char * preNum =
" ";
2029 const char * postNum =
": ";
2030 const char * endLine =
"\n";
2031 const char * preList =
"";
2032 const char * postList =
"";
2033 const char * preCount =
" (";
2034 const char * postCount =
")";
2037 preNum =
"\\textbf{"; postNum =
":} ";
2039 preCount =
" \\textbf{("; postCount =
")}";
2041 preNum =
""; postNum =
": ";
2047 dstr->
Append (NumMoveOrders);
2053 for (
uint i=0; i < count; i++) {
2054 if (i == NumMoveOrders) {
break; }
2056 sprintf (tempStr,
"%2u", i+1);
2057 dstr->
Append (preNum, tempStr, postNum);
2059 dstr->
Append (
"<tab><darkblue>");
2060 dstr->
Append (
"<run sc_report ", Type,
" select mo ");
2061 dstr->
Append (MoveOrder[i].
id,
"; ::windows::stats::Refresh>");
2064 dstr->
Append (preCount, MoveOrder[i].count, postCount);
2066 dstr->
Append (
"</run></darkblue></tab>");
2076 const char * endLine =
"\n";
2077 const char * percentStr =
"%";
2078 const char * startTable =
"";
2079 const char * endTable =
"";
2080 const char * startRow =
" ";
2081 const char * endRow =
"\n";
2082 const char * nextCell =
" ";
2083 const char * nextCellRight =
" ";
2089 startTable =
"<table border=0 cellspacing=0 cellpadding=4>\n";
2090 endTable =
"</table>\n";
2091 startRow =
"<tr><td>"; endRow =
"</td></tr>\n";
2092 nextCell =
"</td><td>"; nextCellRight =
"</td><td align=\"right\">";
2096 startTable =
"<tt>"; endTable =
"</tt>";
2100 startTable =
"\n\\begin{tabular}{lrlr}\n";
2101 endTable =
"\\end{tabular}\n";
2102 startRow =
""; endRow =
" \\\\ \n";
2103 nextCell =
" & "; nextCellRight = nextCell;
2120 sprintf (tempStr, argv[0], MaxThemeMoveNumber);
2121 dstr->
Append (tempStr, endLine);
2125 dstr->
Append (startTable);
2127 uint longestLength = 0;
2130 if (len > longestLength) { longestLength = len; }
2135 dstr->
Append (theme < leftcol ? startRow : nextCell);
2136 strPad (tempStr, argv[theme], longestLength,
' ');
2138 dstr->
Append (
"<darkblue><run sc_report ", Type,
" select theme ");
2139 dstr->
Append (theme,
"; ::windows::stats::Refresh>");
2141 dstr->
Append (
" ", tempStr);
2143 dstr->
Append (nextCellRight);
2145 if (FilterCount > 0) {
2146 percent = ((100 * ThemeCount[theme]) + (FilterCount/2)) / FilterCount;
2149 sprintf (rstr,
"%3u", percent);
2150 dstr->
Append (rstr, percentStr);
2151 if (theme < leftcol) {
2156 if (theme == NUM_POSTHEMES - 1) {
break; }
2157 if (theme < leftcol) {
2164 if (NUM_POSTHEMES % 2 == 1) { dstr->
Append (endRow); }
2180 const char * allGames)
2182 const char * startTable =
"";
2183 const char * endTable =
"";
2184 const char * startRow =
"";
2185 const char * endRow =
"\n";
2186 const char * nextCell =
" ";
2187 const char * percentStr =
"%";
2188 const char * preNum =
"";
2189 const char * postNum =
"";
2192 startTable =
"<table border=0 cellspacing=0 cellpadding=4>\n";
2193 endTable =
"</table>\n";
2194 startRow =
"<tr><td>"; endRow =
"</td></tr>\n";
2195 nextCell =
"</td><td align=\"right\">";
2199 startTable =
"<tt>"; endTable =
"</tt>";
2202 startTable =
"\n\\begin{tabular}{l*{8}{p{0.8cm}}}\n\\hline\n";
2203 endTable =
"\\hline\n\\end{tabular}\n";
2204 startRow =
""; endRow =
" \\\\ \n";
2205 nextCell =
" & "; percentStr =
"\\%";
2206 preNum =
"\\multicolumn{1}{r}{"; postNum =
"}";
2210 dstr->
Append (startTable);
2216 const char * q =
" & \\hspace*{\\fill}{\\F Q}\\hspace*{\\fill}";
2217 const char * r =
" & \\hspace*{\\fill}{\\F R}\\hspace*{\\fill}";
2218 const char * qr =
" & \\hspace*{\\fill}{\\F QR}\\hspace*{\\fill}";
2219 const char * bn =
" & \\hspace*{\\fill}{\\F BN}\\hspace*{\\fill}";
2220 const char * p =
" & \\hspace*{\\fill}{{\\F p}}\\hspace*{\\fill}";
2221 const char * x =
" & ";
2224 dstr->
Append (endRow, startRow);
2225 dstr->
Append (p, bn, r, bn); dstr->
Append (q, bn, qr, bn);
2226 dstr->
Append (endRow,
"\\hline\n");
2232 for (
uint space=0; space < len; space++) { dstr->
AddChar (
' '); }
2233 char t1[10];
char t2[10];
2234 strcpy(t1,
" P"); strcpy(t2,
" BN");
2236 dstr->
Append (nextCell, t1, nextCell, t2);
2237 strcpy(t1,
" R"); strcpy(t2,
" R,BN");
2239 dstr->
Append (nextCell, t1, nextCell, t2);
2240 strcpy(t1,
" Q"); strcpy(t2,
" Q,BN");
2242 dstr->
Append (nextCell, t1, nextCell, t2);
2243 strcpy(t1,
" Q,R"); strcpy(t2,
"Q,R,BN");
2245 dstr->
Append (nextCell, t1, nextCell, t2);
2252 const char * rowName [2] = { repGames, allGames };
2255 dstr->
Append (startRow, rowName[t]);
2256 int diff = length[1-t] - length[t];
2257 while (diff > 0) { dstr->
AddChar (
' '); diff--; }
2260 for (i=0; i <
NUM_EGTHEMES; i++) { sum += EndgameCount[t][i]; }
2263 if (sum > 0) { pc = ((100 * EndgameCount[t][i]) + (sum/2)) / sum; }
2264 sprintf (numStr,
"%5u", pc);
2267 dstr->
Append (
"<darkblue><run sc_report ", Type);
2268 dstr->
Append (
" select end ", i,
"; ::windows::stats::Refresh>");
2270 dstr->
Append (preNum, numStr, percentStr, postNum);
2272 dstr->
Append (
"</run></darkblue>");
2295 uint * matches = (
uint *) my_Tcl_Alloc(
sizeof(
uint [NumLines * 2 + 2]));
2297 uint * matches =
new uint [NumLines * 2 + 2];
2299 uint * match = matches;
2301 for (
uint i=0; i < NumLines; i++) {
2303 if (line == NULL) {
continue; }
2304 if (line->GameNumber == 0) {
continue; }
2305 bool selected =
false;
2308 if (line->EgTheme == number) { selected =
true; }
2309 }
else if (type ==
't') {
2315 }
else if (type ==
'n') {
2317 if (line->NoteNumber == number) { selected =
true; }
2318 }
else if (type ==
'm') {
2320 if (line->MoveOrderID == number) { selected =
true; }
2321 }
else if (type ==
'a') {
2326 *match++ = line->GameNumber;
2327 *match++ = line->StartPly;
uint date_GetYear(dateT date)
const uint POSTHEME_CastSame
bool posHasAdvancedPawn(Position *pos, colorT c)
uint strLength(const char *str)
const uint POSTHEME_THRESHOLD
void MakeSANString(simpleMoveT *sm, char *s, sanFlagT flag)
uint endgameTheme(matSigT msig)
const uint OPTABLE_MAX_ROWS
uint AvgElo(colorT color, uint *count, uint *oppScore, uint *oppPerf)
uint PercentFreq(resultT result)
const uint POSTHEME_OneBPair
const uint POSTHEME_CastOpp
bool strEqual(const char *str1, const char *str2)
const char * strFirstChar(const char *target, char matchChar)
uint CommonLength(OpLine *line)
void AddEndMaterial(matSigT ms, bool inFilter)
void restoreLocation(const GameSavedPos &savedPos)
char * strDuplicate(const char *original)
uint FyleCount(pieceT p, fyleT f) const
#define PLAYERFREQ_MAXNOTES
const uint OPTABLE_COLUMNS
const resultT RESULT_Black
const uint OPTABLE_MAX_STARTLINE
squareT GetKingSquare(colorT c)
const uint OPTABLE_DEFAULT_ROWS
const uint POSTHEME_OpenFyle
bool posHasOpenFyle(Position *pos, fyleT f)
const resultT RESULT_OPPOSITE[4]
void PrintHTML(DString *str, const char *title, const char *comment)
void PrintSummary(DString *dstr, uint format, bool fullDate, bool nmoves)
matSigT GetFinalMatSig() const
static void PrintMove(DString *dstr, const char *move, uint format)
const uint POSTHEME_Kstorm
void SetFormat(const char *str)
void date_DecodeToString(dateT date, char *str)
const resultT RESULT_Draw
#define DATE_MAKE(y, m, d)
const uint OPTABLE_MAX_LINES
void Insert(OpLine *subline)
byte PieceCount(pieceT p)
void TopPlayers(DString *dstr, colorT c, uint count)
bool posHasIQP(Position *pos, colorT c)
ushort GetCurrentPly() const
const char RESULT_STR[4][4]
const uint OPTABLE_MIN_ROWS
const pieceT * GetBoard() const
void EndMaterialReport(DString *dstr, const char *repGames, const char *allGames)
void PrintStemLine(DString *dstr, uint format, bool exclude)
const uint POSTHEME_BAdvPawn
uint strPad(char *target, const char *original, int width, char padding)
resultT GetResult() const
void PrintLaTeX(DString *dstr, const char *title, const char *comment)
const resultT RESULT_White
void TopEcoCodes(DString *dstr, uint count)
static uint Performance(uint oppAvg, uint percentage)
idNumberT GetWhite() const
const char * GetBlackStr() const
#define MATSIG_HasBishops(x)
#define MATSIG_HasQueens(x)
Position * GetCurrentPos()
simpleMoveT * GetCurrentMove()
const char * GetWhiteStr() const
idNumberT GetBlack() const
const sanFlagT SAN_CHECKTEST
GameSavedPos currentLocation() const
errorT MoveExitVariation()
bool posHasKPawnStorm(Position *pos, colorT c)
const uint RESULT_SCORE[4]
void MoveToPly(int hmNumber)
void ThemeReport(DString *dstr, uint argc, const char **argv)
uint RankCount(pieceT p, rankT r) const
#define MATSIG_HasRooks(x)
const char * GetSiteStr() const
const uint OPTABLE_MAX_TABLE_LINES
const uint POSTHEME_WAdvPawn
void Init(const char *type, Game *g, PBook *ecoBook)
void strCopy(char *target, const char *original)
#define MATSIG_HasKnights(x)
uint AvgLength(resultT result)
void BestGames(DString *dstr, uint count, const char *rtype)
void PrintNote(DString *dstr, uint movenum, uint start, uint format)
uint * SelectGames(char type, uint number)
void transPieces(char *s)
const uint POSTHEME_QueenSwap
void PrintText(DString *str, const char *title, const char *comment, bool htext)
uint noteNumber[PLAYERFREQ_MAXNOTES+1]
static uint FormatFromStr(const char *str)
const resultT RESULT_None
void PopularMoveOrders(DString *dstr, uint count)
std::pair< const char *, const char * > findECOstr(Position *pos) const
Retrieve an ECO string containing the ECO code and the mnemonic name.
void eco_ToBasicString(ecoT ecoCode, char *ecoStr)
int strCompare(const char *s1, const char *s2)
void PrintTable(DString *dstr, const char *title, const char *comment)
void strStrip(char *str, char ch)
errorT GetPartialMoveList(DString *str, uint plyCount)
pieceT piece_Make(colorT c, pieceT p)
uint AddMoveOrder(Game *g)
A PBook is a collection of chess positions, each with the corresponding ECO code, a mnemonic name...
const char * GetMove(uint depth)
void SetPositionalThemes(Position *pos)
const uint OPTABLE_Compact
fyleT square_Fyle(squareT sq)