Ported ICSAPI.
[tagua.git] / src / hlvariant / chess / san.cpp
blob0f60f38ec8bd3c40770acc1d94f84f06e31b21e8
1 /*
2 Copyright (c) 2007 Paolo Capriotti <p.capriotti@sns.it>
3 (c) 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 "san.h"
12 #include "piece.h"
14 namespace HLVariant {
15 namespace Chess {
17 // 1 2 3
18 QRegExp SAN::pattern("^([PRNBKQ])?([a-wyzA-Z]?\\d*|x\\d+)([-x@])?"
19 // 4 5 6
20 "([a-zA-Z]\\d+)(=?([RNBKQrnbkq]))?[+#]?[\?!]*");
21 QRegExp SAN::kingCastlingPattern("^[oO0]-?[oO0][+#]?");
22 QRegExp SAN::queenCastlingPattern("^[oO0]-?[oO0]-?[oO0][+#]?");
23 QRegExp SAN::nonePattern("^none");
25 SAN::SAN()
26 : from(Point::invalid())
27 , to(Point::invalid())
28 , type(-1)
29 , promotion(-1)
30 , castling(NoCastling)
31 , drop(false) {
34 int SAN::getType(const QString& letter) {
35 if (letter.isEmpty())
36 return Piece::PAWN;
38 QChar c = letter[0].toLower();
39 if (c == 'k')
40 return Piece::KING;
41 else if (c == 'q')
42 return Piece::QUEEN;
43 else if (c == 'r')
44 return Piece::ROOK;
45 else if (c == 'n')
46 return Piece::KNIGHT;
47 else if (c == 'b')
48 return Piece::BISHOP;
49 else if (c == 'p')
50 return Piece::PAWN;
51 else
52 return Piece::INVALID_TYPE;
55 void SAN::load(const QString& str, int& offset, int ysize) {
56 if (nonePattern.indexIn(str, offset, QRegExp::CaretAtOffset) != -1) {
57 from = Point::invalid();
58 to = Point::invalid();
59 offset += nonePattern.matchedLength();
61 else if (pattern.indexIn(str, offset, QRegExp::CaretAtOffset) != -1) {
62 type = getType(pattern.cap(1));
63 drop = pattern.cap(3) == "@";
64 if (drop)
65 from = Point::invalid();
66 else
67 from = Point(pattern.cap(2), ysize);
68 to = Point(pattern.cap(4), ysize);
69 promotion = pattern.cap(6).isEmpty() ? -1 : getType(pattern.cap(6));
70 castling = NoCastling;
71 offset += pattern.matchedLength();
73 else if (queenCastlingPattern.indexIn(str, offset, QRegExp::CaretAtOffset) != -1) {
74 castling = QueenSide;
76 offset += queenCastlingPattern.matchedLength();
78 else if (kingCastlingPattern.indexIn(str, offset, QRegExp::CaretAtOffset) != -1) {
79 castling = KingSide;
81 offset += kingCastlingPattern.matchedLength();
83 else {
84 //std::cout << "error!!!! " << str.mid(offset) << std::endl;
85 to = Point::invalid();
89 void SAN::load(const QString& str, int ysize) {
90 int offset = 0;
91 load(str, offset, ysize);
94 std::ostream& operator<<(std::ostream& os, const SAN& move) {
95 if (move.castling == SAN::KingSide)
96 return os << "O-O";
97 else if (move.castling == SAN::QueenSide)
98 return os << "O-O-O";
99 else
100 return os << move.type << ": " << move.from << " -> " << move.to;
104 } // namespace Chess
105 } // namespace HLVariant