お世話様です。ebifurai55です。私はWeb系の仕事に就きたく最近、Javascriptを勉強しています。800ページぐらいあった本を読破したのですが、実際のコードは書いたことがないので、自分なりに目標を定め、とりあえずリバーシを作ろうと思ってネット検索を含め、ソースがないかどうか探しました。そこでたどり着いたのがteratailなのですが、以前ここにリバーシ(オセロ)のサンプルプログラムがあったので、実装してみました。ただ少し残念なのは、黒白、順番の表示は点数の判定などがなかったので、自分で考えようと思いましたが、プログラミング初心者の為、どこから手をつけていいのかわからない、わからないことがわからない、、、という状態になっています。一応自分なりの概念は
・盤面の状態の保存
・チェック
・白黒の数値を表示
・勝利判定
・再スタート
という流れなのかな?と思いますが、いろいろと検索しても変数やパラメーターが違うので、どこを変えればいいのか?という結論になりました。私のメンターの人もゆっくりやっていいよ、と言ってくれますが、概念がわからないと同実装したらわかりません。ちょっと自分でもやってみますが、どうしようもない時にこちらに投稿してもいいでしょうか?
今現在勝利判定の所で何を対象にチェックをしたらいいのか、苦戦しています。できれば解決方法のソースを教えてもらいたいです。が、自分の力でどこまでやれるか頑張ります
以下にこのサイトで参考にしたソースコードを載せます。
index.html
1<!DOCTYPE html> 2<html> 3 <head> 4 <meta http-equiv="content-language" content="ja"> 5 <meta charset="UTF-8"> 6</head> 7<html> 8 <body> 9 <div id="othello"></div> 10 <script type="text/javascript" src="reversi.js"></script> 11 </body> 12</html>
reversi.js
1var STONE_BLACK = 'url("http://i.imgur.com/CLEpdaJ.png")'; 2var STONE_WHITE = 'url("http://i.imgur.com/VZgXNBM.png")'; 3var BLACK = 1; 4var WHITE = 2; 5 6var turn = BLACK; // 先手は黒 7 8// 10×10のフィールドを作って、石の色を保持する。 9// 0: 石がない, BLACK: 黒石, WHITE: 白石、9: 壁 10var field = [ 11 [9, 9, 9, 9, 9, 9, 9, 9, 9, 9], 12 [9, 0, 0, 0, 0, 0, 0, 0, 0, 9], 13 [9, 0, 0, 0, 0, 0, 0, 0, 0, 9], 14 [9, 0, 0, 0, 0, 0, 0, 0, 0, 9], 15 [9, 0, 0, 0, 0, 0, 0, 0, 0, 9], 16 [9, 0, 0, 0, 0, 0, 0, 0, 0, 9], 17 [9, 0, 0, 0, 0, 0, 0, 0, 0, 9], 18 [9, 0, 0, 0, 0, 0, 0, 0, 0, 9], 19 [9, 0, 0, 0, 0, 0, 0, 0, 0, 9], 20 [9, 9, 9, 9, 9, 9, 9, 9, 9, 9] 21]; 22// ------------------------------------------------------- 23// 盤面を表示する。 24function showBoard() { 25 var element = document.getElementById("othello"); 26 27 for (var y = 1; y <= 8; y++) { 28 for(var x = 1; x <= 8; x++) { 29 var f = document.createElement("div"); 30 f.id = "p" + y + x; 31 f.style.border = "1px solid black"; 32 f.style.cssFloat = "left"; 33 f.style.height = "60px"; 34 f.style.width = "60px"; 35 f.style.background = "lime"; 36 f.style.cursor = "pointer"; 37 f.addEventListener("click", clickEvent, false); 38 39 if ((x % 8) == 1) { 40 f.style.clear = "both"; 41 } 42 43 if (field[y][x] !== 0) { 44 var image = (field[y][x] == BLACK)? STONE_BLACK :STONE_WHITE; 45 f.style.backgroundImage = image; 46 } 47 element.appendChild(f); 48 } 49 } 50} 51 52function playable(y, x, player) { 53 var ans = false; 54 var opponent = (player == BLACK) ? WHITE : BLACK; 55 var delta_y = [-1, -1, 0, 1, 1, 1, 0, -1]; 56 var delta_x = [0, 1, 1, 1, 0, -1, -1, -1]; 57 58 if (field[y][x] === 0) { 59 for (var pos = 0; pos < 8; pos++) { 60 var count = 0; 61 var n = y + delta_y[pos]; 62 var m = x + delta_x[pos]; 63 64 if (field[n][m] === 9 || field[n][m] === player || field[n][m] === 0) { 65 continue; 66 } 67 68 while (field[n][m] === opponent) { 69 n += delta_y[pos]; 70 m += delta_x[pos]; 71 count++; 72 73 if (field[n][m] === player) { 74 ans = true; 75 while (count >= 0) { 76 n -= delta_y[pos]; 77 m -= delta_x[pos]; 78 var f = document.getElementById("p" + n + m); 79 f.style.backgroundImage = (player == BLACK)? STONE_BLACK : STONE_WHITE; 80 field[n][m] = player; 81 count--; 82 } 83 84 } 85 } 86 } 87 } 88 return ans; 89 90} 91 92function showWinner(field) { 93 var nt = {}; 94 nt[BLACK] = 0; 95 nt[WHITE] = 0; 96 97 for (var x = 1; x < 8; x++) 98 for (var y = 1; y < 8; y++) 99 nt[field[[x, y]]]++; 100 101 console.log((nt[BLACK] == nt[WHITE]) 102 ? 'The game ends in a draw.' 103 : 'The winner is ' + (nt[WHITE] < nt[BLACK] ? BLACK : WHITE) + '.' 104 ); 105} 106 107function clickEvent() { 108 var element = document.getElementById(this.id); 109 var y = parseInt(element.id.substr(-2, 1)); 110 var x = parseInt(element.id.substr(-1, 1)); 111 112 var check = playable(y, x, turn); 113 if (check) { 114 turn = (turn == BLACK)? WHITE : BLACK; 115 if ( turn == BLACK) { 116 console.log('黒の番です'); 117 } else { 118 console.log('白の番です'); 119 } 120 } 121 var win = showWinner(field); 122 123} 124 125onload = function() { 126 // 黒と白の初期配置 127 field[4][5] = BLACK; 128 field[5][4] = BLACK; 129 field[4][4] = WHITE; 130 field[5][5] = WHITE; 131 showBoard(); 132}; 133 134//オセロ実践写経
showWinnerはどこからか引っ張ってきたメソッドです。普通に動きません。なにかご助言いただけないでしょうか?たくさんの方からの投稿まっています。
情報追記
やりたい事
・黒と白の数を表示
・64マスに達したら黒か白かどちらが勝ったか判定をする
現状の問題
・nt[board[[x,y]]]++;
で nt[BLACK]とnt[WHITE]の値が更新されてない。
そのため、ずっと”引き分けの"の表示になる。
・nt[BLACK]とnt[WHITE]をカウントしたいが、どの様に表現しないといけないのか分からない。
将来の実装
64マスに達したらというのではあれば
if ( any === 64 )とかで判定して処理を書きたい
09/29
あれから試したものの、nt[BLACK]とnt[white]の動きがどうしてもわからなかったので、以下の様な実装をしてみました
reversi.js
1 2 // 左端からすべてのマスの確認を行う 3 var white_cnt = 0 4 var black_cnt = 0 5 for (var x = 0; x < 8; x++) { 6 for (var y = 0; y < 8; y++) { 7 // 空白マスのみおけるのでチェック 8 // それ以外は石の数を加算 9 switch( field[x][y] ) { 10 //case 0: 11 //console.log('何もしない'); 12 //break; 13 case 1: 14 black_cnt++; 15 console.log('黒を1加算'); 16 console.log('黒の数' + black_cnt); 17 18 break; 19 case 2: 20 white_cnt++; 21 console.log('白を1加算'); 22 console.log('白の数' + white_cnt); 23 break; 24 } 25 } 26 } 27 28}
これで正常に動いた!と思ったのですが、譜面が進むと、白か黒か枚数が同一ではなくなります。どうすればいいのか思案してましたが、当方playable関数に関してまったく理解がないので、どうも自分流で作れれば作った方がいいのではないかと思いました。トレーニングしてないのに野球の実践で活躍できるかと言うと、リトルリーグと大リーグぐらい違うものだと認識しました。たかだか100行くらいですけど、明日までに解決策が出なかったら、メンターに失敗だったと報告します。
他に何かご助言ありますでしょうか?人格攻撃とか向いてないとか言うのはご遠慮ください。
追記。Switchの0も何を指してるかわかりません