毎日Podcastを配信している、弓削田です。
毎月、10人ずつぐらいずつ増えていて、番組の成長を感じていますが、
企画などを考えるのは本当にタイヘンなんです・・・
ちなみに、そのPodcastは、こちら。
プログラミング学習に役立つ情報をお届けするナンチャッテ・ラジオ
そして、最近放送し始めた企画で「プログラミングカフェ」というのがあり、
プログラミング初心者の人は、とにかく他の人がどのようにプログラミングをしているかを見てみたいという意見を元に、
自分で1からプログラムを作るのではなく、他の人が作った内容を解説してもらうとか、
その手順や環境などを、説明してもらって、参考にして、自分の学習を加速する事も重要なスキルアップ方法です。
初回の企画は「マルバツゲームを作る」という事で、簡単なゲームを作って、ついでに遊んでしまおうという内容です。
ちなみに、第一回はこちら。
#331 プログラミングカフェ(1)「マルバツゲームを作ってプログラミング体験してみよう!」
※podcastで聞いてもらった方が、便利ですよ。
その中で解説しているプログラムコードを、
ブログに掲載しておきたいと思います。
プログラム・ソース
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
<title>MaruBatsu</title>
<link rel="stylesheet" href="marubatsu.css">
<script src="marubatsu.js"></script>
</head>
<body>
<h1>マルバツゲーム</h1>
<button class="start">ゲームスタート</button>
<table class="marubatsu">
<tr><td></td><td></td><td></td></tr>
<tr><td></td><td></td><td></td></tr>
<tr><td></td><td></td><td></td></tr>
</table>
</bodfy>
</html>
table.marubatsu{
border-collapse:collapse;
margin:20px;
}
table.marubatsu td{
border:1px solid black;
width:50px;
height:50px;
text-align:center;
vertical-align:middle;
cursor:pointer;
}
table.marubatsu td:hover{
background-color:#FEE;
}
*[data-hidden="1"]{
display:none;
}
(function(){
let MAIN = function(){
this.set_event();
};
// イベント設定
MAIN.prototype.set_event = function(){
let button = this.get_start_button();
if(button){
button.addEventListener("click" , this.click_start.bind(this));
}
let table = this.get_game_table();
if(table){
table.addEventListener("click" , this.click_table.bind(this));
}
};
// スタートボタンクリック
MAIN.prototype.click_start = function(){
let result = confirm("先攻にしますか?");
if(result === true){
this.first = "player";
this.second = "computer";
}
else{
this.first = "computer";
this.second = "player";
}
this.clear();
this.game_start();
};
// 要素の取得
MAIN.prototype.get_start_button = function(){
return document.querySelector("button.start");
};
MAIN.prototype.get_game_table = function(){
return document.querySelector("table.marubatsu");
};
MAIN.prototype.get_game_cells = function(){
let table = this.get_game_table();
if(!table){
console.log("Error !");
return;
}
return table.querySelectorAll("td");
};
// 情報の初期化
MAIN.prototype.clear = function(){
this.count = 0;
let cells = this.get_game_cells();
for(let cell of cells){
cell.textContent = "";
}
};
// ゲーム開始
MAIN.prototype.game_start = function(){
switch(this.first){
case "player":
console.log("先攻で開始します");
break;
case "computer":
console.log("後攻で開始します");
this.proc_computer();
break;
default:
console.log("Error!");
break;
}
};
// プレイヤーがマス目をクリックした時の処理
MAIN.prototype.click_table = function(e){
if(!this.first){
console.log("Error !");
return;
}
let target = e.target;
if(target.tagName !== "TD"){
console.log("Error !");
return;
}
// すでに値が書き込まれていると何もしない
if(target.textContent !== ""){
console.log("Error !");
return;
}
// 自分の番を判定
if(this.first === "player" && (this.count % 2)){
console.log("Error !");
return;
}
else if(this.first === "computer" && !(this.count % 2)){
console.log("Error !");
return;
}
// 後攻
if(this.count % 2){
target.textContent = "✗";
}
// 先攻
else{
target.textContent = "○";
}
let res = this.check();
if(res === true){
this.proc_computer();
}
};
// コンピュータの番
MAIN.prototype.proc_computer = function(){
let cells = this.get_game_cells();
if(!cells || !cells.length){
console.log("Error !");
return;
}
// 記号がおけるマスの一覧を取得
let empty = [];
for(let i=0; i<cells.length; i++){
if(!cells[i].textContent){
empty.push(i);
}
}
if(!empty.length){
return;
}
// 空欄にランダムで記号をセット
let rnd = Math.floor(Math.random() * empty.length);
// 後攻
if(this.count % 2){
cells[empty[rnd]].textContent = "✗";
}
// 先攻
else{
cells[empty[rnd]].textContent = "○";
}
this.check();
};
//
MAIN.prototype.check = function(){
let cells = this.get_game_cells();
if(!cells || !cells.length){
console.log("Error !");
return;
}
// 配置されている記号を配列に格納する。
let empty_count = 0;
let datas = [];
for(let i=0; i<cells.length; i++){
datas.push(cells[i].textContent);
if(!cells[i].textContent){
empty_count++;
}
}
let winner = (this.count % 2) ? this.second : this.first;
// 3つ並んでいるかチェックする
if(this.check_line(datas)){
this.game_over(winner);
}
// 引き分け処理
else if(empty_count === 0){
this.game_over();
return;
}
// 相手の番に変更する
else{
this.count++;
return true;
}
};
// マス目のデータをもとに、縦横ナナメ一列に並んでいるかどうかを返す処理
let pattern = [
[0,1,2],
[3,4,5],
[6,7,8],
[0,3,6],
[1,4,7],
[2,5,8],
[0,4,8],
[2,4,6]
];
MAIN.prototype.check_line = function(datas){
if(!datas){return null;}
for(let i=0; i<pattern.length; i++){
if(!datas[pattern[i][0]]){continue;}
if(datas[pattern[i][0]] === datas[pattern[i][1]]
&& datas[pattern[i][0]] === datas[pattern[i][2]]){
return datas[pattern[i][0]];
}
}
return false;
};
MAIN.prototype.game_over = function(winner){
if(winner === "player"){
setTimeout((function(){
alert("あなたの勝ちです!!!");
}).bind(this),100);
}
else if(winner === "computer"){
setTimeout((function(){
alert("あなたの負けです・・・");
}).bind(this),100);
}
else{
setTimeout((function(){
alert("引き分けです。");
}).bind(this),100);
}
};
// 起動処理
if(document.readyState === "complete"){
new MAIN();
}
else{
window.addEventListener("load" , function(){new MAIN()});
}
})();
どんなゲーム?
そんなに長ったらしいプログラムではないので、中級クラスの人がみたら簡単に理解できる内容にしています。
HTMLが動けば簡単に実行できるので、サーバーなどもいらない環境で動かせます。
ゲーム自体は簡単な構成にしていて、
デザインなどは、無くしているので、CSSは非常に簡素です。
スタートボタンを押して、先攻後攻を選んで、コンピュータと勝負することができるんですが、
コンピュータは、単なるランダムなので、負けたら非常に悔しいでしょう。
まあ、このゲームって必勝法があって、絶対に負けない方法を知っていると、何にも面白くないゲームなんですが、
実際にプログラミング学習で、こうしたゲームを作っていくというのは、
僕の経験上悪くない方法なんですよね。
内容が気になる人は、是非、Podcastを聞いてくださいませ。
0 件のコメント:
コメントを投稿