Code:
runit* tunit = NULL;
deque<runit> open;
deque<runit> closed;
int h;
// set starting point
tunit = new runit;
tunit->pt.x = pt.x;
tunit->pt.y = pt.y;
tunit->h = GetRValue(_map.GetPixel(pt.x,pt.y));
open.push_back(*tunit);
_river.SetPixel(pt.x,pt.y,RGB(255,255,0));
delete tunit;
// A*
while (open.size() > 0)
{
// select first untested point and test its surroundings
for (int dir = 0; dir < 4; dir++)
{
int dx;
int dy;
switch (dir)
{
case 0:
dx = 1;
dy = 0;
break;
case 1:
dx = -1;
dy = 0;
break;
case 2:
dx = 0;
dy = 1;
break;
case 3:
dx = 0;
dy = -1;
break;
}
// x+1
mPOINT point;
point.x = open.at(0).pt.x+dx;
point.y = open.at(0).pt.y+dy;
COLORREF riv = _river.GetPixel(point.x,point.y);
// test if it's valid (not already part of the path or outside the map)
if (!(point.x > 0 && point.x < _ms.width && point.y > 0 && point.y < _ms.height))
continue;
try
{
tunit = new runit;
}
catch (exception& e)
{
CString str = CString("River creation error: ");
str += e.what();
::MessageBox(NULL,str,"Error",MB_OK);
return -2;
}
tunit->pt.x = point.x;
tunit->pt.y = point.y;
tunit->path = open.at(0).path;
tunit->path.push_back(open.at(0).pt);
h = GetRValue(_map.GetPixel(tunit->pt.x,tunit->pt.y));
tunit->h = h + rand()%10-5;
deque<runit>::iterator it;
switch (riv)
{
case RGB(255,255,255):
open.push_back(*tunit);
_river.SetPixel(tunit->pt.x,tunit->pt.y,RGB(255,255,0));
break;
case RGB(255,255,0):
it = find(open.begin(),open.end(),*tunit);
if (it->path.size() > tunit->path.size())
{
open.erase(it);
open.push_back(*tunit);
_river.SetPixel(tunit->pt.x,tunit->pt.y,RGB(255,255,0));
}
break;
case RGB(255,0,255):
it = find(closed.begin(),closed.end(),*tunit);
if (it->path.size() > tunit->path.size())
{
closed.erase(it);
open.push_back(*tunit);
_river.SetPixel(tunit->pt.x,tunit->pt.y,RGB(255,255,0));
}
break;
case RGB(255,0,128):
tunit->path.push_back(tunit->pt);
prlist = tunit->path;
delete tunit;
for (size_t i = 0; i < open.size(); i++)
{
_river.SetPixel(open.at(i).pt.x,open.at(i).pt.y,RGB(255,255,255));
}
for (size_t i = 0; i < closed.size(); i++)
{
_river.SetPixel(closed.at(i).pt.x,closed.at(i).pt.y,RGB(255,255,255));
}
return -1;
break;
default:
for (size_t i = 0; i < River::riverlist.size();i++)
{
int r = River::riverlist.at(i).Compare(point);
if (r != -1)
{
//tunit->path.push_back(tunit->pt);
SetConnection(tunit->pt);
prlist = tunit->path;
delete tunit;
for (int i = 0; i < open.size(); i++)
{
_river.SetPixel(open.at(i).pt.x,open.at(i).pt.y,RGB(255,255,255));
}
for (int i = 0; i < closed.size(); i++)
{
_river.SetPixel(closed.at(i).pt.x,closed.at(i).pt.y,RGB(255,255,255));
}
return r;
}
}
break;
}
delete tunit;
}
closed.push_back(open.at(0));
_river.SetPixel(open.at(0).pt.x,open.at(0).pt.y,RGB(255,0,255));
open.pop_front();
int best = 1000000;
int bestid = -1;
for (size_t i = 0; i < open.size(); i++)
{
if (open.at(i).h < best)
{
best = open.at(i).h;
bestid = i;
}
}
deque<runit>::iterator start = open.begin();
deque<runit>::iterator unit = open.begin() + bestid;
open.push_back(open.front());
*start = *unit;
*unit = open.back();
open.pop_back();
//sort(open.begin(),open.end());
}
// no ocean or river found
return -2;