<head>
<meta charset="UTF-8">
<title>オセロ</title>
<script src="main.js"></script>
<style>
body{
background-color: black
}
h3{
color:white;
}
#table{
background-color:#555000;
}
td.masu{
background-color:#54b549;
width:40px;
height:40px;
margin:2px;
font-size:20px;
text-align:center;
}
td.black{
color:black;
}
td.white{
color:white;
}
</style>
</head>
<body>
<h3 class="white">
白(YOU):<span id="countWhite"></span>枚
</h3>
<table id="table"></table>
<h3 class="black">
黒(CPU):<span id="countBlack"></span>枚
</h3>
</body>
</html>
let omomiData = [
[30, -12, 0, -1, -1, 0, -12, 30],
[-12, -15, -3, -3, -3, -3, -15, -12],
[0, -3, 0, -1, -1, 0, -3, 0],
[-1, -3, -1, -1, -1, -1, -3, -1],
[-1, -3, -1, -1, -1, -1, -3, -1],
[0, -3, 0, -1, -1, 0, -3, 0],
[-12, -15, -3, -3, -3, -3, -15, -12],
[30, -12, 0, -1, -1, 0, -12, 30]
]; // 重みづけデータ
let SIRO = 1;
let KURO = 2;
let data = [];
let myTurn = false;
function init() {
let table = document.getElementById("table");
for (let i = 0; i < 8; i++) {
let yokoretu = document.createElement("tr");
data[i] = [0, 0, 0, 0, 0, 0, 0, 0];
for (let j = 0; j < 8; j++) {
let itimasu = document.createElement("td");
itimasu.className = "masu";
itimasu.id = "masu" + i + j;
itimasu.onclick = touch; //②追加分
yokoretu.appendChild(itimasu);
}
table.appendChild(yokoretu);
}
//初期配置
put(3, 3, SIRO);
put(4, 4, SIRO);
put(3, 4, KURO);
put(4, 3, KURO);
kousin();
}
function put(i, j, color) {
let masu = document.getElementById("masu" + i + j);
masu.textContent = "●";
masu.className = "masu " + (color === SIRO ? "white" : "black");
data[i][j] = color;
}
function kousin() {
//白と黒の数を数えて、表示する
let countWhite = 0;
let countBlack = 0;
for (let x = 0; x < 8; x++) {
for (let y = 0; y < 8; y++) {
if (data[x][y] === SIRO) {
countWhite++;
}
if (data[x][y] === KURO) {
countBlack++;
}
}
}
document.getElementById("countBlack").textContent = countBlack;
document.getElementById("countWhite").textContent = countWhite;
//②追加分//②追加分//②追加分//②追加分//②追加分
let turnSIRO = canReverce(SIRO);
let turnKURO = canReverce(KURO);
if (
countWhite + countBlack === 64 ||
(turnKURO === false && turnSIRO === false)
) {
if (countWhite > countBlack) {
alert("白の勝ち");
} else if (countWhite < countBlack) {
alert("黒の勝ち");
} else {
alert("引き分け");
}
return;
}
if (turnSIRO === false) {
alert("白スキップ");
myTurn = false;
} else if (turnKURO === false) {
alert("黒スキップ");
myTurn = true;
} else {
myTurn = !myTurn;
}
if (myTurn === false) {
setTimeout(cpuThinking, 1000);
}
}
function touch(masu) {
if (!myTurn) {
return;
}
let id = masu.target.id;
let tate = parseInt(id.charAt(4));
let yoko = parseInt(id.charAt(5));
let canReverseMasu = canReverceMasu(tate, yoko, SIRO);
if (canReverseMasu.length > 0) {
for (let k = 0; k < canReverseMasu.length; k++) {
put(canReverseMasu[k][0], canReverseMasu[k][1], SIRO);
}
put(tate, yoko, SIRO);
kousin();
}
}
// 挟める石があるか?
//ターンプレイヤーを確定させるために64マスを調べている
function canReverce(color) {
for (let x = 0; x < 8; x++) {
for (let y = 0; y < 8; y++) {
let canReverseMasu = canReverceMasu(x, y, color);
if (canReverseMasu.length > 0) {
return true;
}
}
}
return false;
}
// (i,j)に石を置いた時 挟める座標(配列) を返す
function canReverceMasu(i, j, color) {
if (data[i][j] === KURO || data[i][j] === SIRO) {
return []; // すでに石があるときは何もしない
}
// 相手を挟めるか、左上、上、右上、左、右、左下、下、右下と順番に調査
let touchedMawari = [
[-1, -1],
[0, -1],
[1, -1],
[-1, 0],
[1, 0],
[-1, 1],
[0, 1],
[1, 1]
];
let result = [];
for (let p = 0; p < touchedMawari.length; p++) {
let canReverseMasu = canReverceHoukou(
i,
j,
touchedMawari[p][0],
touchedMawari[p][1],
color
);
result = result.concat(canReverseMasu);
}
return result;
}
// (i,j)に石を置いたときに、(Xhoukou,Yhoukou)方向で石を挟めるか?
function canReverceHoukou(i, j, Xhoukou, Yhoukou, color) {
let checkedX = i + Xhoukou;
let checkedY = j + Yhoukou;
if (
checkedX < 0 ||
checkedY < 0 ||
checkedX > 7 ||
checkedY > 7 ||
data[checkedX][checkedY] === color ||
data[checkedX][checkedY] === 0
) {
return []; // 盤外、同色、空ならfalse(挟めない)
}
// 挟める候補の座標 = クリックした座標から見て違う色の石を重複配列で格納
let canReverseMasu = [];
canReverseMasu.push([checkedX, checkedY]);
while (true) {
checkedX += Xhoukou;
checkedY += Yhoukou;
if (
checkedX < 0 ||
checkedY < 0 ||
checkedX > 7 ||
checkedY > 7 ||
data[checkedX][checkedY] === 0
) {
return []; // 盤外、空ならfalse(挟めない)
}
if (data[checkedX][checkedY] === color) {
return canReverseMasu; // 挟めた!
} else {
canReverseMasu.push([checkedX, checkedY]);
}
}
}
function cpuThinking() {
let highScore = -1000;
let px = -1;
let py = -1;
for (let x = 0; x < 8; x++) {
for (let y = 0; y < 8; y++) {
let kariData = copyData();
let cpuCanReverceMasu = canReverceMasu(x, y, KURO);
if (cpuCanReverceMasu.length > 0) {
for (let i = 0; i < cpuCanReverceMasu.length; i++) {
let p = cpuCanReverceMasu[i][0];
let q = cpuCanReverceMasu[i][1];
kariData[p][q] = KURO;
kariData[x][y] = KURO;
}
let score = keisanOmomiData(kariData);
if (score > highScore) {
highScore = score;
(px = x), (py = y);
}
}
}
}
if (px >= 0 && py >= 0) {
let cpuCanReverceMasu = canReverceMasu(px, py, KURO);
if (cpuCanReverceMasu.length > 0) {
for (let k = 0; k < cpuCanReverceMasu.length; k++) {
put(cpuCanReverceMasu[k][0], cpuCanReverceMasu[k][1], KURO);
}
}
put(px, py, KURO);
}
kousin();
}
// 重みづけ計算;
function keisanOmomiData(kariData) {
let score = 0;
for (let x = 0; x < 8; x++) {
for (let y = 0; y < 8; y++) {
if (kariData[x][y] === KURO) {
score += omomiData[x][y];
}
}
}
return score;
}
// 石テーブルデータをコピー;
function copyData() {
let kariData = [];
for (let x = 0; x < 8; x++) {
kariData[x] = [];
for (let y = 0; y < 8; y++) {
kariData[x][y] = data[x][y];
}
}
// console.log(kariData);
return kariData;
}
window.addEventListener("load", init);
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.