-
Notifications
You must be signed in to change notification settings - Fork 2
/
CellReservation.c
404 lines (349 loc) · 10 KB
/
CellReservation.c
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
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
//Functions for reserving and releasing cells
#include <signal.h>
#include "CellReservation.h"
#include "MazeManipulation.h"
#include "Config.h"
#include "RfPacket.h"
#include "nRF24L01.h"
#include "softDelay.h"
extern unsigned int Maze [MAZEY][MAZEX];
extern unsigned char TxPacket[32];
volatile extern unsigned char CTS;
unsigned char GetCellReserved(unsigned char x, unsigned char y)
{
unsigned char temp = (Maze[y][x] >> 8);
temp &= 0x0f;
return temp;
}
void SetCellReserved(unsigned char x, unsigned char y)
{
unsigned int number = (MOUSENUMBER << 8); //move mousenumber to correct position
number &= 0x0F00; // make sure that mousenumber does not affect any other bits
Maze[y][x] &= 0xF0FF; // clear mousenumber bits
Maze[y][x] |= number;
}
void SetCellReservedByAnotherMouse(unsigned char x, unsigned char y, unsigned char mouse)
{
unsigned int number = (mouse << 8); //move mousenumber to correct position
number &= 0x0F00; // make sure that mousenumber does not affect any other bits
Maze[y][x] &= 0xF0FF; // clear mousenumber bits
Maze[y][x] |= number;
}
void SetCellUnreserved(unsigned char x, unsigned char y)
{
Maze[y][x] &= 0xF0FF; // clear bits
}
void SetCurrentCellUnreserved( void )
{
Maze[GetMouseY()][GetMouseX()] &= 0xF0FF; // clear bits
}
void ReserveCell(unsigned char x,unsigned char y)
{//Cell required, so tell other mice to reserve cells
SetCellReserved(x,y);
while(!CTS);
dint();
AssembleCellReservePacket(x,y);
rfStandbyMode();
rfSendPacket2Module(&TxPacket[0],32);
rfTxMode();
eint();
softDelay(65535);
}
void ReserveCurrentCell(void)
{
unsigned char MouseX = GetMouseX();
unsigned char MouseY = GetMouseY();
ReserveCell(MouseX,MouseY);
}
unsigned char ReserveCellsAround(unsigned char MoveDir)
{
unsigned char MouseX = GetMouseX();
unsigned char MouseY = GetMouseY();
unsigned char Failure = 0x0F;
//unsigned int number = (MOUSENUMBER << 8); //move mousenumber to correct position
/* Reserve cell for this mouse by putting its mousenumber
in 3rd Nibble of MAZE (0x0F00 is mask)
Want to reserve 3 cells around CurrentPos + MoveDir
Must check first that maze bounds not exceeded (can not reserve cell [-1] or cell [>MAZEX] or [>MAZEY] )
& Can not reserve cell if already reserved
*/
switch(MoveDir)
{
case NORTH:
MouseY--; //move centre north
if (MouseY && (!GetCellReserved(MouseX, MouseY-1)) ) //bound check & not already reserved
{
ReserveCell(MouseX, MouseY-1); //reserve north
Failure &= ~NORTH;
}
if ( (MouseX != (MAZEX-1)) && (!GetCellReserved(MouseX+1, MouseY)) )
{
ReserveCell(MouseX+1, MouseY); //reserve east
Failure &= ~EAST;
}
// no need to reserve south as moving from that direction South
if (MouseX && (!GetCellReserved(MouseX-1, MouseY)) )
{
ReserveCell(MouseX-1, MouseY); //reserve west
Failure &= ~WEST;
}
break;
case EAST:
MouseX++; //move centre East
if (MouseY && (!GetCellReserved(MouseX, MouseY-1)) )
{
ReserveCell(MouseX, MouseY-1); //reserve north
Failure &= ~NORTH;
}
if ( (MouseX != (MAZEX-1)) && (!GetCellReserved(MouseX+1, MouseY)) )
{
ReserveCell(MouseX+1, MouseY); //reserve ease
Failure &= ~EAST;
}
if ( (MouseY != (MAZEY-1)) && (!GetCellReserved(MouseX, MouseY+1)) )
{
ReserveCell(MouseX, MouseY+1); //reserve south
Failure &= ~SOUTH;;
}
//no need to reserve west as moving from that direction West
break;
case SOUTH:
MouseY++; //move centre south
//no need to reserve north as moving from that direction North
if ((MouseX != (MAZEX-1)) && (!GetCellReserved(MouseX+1, MouseY)) )
{
ReserveCell(MouseX+1, MouseY); //reserve ease
Failure &= ~EAST;
}
if ((MouseY != (MAZEY-1)) && (!GetCellReserved(MouseX, MouseY+1)) )
{
ReserveCell(MouseX, MouseY+1); //reserve south
Failure &= ~SOUTH;;
}
if (MouseX && (!GetCellReserved(MouseX-1, MouseY)) )
{
ReserveCell(MouseX-1, MouseY); //reserve west
Failure &= ~WEST;
}
break;
case WEST:
MouseX--; //move centre west
if (MouseY && (!GetCellReserved(MouseX, MouseY-1)) )
{
ReserveCell(MouseX, MouseY-1); //reserve north
Failure &= ~NORTH;;
}
//no need to reserve east as moving from that direction East
if ((MouseY != (MAZEY-1)) && (!GetCellReserved(MouseX, MouseY+1)) )
{
ReserveCell(MouseX, MouseY+1); //reserve south
Failure &= ~SOUTH;
}
if (MouseX && (!GetCellReserved(MouseX-1, MouseY)) )
{
ReserveCell(MouseX-1, MouseY); //reserve west
Failure &= ~WEST;
}
break;
default:
//error
break;
}
return Failure; //if a cell has not been able to be reserved, this will show it
}
void ReserveCellsAroundHere (void)
{
unsigned char MouseX = GetMouseX();
unsigned char MouseY = GetMouseY();
unsigned char Exits = GetExits(MouseX,MouseY);
/* Reserve cell for this mouse by putting its mousenumber
in 3rd Nibble of MAZE (0x0F00 is mask)
Must check first that maze bounds not exceeded (can not reserve cell [-1] or cell [>MAZEX] or [>MAZEY] )
& Can not reserve cell if already reserved
*/
if (MouseY)
{
if ( (!GetCellReserved(MouseX, MouseY-1)) && (Exits & NORTH) )
{ //bound check & not already reserved & No Wall
SetCellReserved(MouseX, MouseY-1); //reserve north
}
}
if ( (MouseX != (MAZEX-1)) )
{
if ( (!GetCellReserved(MouseX+1, MouseY)) && (Exits & EAST) )
{
SetCellReserved(MouseX+1, MouseY); //reserve east
}
}
if ( (MouseY != (MAZEY-1)) )
{
if ( (!GetCellReserved(MouseX, MouseY+1)) && (Exits & SOUTH) )
{
SetCellReserved(MouseX, MouseY+1); //reserve south
}
}
if (MouseX)
{
if ( (!GetCellReserved(MouseX-1, MouseY)) && (Exits & WEST) )
{
SetCellReserved(MouseX-1, MouseY); //reserve west
}
}
}
void ReleaseCell(unsigned char x,unsigned char y)
{//Cells not required any more, so tell other mice to unreserve cells
SetCellUnreserved(x,y);
while(!CTS);
dint();
AssembleCellReleasePacket(x,y);
rfStandbyMode();
rfSendPacket2Module(&TxPacket[0],32);
rfTxMode();
eint();
softDelay(65535);
}
void ReleaseCurrentCell(void)
{
unsigned char MouseX = GetMouseX();
unsigned char MouseY = GetMouseY();
ReleaseCell(MouseX,MouseY);
}
void ReleaseOldCells(unsigned char MoveDir)
{
unsigned char MouseX = GetMouseX();
unsigned char MouseY = GetMouseY();
//unsigned char Failure = 0x0F;
/*
To release a cell:
must have already been reserved (by this mouse)
must be in the maze [such that array indexis not out of bounds etc.]
*/
MoveDir = ShiftLeftWrapNibble(ShiftLeftWrapNibble(MoveDir)); //Swap dir [N<==>S], [E<==>W]
switch(MoveDir)
{
case NORTH:
MouseY--; //move centre north
if (MouseY) //North boundary check
{
if ( GetCellReserved(MouseX, MouseY-1) == MOUSENUMBER )
{
ReleaseCell(MouseX, MouseY-1); //release north
}
}
if ( (MouseX != (MAZEX-1)) && (GetCellReserved(MouseX+1, MouseY) == MOUSENUMBER) )
{
ReleaseCell(MouseX+1, MouseY); //release east
}
//have moved south so don't release South
if (MouseX) //West boundary check
{
if ( GetCellReserved(MouseX-1, MouseY) == MOUSENUMBER )
{
ReleaseCell(MouseX-1, MouseY); //release west
}
}
break;
case EAST:
MouseX++; //move centre East
if (MouseY) //North boundary check
{
if ( GetCellReserved(MouseX, MouseY-1) == MOUSENUMBER )
{
ReleaseCell(MouseX, MouseY-1); //release north
}
}
if ( (MouseX != (MAZEX-1)) && (GetCellReserved(MouseX+1, MouseY) == MOUSENUMBER) )
{
ReleaseCell(MouseX+1, MouseY); //release east
}
if ( (MouseY != (MAZEY-1)) && (GetCellReserved(MouseX, MouseY+1) == MOUSENUMBER) )
{
ReleaseCell(MouseX, MouseY+1); //release south
}
//no need to release west as moved to that direction West
break;
case SOUTH:
MouseY++; //move centre south
//no need to release north as moved to that direction North
if ( (MouseX != (MAZEX-1)) && (GetCellReserved(MouseX+1, MouseY) == MOUSENUMBER) )
{
ReleaseCell(MouseX+1, MouseY); //release east
}
if ( (MouseY != (MAZEY-1)) && (GetCellReserved(MouseX, MouseY+1) == MOUSENUMBER) )
{
ReleaseCell(MouseX, MouseY+1); //release south
}
if (MouseX) //West boundary check
{
if ( GetCellReserved(MouseX-1, MouseY) == MOUSENUMBER )
{
ReleaseCell(MouseX-1, MouseY); //release west
}
}
break;
case WEST:
MouseX++; //move centre west
if (MouseY) //North boundary check
{
if ( GetCellReserved(MouseX, MouseY-1) == MOUSENUMBER )
{
ReleaseCell(MouseX, MouseY-1); //release north
}
}
//no need to release East as moved to that direction East
if ( (MouseY != (MAZEY-1)) && (GetCellReserved(MouseX, MouseY+1) == MOUSENUMBER) )
{
ReleaseCell(MouseX, MouseY+1); //release south
}
if (MouseX) //West boundary check
{
if ( GetCellReserved(MouseX-1, MouseY) == MOUSENUMBER )
{
ReleaseCell(MouseX-1, MouseY); //release west
}
}
break;
default:
//error
break;
}
}
void ReleaseWalledCells (void)
{
unsigned char MouseX = GetMouseX();
unsigned char MouseY = GetMouseY();
unsigned char Walls = GetWalls(MouseX,MouseY);
/*
Having reserved all cells around destination, some may be unaccessible as
there is a wall in the way. If so, cell does not need to be reserved, so
release that cell.
*/
if (MouseY) //North boundary check
{
if ( (GetCellReserved(MouseX, MouseY-1)) && (Walls & NORTH) )
{
ReleaseCell(MouseX, MouseY-1); //release north
}
}
if ( MouseX != (MAZEX-1) ) //East boundary check
{
if( (GetCellReserved(MouseX+1, MouseY)) && (Walls & EAST) )
{
ReleaseCell(MouseX+1, MouseY); //release east
}
}
if ( MouseY != (MAZEY-1) ) //South boundary check
{
if ( (GetCellReserved(MouseX, MouseY+1)) && (Walls & SOUTH) )
{
ReleaseCell(MouseX, MouseY+1); //release south
}
}
if (MouseX) //West boundary check
{
if ( (GetCellReserved(MouseX-1, MouseY)) && (Walls & WEST) )
{
ReleaseCell(MouseX-1, MouseY); //release west
}
}
}