1 //------------------------------------------------------------------------------
2 // emNetwalkModel.h
3 //
4 // Copyright (C) 2010-2012,2014,2018 Oliver Hamann.
5 //
6 // Homepage: http://eaglemode.sourceforge.net/
7 //
8 // This program is free software: you can redistribute it and/or modify it under
9 // the terms of the GNU General Public License version 3 as published by the
10 // Free Software Foundation.
11 //
12 // This program is distributed in the hope that it will be useful, but WITHOUT
13 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14 // FOR A PARTICULAR PURPOSE. See the GNU General Public License version 3 for
15 // more details.
16 //
17 // You should have received a copy of the GNU General Public License version 3
18 // along with this program. If not, see <http://www.gnu.org/licenses/>.
19 //------------------------------------------------------------------------------
20
21 #ifndef emNetwalkModel_h
22 #define emNetwalkModel_h
23
24 #ifndef emRecFileModel_h
25 #include <emCore/emRecFileModel.h>
26 #endif
27
28
29 class emNetwalkModel : public emRecFileModel, private emStructRec
30 {
31
32 public:
33
34 static emRef<emNetwalkModel> Acquire(
35 emContext & context, const emString & name, bool common=true
36 );
37
38 virtual const char * GetFormatName() const;
39
40 int GetWidth() const;
41 int GetHeight() const;
42
43 bool IsBorderless() const;
44 bool IsNoFourWayJunctions() const;
45 int GetComplexity() const;
46 bool IsDigMode() const;
47
48 void SetAutoMark(bool autoMark, bool saveFile=true);
49 bool IsAutoMark() const;
50
51 bool IsFinished() const;
52 int GetPenaltyPoints() const;
53
54 int GetPiece(int x, int y) const;
55 enum {
56 PF_EAST =(1<<0),
57 PF_SOUTH =(1<<1),
58 PF_WEST =(1<<2),
59 PF_NORTH =(1<<3),
60 PF_SOURCE =(1<<4),
61 PF_TARGET =(1<<5),
62 PF_FILLED =(1<<6),
63 PF_TOUCHED=(1<<7),
64 PF_MARKED =(1<<8),
65 PF_BLOCKED=(1<<9),
66 PF_CONMASK=PF_EAST|PF_SOUTH|PF_WEST|PF_NORTH
67 };
68
69 void TrySetup(
70 int width, int height, bool borderless, bool noFourWayJunctions,
71 int complexity, bool digMode, bool autoMark, bool saveFile=true
72 );
73
74 void MarkOrUnmark(int x, int y, bool saveFile=true);
75 void UnmarkAll(bool saveFile=true);
76
77 void Rotate(int x, int y, int angle, bool saveFile=true);
78 void RotateLeft(int x, int y, bool saveFile=true);
79 void RotateRight(int x, int y, bool saveFile=true);
80
81 void Scroll(int dx, int dy, bool saveFile=true);
82
83 protected:
84
85 emNetwalkModel(emContext & context, const emString & name);
86 virtual ~emNetwalkModel();
87
88 virtual bool TryContinueLoading();
89
90 virtual bool Cycle();
91
92 private:
93
94 int GetPiece(int index) const;
95 void SetPiece(int index, int piece);
96 void XorPiece(int index, int flags);
97 void OrPiece(int index, int flags);
98 void AndPiece(int index, int flags);
99
100 int GetNeighborIndex(int index, int angle) const;
101 bool IsConnected(int index, int angle) const;
102 void Connect(int index, int angle);
103
104 void Invent();
105 void Shuffle();
106 void Fill();
107 void Dig(bool reset);
108
109 void DoAutoMark();
110
111 static int RawRotate(int piece, int angle);
112
113 class Solver : public emUncopyable {
114 public:
115 Solver(emNetwalkModel * model);
116 ~Solver();
117 bool IsUniqueSolution();
118 private:
119 struct Piece {
120 int OrigDirs;
121 int Dirs;
122 int Placed;
123 int Group;
124 int NextPiece;
125 int FrontRing;
126 int Neighbor[4];
127 };
128 struct Group {
129 int FirstPiece;
130 int PieceCount;
131 int OpenCount;
132 };
133 struct TBEntry {
134 int * Ptr; // NULL for start-mark
135 int Val;
136 };
137 bool CheckPiece(int i) const;
138 void PlacePiece(int i);
139 bool UpdateGroups(int i);
140 int FindAndGetBestNext();
141 void TBClear();
142 void TBStart();
143 void TBSet(int & rInt, int val);
144 void TakeBack();
145 int PieceCount;
146 int GroupCount;
147 int FrontRing;
148 int Current;
149 Piece * Pieces;
150 Group * Groups;
151 TBEntry * TBBuf, * TBTop, * TBEnd;
152 };
153 friend class Solver;
154
155 emIntRec Width;
156 emIntRec Height;
157 emBoolRec Borderless;
158 emBoolRec NoFourWayJunctions;
159 emIntRec Complexity;
160 emBoolRec DigMode;
161 emBoolRec AutoMark;
162 emBoolRec Finished;
163 emIntRec PenaltyPoints;
164 emIntRec CurrentPiece;
165 emTArrayRec<emIntRec> Raster;
166
167 emTimer AutoMarkTimer;
168 int AutoMarkPiece;
169 bool AutoMarkToSave;
170
171 static const int A2PF[4];
172 };
173
GetWidth()174 inline int emNetwalkModel::GetWidth() const
175 {
176 return Width;
177 }
178
GetHeight()179 inline int emNetwalkModel::GetHeight() const
180 {
181 return Height;
182 }
183
IsBorderless()184 inline bool emNetwalkModel::IsBorderless() const
185 {
186 return Borderless;
187 }
188
IsNoFourWayJunctions()189 inline bool emNetwalkModel::IsNoFourWayJunctions() const
190 {
191 return NoFourWayJunctions;
192 }
193
GetComplexity()194 inline int emNetwalkModel::GetComplexity() const
195 {
196 return Complexity;
197 }
198
IsDigMode()199 inline bool emNetwalkModel::IsDigMode() const
200 {
201 return DigMode;
202 }
203
IsAutoMark()204 inline bool emNetwalkModel::IsAutoMark() const
205 {
206 return AutoMark;
207 }
208
IsFinished()209 inline bool emNetwalkModel::IsFinished() const
210 {
211 return Finished;
212 }
213
GetPenaltyPoints()214 inline int emNetwalkModel::GetPenaltyPoints() const
215 {
216 return PenaltyPoints;
217 }
218
RotateLeft(int x,int y,bool saveFile)219 inline void emNetwalkModel::RotateLeft(int x, int y, bool saveFile)
220 {
221 Rotate(x,y,-1,saveFile);
222 }
223
RotateRight(int x,int y,bool saveFile)224 inline void emNetwalkModel::RotateRight(int x, int y, bool saveFile)
225 {
226 Rotate(x,y,1,saveFile);
227 }
228
GetPiece(int index)229 inline int emNetwalkModel::GetPiece(int index) const
230 {
231 return Raster[index].Get();
232 }
233
SetPiece(int index,int piece)234 inline void emNetwalkModel::SetPiece(int index, int piece)
235 {
236 Raster[index].Set(piece);
237 }
238
XorPiece(int index,int flags)239 inline void emNetwalkModel::XorPiece(int index, int flags)
240 {
241 SetPiece(index,GetPiece(index)^flags);
242 }
243
OrPiece(int index,int flags)244 inline void emNetwalkModel::OrPiece(int index, int flags)
245 {
246 SetPiece(index,GetPiece(index)|flags);
247 }
248
AndPiece(int index,int flags)249 inline void emNetwalkModel::AndPiece(int index, int flags)
250 {
251 SetPiece(index,GetPiece(index)&flags);
252 }
253
TBClear()254 inline void emNetwalkModel::Solver::TBClear()
255 {
256 TBTop=TBBuf;
257 }
258
TBStart()259 inline void emNetwalkModel::Solver::TBStart()
260 {
261 TBTop->Ptr=NULL;
262 TBTop++;
263 }
264
TBSet(int & rInt,int val)265 inline void emNetwalkModel::Solver::TBSet(int & rInt, int val)
266 {
267 TBTop->Ptr=&rInt;
268 TBTop->Val=rInt;
269 TBTop++;
270 rInt=val;
271 }
272
273
274 #endif
275