Card Game of a 6x6 grid of carts played with pawns

39 Views Asked by At

I am trying to build a webpage app of a card game using html and javascript. The card deck is created and shuffled and split in red en green. Then the cards are placed in a 6x6 grid. In the game pawns can only be placed at certain valid points described in the code taking in account other pawns and revealed cards. But when the script is first run all four pawns seem to be placed at once because they dont take one other into account. Because when the game is played and a card is revealed resulting in the replcament of a pawn, the new replaced pawn does take the other pawns into account and when there no valid positions left it just deletes the pawn.

What i want is that the pawns are placed one by one so that they do take each other into account.

Invalid combinations when first run

Valid positions when game is played

This code snippet contains the function with the logic of the pawns:

let pawnPositions = [];
      let currentX = 1;
      let currentY = 1;
      function placePawns() {
  const deckContainer = document.getElementById('deck-container');
  let possiblePositions = [];

  for (let row = 0; row < 5; row++) {
    for (let col = 0; col < 5; col++) {
      const index = row * 6 + col;
      possiblePositions.push({ topLeftIndex: index, relatedIndices: [index, index + 1, index + 6, index + 7] });
    }
  }

  // Filter out positions where all related cards are unrevealed and not in unavailableCenterPoints
  possiblePositions = possiblePositions.filter(position =>
    position.relatedIndices.every(index =>
      !deck[index].revealed &&
      !pawnPositions.some(pawnPosition =>
        pawnPosition.relatedIndices.some(pawnIndex =>
          position.relatedIndices.includes(pawnIndex)
        )
      ) &&
      !unavailableCenterPoints.includes(index)
    )
  );

  for (let i = possiblePositions.length - 1; i > 0; i--) {
    const j = Math.floor(Math.random() * (i + 1));
    [possiblePositions[i], possiblePositions[j]] = [possiblePositions[j], possiblePositions[i]];
  }

  pawnPositions = pawnPositions.filter(position =>
    position.relatedIndices.every(index => !deck[index].revealed)
  );

  while (pawnPositions.length < 4 && possiblePositions.length > 0) {
    const newPosition = possiblePositions.shift();
    pawnPositions.push(newPosition);

    // Mark the center point and its corners as unavailable
    unavailableCenterPoints.push(newPosition.topLeftIndex);
    newPosition.relatedIndices.forEach(cornerIndex => unavailableCenterPoints.push(cornerIndex));
  }

  document.querySelectorAll('.pawn').forEach(pawn => pawn.remove());

  pawnPositions.forEach((position) => {
    const topLeftCard = deckContainer.querySelector(`.card[data-index="${position.topLeftIndex}"]`);
    const topRightCard = deckContainer.querySelector(`.card[data-index="${position.topLeftIndex + 1}"]`);
    const bottomLeftCard = deckContainer.querySelector(`.card[data-index="${position.topLeftIndex + 6}"]`);

    if (topLeftCard && topRightCard && bottomLeftCard) {
      const centerX = (topLeftCard.offsetLeft + topRightCard.offsetLeft + topRightCard.offsetWidth) / 2;
      const centerY = (topLeftCard.offsetTop + bottomLeftCard.offsetTop + bottomLeftCard.offsetHeight) / 2;

      const pawn = document.createElement('div');
      pawn.className = 'pawn';
      pawn.style.position = 'absolute';
      pawn.style.left = `${centerX}px`;
      pawn.style.top = `${centerY}px`;
      pawn.style.transform = 'translate(-50%, -50%)';

      deckContainer.appendChild(pawn);
    }
  });
}

I tried iterating through the pawns with the snippet under here but now it wont display any pawns:

function placePawns() {
  const deckContainer = document.getElementById('deck-container');
  let possiblePositions = [];

  // Generate all possible positions for pawns
  for (let row = 0; row < 5; row++) {
    for (let col = 0; col < 5; col++) {
      const index = row * 6 + col;
      possiblePositions.push({ topLeftIndex: index, relatedIndices: [index, index + 1, index + 6, index + 7] });
    }
  }

  // Shuffle possible positions to randomize pawn placement
  for (let i = possiblePositions.length - 1; i > 0; i--) {
    const j = Math.floor(Math.random() * (i + 1));
    [possiblePositions[i], possiblePositions[j]] = [possiblePositions[j], possiblePositions[i]];
  }

  // Clear previous pawns and unavailable center points
  document.querySelectorAll('.pawn').forEach(pawn => pawn.remove());
  unavailableCenterPoints = [];
  pawnPositions = [];

  // Attempt to place each pawn
  for (let i = 0; i < 4; i++) {
    let positionFound = false;
    while (!positionFound && possiblePositions.length > 0) {
      const newPosition = possiblePositions.shift();

      // Check if the newPosition conflicts with any existing pawns
      if (!doesConflict(newPosition)) {
        pawnPositions.push(newPosition);
        positionFound = true;
        // Mark the center point and its corners as unavailable
        unavailableCenterPoints.push(newPosition.topLeftIndex);
        newPosition.relatedIndices.forEach(cornerIndex => unavailableCenterPoints.push(cornerIndex));
      }
    }

    // If a position is not found, break the loop to avoid an infinite loop
    if (!positionFound) {
      console.warn('Could not place all pawns. Positions exhausted.');
      break;
    }
  }

  // Place the pawns in the found positions
  pawnPositions.forEach((position) => {
    const topLeftCard = deckContainer.querySelector(`.card[data-index="${position.topLeftIndex}"]`);
    const topRightCard = deckContainer.querySelector(`.card[data-index="${position.topLeftIndex + 1}"]`);
    const bottomLeftCard = deckContainer.querySelector(`.card[data-index="${position.topLeftIndex + 6}"]`);

    if (topLeftCard && topRightCard && bottomLeftCard) {
      const centerX = (topLeftCard.offsetLeft + topRightCard.offsetLeft + topRightCard.offsetWidth) / 2;
      const centerY = (topLeftCard.offsetTop + bottomLeftCard.offsetTop + bottomLeftCard.offsetHeight) / 2;

      const pawn = document.createElement('div');
      pawn.className = 'pawn';
      pawn.style.position = 'absolute';
      pawn.style.left = `${centerX}px`;
      pawn.style.top = `${centerY}px`;
      pawn.style.transform = 'translate(-50%, -50%)';

      deckContainer.appendChild(pawn);
    }
  });
}

// Helper function to check if the new position conflicts with existing pawns
function doesConflict(newPosition) {
  return pawnPositions.some(pawnPosition =>
    pawnPosition.relatedIndices.some(pawnIndex =>
      newPosition.relatedIndices.includes(pawnIndex)
    )
  );
}
0

There are 0 best solutions below