Vue.jsでスライドパズルゲームを作る

Vue.jsで作成された単純なスライドパズルゲームのコードです。
このゲームは、4x4のマトリックス上に表示される15枚のピースを並び替えて、最後に1枚のピースが空白の場所に移動するようにするものです。
<template>
<div>
<div class="grid" :style="{ gridTemplateColumns: `repeat(${gridSize}, 1fr)` }">
<div v-for="(tile, index) in tiles" :key="index" :class="{ tile: true, empty: tile === gridSize }" :style="{ gridColumn: `span ${tileSize}`, gridRow: `span ${tileSize}` }" @click="moveTile(index)">
{{ tile }}
</div>
</div>
<div class="controls">
<button @click="shuffleTiles">Shuffle</button>
<button @click="solvePuzzle">Solve</button>
<span>Moves: {{ moves }}</span>
</div>
</div>
</template>
<script>
export default {
data() {
return {
gridSize: 4,
tileSize: 4,
tiles: [],
moves: 0,
}
},
mounted() {
this.initializeTiles()
},
methods: {
initializeTiles() {
this.tiles = [...Array(this.gridSize * this.gridSize - 1).keys()].map(i => i + 1)
this.tiles.push(this.gridSize * this.gridSize)
},
shuffleTiles() {
for (let i = this.tiles.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[this.tiles[i], this.tiles[j]] = [this.tiles[j], this.tiles[i]];
}
this.moves = 0
},
solvePuzzle() {
this.tiles = [...Array(this.gridSize * this.gridSize - 1).keys()].map(i => i + 1)
this.tiles.push(this.gridSize * this.gridSize)
this.moves = 0
},
moveTile(index) {
if (this.tiles[index] !== this.gridSize) {
const emptyIndex = this.tiles.indexOf(this.gridSize)
const rowIndex = Math.floor(index / this.gridSize)
const emptyRowIndex = Math.floor(emptyIndex / this.gridSize)
if (rowIndex === emptyRowIndex) {
const colIndex = index % this.gridSize
const emptyColIndex = emptyIndex % this.gridSize
if (Math.abs(colIndex - emptyColIndex) === 1) {
[this.tiles[index], this.tiles[emptyIndex]] = [this.tiles[emptyIndex], this.tiles[index]]
this.moves++
}
} else if (Math.abs(rowIndex - emptyRowIndex) === 1) {
const colIndex = index % this.gridSize
const emptyColIndex = emptyIndex % this.gridSize
if (colIndex === emptyColIndex) {
[this.tiles[index], this.tiles[emptyIndex]] = [this.tiles[emptyIndex], this.tiles[index]]
this.moves++
}
}
}
},
},
}
</script>
<style scoped>
.tile {
display: flex;
align-items: center;
justify-content: center;
border: 1px solid #000;
font-size: 2rem;
font-weight: bold;
cursor: pointer;
}
.empty {
visibility: hidden;
}
.grid {
display: grid;
grid-template-rows: repeat(4, 1fr);
grid-gap: 2px;
margin: 20px 0;
}
.controls {
display: flex;
justify-content: space-between;
align-items: center;
margin-top: 20px;
}
button {
background-color: #4CAF50;
color: white;
padding: 10px 20px;
border: none;
border-radius: 4px;
cursor: pointer;
font-size: 1rem;
}
</style>
このコードでは、Vue.jsを使用して、スライドパズルゲームの各部分をコンポーネントに分割しています。単純なコンポーネントである `Tile` は、スライドパズルの各タイルを表示するために使用されます。
これは、カーソルがタイルの上にあるときにクリック可能で、空白の場所に移動できるようにするためです。
Vue.jsのコンポーネントは、データ、テンプレート、メソッド、およびスタイルの4つのセクションで構成されています。上記のコードでは、次のようにコンポーネントを定義しています。
- `data`: `gridSize`、 `tileSize`、 `tiles`、および `moves`の4つのプロパティを定義します。
`gridSize`はマトリックスのサイズ、`tileSize`は各タイルのサイズ、`tiles`はタイルの配列、`moves`はプレイヤーの動きの数を追跡するために使用されます。
- `mounted`: Vue.jsのライフサイクルフックで、コンポーネントがマウントされた後に `initializeTiles` メソッドを呼び出します。
- `methods`: `initializeTiles`、 `shuffleTiles`、 `solvePuzzle`、および `moveTile` の4つのメソッドを定義します。
`initializeTiles` は、マトリックスを初期化し、 `shuffleTiles` は、ランダムなタイル配列でマトリックスをシャッフルします。
`solvePuzzle` は、プレイヤーがゲームを解決するために使用することができる「解決」ボタンを実装します。
`moveTile` は、プレイヤーがタイルを移動するときに呼び出されます。
- `template`: ゲームを表示するために使用されます。 `grid` クラスは、 `gridSize` に応じてグリッドを設定し、 `tiles` 配列の各値を使用してタイルをレンダリングします。 `controls` セクションには、「新しいゲーム」ボタン、moves を表示する p タグ、そして「解決」ボタンが含まれています。
最後に、JavaScriptの shuffle メソッドを使用して、初期化されたタイル配列をシャッフルします。