【JavaScript】コネクト・フォーを作成してみた
今回はJavaScriptでコネクト・フォーを作成しました。
オセロと同じように、赤犬と青雉の決闘をイメージしました。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title></title>
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css"
integrity="sha384-JcKb8q3iqJ61gNV9KGb8thSsNjpSL0n8PARn9HuZOnIxN0hoP+VmmDGMN5t9UJ0Z" crossorigin="anonymous">
<link rel="stylesheet" media="screen" href="style.css">
</head>
<body>
<h1>赤犬 VS 青雉</h1>
<div id="board"></div>
<h2 id="winner"></h2>
<script src="index.js"></script>
</body>
</html>
body {
text-align: center;
background-color: antiquewhite;
}
#board {
height: 530px; /* 85✖️6+20 */
width: 615px; /* 85✖️7+20 */
background-color: green;
border: 10px solid black;
margin: 0 auto;
display: flex;
flex-wrap: wrap;
}
.tile {
height: 75px;
width: 75px;
margin: 5px;
background-color: white;
border-radius: 50%;
border: 5px solid black;
}
.red-piece {
background-color: red;
background-size: contain; /*背景画像全体が見えるように*/
background-repeat: no-repeat; /*背景画像の繰り返しをしない*/
background-position: center; /*背景画像を中央にする*/
background-image: url("img/akainu.png");
}
.blue-piece {
background-color: blue;
background-size: contain; /*背景画像全体が見えるように*/
background-repeat: no-repeat; /*背景画像の繰り返しをしない*/
background-position: center; /*背景画像を中央にする*/
background-image: url("img/aokiji.png");
}
let akainu = "R";
let aokiji = "B";
let currPlayer = akainu; //現在のプレイヤー
let gameOver = false;
let board; //最初は' 'を入れて、"R" or "B" が入っていく
let rows = 6;
let columns = 7;
let currColumns = []; //現在の行を管理(下から埋めるから)
window.onload = function () {
setGame();
}
function setGame() {
board = [];
currColumns = [5, 5, 5, 5, 5, 5, 5];//一番下スタート
for (let r = 0; r < rows; r++) {
let row = [];
for (let c = 0; c < columns; c++) {
row.push(' ');
let tile = document.createElement("div");
tile.id = r.toString() + "-" + c.toString();
tile.classList.add("tile");
tile.addEventListener("click", setPiece);
document.getElementById("board").append(tile);
//<div id="0-0" class="tile"></div>
//<div id="0-1" class="tile"></div>
}
console.log(row);
//[' ', ' ', ' ', ' ', ' ', ' ', ' ']
board.push(row);
}
}
function setPiece() {
if (gameOver) {
return; //ピースを置けないようにする
}
let coords = this.id.split("-"); //id="3-4" -> ["3", "4"]
let r = parseInt(coords[0]); //row = 3
let c = parseInt(coords[1]); //column = 4
r = currColumns[c]; //列を特定(最初は5が入る)
if (r < 0) { //その列が埋まっている場合
return;
}
board[r][c] = currPlayer;
let tile = document.getElementById(r.toString() + "-" + c.toString());
if (currPlayer == akainu) {
tile.classList.add("red-piece");
currPlayer = aokiji;
} else {
tile.classList.add("blue-piece");
currPlayer = akainu;
}
r -= 1; //上の行へ
currColumns[c] = r;
checkWinner();
}
function checkWinner() {
// 横方向を確認
for (let r = 0; r < rows; r++) {
for (let c = 0; c < columns - 3; c++) {
if (board[r][c] != ' ') { // "R" or "B"
if (
board[r][c] == board[r][c + 1]
&& board[r][c + 1] == board[r][c + 2]
&& board[r][c + 2] == board[r][c + 3]
) {
setWinner(r, c); //どっちが勝ったか判定するための引数
return;
}
}
}
}
// 縦方向を確認
for (let c = 0; c < columns; c++) {
for (let r = 0; r < rows - 3; r++) {
if (board[r][c] != ' ') {
if (
board[r][c] == board[r + 1][c]
&& board[r + 1][c] == board[r + 2][c]
&& board[r + 2][c] == board[r + 3][c]
) {
setWinner(r, c);
return;
}
}
}
}
// 逆対角線方向を確認
for (let r = 0; r < rows - 3; r++) {
for (let c = 0; c < columns - 3; c++) {
if (board[r][c] != ' ') {
if (
board[r][c] == board[r + 1][c + 1]
&& board[r + 1][c + 1] == board[r + 2][c + 2]
&& board[r + 2][c + 2] == board[r + 3][c + 3]
) {
setWinner(r, c);
return;
}
}
}
}
// 対角線方向を確認
for (let r = 3; r < rows; r++) {
for (let c = 0; c < columns - 3; c++) {
if (board[r][c] != ' ') {
if (
board[r][c] == board[r - 1][c + 1]
&& board[r - 1][c + 1] == board[r - 2][c + 2]
&& board[r - 2][c + 2] == board[r - 3][c + 3]
) {
setWinner(r, c);
return;
}
}
}
}
}
function setWinner(r, c) {
let winner = document.getElementById("winner");
if (board[r][c] == akainu) {
winner.innerText = "赤犬の勝利";
} else {
winner.innerText = "青雉の勝利";
}
gameOver = true;
}