ICSAPI::parseVerbose is now used instead of VariantInfo::getVerboseMove.
[tagua/yd.git] / src / variants / xchess / generator.h
blobd8412ba654da5ef0f042edf0916e7bfd405277d1
1 /*
2 Copyright (c) 2006 Paolo Capriotti <p.capriotti@sns.it>
3 (c) 2006 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 #ifndef GENERATOR_H
12 #define GENERATOR_H
14 #include <functional>
15 #include "variants/xchess/piecetype.h"
16 #include "point.h"
18 template <typename Pos>
19 class LegalMove {
20 const Pos& m_pos;
21 typedef typename Pos::Move Move;
22 public:
23 bool operator()(Move& m) { return m_pos.testMove(m); }
24 LegalMove(const Pos& pos) : m_pos(pos) { }
27 template <typename Pos>
28 class PseudolegalMove {
29 const Pos& m_pos;
30 typedef typename Pos::Move Move;
31 public:
32 bool operator()(Move& m) { return m_pos.pseudolegal(m); }
33 PseudolegalMove(const Pos& pos) : m_pos(pos) { }
36 template <typename Move>
37 class AbstractGenerator {
38 public:
39 virtual ~AbstractGenerator(){};
40 virtual std::vector<Move>& generate() = 0;
43 template <typename Pos, typename MoveTest>
44 class Generator : public AbstractGenerator<typename Pos::Move> {
45 public:
46 virtual ~Generator(){};
48 typedef typename Pos::Move Move;
49 typedef typename Pos::Piece Piece;
50 typedef typename Pos::Board Board;
52 std::vector<Move>& generate();
53 inline std::vector<Move>& moves() { return m_moves; }
54 explicit Generator(const Pos&);
55 protected:
56 const Pos& m_pos;
57 std::vector<Move> m_moves;
58 void generateFrom(const Point& p);
59 MoveTest m_test;
61 bool addMove(const Point& p, const Point& q);
62 void generateSlide(const Point& p, const Point& dir);
63 void generateBishop(const Point& p);
64 void generateRook(const Point& p);
67 template <typename Pos, typename MoveTest>
68 class MoveGenerator : public Generator<Pos, MoveTest> {
69 public:
70 virtual ~MoveGenerator(){};
71 explicit MoveGenerator(const Pos& pos)
72 : Generator<Pos, MoveTest>(pos) { }
75 //BEGIN Implementation
77 template <typename Pos, typename MoveTest>
78 Generator<Pos, MoveTest>::Generator(const Pos& pos)
79 : m_pos(pos)
80 , m_test(pos) { }
82 template <typename Pos, typename MoveTest>
83 std::vector<typename Pos::Move>& Generator<Pos, MoveTest>::generate() {
84 for (Point from = m_pos.first(); from <= m_pos.last(); from = m_pos.next(from)) {
85 generateFrom(from);
87 return m_moves;
90 template <typename Pos, typename MoveTest>
91 void Generator<Pos, MoveTest>::generateFrom(const Point& p) {
92 Piece piece = m_pos[p];
93 if (piece && piece.color() == m_pos.turn()) {
94 switch (piece.type()) {
95 case PAWN:
97 Point dir = Piece::direction(piece.color());
98 addMove(p, p + dir);
99 addMove(p, p + dir * 2);
100 addMove(p, p + dir + Point(1, 0));
101 addMove(p, p + dir - Point(1, 0));
103 break;
104 case KNIGHT:
105 addMove(p, p + Point(1,2));
106 addMove(p, p + Point(1,-2));
107 addMove(p, p + Point(-1,2));
108 addMove(p, p + Point(-1,-2));
109 addMove(p, p + Point(2,1));
110 addMove(p, p + Point(2,-1));
111 addMove(p, p + Point(-2,1));
112 addMove(p, p + Point(-2,-1));
113 break;
114 case BISHOP:
115 generateBishop(p);
116 break;
117 case ROOK:
118 generateRook(p);
119 break;
120 case QUEEN:
121 generateBishop(p);
122 generateRook(p);
123 break;
124 case KING:
125 addMove(p, p + Point(1,0));
126 addMove(p, p + Point(1,1));
127 addMove(p, p + Point(0,1));
128 addMove(p, p + Point(-1,1));
129 addMove(p, p + Point(-1,0));
130 addMove(p, p + Point(-1,-1));
131 addMove(p, p + Point(0,-1));
132 addMove(p, p + Point(1,-1));
133 break;
134 default:
135 break;
140 template <typename Pos, typename MoveTest>
141 void Generator<Pos, MoveTest>::generateSlide(const Point& p, const Point& dir) {
142 Point q = p + dir;
143 while (m_pos.valid(q) && addMove(p,q))
144 q += dir;
147 template <typename Pos, typename MoveTest>
148 bool Generator<Pos, MoveTest>::addMove(const Point& p, const Point& q) {
149 Move move(p,q);
150 if (m_pos.valid(p) && m_pos.valid(q) && m_test(move)) {
151 m_moves.push_back(move);
152 return true;
154 else return false;
157 template <typename Pos, typename MoveTest>
158 void Generator<Pos, MoveTest>::generateBishop(const Point& p) {
159 generateSlide(p, Point(1,1));
160 generateSlide(p, Point(1,-1));
161 generateSlide(p, Point(-1,1));
162 generateSlide(p, Point(-1,-1));
165 template <typename Pos, typename MoveTest>
166 void Generator<Pos, MoveTest>::generateRook(const Point& p) {
167 generateSlide(p, Point(1,0));
168 generateSlide(p, Point(0,1));
169 generateSlide(p, Point(-1,0));
170 generateSlide(p, Point(0,-1));
173 //END Implementation
175 #endif