<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>日本の山県ピンゲーム</title>
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.7.1/dist/leaflet.css" />
<script src="https://unpkg.com/leaflet@1.7.1/dist/leaflet.js"></script>
<style>
body { font-family: Arial, sans-serif; margin: 0; padding: 20px; }
#map { height: 70vh; border: 2px solid #ddd; border-radius: 10px; }
#info, #timer { margin-bottom: 15px; font-size: 18px; }
#remaining { font-weight: bold; color: #007bff; }
.correct-marker, .wrong-marker {
display: flex;
justify-content: center;
align-items: center;
width: 30px;
height: 30px;
border-radius: 50%;
font-size: 20px;
font-weight: bold;
color: white;
}
.correct-marker { background-color: #28a745; }
.wrong-marker { background-color: #dc3545; }
</style>
</head>
<body>
<div id="info">山が名前に含まれる県にピンを打ってください。残り: <span id="remaining"></span></div>
<div id="timer">経過時間: 0分0秒</div>
<div id="map"></div>
<script>
const mountainPrefectures = [
{name: "山形県", lat: 38.2404, lon: 140.3633},
{name: "山梨県", lat: 35.6639, lon: 138.6388},
{name: "岡山県", lat: 34.6618, lon: 133.9344},
{name: "山口県", lat: 34.1859, lon: 131.4706},
{name: "富山県", lat: 36.6958, lon: 137.2137},
{name: "和歌山県", lat: 34.2261, lon: 135.1675}
];
const map = L.map('map', {
center: [36.2048, 138.2529],
zoom: 5,
minZoom: 5,
maxZoom: 7,
maxBounds: L.latLngBounds(L.latLng(20, 122), L.latLng(46, 154))
});
L.tileLayer('https://stamen-tiles-{s}.a.ssl.fastly.net/toner-lite/{z}/{x}/{y}{r}.png', {
attribution: 'Map tiles by Stamen Design, CC BY 3.0 — Map data © OpenStreetMap contributors',
subdomains: 'abcd',
}).addTo(map);
let remainingPrefectures = [...mountainPrefectures];
let startTime = Date.now();
let penaltyTime = 0;
updateRemaining();
updateTimer();
const timerInterval = setInterval(updateTimer, 1000);
map.on('click', function(e) {
const clickedLat = e.latlng.lat;
const clickedLon = e.latlng.lng;
let correctPin = false;
for (let i = 0; i < remainingPrefectures.length; i++) {
const pref = remainingPrefectures[i];
if (Math.abs(clickedLat - pref.lat) < 0.5 && Math.abs(clickedLon - pref.lon) < 0.5) {
L.marker([pref.lat, pref.lon], {icon: L.divIcon({className: 'correct-marker', html: '✓'})})
.addTo(map).bindPopup(pref.name).openPopup();
remainingPrefectures.splice(i, 1);
updateRemaining();
correctPin = true;
break;
}
}
if (!correctPin) {
penaltyTime += 10000;
L.marker([clickedLat, clickedLon], {icon: L.divIcon({className: 'wrong-marker', html: '✗'})})
.addTo(map).bindPopup("不正解!10秒ペナルティ").openPopup();
setTimeout(() => map.closePopup(), 2000);
}
if (remainingPrefectures.length === 0) {
clearInterval(timerInterval);
const totalTime = Math.floor((Date.now() - startTime + penaltyTime) / 1000);
const minutes = Math.floor(totalTime / 60);
const seconds = totalTime % 60;
alert(`クリア!総プレイ時間: ${minutes}分${seconds}秒`);
}
});
function updateRemaining() {
document.getElementById('remaining').textContent = remainingPrefectures.length;
}
function updateTimer() {
const elapsedTime = Math.floor((Date.now() - startTime + penaltyTime) / 1000);
const minutes = Math.floor(elapsedTime / 60);
const seconds = elapsedTime % 60;
document.getElementById('timer').textContent = `経過時間: ${minutes}分${seconds}秒`;
}
</script>
</body>
</html>