Prevent Value Collision in JavaScript

137 views Asked by At

I'm attempting to update the "position" key of each object in the shipArray variable. The goal is to have each position array contain unique values and a length == shipLength of that object. However, this code results in duplicate values being generated on some runs. Any help solving this would be greatly appreciated.

// Array of objects
const shipArray = [
  {
    name: "first ship",
    shipLength: 5,
    position: []
  },
  {
    name: "second ship",
    shipLength: 4,
    position: []
  },
  {
    name: "third ship",
    shipLength: 3,
    position: []
  },
  {
    name: "fourth ship",
    shipLength: 3,
    position: []
  },
  {
    name: "fifth ship",
    shipLength: 2,
    position: []
  },
];

// Generates an array of numbers satisfying the conditions therein.
const createShip = (length) => {
  const directionArray = ["horizontal", "vertical"];
  let direction = directionArray[Math.floor(Math.random() * 2)];
  const num = Math.floor(Math.random() * 100);
  const posArray = []
  for (let i = 0; i < length; i++) {
    if (direction == "vertical" && ((num + (length * 10)) <= 99)) {
      posArray.push(num + (i * 10));
    } else if (direction == "vertical" && ((num + (length * 10)) >= 99)) {
      const newNum = (num - 40);
      posArray.push(newNum + (i * 10));
    } else if (direction == "horizontal" && ((num % 10) <= length)) {
      posArray.push(num + i);
    } else if (direction == "horizontal" && ((num % 10) >= length)) {
      const newNum = (num - (length - 1));
      posArray.push(newNum + i);
    }
  }
  return posArray;
}

// Should theoretically prevent duplicate positions 
const noShipCollision = (array, position) => {
  for (let i = 0; i < array.length; i++) {
    let vessel = array[i];
    for (let j = 0; j < position.length; j++) {
      if (vessel.position.indexOf(position[j]) >= 0) {
        return false;
      }
    }
  }
  return true;
}

// Returns an updated array of objects
const populateBoard = (shipObjectsArray) => {
  // Iterates over array of ship objects
  let ship;

  for (let i = 0; i < shipObjectsArray.length; i++) {
    do {
      ship = createShip(shipObjectsArray[i].shipLength);
    } while (!noShipCollision(shipObjectsArray, shipObjectsArray[i].position))
    shipObjectsArray[i].position = ship;
  }
  return shipObjectsArray;
}
console.log(populateBoard(shipArray));
0

There are 0 answers