-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathHexGrid.cpp
220 lines (186 loc) · 6.19 KB
/
HexGrid.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
/*
* Copyright 2009-2014 Scott McCreary
* Copyright 2013 Luke (noryb009)
* Based on BeVexed by DarkWyrm Copyright 2007-2009
*
* Distributed under terms of the MIT License.
*
*/
/*
example layout, 4 rows, 4 columns = 16 hexagon tiles
col0 col1 col2 col3
______ ______
/\ /\ /\ /\
/tl\ t/tr\ /tl\ t/tr\
row0 /____\/____\ ____ /____\/____\______
\ /\ /\ /\ /\ /\ /\
\bl/ b\br/tl\ t/tr\bl/ b\br/tl\ t/tr\
\/____\/____\/____\/____\/____\/____\
/\ /\ /\ /\ /\ /\ /
/tl\ t/tr\bl/ b\br/tl\ t/tr\bl/ b\br/
row1 /____\/____\/____\/____\/____\/____\/
\ /\ /\ /\ /\ /\ /\
\bl/ b\br/tl\ t/tr\bl/ b\br/tl\ t/tr\
\/____\/____\/____\/____\/____\/____\
\ /\ / \ /\ /
\bl/ b\br/ \bl/ b\br/
\/____\/ \/____\/
*/
#include "HexTile.h"
#include "HexGrid.h"
#include <OS.h>
#include <stdlib.h>
#include <stdio.h>
#include "HexTileView.h"
#define RAND(_min_, _max_) ({ uint8 low = _min_; uint8 high = _max_; rand() % (high-low) + low; })
#define MKRAND RAND(0, fNumberBase)
HexGrid::HexGrid(uint8 size, uint16 id)
{
if(size == 0)
debugger("Programmer Error: Grid has 0 tiles");
fId = id;
fSize = size;
uint16 arraysize = fSize * fSize;
// create all tiles
for (uint8 arrno = 0; arrno < arraysize; arrno++)
{
fTiles.AddItem(new HexTile());
}
for (uint8 row = 0; row < fSize; row++)
{
uint16 index = row * fSize;
for (uint8 col = 0; col < fSize; col++)
{
HexTile *tile = fTiles.ItemAt(index+col);
// top
if (row == 0)
tile->toptile = NULL;
else
tile->toptile = fTiles.ItemAt(index+col-fSize);
// top left
if (col == 0 || (row == 0 && col % 2 != 1))
tile->toplefttile = NULL;
else
if (col % 2 == 1)
tile->toplefttile = fTiles.ItemAt(index+col-1);
else
tile->toplefttile = fTiles.ItemAt(index+col-fSize-1);
// bottom left
if (col == 0 || (row == fSize-1 && col % 2 != 0))
tile->bottomlefttile = NULL;
else
if(col % 2 == 0)
tile->bottomlefttile = fTiles.ItemAt(index+col-1);
else
tile->bottomlefttile = fTiles.ItemAt(index+col+fSize-1);
tile->toprighttile = NULL;
tile->bottomrighttile = NULL;
tile->bottomtile = NULL;
}
}
for (uint16 i = 0; i < arraysize; i++)
{
HexTile *tile = fTiles.ItemAt(i);
if (tile->toplefttile)
tile->toplefttile->bottomrighttile = tile;
if (tile->bottomlefttile)
tile->bottomlefttile->toprighttile = tile;
if (tile->toptile)
tile->toptile->bottomtile = tile;
}
}
HexGrid::~HexGrid(void)
{
for (int32 i = 0; i < fTiles.CountItems(); i++)
delete fTiles.ItemAt(i);
fTiles.MakeEmpty();
}
void HexGrid::GeneratePuzzle(void)
{
HexTile *tile;
if (fNumberBase > 16)
fNumberBase = 16;
if (fNumberBase < 1)
fNumberBase = 10;
// Generate tiles and index when solved
uint16 id = 0;
for (uint8 row = 0; row < fSize; row++)
{
uint16 index = row * fSize;
for (uint8 col = 0; col < fSize; col++)
{
tile = fTiles.ItemAt(index + col);
// if there is a tile above and its bottom has a value,
tile->top = (tile->toptile && tile->toptile->bottom != -1) ?
// get the bottom value. Otherwise, make a random value
tile->toptile->bottom : RAND(0, fNumberBase);
tile->topleft = (tile->toplefttile && tile->toplefttile->bottomright != -1) ?
tile->toplefttile->bottomright : RAND(0, fNumberBase);
tile->topright = (tile->toprighttile && tile->toprighttile->bottomleft != -1) ?
tile->toprighttile->bottomleft : RAND(0, fNumberBase);
tile->bottom = (tile->bottomtile && tile->bottomtile->top != -1) ?
tile->bottomtile->top : RAND(0, fNumberBase);
tile->bottomleft = (tile->bottomlefttile && tile->bottomlefttile->topright != -1) ?
tile->bottomlefttile->topright : RAND(0, fNumberBase);
tile->bottomright = (tile->bottomrighttile && tile->bottomrighttile->topleft != -1) ?
tile->bottomrighttile->topleft : RAND(0, fNumberBase);
tile->id = id++;
}
}
#ifndef TESTMODE
// Now mix them all up
uint16 arraysize = (fSize * fSize);
uint16 count = arraysize * 4;
for (uint8 i = 0; i < count; i++)
{
// swap two random elements
uint16 indexone = RAND(0, arraysize);
uint16 indextwo = RAND(0, arraysize);
HexTile *itemone = fTiles.ItemAt(indexone);
HexTile *tempitem = fTiles.SwapWithItem(indextwo, itemone);
fTiles.SwapWithItem(indexone, tempitem);
}
#endif
}
HexTile *HexGrid::TileAt(const uint16 &index)
{
if (index > (fSize * fSize) - 1)
debugger("Programmer Error: Tile index too big");
return fTiles.ItemAt(index);
}
bool HexGrid::TryTile(HexTile *src, HexTile *dest)
{
if (!src || !dest || src->IsEmpty())
return false;
// Return true if the thing is a valid play
if (dest->toplefttile && !dest->toplefttile->IsEmpty())
if (dest->toplefttile != src && dest->toplefttile->bottomright != src->topleft)
return false;
if (dest->toptile && !dest->toptile->IsEmpty())
if (dest->toptile != src && dest->toptile->bottom != src->top)
return false;
if (dest->toprighttile && !dest->toprighttile->IsEmpty())
if (dest->toprighttile != src && dest->toprighttile->bottomleft != src->topright)
return false;
if (dest->bottomlefttile && !dest->bottomlefttile->IsEmpty())
if (dest->bottomlefttile != src && dest->bottomlefttile->topright != src->bottomleft)
return false;
if (dest->bottomtile && !dest->bottomtile->IsEmpty())
if (dest->bottomtile != src && dest->bottomtile->top != src->bottom)
return false;
if (dest->bottomrighttile && !dest->bottomrighttile->IsEmpty())
if (dest->bottomrighttile != src && dest->bottomrighttile->topleft != src->bottomright)
return false;
return true;
}
bool HexGrid::IsSolved(void)
{
// return true if the puzzle is solved
for (int32 i = 0; i < fTiles.CountItems(); i++)
{
HexTile *t = fTiles.ItemAt(i);
if(t->IsEmpty())
return false;
}
return true;
}