0
function genEnemy(a) {
 //javascript:alert(en[0]+'\n'+genEnemy(en[0])+'\n'+en[0])
 with (Math) {
  a[1]=round(a[1]*(.5+random()))
  a[2]=round(a[2]*(1+random()))
  for (var b=0;b<5;b++) a[3][b]=round(a[3][b]*(a[3][b]/2+random()*a[3][b]/10))
  for (var b=0;b<a[4].length;b++) random()<it[a[4][b]][3]/10?a[4][b]=0:0
  }
 return a
 }

Script to generate an enemy's stats given the bases each enemy array. (RPG game) The problem is, when I am expecting it to return an array containing the new stats, it also sets the enemy array to the new one. Why is this? Obviously you can see how problems are caused by this (the bases being changed so a weak enemy can become uber powerful). How would I stop it from setting the array in en (array of enemy values)?

Anonymous
  • 1,823
  • 7
  • 23
  • 29
  • 2
    I'm not following what you want it to do, your variable names make it hard to decode your code based o the description. – Nick Craver Nov 15 '10 at 00:11
  • 2
    `with (Obj)` can be dangerous, make sure you read [this](http://stackoverflow.com/questions/61088/hidden-features-of-javascript#61118). – alex Nov 15 '10 at 00:26

2 Answers2

6

Objects are passed by reference in JavaScript. That means any changes you make to the array a inside genEnemy is reflected on the original array that was passed in. You need to make a deep copy of the array and return this copy. Here is a function that will do it for you:

function cloneArray(a) {
  var b = [];
  for (var i = 0; i < a.length; i++)
    if (a[i] instanceof Array)
      b[i] = cloneArray(a[i]);
    else
      b[i] = a[i];
  return b;
}

Inside genEnemy, you would then do:

a = cloneArray(a);
// make changes to the new array
return a;

Also, don't forget to include semicolons in your code. Even though they are optional, you may run into unexpected problems if you get into the habit of omitting them.

casablanca
  • 69,683
  • 7
  • 133
  • 150
  • Is there a way to do this without another function? I just hate adding functions for little things. – Anonymous Nov 15 '10 at 00:26
  • @Ruffian Take out the function body and run it procedurally and you don't have a function :P But remember turning often used and useful code into a function is a good thing. – alex Nov 15 '10 at 00:27
  • @Ruffian: If there was a built-in function, I would have definitely suggested that. Unfortunately there isn't. – casablanca Nov 15 '10 at 00:48
  • Meh. I'll just take out the genEnemy function and find a way to put it into a larger function to set up the whole fight. Thanks anyway. – Anonymous Nov 15 '10 at 00:51
  • 1
    @Ruffian be careful with that thinking - Abstraction into separate functions is a _good_ thing! – alternative Nov 15 '10 at 01:32
  • @mathepic: +1, I don't know why he actually *doesn't* want to use functions. – casablanca Nov 15 '10 at 01:40
  • Because unnecessary functions for every little thing aren't necessary. And I don't use other peoples' scripts. Reason: this does the same thing and is smaller: function arrayValue(a) { var b=new Array(a.length) for (var c=0;c – Anonymous Nov 15 '10 at 22:39
  • @Ruffian: That will only copy the array one level deep. In your example, you have a two-dimensional array (you have used `a[3][b]` etc.) and to properly copy the inner dimensions, you need a recursive call. – casablanca Nov 16 '10 at 00:33
0

Are you passing array en to your getEnemy() function? If so then it will change the values in en array as it's passed by reference not by value

MSI
  • 1,124
  • 8
  • 23