対戦結果をピクセルアートにできる「オセロdeアート」

@ハクト 2025-06-12 10:25:10に投稿

CPUと対戦できるオセロゲームで、ゲーム終了後にオセロの結果を128×128ピクセルアートに変換してダウンロードできるツールを作成しました。

戦略的なゲームプレイの結果が、抽象的でユニークなピクセルアート作品に生まれ変わります。

オセロdeアートのスクリーンショット

オセロdeアート

 

上記の結果として以下のようなモダン?ピクセルアートがダウンロードできます。

ファイル構成

othello-pixel-art/
├── index.html          # HTMLマークアップ・ダイアログUI
├── style.css           # CSSスタイル・レスポンシブデザイン
├── script.js           # ゲームロジック・ピクセルアート生成
├── README.md           # プロジェクト説明

技術仕様

  • HTML5, CSS3, Vanilla JavaScript

  • HTML5 Canvas(ピクセルアート生成)

  • CSS Grid Layout(8×8オセロボード)

  • Color Picker API(カラーカスタマイズ)

ピクセルアートの特徴

  • 固定128×128ピクセル: モダンアートに適したミニマルサイズ

  • 16×16ピクセルブロック: 8×8オセロマスを1:2の比率で表現

  • 条件描画: ボード満杯時は空白マスを透明化して美しい仕上がり

  • カラーカスタマイズ: RGB全色対応のカラーピッカー

  • タイムスタンプファイル名: 自動で重複回避されたファイル名

使い方

基本操作

  • ゲームプレイ: 黒(プレイヤー)のターンで有効な位置をクリック

  • CPU対戦: ランダムAIが自動で白の石を配置

  • ピクセルアート変換: ゲーム終了後に「ピクセルアートに変換」をクリック

  • 色彩カスタマイズ: カラーピッカーで黒駒・白駒・空白マスの色を調整

  • ダウンロード: 128×128ピクセルのPNG画像として保存

ゲームの流れ

  • 8×8のオセロボードでCPUと対戦

  • 両プレイヤーが打てる手がなくなるまでプレイ

  • ゲーム終了後にピクセルアート変換オプションを選択

  • カラーピッカーで作品の色彩をカスタマイズ

  • プレビューを確認してからダウンロード

実装のポイント解説

1. オセロゲームロジック

8方向の駒ひっくり返し処理を効率的に実装

JavaScript実装:

/**
 * 指定方向への駒のひっくり返し判定
 * @param {number} row - 配置予定の行
 * @param {number} col - 配置予定の列
 * @param {number} dr - 行方向の増分(-1, 0, 1)
 * @param {number} dc - 列方向の増分(-1, 0, 1)
 * @param {string} player - プレイヤー('black' or 'white')
 */
canFlipInDirection(row, col, dr, dc, player) {
    const opponent = player === 'black' ? 'white' : 'black';
    let r = row + dr;
    let c = col + dc;
    let hasOpponentPiece = false;
    
    // 指定方向に向かって駒をチェック
    while (r >= 0 && r < this.boardSize && c >= 0 && c < this.boardSize) {
        if (this.board[r][c] === null) {
            return false; // 空白マスで中断
        } else if (this.board[r][c] === opponent) {
            hasOpponentPiece = true; // 相手の駒を発見
        } else if (this.board[r][c] === player) {
            return hasOpponentPiece; // 自分の駒で挟めるかチェック
        }
        r += dr;
        c += dc;
    }
    
    return false;
}

/**
 * 8方向の有効手判定
 * オセロの基本ルール:相手の駒を挟める位置のみ有効
 */
isValidMove(row, col, player) {
    if (this.board[row][col] !== null) return false;
    
    const directions = [
        [-1, -1], [-1, 0], [-1, 1],  // 上方向3パターン
        [0, -1],           [0, 1],   // 左右方向
        [1, -1],  [1, 0],  [1, 1]    // 下方向3パターン
    ];
    
    // いずれかの方向で駒をひっくり返せれば有効手
    for (let [dr, dc] of directions) {
        if (this.canFlipInDirection(row, col, dr, dc, player)) {
            return true;
        }
    }
    
    return false;
}

2. ピクセルアート生成

オセロボード(8×8)を128×128ピクセルのモダンアート作品に変換

Canvas実装:

