オセロビンゴ(開発中)携帯に対応1 まだただのオセロ
オセロ・ビンゴゲーム
サンプルコード
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>オセロ・ビンゴゲーム</title>
<style>
#gameBoard {
/* ゲームボードのスタイリング */
margin-top: 20px;
/* 上部に余白を追加 */
margin-bottom: 80px;
/* ボタンの高さとマージンを考慮した下部の余白 */
/* その他のスタイル設定 */
}
#rouletteResult {
/* ルーレット結果表示部のスタイリング */
margin-bottom: 80px;
/* ボタンの高さとマージンを考慮した余白 */
/* その他のスタイル設定 */
}
#newButton,
#rouletteButton {
position: absolute;
bottom: -30px;
/* .boardの外に配置 */
/* ボタンの高さを考慮して適切に調整 */
}
#newButton {
left: 0;
}
#rouletteButton {
right: 0;
}
#rouletteResult {
/* ルーレット結果表示部のスタイリング */
margin-top: 60px;
/* ボタンの分だけ余白を調整 */
}
body {
position: relative;
margin: 0;
min-height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
justify-content: flex-start;
padding-bottom: 100px;
/* ボタンとそのマージンを考慮した下部の余白 */
padding-top: 20px;
/* 上部の余白 */
}
.cell::after {
content: attr(data-bingoNumber);
/* 修正:data-numberからdata-bingoNumberに */
color: rgb(133, 173, 255);
font-size: 25px;
position: absolute;
left: 5px;
top: 5px;
}
.board {
position: relative;
/* これを追加 */
width: min(100vw, 100vh);
/* ビューポートの短い側に合わせてボードのサイズを設定 */
height: min(100vw, 100vh);
/* ビューポートの短い側に合わせてボードのサイズを設定 */
display: grid;
grid-template-columns: repeat(8, 1fr);
/* 8つの等しい列を設定 */
grid-template-rows: repeat(8, 1fr);
/* 8つの等しい行を設定 */
gap: 4px;
margin: 20px auto;
/* 上下に20pxの余白を追加し、左右は中央寄せ */
background-color: #008000;
border: 2px solid black;
padding: 2px;
}
.cell {
width: calc((100% - (7 * 1px)));
height: calc((100% - (7 * 1px)));
background-color: green;
position: relative;
display: flex;
align-items: center;
justify-content: center;
border: 1px solid black;
z-index: 1;
}
.cell.marked {
background-color: rgba(0, 191, 255, 0.5);
/* 光った青色 */
border-color: rgba(0, 191, 255, 1);
/* より濃い青色の枠 */
}
.piece {
width: 80%;
height: 80%;
border-radius: 50%;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
.black {
background-color: black;
}
.white {
background-color: white;
}
@media screen and (max-width: 00px) {
.board {
/* gap, margin, border, paddingを考慮したサイズ調整 */
width: calc(min(100vw, 100vh) - 4px - 4px - 4px - 2px * 2);
height: calc(min(100vw, 100vh) - 4px - 4px - 4px - 2px * 2);
/* ここで、4pxはgap, 4pxは左右のmargin, 2px * 2はborderの幅です */
display: grid;
grid-template-columns: repeat(8, 1fr);
grid-template-rows: repeat(8, 1fr);
gap: 4px;
margin: 2px auto;
background-color: #008000;
border: 2px solid black;
padding: 2px;
/* 最大幅と最大高さを設定してはみ出しを防ぐ */
max-width: calc(100vw - 4px - 4px);
max-height: calc(100vh - 4px - 4px);
/* ここで、4pxは左右のmarginの合計です */
}
}
</style>
</head>
<body>
<div id="gameBoard" class="board">
<button id="newButton">新規ボタン</button> <!-- `.board`内に移動 -->
<button id="rouletteButton">ルーレット</button> <!-- `.board`内に移動 -->
</div>
<div id="rouletteResult"></div>
<script>
document.addEventListener('DOMContentLoaded', () => {
let rouletteInterval; // ルーレットのタイマーIDを保持する変数
const rouletteDelay = 300; // ルーレットが自動で回る間隔(ミリ秒)
const boardSize = 8;
const board = document.getElementById('gameBoard');
let boardState = [];
let currentPlayer = 'black';
// オセロの初期化関数
function initBoard() {
const bingoNumbers = [...Array(boardSize * boardSize).keys()].map(x => x + 1);
shuffleArray(bingoNumbers); // ビンゴ番号をシャッフル
for (let i = 0; i < boardSize; i++) {
boardState[i] = [];
for (let j = 0; j < boardSize; j++) {
const cell = document.createElement('div');
cell.className = 'cell';
cell.dataset.row = i;
cell.dataset.col = j;
cell.dataset.bingoNumber = bingoNumbers[i * boardSize + j]; // シャッフルされたビンゴ番号を割り当てる
cell.addEventListener('click', () => handleCellClick(i, j));
board.appendChild(cell);
boardState[i][j] = null;
}
}
// オセロの標準的な開始配置
const midPoint = Math.floor(boardSize / 2);
boardState[midPoint - 1][midPoint - 1] = 'white';
boardState[midPoint][midPoint] = 'white';
boardState[midPoint - 1][midPoint] = 'black';
boardState[midPoint][midPoint - 1] = 'black';
updateBoard();
//startTurn(); // ゲーム開始時に1ターン目を開始
}
// 1ターンを開始する関数
function startTurn() {
startRoulette(); // ルーレットを開始
// ルーレットが終了するまで待機してからAIの手を実行
setTimeout(() => {
aiMove();
}, rouletteDelay);
}
// 配列をシャッフルする関数
function shuffleArray(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]];
}
}
// AIが手を実行する関数
function aiMove() {
let legalMoves = getLegalMoves('white'); // AIは白と仮定します
if (legalMoves.length > 0) {
let randomIndex = Math.floor(Math.random() * legalMoves.length);
let move = legalMoves[randomIndex];
boardState[move.row][move.col] = 'white'; // 駒を置く
flipPieces(move.row, move.col, 'white'); // 駒を反転させる
updateBoard(); // 盤面を更新
}
switchPlayer(); // プレイヤーを切り替える
}
// 指定した色が置けるかどうかを確認する関数
function canPlacePiece(row, col, color) {
if (boardState[row][col] !== null) return false; // 既に駒がある場合は置けない
const opponentColor = color === 'black' ? 'white' : 'black';
const directions = [
[0, 1], [1, 1], [1, 0], [1, -1],
[0, -1], [-1, -1], [-1, 0], [-1, 1]
]; // 8方向を表す
return directions.some(([dRow, dCol]) =>
hasFlippablePieces(row, col, dRow, dCol, color, opponentColor)
);
}
// 指定した方向に反転可能な駒があるかどうかを確認する関数
function hasFlippablePieces(row, col, dRow, dCol, color, opponentColor) {
let r = row + dRow;
let c = col + dCol;
let hasOpponent = false;
while (r >= 0 && r < boardSize && c >= 0 && c < boardSize) {
if (boardState[r][c] === opponentColor) {
hasOpponent = true; // 相手の駒を見つけた
} else if (boardState[r][c] === color && hasOpponent) {
return true; // 自分の色に戻った場合、かつ一つ以上の相手の駒を挟んでいればtrue
} else {
return false; // 空のセルにぶつかった、または相手の駒を挟んでいない
}
r += dRow;
c += dCol;
}
return false; // 盤外に出たか、条件を満たさない場合
}
// 駒を反転させる関数
function flipPieces(row, col, color) {
const opponentColor = color === 'black' ? 'white' : 'black';
const directions = [
[0, 1], [1, 1], [1, 0], [1, -1],
[0, -1], [-1, -1], [-1, 0], [-1, 1]
];
directions.forEach(([dRow, dCol]) => {
let r = row + dRow;
let c = col + dCol;
let piecesToFlip = [];
while (r >= 0 && r < boardSize && c >= 0 && c < boardSize && boardState[r][c] === opponentColor) {
piecesToFlip.push([r, c]);
r += dRow;
c += dCol;
}
// この方向が反転可能か確認(最後に自分の色の駒がある)
if (r >= 0 && r < boardSize && c >= 0 && c < boardSize && boardState[r][c] === color) {
piecesToFlip.forEach(([fr, fc]) => {
boardState[fr][fc] = color; // 駒を反転
});
}
});
updateBoard(); // 盤面を更新
}
// 盤面の更新を行う関数
function updateBoard() {
for (let i = 0; i < boardSize; i++) {
for (let j = 0; j < boardSize; j++) {
const cell = document.querySelector(`.cell[data-row="${i}"][data-col="${j}"]`);
if (boardState[i][j] === 'black') {
cell.innerHTML = '<div class="piece black"></div>';
} else if (boardState[i][j] === 'white') {
cell.innerHTML = '<div class="piece white"></div>';
} else {
cell.innerHTML = '';
}
}
}
}
// ルーレットを開始する関数
function startRoulette() {
// ルーレットが既に起動していない場合のみ、ルーレットを開始
if (!rouletteInterval) {
rouletteInterval = setInterval(() => {
document.getElementById('rouletteButton').click();
}, rouletteDelay);
}
}
// セルをマークしてビンゴ成立チェックを行う関数
function markBingo(number) {
const row = Math.floor((number - 1) / boardSize);
const col = (number - 1) % boardSize;
const cell = document.querySelector(`.cell[data-row="${row}"][data-col="${col}"]`);
cell.classList.add('marked'); // ビンゴマークのスタイルを適用
checkBingo(); // ビンゴ成立チェック
}
// ビンゴ成立をチェックする関数
function checkBingo() {
// 省略:ビンゴ成立のチェックロジック
}
// プレイヤーを切り替える関数
function switchPlayer() {
currentPlayer = currentPlayer === 'black' ? 'white' : 'black';
}
// 指定した色の合法手を取得する関数
function getLegalMoves(color) {
let moves = [];
for (let row = 0; row < boardSize; row++) {
for (let col = 0; col < boardSize; col++) {
if (boardState[row][col] === null && canPlacePiece(row, col, color)) {
moves.push({ row: row, col: col });
}
}
}
return moves;
}
function handleCellClick(row, col) {
// ルーレットの結果を取得
let rouletteResultElement = document.getElementById('rouletteResult');
if (rouletteResultElement) {
// 現在のプレイヤーが駒を置くことができる場合のみ処理する
if (canPlacePiece(row, col, currentPlayer)) {
boardState[row][col] = currentPlayer; // 駒を置く
flipPieces(row, col, currentPlayer); // 駒を反転させる
updateBoard(); // 盤面を更新
// ルーレットの結果が数字であることを確認
let rouletteResultMatch = rouletteResultElement.textContent.match(/\d+/);
if (rouletteResultMatch) {
markBingo(parseInt(rouletteResultMatch[0])); // ビンゴマーキング関数を呼び出す
}
switchPlayer(); // プレイヤーを切り替える
startTurn(); // 次のターンを開始
}
}
}
// ルーレットボタンがクリックされたときの処理を行う関数
document.getElementById('rouletteButton').addEventListener('click', () => {
let randomNumber = Math.floor(Math.random() * (boardSize * boardSize)) + 1;
document.getElementById('rouletteResult').textContent = `ルーレット結果: ${randomNumber}`;
});
initBoard(); // ゲームボードの初期化
});
</script>
</body>
</html>