#include <u.h>
#include <libc.h>
#include <draw.h>
#include "rushhour.h"
int
item(Point p)
{
return level.board[p.x][p.y];
}
void
setitem(Point p, int v)
{
level.board[p.x][p.y] = v;
}
int
isvehicle(int square)
{
switch(square) {
case CarX:
case CarY:
case CarZ:
case CarA:
case CarB:
case CarC:
case CarD:
case CarE:
case CarF:
case CarG:
case CarH:
case CarI:
case CarJ:
case CarK:
case CarL:
case CarM:
case CarN:
case TruckO:
case TruckP:
case TruckQ:
case TruckR:
case TruckS:
case TruckT:
case TruckU:
case TruckV:
return 1;
default:
return 0;
}
}
Point
next(Point p)
{
int b, o;
Point t;
Point one[] = {
[OHoriz] Pt(1, 0),
[OVert] Pt(0,1)
};
b = item(p);
if (isvehicle(b)) {
o = level.orient[b];
t = addpt(p, one[o]);
return t;
} else {
return p;
}
}
Point
prev(Point p)
{
int b, o;
Point t;
Point one[] = {
[OHoriz] Pt(1, 0),
[OVert] Pt(0,1)
};
b = item(p);
if (isvehicle(b)) {
o = level.orient[b];
t = subpt(p, one[o]);
return t;
} else {
return p;
}
}
Point
gettopleft(Point p)
{
int b;
Point s, t;
b = item(p);
if (isvehicle(b)) {
s = p;
t = prev(s);
while (item(t) == b) {
s = t;
t = prev(s);
}
return s;
} else {
return p;
}
}
int
canmove(Point p, Point dir)
{
int b, res;
Point d;
if (eqpt(dir, ZP))
return 0;
res = 0;
b = item(p);
if (isvehicle(b)) {
d = addpt(p, dir);
/*
* check that we do not go beyond the allocated board
* (allocated: Rpt(ZP, Pt(MazeX, MazeY))
* (used: Rpt(ZP, level.max)
*/
while (ptinrect(d, Rect(0,0, MazeX, MazeY)) && item(d) == b) {
d = addpt(d, dir);
}
if (ptinrect(d, Rect(0,0, MazeX, MazeY))) {
switch(item(d)) {
case Empty:
res = 1;
break;
}
}
}
return res;
}
Point
destof(Point p, Point dir)
{
int b;
Point d;
if (eqpt(dir, ZP))
return Pt(-1,-1);
b = item(p);
if (isvehicle(b)) {
d = addpt(p, dir);
while (item(d) == b) {
d = addpt(d, dir);
}
switch(item(d)) {
case Empty:
return d;
break;
}
}
return Pt(-1,-1);
}
int
onestep(Point p, Point dir, Point *vacant)
{
int b;
Point e, d, t, v;
if (eqpt(dir, ZP))
return 0;
b = item(p);
if (isvehicle(b)) {
v = p;
t = subpt(v, dir);
while (item(t) == b) {
v = t;
t = subpt(v, dir);
}
e = p;
t = addpt(e, dir);
while (item(t) == b) {
e = t;
t = addpt(e, dir);
}
d = t;
switch(item(d)) {
case Empty:
*vacant = v;
setitem(d, b);
setitem(v, Empty);
/* make escaping car disappear */
if (ptinrect(v, Rpt(Pt(Off,Off), level.max)) &&
!ptinrect(addpt(v,dir), Rpt(Pt(Off,Off), level.max))) {
t = gettopleft(d);
while(item(t) == b) {
p = t;
t = next(t);
setitem(p, Empty);
}
}
return 1;
}
}
return 0;
}
|