/**
 * カスタムカラーでピクセルアート生成
 * @param {string} blackColor - 黒駒の色(例: '#1e1e2e')
 * @param {string} whiteColor - 白駒の色(例: '#f0f0f0')
 * @param {string} greenColor - 空白マスの色(例: '#4ade80')
 */
generatePixelArtWithColors(blackColor, whiteColor, greenColor = '#4ade80') {
    const canvas = document.getElementById('pixel-canvas');
    const ctx = canvas.getContext('2d');
    const pixelSize = 16; // 128÷8 = 16ピクセル/マス
    
    // 固定128×128ピクセルでキャンバス設定
    canvas.width = 128;
    canvas.height = 128;
    
    // 元のボード状態を使用(色変更時の整合性保持)
    const boardToUse = this.originalBoard || this.board;
    
    // ボード満杯チェック(空白マス描画制御用)
    let totalPieces = 0;
    for (let row = 0; row < this.boardSize; row++) {
        for (let col = 0; col < this.boardSize; col++) {
            if (boardToUse[row][col]) totalPieces++;
        }
    }
    const isBoardFull = totalPieces === 64;
    
    // 8×8マスを16×16ピクセルブロックで描画
    for (let row = 0; row < this.boardSize; row++) {
        for (let col = 0; col < this.boardSize; col++) {
            const x = col * pixelSize;
            const y = row * pixelSize;
            
            if (boardToUse[row][col] === 'black') {
                ctx.fillStyle = blackColor;
                ctx.fillRect(x, y, pixelSize, pixelSize);
            } else if (boardToUse[row][col] === 'white') {
                ctx.fillStyle = whiteColor;
                ctx.fillRect(x, y, pixelSize, pixelSize);
            } else {
                // 空白マス:満杯でない場合のみ緑色描画
                if (!isBoardFull) {
                    ctx.fillStyle = greenColor;
                    ctx.fillRect(x, y, pixelSize, pixelSize);
                }
                // 満杯時は透明(未描画)で美しい仕上がり
            }
        }
    }
}

3. 条件付きカラーピッカー表示

ボード状態に応じて不要なカラーピッカーを自動非表示

JavaScript制御:

/**
 * ボード状態に応じたカラーピッカーUI制御
 * 効率的なユーザー体験を提供
 */
convertToPixelArt() {
    // ボード駒数を分析
    let blackCount = 0;
    let whiteCount = 0;
    let totalPieces = 0;
    
    for (let row = 0; row < this.boardSize; row++) {
        for (let col = 0; col < this.boardSize; col++) {
            if (this.board[row][col] === 'black') blackCount++;
            else if (this.board[row][col] === 'white') whiteCount++;
            if (this.board[row][col]) totalPieces++;
        }
    }
    
    const isBoardFull = totalPieces === 64;
    const isBlackOnly = blackCount > 0 && whiteCount === 0;
    const isWhiteOnly = whiteCount > 0 && blackCount === 0;
    
    // UI要素を取得
    const blackColorGroup = document.querySelector('#black-color-picker').parentElement;
    const whiteColorGroup = document.querySelector('#white-color-picker').parentElement;
    const greenColorGroup = document.querySelector('#green-color-picker').parentElement;
    
    // 条件付き表示制御
    // 白一色ボード  黒駒カラーピッカーを非表示
    if (isWhiteOnly) {
        blackColorGroup.style.display = 'none';
    } else {
        blackColorGroup.style.display = 'flex';
    }
    
    // 黒一色ボード  白駒カラーピッカーを非表示
    if (isBlackOnly) {
        whiteColorGroup.style.display = 'none';
    } else {
        whiteColorGroup.style.display = 'flex';
    }
    
    // 満杯ボード  空白マスカラーピッカーを非表示
    if (isBoardFull) {
        greenColorGroup.style.display = 'none';
    } else {
        greenColorGroup.style.display = 'flex';
    }
    
    // ピクセルアート生成とダイアログ表示
    this.generatePixelArt();
    document.getElementById('pixel-art-dialog').style.display = 'flex';
}

まとめ

ふとオセロの結果がなにかの模様にならないかなと思い作ったツールです。

強引にモダンなピクセルアート作品に生まれ変わるという意味付けをしましたw

ユニークなピクセルアート作ってみてください。

@ハクト

サービス作り・デザイン好き。70年代生まれのWEBエンジニア。WEBパーツをCSSでカスタマイズしてコピペできるサービスを運営中「Pa-tu」。実装したWEBパーツやツールを利用してWEB情報やライフハックを発信してます。

Twitter