1 /****************************************************************************
2 
3  Copyright (C) 2002-2014 Gilles Debunne. All rights reserved.
4 
5  This file is part of the QGLViewer library version 2.7.2.
6 
7  http://www.libqglviewer.com - contact@libqglviewer.com
8 
9  This file may be used under the terms of the GNU General Public License
10  versions 2.0 or 3.0 as published by the Free Software Foundation and
11  appearing in the LICENSE file included in the packaging of this file.
12  In addition, as a special exception, Gilles Debunne gives you certain
13  additional rights, described in the file GPL_EXCEPTION in this package.
14 
15  libQGLViewer uses dual licensing. Commercial/proprietary software must
16  purchase a libQGLViewer Commercial License.
17 
18  This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
19  WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
20 
21 *****************************************************************************/
22 
23 #ifndef DVONN_BOARD_H
24 #define DVONN_BOARD_H
25 
26 #include <deque>
27 #include <iostream>
28 #include <map>
29 #include <stack>
30 #include <string>
31 #include <vector>
32 
33 namespace dvonn {
34 const unsigned int nbColors = 3;
35 typedef enum { Red = 0, White = 1, Black = 2 } Color;
36 const char *nameOf(const Color p);
37 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
38 // Interface of Piece
39 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
40 class Piece {
41 public:
42   Color color() const;
43   bool isWhite() const;
44   bool isBlack() const;
45   bool isRed() const;
46   bool is(Color c) const;
47 
48 protected:
49   friend class Board;
50   Piece(Color c);
51 
52 private:
53   Color color_;
54 };
55 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
56 // Interface of Stack
57 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
58 class Stack : public std::deque<const Piece *> {
59 public:
60   Stack();
61   unsigned int height() const;
62   bool hasPieces() const;
63   const Piece *onTop() const;
64   bool hasRed() const;
65 
66 protected:
67   friend class Board;
68 };
69 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
70 // Interface of Board
71 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
72 class Board {
73 public:
74   class Coord;
75   static unsigned int nbSpacesMaxOnRow();
76   static unsigned int nbRows();
77   static bool isValid(Coord);
78   static bool areAligned(Coord c0, Coord c1);
79   static unsigned int distance(Coord c0, Coord c1);
80 
81   static unsigned int nbPieces(Color c);
82 
83   Board();
84   void reinit();
85   virtual ~Board();
86   class ConstStackHandle;
87   ConstStackHandle stackAt(Coord c) const;
88   ConstStackHandle stackAt(int x, int y) const;
89   class ConstStackIterator;
90   ConstStackIterator stacks_begin() const;
91   ConstStackIterator stacks_end() const;
92 
93   bool isFree(const ConstStackHandle &h) const;
94 
95   unsigned int nbUnplacedPieces(Color c) const;
96   const Piece *getUnplacedPiece(Color c) const;
97   void place(const Piece *p, Coord c);
98 
99   unsigned int heightMax() const;
100 
101   class Ghost;
102   typedef std::deque<Ghost> Ghosts;
103   Ghosts move(Coord src, Coord dst, bool killDeads);
104 
105   std::string prettyPrinted(const char *prefix = "") const;
106 
107 private:
108   Board &operator=(const Board &);
109   Board(const Board &);
110   friend class ConstStackHandle;
111   friend class ConstStackIterator;
112   static unsigned int coord2idx(Coord c);
113   static Coord idx2coord(unsigned int);
114   typedef std::pair<Stack, int> Space;
115   std::vector<Space> spaces_;
116   std::deque<Piece> pieces_;
117   std::stack<const Piece *> unplaced_[3];
118   std::map<const Piece *, Coord> redSpaces_;
119 
120   void updateStatus(Ghosts &ghosts, bool killDeads);
121 
122 public:
123   class State {
124   private:
125     friend class Board;
126     std::vector<Space> spaces_;
127     std::stack<const Piece *> unplaced_[3];
128     std::map<const Piece *, Coord> redSpaces_;
129   };
130   State state() const;
131   void restore(State);
132 };
133 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
134 // Interface of Board::Coord
135 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
136 class Board::Coord {
137 public:
138   Coord(int x = -1, int y = -1);
139   int x() const;
140   int y() const;
141   bool operator==(const Coord) const;
142   bool operator!=(const Coord) const;
143   bool operator<(const Coord) const;
144 
145 private:
146   int x_;
147   int y_;
148 };
149 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
150 // Interface of Board::ConstStackHandle
151 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
152 class Board::ConstStackHandle {
153 public:
154   virtual ~ConstStackHandle();
155   virtual operator bool() const;
156   const Stack *operator->() const;
157   const Stack &operator*() const;
158   virtual bool operator==(const ConstStackHandle &other) const;
159   virtual bool operator!=(const ConstStackHandle &other) const;
160   Board::Coord stackCoord() const;
161   int stackStatus() const;
162 
163   bool isNull() const;
164   static ConstStackHandle null();
165 
166 protected:
167   friend class Board;
168   ConstStackHandle();
169   ConstStackHandle(Coord c, const Space *s);
170   void setCoord(Coord c);
171   void setSpace(const Space *);
172   const Space *space() const;
173 
174 private:
175   Board::Coord coord_;
176   const Space *space_;
177 };
178 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
179 // Interface of Board::ConstStackIterator
180 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
181 class Board::ConstStackIterator : public Board::ConstStackHandle {
182 public:
183   virtual ~ConstStackIterator();
184   virtual bool operator==(const ConstStackHandle &other) const;
185   virtual bool operator!=(const ConstStackHandle &other) const;
186   bool operator==(const ConstStackIterator &other) const;
187   bool operator!=(const ConstStackIterator &other) const;
188   ConstStackIterator &operator++();
189 
190 protected:
191   friend class Board;
192   ConstStackIterator();
193   ConstStackIterator(Coord c, const Space *s, const Board *b);
194 
195 private:
196   const Board *board_;
197 };
198 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
199 // Interface of Board::Ghost
200 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
201 class Board::Ghost {
202 public:
203   Coord coord;
204   std::deque<const Piece *> stack;
205 
206 protected:
207   friend class Board;
208   Ghost(Coord c, const Stack &s);
209 };
210 }; // namespace dvonn
211 extern std::ostream &operator<<(std::ostream &, const dvonn::Piece &);
212 extern std::ostream &operator<<(std::ostream &, const dvonn::Stack &);
213 extern std::ostream &operator<<(std::ostream &, const dvonn::Board::Coord);
214 extern std::ostream &operator<<(std::ostream &,
215                                 const dvonn::Board::ConstStackHandle &);
216 
217 #endif // DVONN_BOARD_H
218