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.
15 #include "variants/xchess/piecetype.h"
18 template <typename Pos
>
21 typedef typename
Pos::Move Move
;
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
{
30 typedef typename
Pos::Move Move
;
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
{
39 virtual ~AbstractGenerator(){};
40 virtual std::vector
<Move
>& generate() = 0;
43 template <typename Pos
, typename MoveTest
>
44 class Generator
: public AbstractGenerator
<typename
Pos::Move
> {
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
&);
57 std::vector
<Move
> m_moves
;
58 void generateFrom(const Point
& p
);
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
> {
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
)
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
)) {
90 template <typename Pos
, typename MoveTest
>
91 void Generator
<Pos
, MoveTest
>::generateFrom(const Point
& p
) {
92 const Piece
* piece
= m_pos
[p
];
93 if (piece
&& piece
->color() == m_pos
.turn()) {
94 switch (piece
->type()) {
97 Point dir
= Piece::direction(piece
->color());
99 addMove(p
, p
+ dir
* 2);
100 addMove(p
, p
+ dir
+ Point(1, 0));
101 addMove(p
, p
+ dir
- Point(1, 0));
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));
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));
140 template <typename Pos
, typename MoveTest
>
141 void Generator
<Pos
, MoveTest
>::generateSlide(const Point
& p
, const Point
& dir
) {
143 while (m_pos
.valid(q
) && addMove(p
,q
))
147 template <typename Pos
, typename MoveTest
>
148 bool Generator
<Pos
, MoveTest
>::addMove(const Point
& p
, const Point
& q
) {
150 if (m_pos
.valid(p
) && m_pos
.valid(q
) && m_test(move
)) {
151 m_moves
.push_back(move
);
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));