Hi
I am having a problem with some cellular automata logic I am working on.
I have been stewing over this for a few weeks and can't come up with the answer (although I feel I am very close).
Basically I have a grid and I am trying to make a water like flow. It seems to work fine during testing flowing over 1 level or flowing down levels but I can't seem to get it to flow up levels (when enough water has built up).
I should point out the code I place below is the update() function for my grid. this is were the logic fails.
I have a tried a number of solutions that I will post below.
First I tried this:
PHP Code:
public function update(e:Event = null):void
{
var _cell:Cell;
var _avgLevel:Number;
var _avgCount:Number;
for (var i:int = 0; i < _horCount; i++)
{
for (var j:int = 0; j < _verCount; j++)
{
_cell = _currentArray[i][j];
_avgLevel = 0;
_avgCount = 0;
if (_cell._hasUpdated == false)
{
if (i < _maxWidth && _cell._landLevel <= (_currentArray[i + 1][j]._landLevel + _currentArray[i + 1][j]._waterLevel) && _currentArray[i + 1][j]._waterLevel > 0)
{
_avgLevel += _currentArray[i + 1][j]._waterLevel;
_avgCount++;
}
if (i > 0 && _cell._landLevel <= (_currentArray[i - 1][j]._landLevel + _currentArray[i - 1][j]._waterLevel) && _currentArray[i - 1][j]._waterLevel > 0)
{
_avgLevel += _currentArray[i - 1][j]._waterLevel;
_avgCount++;
}
if (j < _maxHeight && _cell._landLevel <= (_currentArray[i][j + 1]._landLevel + _currentArray[i][j + 1]._waterLevel) && _currentArray[i][j + 1]._waterLevel > 0)
{
_avgLevel += _currentArray[i][j + 1]._waterLevel;
_avgCount++;
}
if (j > 0 && _cell._landLevel <= (_currentArray[i][j - 1]._landLevel + _currentArray[i][j - 1]._waterLevel) && _currentArray[i][j - 1]._waterLevel > 0)
{
_avgLevel += _currentArray[i][j - 1]._waterLevel;
_avgCount++;
}
if(_avgCount > 0){
_cell._waterLevel = (_avgLevel / (_avgCount));
_cell._hasUpdated = true;
}
}
}
}
drawGrid();
}
The problem with this is it seems to have a bug with land and water levels, also when it the water does get above the land it seems to flood instantly instead of slowly.
SWF here: it4kids.co.nz/hosted/1.swf
Then I tried adding in the land levels to my equations:
PHP Code:
public function update(e:Event = null):void
{
var _cell:Cell;
var _avgLevel:Number;
var _avgCount:Number;
for (var i:int = 0; i < _horCount; i++)
{
for (var j:int = 0; j < _verCount; j++)
{
_cell = _currentArray[i][j];
_avgLevel = 0;
_avgCount = 0;
if (_cell._hasUpdated == false)
{
if (i < _maxWidth && _cell._landLevel <= (_currentArray[i + 1][j]._landLevel + _currentArray[i + 1][j]._waterLevel) && _currentArray[i + 1][j]._waterLevel > 0)
{
_avgLevel += _currentArray[i + 1][j]._waterLevel - (_cell._landLevel - _currentArray[i + 1][j]._landLevel);
_avgCount++;
}
if (i > 0 && _cell._landLevel <= (_currentArray[i - 1][j]._landLevel + _currentArray[i - 1][j]._waterLevel) && _currentArray[i - 1][j]._waterLevel > 0)
{
_avgLevel += _currentArray[i - 1][j]._waterLevel - (_cell._landLevel - _currentArray[i - 1][j]._landLevel);
_avgCount++;
}
if (j < _maxHeight && _cell._landLevel <= (_currentArray[i][j + 1]._landLevel + _currentArray[i][j + 1]._waterLevel) && _currentArray[i][j + 1]._waterLevel > 0)
{
_avgLevel += _currentArray[i][j + 1]._waterLevel - (_cell._landLevel - _currentArray[i][j + 1]._landLevel);
_avgCount++;
}
if (j > 0 && _cell._landLevel <= (_currentArray[i][j - 1]._landLevel + _currentArray[i][j - 1]._waterLevel) && _currentArray[i][j - 1]._waterLevel > 0)
{
_avgLevel += _currentArray[i][j - 1]._waterLevel - (_cell._landLevel - _currentArray[i][j - 1]._landLevel);
_avgCount++;
}
if(_avgCount > 0){
_cell._waterLevel = (_avgLevel / (_avgCount));
_cell._hasUpdated = true;
}
}
}
}
drawGrid();
}
The problem with this is the lower land levels seem to fill the water for now reason, the height seems to work though.
SWF here: it4kids.co.nz/hosted/2.swf
So at this point I though my problem was simple, SO I put a simple if statement in but the result was not as expected:
PHP Code:
public function update(e:Event = null):void
{
var _cell:Cell;
var _avgLevel:Number;
var _avgCount:Number;
for (var i:int = 0; i < _horCount; i++)
{
for (var j:int = 0; j < _verCount; j++)
{
_cell = _currentArray[i][j];
_avgLevel = 0;
_avgCount = 0;
if (_cell._hasUpdated == false)
{
if (i < _maxWidth && _cell._landLevel <= (_currentArray[i + 1][j]._landLevel + _currentArray[i + 1][j]._waterLevel) && _currentArray[i + 1][j]._waterLevel > 0)
{
if(_cell._landLevel > _currentArray[i + 1][j]._landLevel){
_avgLevel += _currentArray[i + 1][j]._waterLevel - (_cell._landLevel - _currentArray[i + 1][j]._landLevel);
_avgCount++;
}else{
_avgLevel += _currentArray[i + 1][j]._waterLevel;
_avgCount++;
}
}
if (i > 0 && _cell._landLevel <= (_currentArray[i - 1][j]._landLevel + _currentArray[i - 1][j]._waterLevel) && _currentArray[i - 1][j]._waterLevel > 0)
{
if(_cell._landLevel > _currentArray[i - 1][j]._landLevel){
_avgLevel += _currentArray[i - 1][j]._waterLevel - (_cell._landLevel - _currentArray[i - 1][j]._landLevel);
_avgCount++;
}else{
_avgLevel += _currentArray[i - 1][j]._waterLevel;
_avgCount++;
}
}
if (j < _maxHeight && _cell._landLevel <= (_currentArray[i][j + 1]._landLevel + _currentArray[i][j + 1]._waterLevel) && _currentArray[i][j + 1]._waterLevel > 0)
{
if(_cell._landLevel > _currentArray[i][j + 1]._landLevel){
_avgLevel += _currentArray[i][j + 1]._waterLevel - (_cell._landLevel - _currentArray[i][j + 1]._landLevel);
_avgCount++;
}else{
_avgLevel += _currentArray[i][j + 1]._waterLevel;
_avgCount++;
}
}
if (j > 0 && _cell._landLevel <= (_currentArray[i][j - 1]._landLevel + _currentArray[i][j - 1]._waterLevel) && _currentArray[i][j - 1]._waterLevel > 0)
{
if(_cell._landLevel > _currentArray[i][j - 1]._landLevel){
_avgLevel += _currentArray[i][j - 1]._waterLevel - (_cell._landLevel - _currentArray[i][j - 1]._landLevel);
_avgCount++;
}else{
_avgLevel += _currentArray[i][j - 1]._waterLevel;
_avgCount++;
}
}
if(_avgCount > 0){
_cell._waterLevel = (_avgLevel / (_avgCount));
_cell._hasUpdated = true;
}
}
}
}
drawGrid();
}
SWF here: it4kids.co.nz/hosted/3.swf
I posted this in another forum but got no replies.
Any help would be really really great guys as I am up against a brick wall right now.