Newer
Older
2025-shino / card.js
const board = document.getElementById('board');
const moveInfo = document.getElementById('moveInfo');
const timerDisplay = document.getElementById('timer');
const startBtn = document.getElementById('startBtn');

let symbols = ["🍎", "🍌", "🍇", "🍒", "🍑", "🍉"];
let cards = [];
let openCards = [];
let matched = 0;
let moves = 0;
let timer = null;
let startTime = 0;
let running = false; // ゲームが動作中かどうか

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 = () => {
      if (running) 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) {
      stopTimer();
      setTimeout(() => {
        alert(`クリア!手数:${moves} 時間:${timerDisplay.textContent} 秒`);
      }, 300);
    }
  } else {
    cards[a].open = cards[b].open = false;
  }
  render();
  openCards = [];
}

function resetGame() {
  stopTimer();
  timerDisplay.textContent = "0.0";
  running = false;
  startBtn.disabled = false;
  initGame();
}

function startGame() {
  if (running) return;
  running = true;
  startBtn.disabled = true;
  startTime = Date.now();
  timer = setInterval(() => {
    const now = Date.now();
    const elapsed = ((now - startTime) / 1000).toFixed(1);
    timerDisplay.textContent = elapsed;
  }, 100);
  initGame();
}

function stopTimer() {
  clearInterval(timer);
  running = false;
  startBtn.disabled = false;
}

startBtn.addEventListener('click', startGame);

initGame(); // 初期描画だけ