skip to Main Content

I try to work on nested arrays for space battle program.
For fleet fighting i write this:


//Roll a dice function
const randomNumber = (number) => {
    return Math.floor(Math.random() * number);
}


//Here we declare ships stats
// - 0 : Health
// - 1 : Damages
// - 2 : Chances to hit
// - 3 : Chances to be hit
//  - 4 (add by decideTargets function (line 100)) : Position of the target in enemy fleet

const vaisseaux = {
    frigate : [500, 200, 90, 50],
    heavyFrigate : [750, 300, 80, 25],
    cruiser : [1500, 500, 75, 15],
    attackCruiser : [750, 750, 80, 15],
    battleship : [3000, 1000, 70, 10]
}

/**
* Here we declare the composition of the fleet
*  - 0 : Friates
*  - 1 : Heavy Frigates
*  - 2 : Cruisers
*  - 3 : Attack Cruisers
*  - 4 : Battleships
*/
const fleet1 = [3, 3, 3, 3, 3];
const fleet2 = [10, 10, 10, 10, 10];

function fleetConstructor(fleet) {
    /**
     * Here, we build an array of ships in fleets.
     * It'll be a 2 dimentions array
     * ___________________________________________________________
     * |Frigates | HFrigates | Cruisers  | ACruisers  | BShip     |
     * |---------|-----------|-----------|------------|-----------|
     * |stats F1 | stats HF1 | stats C1  | stats AC1  | stats BS1 |
     * |stats F2 | stats HF2 | stats C2  | stats AC2  | stats BS2 |
     * |etc ...  | etc ...   | etc ...   | etc ...    | etc ...   |
     * 
     */
    
    const finalFleetArray = [[], [], [], [], []];

    for (let f = 0; f < fleet[0]; f++) {
        finalFleetArray[0].push(vaisseaux.frigate);
    }

    for (let f = 0; f < fleet[0]; f++) {
        finalFleetArray[1].push(vaisseaux.heavyFrigate);
    }

    for (let f = 0; f < fleet[0]; f++) {
        finalFleetArray[2].push(vaisseaux.cruiser);
    }

    for (let f = 0; f < fleet[0]; f++) {
        finalFleetArray[3].push(vaisseaux.attackCruiser);
    }

    for (let f = 0; f < fleet[0]; f++) {
        finalFleetArray[4].push(vaisseaux.battleship);
    }

    return finalFleetArray;
}

function decideTargets(firstFleet, secondFleet) {
    /**
     * Here we need to find distint target to every ships in fleets
     * Return fleet array
     */

    // i go throught ship types
    for(let i = 0; i < firstFleet.length; i++) {

        // j go throught each ship
        for (let j = 0; j < firstFleet[i].length; j++) {

            firstFleet[i][j].push([
                randomNumber(secondFleet.length - 1), 
                randomNumber(secondFleet[i].length - 1)
            ]);

        }
        
        console.log(firstFleet[i]);
    }
    return firstFleet;
}


/**
 * DEBUG
 */

//Building fleets
const attackerFleet = fleetConstructor(fleet1);
const defenderFleet = fleetConstructor(fleet2);


//Acquire targets
const finalCountdown = decideTargets(attackerFleet, defenderFleet);

My problem is that decideTargets function have the objective of finding unique random array each time. But the log display that :

[
  [ 500, 200, 90, 50, [ 3, 4 ], [ 2, 7 ], [ 1, 0 ] ],
  [ 500, 200, 90, 50, [ 3, 4 ], [ 2, 7 ], [ 1, 0 ] ],
  [ 500, 200, 90, 50, [ 3, 4 ], [ 2, 7 ], [ 1, 0 ] ]
]
[
  [ 750, 300, 80, 25, [ 1, 6 ], [ 2, 3 ], [ 2, 4 ] ],
  [ 750, 300, 80, 25, [ 1, 6 ], [ 2, 3 ], [ 2, 4 ] ],
  [ 750, 300, 80, 25, [ 1, 6 ], [ 2, 3 ], [ 2, 4 ] ]
]
[
  [ 1500, 500, 75, 15, [ 3, 8 ], [ 3, 8 ], [ 0, 8 ] ],
  [ 1500, 500, 75, 15, [ 3, 8 ], [ 3, 8 ], [ 0, 8 ] ],
  [ 1500, 500, 75, 15, [ 3, 8 ], [ 3, 8 ], [ 0, 8 ] ]
]
[
  [ 750, 750, 80, 15, [ 0, 0 ], [ 2, 6 ], [ 0, 7 ] ],
  [ 750, 750, 80, 15, [ 0, 0 ], [ 2, 6 ], [ 0, 7 ] ],
  [ 750, 750, 80, 15, [ 0, 0 ], [ 2, 6 ], [ 0, 7 ] ]
]
[
  [ 3000, 1000, 70, 10, [ 1, 4 ], [ 3, 8 ], [ 1, 4 ] ],
  [ 3000, 1000, 70, 10, [ 1, 4 ], [ 3, 8 ], [ 1, 4 ] ],
  [ 3000, 1000, 70, 10, [ 1, 4 ], [ 3, 8 ], [ 1, 4 ] ]
]


