| name | create-game |
| description | Creates browser-based board games (Othello, Gomoku, Chess, etc.) with HTML/CSS/JS. Use when the user wants to create a new board game, implement game logic, or add AI opponents. |
| allowed-tools | Read, Write, Edit, Glob, Grep, Bash(python3 -m http.server*), Bash(open http://*) |
Board Game Creator Skill
ブラウザで動作するボードゲームを作成するためのスキルです。
概要
このスキルは以下のようなゲームの作成をサポートします:
- オセロ / リバーシ - 8x8ボード、石をひっくり返す
- 五目並べ / 連珠 - 15x15または19x19ボード、5つ並べたら勝ち
- 将棋 / チェス - 駒の移動、取り合い
- 囲碁 - 19x19ボード、陣地を囲む
- その他のボードゲーム - カスタムルール対応
ゲーム作成手順
1. 要件確認
ユーザーに以下を確認してください:
- ゲームの種類(オセロ、五目並べ、etc.)
- ボードサイズ(8x8、15x15、etc.)
- 対戦形式(プレイヤー vs CPU、2人対戦、etc.)
- AI の難易度(簡単、普通、難しい)
- 追加機能(アニメーション、サウンド、履歴、etc.)
2. ファイル構成
すべてのゲームは以下の構成で作成します:
games/<game-name>/
├── index.html # UI構造
├── script.js # ゲームロジック + AI
└── style.css # スタイリング
3. 参照サンプル
既存のサンプルを参照してください:
cat games/nike-othello/script.js
共通アーキテクチャ
HTML構造(必須要素)
<div class="container">
<h1>ゲーム名</h1>
<div class="game-info">
<div class="turn-display">
現在のターン: <span id="current-turn">...</span>
</div>
<div class="score-display">
</div>
</div>
<div id="board" class="board"></div>
<div id="message" class="message"></div>
<button id="reset-btn" class="reset-btn">リセット</button>
</div>
JavaScript クラス構造(必須メソッド)
class GameName {
constructor() {
this.board = [];
this.currentPlayer = 1;
this.gameOver = false;
this.init();
}
init() { }
renderBoard() { }
handleCellClick(row, col) { }
isValidMove(row, col, player) { }
getValidMoves(player) { }
makeMove(row, col, player) { }
switchTurn() { }
cpuMove() { }
selectBestMove(validMoves) { }
checkWinner() { }
endGame() { }
updateInfo() { }
showMessage(msg) { }
}
CSS共通スタイル
重要: 16:9アスペクト比対応
ゲームは配信用途で使用されるため、16:9の横長画面(1280x720) に収まるようにレイアウトを設計してください。
- 最大高さ: 720px以内 に収める
- 横長レイアウト: ボードが大きい場合は ボードを左、情報パネルを右 に配置
- コンパクト設計: 不要な余白を削減
* { margin: 0; padding: 0; box-sizing: border-box; }
body {
font-family: 'Hiragino Sans', 'Meiryo', sans-serif;
background: linear-gradient(135deg, #1a1a2e 0%, #16213e 100%);
min-height: 100vh;
display: flex;
justify-content: center;
align-items: center;
}
.container {
display: flex;
align-items: center;
gap: 30px;
}
.game-panel {
text-align: center;
display: flex;
flex-direction: column;
justify-content: center;
}
.board {
display: grid;
grid-template-columns: repeat(BOARD_SIZE, 1fr);
gap: 2px;
background: #333;
padding: 10px;
border-radius: 10px;
}
.cell {
width: 50px;
height: 50px;
background: #2e8b57;
display: flex;
justify-content: center;
align-items: center;
cursor: pointer;
}
ボードサイズ別の推奨セルサイズ
| ボードサイズ | 推奨セルサイズ | ボード全体の高さ |
|---|
| 8x8 (オセロ) | 50px | 約420px |
| 10x10 | 40px | 約420px |
| 15x15 (五目並べ) | 35px | 約545px |
| 19x19 (囲碁) | 30px | 約600px |
AI実装パターン
パターン1: 位置評価ベース(シンプル)
オセロのような「角が有利」なゲーム向け。
const POSITION_WEIGHTS = [
[100, -20, 10, ...],
[-20, -50, -2, ...],
];
selectBestMove(validMoves) {
let bestScore = -Infinity;
let bestMoves = [];
for (const move of validMoves) {
const score = POSITION_WEIGHTS[move.row][move.col];
if (score > bestScore) {
bestScore = score;
bestMoves = [move];
} else if (score === bestScore) {
bestMoves.push(move);
}
}
return bestMoves[Math.floor(Math.random() * bestMoves.length)];
}
パターン2: Minimax(中級)
先読みが必要なゲーム向け。
minimax(board, depth, isMaximizing, alpha, beta) {
if (depth === 0 || this.isGameOver(board)) {
return this.evaluate(board);
}
if (isMaximizing) {
let maxEval = -Infinity;
for (const move of this.getValidMoves(board, CPU)) {
const newBoard = this.applyMove(board, move, CPU);
const eval = this.minimax(newBoard, depth - 1, false, alpha, beta);
maxEval = Math.max(maxEval, eval);
alpha = Math.max(alpha, eval);
if (beta <= alpha) break;
}
return maxEval;
} else {
let minEval = Infinity;
for (const move of this.getValidMoves(board, PLAYER)) {
const newBoard = this.applyMove(board, move, PLAYER);
const eval = this.minimax(newBoard, depth - 1, true, alpha, beta);
minEval = Math.min(minEval, eval);
beta = Math.min(beta, eval);
if (beta <= alpha) break;
}
return minEval;
}
}
パターン3: パターンマッチング(五目並べ向け)
const PATTERNS = {
FIVE: /11111/,
OPEN_FOUR: /011110/,
FOUR: /11110|01111/,
OPEN_THREE: /01110/,
};
evaluateLine(line, player) {
const str = line.map(c => c === player ? '1' : c === 0 ? '0' : '2').join('');
if (PATTERNS.FIVE.test(str)) return 100000;
if (PATTERNS.OPEN_FOUR.test(str)) return 10000;
}
ゲーム別実装ガイド
詳細な実装ガイドは以下を参照:
テンプレート
すぐに使えるテンプレートファイル:
動作確認
作成したゲームの動作確認:
cd games/<game-name>
python3 -m http.server 8080
open http://localhost:8080
チェックリスト
ゲーム作成時の確認事項:
ゲーム一覧・レジストリへの登録
ゲーム作成後、以下の3箇所に新しいゲームを登録してください:
1. GameId 型の追加(src/types.ts)
export type GameId = "othello" | "gomoku" | ... | "<new-game>";
2. ゲームレジストリへの追加(src/games/game-registry.ts)
"<new-game>": {
id: "<new-game>",
name: "Game Name",
nameJa: "ゲーム名",
directory: "<new-game>",
controlMethod: "cell-click",
apiMethods: ["handleCellClick", "getGameState", "init"],
port: 8888,
},
3. ゲーム一覧ページへの追加(games/index.html)
.grid 内にカードを追加し、ホバーカラー用のCSSも追加する:
<a href="<new-game>/" class="card card-<new-game>">
<img src="icons/<icon>.png" alt="ゲーム名" class="card-icon">
<div class="card-name">ゲーム名</div>
<div class="card-desc">ゲームの簡単な説明</div>
</a>
4. ビルド確認
登録後に npm run build を実行して型エラーがないことを確認する。
アイコン作成
ゲーム一覧に表示するためのアイコンを作成します。generate-transparent-image スキルを使用してください。
要件
- 画風: ドットアート(ピクセルアート)スタイルで作成する
- 内容: そのゲームが何であるか一目でわかるデザインにする(例: オセロなら白黒の石、五目並べなら碁盤と石、倉庫番なら箱とキャラクター)
- 背景: 透過PNG として出力する
- 保存先:
games/<game-name>/icon.png
- サイズ: アスペクト比1:1、1024x1024 ピクセル
手順
generate-transparent-image スキルを呼び出す
- プロンプトにはゲームの特徴を示すモチーフと「pixel art style」を含める
- 生成された透過PNGを
games/<game-name>/icon.png として保存する