Newer
Older
2025-shino / card.js
const board = document.getElementById('board');
const moveInfo = document.getElementById('moveInfo');
let symbols = ["🍎", "🍌", "🍇", "🍒", "🍑", "🍉"];
let cards = [];
let openCards = [];
let matched = 0;
let moves = 0;

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

function initGame() {
  cards = [];
  openCards = [];
  matched = 0;
  moves = 0;
  moveInfo.textContent = `手数: 0`;
  let allSymbols = symbols.concat(symbols);
  shuffle(allSymbols);
  for (let i = 0; i < 12; i++) {
    cards.push({ symbol: allSymbols[i], open: false, matched: false });
  }
  render();
}

function render() {
  board.innerHTML = "";
  cards.forEach((card, i) => {
    let div = document.createElement("div");
    div.className = "card";
    if (card.open || card.matched) div.classList.add(card.matched ? 'matched' : 'open');
    div.textContent = (card.open || card.matched) ? card.symbol : "";
    div.onclick = () => openCard(i);
    board.appendChild(div);
  });
}

function openCard(idx) {
  if (cards[idx].open || cards[idx].matched || openCards.length >= 2) return;
  cards[idx].open = true;
  openCards.push(idx);
  render();
  if (openCards.length === 2) {
    moves++;
    moveInfo.textContent = `手数: ${moves}`;
    setTimeout(checkMatch, 700);
  }
}

function checkMatch() {
  let [a, b] = openCards;
  if (cards[a].symbol === cards[b].symbol) {
    cards[a].matched = cards[b].matched = true;
    matched += 2;
    if (matched === cards.length) {
      setTimeout(() => alert(`クリア!手数: ${moves}`), 300);
    }
  } else {
    cards[a].open = cards[b].open = false;
  }
  render();
  openCards = [];
}

window.initGame = initGame;
initGame();