1 /* BurrTools
2  *
3  * BurrTools is the legal property of its developers, whose
4  * names are listed in the COPYRIGHT file, which is included
5  * within the source distribution.
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11 
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16 
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
20  */
21 #ifndef __PUZZLE_H__
22 #define __PUZZLE_H__
23 
24 /** @ file
25  * Contains the definitions for the puzzle class
26  */
27 
28 #include "bt_assert.h"
29 
30 #include <stdint.h>
31 #include <vector>
32 #include <string>
33 
34 #include <stdint.h>
35 
36 class voxel_c;
37 class gridType_c;
38 class problem_c;
39 class xmlWriter_c;
40 class xmlParser_c;
41 
42 /**
43  * This class defines the puzzle.
44  * A puzzle is a collection of shapes and a set of problems associated
45  * with these shapes and finally the color used for color constraint colors
46  */
47 class puzzle_c {
48 
49 private:
50 
51   /** The gridtype of the puzzle.
52    * each puzzle has exactly one grid type, this is it
53    * normally it doesn't change, except if you convert
54    * a puzzle of one grid type into an other with a converter
55    */
56   gridType_c *gt;
57 
58   /**
59    * The vector with the shapes
60    */
61   std::vector<voxel_c*> shapes;
62 
63   /**
64    * the vector with the problems
65    */
66   std::vector<problem_c*> problems;
67 
68   /** The constraint colours.
69    * there can be many colours to constrain the placement of pieces
70    * these are the actual colours used to display them
71    * the red part is in the lowest 8 bit, followed by green and blue in the
72    * highest part
73    */
74   std::vector<uint32_t> colors;
75 
76   /**
77    * some information about the puzzle
78    * no format is forced its free for the user
79    */
80   std::string comment;
81 
82   /**
83    * bool to signify if the comment should open on load.
84    * so when the gui loads a puzzle where this is true, it
85    * will always display the comment.
86    */
87   bool commentPopup;
88 
89 public:
90 
91   /**
92    * copy constructor this will NOT copy the labels and solutions of
93    * the problems.
94    */
95   puzzle_c(const puzzle_c * orig);
96 
97   /**
98    * Constructor for empty puzzle. no shape, no problem and no colours
99    * ownership of the given gridtype is taken over, the memory
100    * is freed on destruction of this class
101    */
puzzle_c(gridType_c * g)102   puzzle_c(gridType_c * g) : gt(g) , commentPopup(false) { }
103 
104   /**
105    * load the puzzle from the XML file
106    */
107   puzzle_c(xmlParser_c & pars);
108 
109   /**
110    * save the puzzle into a XML node that is returned
111    */
112   void save(xmlWriter_c & xml) const;
113 
114   /**
115    * Destructor.
116    * Deletes all the shapes in the puzzle
117    */
118   ~puzzle_c(void);
119 
120   /** \name some functions to get the current set grid type for this puzzle */
121   //@{
getGridType(void)122   const gridType_c * getGridType(void) const { return gt; }
getGridType(void)123   gridType_c * getGridType(void) { return gt; }
124   //@}
125 
126 
127   /** \name shape handling */
128   //@{
129   /** Add the given shape to the puzzle.
130    * The space is taken over, and freed when the puzzle is destroyed
131    * Returns the index of the new shape
132    */
133   unsigned int addShape(voxel_c * p);
134   /** add an empty shape of the given size return the index of the new shape */
135   unsigned int addShape(unsigned int sx, unsigned int sy, unsigned int sz);
136   /** return how many shapes there are in the puzzle */
shapeNumber(void)137   unsigned int shapeNumber(void) const { return shapes.size(); }
138   /** get a shape */
getShape(unsigned int idx)139   const voxel_c * getShape(unsigned int idx) const { bt_assert(idx < shapes.size()); return shapes[idx]; }
140   /** get a shape */
getShape(unsigned int idx)141   voxel_c * getShape(unsigned int idx) { bt_assert(idx < shapes.size()); return shapes[idx]; }
142   /**
143    * remove the num-th shape.
144    * be careful this changes all ids and so all problems must be updated
145    * changing them, removing solutions, result shapes or pieces in problems...
146    */
147   void removeShape(unsigned int);
148   /**
149    *  exchange 2 shapes in the list of shapes.
150    *  this function takes care to update all the problems and solutions
151    *  because they only index into the shape list and exchangin shapes requires
152    *  updating tose indices
153    */
154   void exchangeShape(unsigned int s1, unsigned int s2);
155   //@}
156 
157 
158   /** \name  handle puzzle colours */
159   //@{
160   /** add a color, return the index of the new color */
161   unsigned int addColor(unsigned char r, unsigned char g, unsigned char b);
162   /**
163    * remove a color with given index.
164    * All shapes are updated to not use that
165    * color any more, color constraints are updated for all problems to no
166    * longer use that color, its your task to make sure the now invalid solutions
167    * are removed
168    */
169   void removeColor(unsigned int idx);
170   /** change the RGB value of one color */
171   void changeColor(unsigned int idx, unsigned char r, unsigned char g, unsigned char b);
172   /** get the RGB value of one color */
173   void getColor(unsigned int idx, unsigned char * r, unsigned char * g, unsigned char * b) const;
174   /** return the number of defined colors */
colorNumber(void)175   unsigned int colorNumber(void) const { return colors.size(); }
176   //@}
177 
178 
179   /** \name handle problems */
180   //@{
181   /** add a new empty problem return its index */
182   unsigned int addProblem(void);
183   /** add a new problem as copy from another problem (from another puzzle).
184    * A copy of the provided problem is created
185    */
186   unsigned int addProblem(const problem_c * prob);
187   /** return the number of problems within this puzzle */
problemNumber(void)188   unsigned int problemNumber(void) const { return problems.size(); }
189   /** remove problem with the given index freeing all its ressources */
190   void removeProblem(unsigned int p);
191   /** exchange problem at indes p1 with problem at index p2 */
192   void exchangeProblem(unsigned int p1, unsigned int p2);
193   /** get the problem at index p */
getProblem(unsigned int p)194   const problem_c * getProblem(unsigned int p) const { bt_assert(p < problems.size()); return problems[p]; }
195   /** get the problem at index p */
getProblem(unsigned int p)196   problem_c * getProblem(unsigned int p) { bt_assert(p < problems.size()); return problems[p]; }
197   //@}
198 
199 
200   /** \name the puzzle comment functions */
201   //@{
202   /** set comment there is no limitation in size or characters.  */
setComment(const std::string & com)203   void setComment(const std::string & com) { comment = com; }
204   /** get comment */
getComment(void)205   const std::string & getComment(void) const { return comment; }
206   /** find out if the comment popup flas is set */
getCommentPopup(void)207   bool getCommentPopup(void) const { return commentPopup; }
208   /** set or reset comment popup flag */
setCommentPopup(bool val)209   void setCommentPopup(bool val) { commentPopup = val; }
210   //@}
211 
212 private:
213 
214   // no copying and assigning
215   puzzle_c(const puzzle_c&);
216   void operator=(const puzzle_c&);
217 
218 };
219 
220 #endif
221