refresh 77518ae98cef372c3d26fc7e5c43c5ad4a09c6f5
[tagua/yd.git] / src / positioninfo.cpp
blob9977f1c87d4aebbdf77345f5ab6c24c0f732f93b
1 /*
2 Copyright (c) 2006-2007 Paolo Capriotti <p.capriotti@gmail.com>
3 (c) 2006-2007 Maurizio Monge <maurizio.monge@kdemail.net>
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9 */
11 #include "positioninfo.h"
13 #include <KDebug>
15 #include <core/board.h>
16 #include <core/state.h>
18 #include "variants.h"
19 #include "gameinfo.h"
20 #include "icsapi.h"
22 using namespace boost;
24 // Style 12 was designed by Daniel Sleator (sleator+@cs.cmu.edu) Darooha@ICC
25 QRegExp PositionInfo::pattern(
26 "^<12>\\s+" //header
27 "([qkbnrpQKBNRP-]{8})\\s+" //chessboard
28 "([qkbnrpQKBNRP-]{8})\\s+" //chessboard
29 "([qkbnrpQKBNRP-]{8})\\s+" //chessboard
30 "([qkbnrpQKBNRP-]{8})\\s+" //chessboard
31 "([qkbnrpQKBNRP-]{8})\\s+" //chessboard
32 "([qkbnrpQKBNRP-]{8})\\s+" //chessboard
33 "([qkbnrpQKBNRP-]{8})\\s+" //chessboard
34 "([qkbnrpQKBNRP-]{8})\\s+" //chessboard
35 "([BW])\\s+" //black/white
36 "(-1|[0-7])\\s+" //passing pawn
37 "([01])\\s+" //castle rights
38 "([01])\\s+" //castle rights
39 "([01])\\s+" //castle rights
40 "([01])\\s+" //castle rights
41 "(-?\\d+)\\s+" //50 moves made
42 "(\\d+)\\s+" //game num
43 "(\\S+)\\s+" //white name
44 "(\\S+)\\s+" //black name
45 "(-[1-4]|[0-2])\\s+" //status
46 "(\\d+)\\s+" //time
47 "(\\d+)\\s+" //inc
48 "(\\d+)\\s+" //w material
49 "(\\d+)\\s+" //b material
50 "(-?\\d+)\\s+" //w time
51 "(-?\\d+)\\s+" //b time
52 "(\\d+)\\s+" //move made
53 "(\\S+)\\s+" //coordmove
54 "(\\S+)\\s+" //time used
55 "(\\S+)\\s+" //algmove
56 "([0-1])" //flip
60 PositionInfo::PositionRow::PositionRow(const ICSAPIPtr& icsapi, const QString& str) {
61 Q_ASSERT(str.length() == 8);
63 row.resize(str.length());
64 for (int i = 0; i < str.length(); ++i) {
65 QChar c = str[i];
67 row[i] = icsapi->createPiece(c);
71 /**
72 * @return Position index as a 0-based halfmove count.
74 int PositionInfo::index() const {
75 int res = (moveIndex - 1) * 2;
76 if (turn == 1) res++;
77 return res;
80 PositionInfo::PositionInfo()
81 : valid(false) { }
83 bool PositionInfo::load(std::map<int, ICSGameData>& games, const QString& str) {
84 if (pattern.indexIn(str) != 0) {
85 valid = false;
86 return true;
89 bool new_game = false;
91 valid = true;
92 int gn = pattern.cap(CaptureIndexes::GameNumber).toInt();
93 std::map<int, ICSGameData>::iterator gi = games.find(gn);
94 ICSAPIPtr icsapi;
96 if (gi == games.end()) {
97 kWarning() << "Received style12 for unknown game" << gn;
98 // create a gameinfo of type "dummy"
99 gi = games.insert(std::make_pair(gn, ICSGameData(gn, ""))).first;
100 new_game = true;
103 // FIXME load icsapi
104 // icsapi = gi->second.icsapi;
106 std::vector<PositionRow> rows;
107 for (uint i = 0; i < 8; ++i)
108 rows.push_back(PositionRow(icsapi, pattern.cap(CaptureIndexes::ChessboardStart + i)));
110 gameNumber = pattern.cap(CaptureIndexes::GameNumber).toInt();
111 moveIndex = pattern.cap(CaptureIndexes::MoveOrdinal).toInt();
112 whitePlayer = pattern.cap(CaptureIndexes::WhitePlayer);
113 blackPlayer = pattern.cap(CaptureIndexes::BlackPlayer);
114 turn = pattern.cap(CaptureIndexes::Turn) == "W"? 0 : 1;
116 int ep = pattern.cap(CaptureIndexes::EnPassant).toInt();
117 if (ep == -1)
118 enPassantSquare = Point::invalid();
119 else
120 enPassantSquare = Point(ep, turn == 0? 2 : 5);
122 bool wkCastle = pattern.cap(CaptureIndexes::WhiteKingCastle).toInt() == 1;
123 bool wqCastle = pattern.cap(CaptureIndexes::WhiteQueenCastle).toInt() == 1;
124 bool bkCastle = pattern.cap(CaptureIndexes::BlackKingCastle).toInt() == 1;
125 bool bqCastle = pattern.cap(CaptureIndexes::BlackQueenCastle).toInt() == 1;
127 position = icsapi->createChessboard(turn, wkCastle, wqCastle, bkCastle, bqCastle, enPassantSquare);
128 for (uint i = 0; i < 8; ++i) {
129 for (uint j = 0; j < rows[i].row.size(); ++j) {
130 position->board()->set(Point(j,i), rows[i].row[j]);
134 relation = static_cast<Relation>(pattern.cap(CaptureIndexes::Relation).toInt());
136 whiteTime = pattern.cap(CaptureIndexes::WhiteTime).toInt();
137 blackTime = pattern.cap(CaptureIndexes::BlackTime).toInt();
138 if (pattern.cap(CaptureIndexes::TimeUsed).indexOf('.') == -1) {
139 // time is in seconds
140 whiteTime *= 1000;
141 blackTime *= 1000;
144 lastMoveSAN = pattern.cap(CaptureIndexes::LastMove);
145 lastMove = pattern.cap(CaptureIndexes::LastMoveVerbose);
147 return new_game;