Each time the second for iterate, it push the random array for all j values.

I try to change the loops by while loops, change the second for loop by foreach. I also tried to separate the arrayArgument.push statement in an other function (and the double for loop call it)
I get the same result each time.

The array i want is :

[
  [ 500, 200, 90, 50, [ 3, 4 ] ],
  [ 500, 200, 90, 50, [ 2, 7 ] ],
  [ 500, 200, 90, 50, [ 1, 0 ] ]
]
[
  [ 750, 300, 80, 25, [ 1, 6 ] ],
  [ 750, 300, 80, 25, [ 2, 3 ] ],
  [ 750, 300, 80, 25, [ 2, 4 ] ]
]
[
  [ 1500, 500, 75, 15, [ 3, 8 ] ],
  [ 1500, 500, 75, 15, [ 4, 5 ] ],
  [ 1500, 500, 75, 15, [ 0, 8 ] ]
]
[
  [ 750, 750, 80, 15, [ 0, 0 ] ],
  [ 750, 750, 80, 15, [ 2, 6 ] ],
  [ 750, 750, 80, 15, [ 0, 7 ] ]
]
[
  [ 3000, 1000, 70, 10, [ 1, 4 ] ],
  [ 3000, 1000, 70, 10, [ 3, 8 ] ],
  [ 3000, 1000, 70, 10, [ 1, 4 ] ]
]

2

Answers


  1. I would not recommend mutating the original 3D matrix.

    Instead, you can map each plane, row, column to a new copy with modified columns.

    Note: I modified the randomNumber function to take a min and a max.

    const originalMatrix3d = [
      [[1,  2,  3,  4] , [1,  2,  3,  4] , [1,  2,  3,  4]],
      [[5,  6,  7,  8] , [5,  6,  7,  8] , [5,  6,  7,  8]],
      [[9, 10, 11, 12] , [9, 10, 11, 12] , [9, 10, 11, 12]]
    ];
    
    const updatedMatrix3d = decideTargets(originalMatrix3d);
    
    console.log(updatedMatrix3d.map(JSON.stringify));
    
    function decideTargets(matrix3d) {
      return matrix3d.map(function(plane) {
        return plane.map(function(row) {
          return [...row, [randomNumber(1, 20), randomNumber(1, 20)]]
        });
      })
    }
    
    // Roll a dice function
    function randomNumber(min, max) {
      if (arguments.length === 0) {
        throw new Error('You must supply a value');
      }
      if (arguments.length === 1) {
        max = min;
        min = 0;
      }
      return Math.floor(Math.random() * (max - min + 1)) + min;
    }
    .as-console-wrapper { top: 0; max-height: 100% !important; }
    Login or Signup to reply.
  2. The fix easy, instead

    arrayArgument[i][j].push([
        randomNumber(10),     
        randomNumber(10)
    ]);
    

    just write your random array at index 4:

    //push array of random
    arrayArgument[i][j][4] = [
        randomNumber(10), 
        randomNumber(10)
    ];
    
    const array = [
        [
            [1, 2, 3, 4],
            [1, 2, 3, 4],
            [1, 2, 3, 4]
        ],
        [
            [5, 6, 7, 8],
            [5, 6, 7, 8],
            [5, 6, 7, 8]
        ],
        [
            [9, 10, 11, 12],
            [9, 10, 11, 12],
            [9, 10, 11, 12]
        ],
    ];
    
    function decideTargets(arrayArgument) {
    
        // first loop
        for(let i = 0; i < arrayArgument.length; i++) {
    
            // second loop
            for (let j = 0; j < arrayArgument[i].length; j++) {
    
                //push array of random
                arrayArgument[i][j][4] = [
                    randomNumber(10), 
                    randomNumber(10)
                ];
                
            }
            
        }
        return arrayArgument;
    }
    
    //Roll a dice function
    const randomNumber = (number) => {
        return Math.floor(Math.random() * number);
    }
    
    const rollDice = () => console.log('rolling the dice') || decideTargets(array).map(array => console.log(JSON.stringify(array)));
    <button onclick="rollDice()">Roll Dice</button>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search