JavaScriptでcanvasを使って、三目並べの○×ゲームを作ってみた。
canvasで作るよりもTableやButtonで作った方が大分楽。
<!DOCTYPE html>
<html lang="jp">
<head>
<meta charset="utf-8">
<script>
let canvas;
let context;
let Magnification = 100;
let Finished = false;
let FirstStrike=true;
let MarubatsuTable={};
function drawFrame()
{
// #を描画
context.beginPath();
context.moveTo(Magnification*0, Magnification*1);
context.lineTo(Magnification*3, Magnification*1);
context.moveTo(Magnification*0, Magnification*2);
context.lineTo(Magnification*3, Magnification*2);
context.moveTo(Magnification*1, Magnification*0);
context.lineTo(Magnification*1, Magnification*3);
context.moveTo(Magnification*2, Magnification*0);
context.lineTo(Magnification*2, Magnification*3);
context.stroke();
}
function onClick(e)
{
if( Finished )
{
// ゲームが終わっている場合はリセット
context.clearRect(0, 0, canvas.width, canvas.height);
drawFrame();
MarubatsuTable = {};
Finished = false;
FirstStrike = true;
return;
}
// クリックされたセルを検出
let rect = e.target.getBoundingClientRect();
let x = Math.floor( (e.clientX - rect.left) / Magnification );
let y = Math.floor( (e.clientY - rect.top) / Magnification );
let id = "X"+ x + "Y" + y;
if( !MarubatsuTable[id] )
{
if( FirstStrike )
{
MarubatsuTable[id] = "○";
context.beginPath();
context.arc( (x+0.5)*Magnification, (y+0.5)*Magnification, Magnification/3 , 0, 2 * Math.PI, false ) ;
context.stroke();
}
else
{
MarubatsuTable[id] = "×";
context.beginPath();
context.moveTo((x+0.2)*Magnification, (y+0.2)*Magnification);
context.lineTo((x+0.8)*Magnification, (y+0.8)*Magnification);
context.moveTo((x+0.8)*Magnification, (y+0.2)*Magnification);
context.lineTo((x+0.2)*Magnification, (y+0.8)*Magnification);
context.stroke();
}
// 結果判定
const decisionTable =
[ {dicision:["X0Y0","X1Y0","X2Y0"],line:{x0:0,y0:0.5,x1:3,y1:0.5}},
{dicision:["X0Y1","X1Y1","X2Y1"],line:{x0:0,y0:1.5,x1:3,y1:1.5}},
{dicision:["X0Y2","X1Y2","X2Y2"],line:{x0:0,y0:2.5,x1:3,y1:2.5}},
{dicision:["X0Y0","X0Y1","X0Y2"],line:{x0:0.5,y0:0,x1:0.5,y1:3}},
{dicision:["X1Y0","X1Y1","X1Y2"],line:{x0:1.5,y0:0,x1:1.5,y1:3}},
{dicision:["X2Y0","X2Y1","X2Y2"],line:{x0:2.5,y0:0,x1:2.5,y1:3}},
{dicision:["X0Y0","X1Y1","X2Y2"],line:{x0:0,y0:0,x1:3,y1:3}},
{dicision:["X2Y0","X1Y1","X0Y2"],line:{x0:0,y0:3,x1:3,y1:0}} ];
decisionTable.forEach((a)=>
{
var temp = MarubatsuTable[a.dicision[0]] + MarubatsuTable[a.dicision[1]] + MarubatsuTable[a.dicision[2]];
if( temp == "○○○" || temp == "×××" )
{
context.beginPath();
context.moveTo( a.line.x0*Magnification, a.line.y0*Magnification);
context.lineTo( a.line.x1*Magnification, a.line.y1*Magnification);
context.stroke();
Finished = true;
}
if( Object.keys(MarubatsuTable).length == 9 )
{
Finished = true;
}
});
// 先攻後攻変更
FirstStrike = !FirstStrike;
}
}
function onLoad(){
canvas = document.getElementById('sampleCanvas');
context = canvas.getContext('2d');
if ( ! canvas || ! context ) {
return false;
}
canvas.style.width = Magnification * 3+"px";
canvas.style.height = Magnification * 3+"px";
canvas.width = Magnification * 3;
canvas.height = Magnification * 3;
drawFrame();
canvas.addEventListener('click', onClick, false);
}
</script>
</head>
<body onload="onLoad();">
<canvas id="sampleCanvas"></canvas>
</body>
</html>
おまけ:Canvas縛りがない場合はもっと簡単
<!DOCTYPE html>
<html lang="jp">
<head>
<meta charset="utf-8">
<script>
let FirstStrike=true;
let Finished = false;
let Count = 0;
function onClick(event){
// 勝敗決定後のクリックは結果クリア
if( Finished )
{
for (const td of event.currentTarget.querySelectorAll("td")) {
td.innerText = " ";
td.style.backgroundColor = "";
}
FirstStrike=true;
Finished = false;
Count = 0;
return;
}
// クリックされたセルに"○"/"×"を記録
if(event.target.tagName=="TD")
{
if( event.target.innerText==" " ){
event.target.innerText = FirstStrike?"○":"×";
FirstStrike =! FirstStrike;
Count++;
// 結果判定
const decisionTable =
[ ["00","01","02"],
["01","11","12"],
["02","21","22"],
["00","10","20"],
["01","11","21"],
["02","12","22"],
["00","11","22"],
["20","11","02"] ];
decisionTable.forEach((a)=>
{
var temp = document.getElementById(a[0]).innerText+document.getElementById(a[1]).innerText+document.getElementById(a[2]).innerText;
if( temp == "○○○" || temp == "×××" )
{
Finished = true;
document.getElementById(a[0]).style.backgroundColor = "lightblue";
document.getElementById(a[1]).style.backgroundColor = "lightblue";
document.getElementById(a[2]).style.backgroundColor = "lightblue";
}
});
if( Count >=9 )
{
Finished = true;
}
}
}
}
</script>
</head>
<body>
<table onclick="onClick(event);" border="1">
<tr><td id="00"> </td><td id="01"> </td><td id="02"> </td></tr>
<tr><td id="10"> </td><td id="11"> </td><td id="12"> </td></tr>
<tr><td id="20"> </td><td id="21"> </td><td id="22"> </td></tr>
</table>
</body>
</html>