Hi, I'm attempting to program a fire emblem/final fantasy tactics sort of game. I'm having trouble getting the movement range to layout correctly. The way I'm doing it works, but most of the time gets stuck in an infinite loop, and doesn't always show all of the possible movement/attack locations. I was thinking about starting with the basic diamond, and checking the terrains movement cost (field/plains/grass has no cost, forest/woods has 1, ect.) and subtracting it from the units' total movement, and seeing if I can reach that spot from the edge of the diamond. As I'm writing this I see that that could cause problems, seeing as there is more than 1 path to each spot... Below is the code that I'm using to generate it now, and I was wondering if someone could help me find a way to make it more efficent, and not get stuck in infinite loops any more >.<
public boolean[][][] generateAction2(int[][] field, Terrain[][] ter)
{
for(int z=0;z<3000;z++) // do the following 3500 times (ouch...)
{
boolean[][][] actionRange = new boolean[2][32][29]; // 0=movement spaces, 1=attack spaces.
int tempX = x; int tempY = y; // don't edit the units actual x and y coordinates
for(int i=movement;i>0;i--) //generate however many points the unit can move.
{
boolean good=true; //default good to false after each place generation
do
{
good=true;
int choice = randy.nextInt(4); // randomly choose a direction to go
if(choice==0) tempX++;
if(choice==1) tempX--;
if(choice==2) tempY++;
if(choice==3) tempY--;
// if the new spot is outside the array bounds...
if(tempX>=FIELD_WIDTH || tempX<0 || tempY>=FIELD_HEIGHT || tempY<0)
{
good=false; // it is not a good spot,
if(choice==0) tempX--; //
if(choice==1) tempX++; // and reset tempX or tempY
if(choice==2) tempY--; //
if(choice==3) tempY++; //
}
// don't overlap already-generated spaces.
if(good) if(actionRange[1][tempX][tempY])
{
good=false; // it is not a good spot,
if(choice==0) tempX--; //
if(choice==1) tempX++; // and reset tempX or tempY
if(choice==2) tempY--; //
if(choice==3) tempY++; //
}
//if (including the walk deduction) movement left < 0
if(good) if(i-ter[tempX][tempY].getWalkDeduction()<0)
{
good=false; // it is not a good spot,
if(choice==0) tempX--; //
if(choice==1) tempX++; // and reset tempX or tempY
if(choice==2) tempY--; //
if(choice==3) tempY++; //
}
//if the terrain is un-walkable
if(good) if(ter[tempX][tempY].canWalkHere()==false)
{
good=false; // it is not a good spot,
if(choice==0) tempX--; //
if(choice==1) tempX++; // and reset tempX or tempY
if(choice==2) tempY--; //
if(choice==3) tempY++; //
}
// if there is an enemy in the new spot...
if(good) if(field[tempX][tempY]==2)
{
good=false; // it is not a good spot,
if(choice==0) tempX--; //
if(choice==1) tempX++; // and reset tempX or tempY
if(choice==2) tempY--; //
if(choice==3) tempY++; //
}
}while(!good); // continue to find points until a good point is found
//the unit CAN move to the tempX, tempY position
actionRange[1][tempX][tempY]=true;
moveSpots.add(new Point(tempX, tempY)); // left the unit know that it can move here
// subtract the terrains' movement penilty form the units remaining movement
i-=ter[tempX][tempY].getWalkDeduction();
}// - end i loop
addToRange(actionRange);
}// - end z loop
//////////////////////////
//find attack areas
//////////////////////////
for(int i=0;i<moveSpots.size();i++)
{
if(actionRangeFinal[1][(int)moveSpots.get(i).getX()][(int)moveSpots.get(i).getY()]==true)
{
int counter=0;
for(int j=0;j<items[0].range;j++)
{
for(int k=items[0].range-j;k>=0;k--)
{
try{actionRangeFinal[0][(int)moveSpots.get(i).getX()+k][(int)moveSpots.get(i).getY()]=true;} catch(Exception e) {}
try{actionRangeFinal[0][(int)moveSpots.get(i).getX()+k][(int)moveSpots.get(i).getY()]=true;} catch(Exception e) {}
try{actionRangeFinal[0][(int)moveSpots.get(i).getX()-k][(int)moveSpots.get(i).getY()]=true;} catch(Exception e) {}
try{actionRangeFinal[0][(int)moveSpots.get(i).getX()-k][(int)moveSpots.get(i).getY()]=true;} catch(Exception e) {}
counter++;
}
counter=0;
}
}
}
return actionRangeFinal;
}
public void addToRange(boolean[][][] oldRange)
{
for(int i=0;i<2;i++)
{
for(int j=0;j<FIELD_WIDTH;j++)
{
for(int k=0;k<FIELD_HEIGHT;k++)
{
if(oldRange[i][j][k])actionRangeFinal[i][j][k]=true;
}
}
}
}
I think that most of it is pretty well commented, if you have a question, please ask =]