情報学部 | 菅沼ホーム | JavaScript 目次 | 索引 |
01 <!DOCTYPE HTML> 02 <HTML> 03 <HEAD> 04 <TITLE>オセロ:ステップ1</TITLE> 05 <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=utf-8"> 06 <META NAME=viewport CONTENT="width=device-width, initial-scale=1"> 07 <LINK REL="stylesheet" TYPE="text/css" HREF="../../../master.css"> 08 <SCRIPT TYPE="text/javascript" SRC="main/MainPanel.js"></SCRIPT> 09 <SCRIPT TYPE="text/javascript" SRC="start/StartPanel.js"></SCRIPT> 10 <SCRIPT TYPE="text/javascript" SRC="game/GamePanel.js"></SCRIPT> 11 </HEAD> 12 <BODY CLASS="eeffee" onLoad="mp_start()"> 13 <H1>オセロ:ステップ1</H1> 14 <CANVAS ID="canvas_e" STYLE="background-color: #ffffff;" WIDTH="435" HEIGHT="435"></CANVAS><BR> 15 <A HREF="method.htm" TARGET="method"><BUTTON ID="method" CLASS="std">遊び方</BUTTON></A> 16 <BUTTON ID="g_method0" CLASS="std" onClick="JavaScript: mp.method=0; gp_start()">対人間</BUTTON> 17 <BUTTON ID="g_method1" CLASS="std" onClick="JavaScript: mp.method=1; gp_start()">対コンピュータ(人先手)</BUTTON> 18 <BUTTON ID="g_method2" CLASS="std" onClick="JavaScript: mp.method=2; gp_start()">対コンピュータ(人後手)</BUTTON> 19 <TEXTAREA ID="ta" TYPE="text" NAME="ta" COLS="40" ROWS="5" CLASS="std"></TEXTAREA><BR> 20 <BUTTON ID="first" CLASS="std" onClick="st_start()">再開</BUTTON> 21 <BUTTON ID="finish" CLASS="std" onClick="mp.finish()">終了</BUTTON> 22 </BODY> 23 </HTML>
mp = null; // MainPanel オブジェクト // // MainPanel の開始 // function mp_start() { // キャンバス情報 let canvas = document.getElementById('canvas_e'); // キャンバス要素の取得 let ctx = canvas.getContext('2d'); // キャンバスからコンテキストを取得 // MainPanel オブジェクト mp = new MainPanel(canvas, ctx); // StartPanel の表示 st_start(); } // // MainPanel オブジェクト(プロパティ) // function MainPanel(canvas, ctx) { this.canvas = canvas; // キャンバス要素 this.ctx = ctx; // キャンバスのコンテキスト this.method = 0; // ゲーム方法(0:対人間,1:対PC(先手),2:対PC(後手)) return this; } // // MainPanel オブジェクト(メソッド) // MainPanel.prototype.finish = function() { // キャンバスのクリア mp.ctx.clearRect(0, 0, mp.canvas.width, mp.canvas.height); // ボタンを非表示 document.getElementById('method').style.display = "none"; document.getElementById('g_method0').style.display = "none"; document.getElementById('g_method1').style.display = "none"; document.getElementById('g_method2').style.display = "none"; document.getElementById('ta').style.display = "none"; document.getElementById('first').style.display = "none"; document.getElementById('finish').style.display = "none"; }
// // StartPanel の開始 // function st_start() { mp.level = 1; // ゲームレベルの設定 // キャンバスのクリア mp.ctx.clearRect(0, 0, mp.canvas.width, mp.canvas.height); // ゲームタイトルの表示 mp.ctx.font = "40px 'MS ゴシック'"; mp.ctx.textBaseline = "middle"; mp.ctx.textAlign = "center"; mp.ctx.fillStyle = "rgb(0, 0, 0)"; mp.ctx.fillText("オセロ", mp.canvas.width/2, mp.canvas.height/2); // ボタンの表示制御 document.getElementById('method').style.display = ""; document.getElementById('g_method0').style.display = ""; document.getElementById('g_method1').style.display = ""; document.getElementById('g_method2').style.display = ""; document.getElementById('ta').style.display = "none"; document.getElementById('first').style.display = "none"; document.getElementById('finish').style.display = "none"; }
01 gp = null; // GamePanel オブジェクト 02 03 // 04 // GamePanel の開始 05 // 06 function gp_start() 07 { 08 // GamePanel オブジェクト 09 gp = new GamePanel(); 10 // 描画 11 gp.draw(); 12 // ボタンの表示制御 13 document.getElementById('method').style.display = "none"; 14 document.getElementById('g_method0').style.display = "none"; 15 document.getElementById('g_method1').style.display = "none"; 16 document.getElementById('g_method2').style.display = "none"; 17 document.getElementById('ta').style.display = ""; 18 document.getElementById('ta').style.color = "black"; 19 document.getElementById('ta').innerHTML = "黒の番です."; 20 document.getElementById('first').style.display = ""; 21 document.getElementById('finish').style.display = ""; 22 } 23 // 24 // GamePanel オブジェクト(プロパティ) 25 // 26 function GamePanel() 27 { 28 this.sz = 51; // マス目の大きさ 29 this.gap = 3; // マス目間のギャップ 30 return this; 31 } 32 // 33 // GamePanel オブジェクト(メソッド draw) 34 // 35 GamePanel.prototype.draw = function() 36 { 37 // キャンバスのクリア 38 mp.ctx.clearRect(0, 0, mp.canvas.width, mp.canvas.height); 39 // 描画 40 mp.ctx.beginPath(); 41 mp.ctx.fillStyle = "rgb(165, 42, 42)"; 42 mp.ctx.fillRect(0, 0, mp.canvas.width, mp.canvas.height); 43 mp.ctx.fill(); 44 45 for (let i1 = 0; i1 < 8; i1++) { 46 for (let i2 = 0; i2 < 8; i2++) { 47 let x = gp.gap + i2 * (gp.sz + gp.gap); 48 let y = gp.gap + i1 * (gp.sz + gp.gap); 49 mp.ctx.beginPath(); 50 mp.ctx.fillStyle = "rgb(0, 255, 0)"; 51 mp.ctx.fillRect(x, y, gp.sz, gp.sz); 52 mp.ctx.fill(); 53 } 54 } 55 }
01 gp = null; // GamePanel オブジェクト 02 03 // 04 // GamePanel の開始 05 // 06 function gp_start() 07 { 08 // GamePanel オブジェクト 09 gp = new GamePanel(); 10 // 描画 11 gp.draw(); 12 // ボタンの表示制御 13 document.getElementById('method').style.display = "none"; 14 document.getElementById('g_method0').style.display = "none"; 15 document.getElementById('g_method1').style.display = "none"; 16 document.getElementById('g_method2').style.display = "none"; 17 document.getElementById('ta').style.display = ""; 18 document.getElementById('ta').style.color = "black"; 19 document.getElementById('ta').innerHTML = "黒の番です."; 20 document.getElementById('first').style.display = ""; 21 document.getElementById('finish').style.display = ""; 22 } 23 // 24 // GamePanel オブジェクト(プロパティ) 25 // 26 function GamePanel() 27 { 28 this.sz = 51; // マス目の大きさ 29 this.gap = 3; // マス目間のギャップ 30 this.st = new Array(); // 盤面の状態(0:コマが置かれてない,-1:黒,1:白) 31 this.st[0] = new Array(0, 0, 0, 0, 0, 0, 0, 0); 32 this.st[1] = new Array(0, 0, 0, 0, 0, 0, 0, 0); 33 this.st[2] = new Array(0, 0, 0, 0, 0, 0, 0, 0); 34 this.st[3] = new Array(0, 0, 0, 1, -1, 0, 0, 0); 35 this.st[4] = new Array(0, 0, 0, -1, 1, 0, 0, 0); 36 this.st[5] = new Array(0, 0, 0, 0, 0, 0, 0, 0); 37 this.st[6] = new Array(0, 0, 0, 0, 0, 0, 0, 0); 38 this.st[7] = new Array(0, 0, 0, 0, 0, 0, 0, 0); 39 return this; 40 } 41 // 42 // GamePanel オブジェクト(メソッド draw) 43 // 44 GamePanel.prototype.draw = function() 45 { 46 // キャンバスのクリア 47 mp.ctx.clearRect(0, 0, mp.canvas.width, mp.canvas.height); 48 // 描画 49 mp.ctx.beginPath(); 50 mp.ctx.fillStyle = "rgb(165, 42, 42)"; 51 mp.ctx.fillRect(0, 0, mp.canvas.width, mp.canvas.height); 52 mp.ctx.fill(); 53 54 for (let i1 = 0; i1 < 8; i1++) { 55 for (let i2 = 0; i2 < 8; i2++) { 56 let x = gp.gap + i2 * (gp.sz + gp.gap); 57 let y = gp.gap + i1 * (gp.sz + gp.gap); 58 mp.ctx.beginPath(); 59 mp.ctx.fillStyle = "rgb(0, 255, 0)"; 60 mp.ctx.fillRect(x, y, gp.sz, gp.sz); 61 mp.ctx.fill(); 62 if (gp.st[i1][i2] != 0) { 63 x += Math.floor(gp.sz / 2); 64 y += Math.floor(gp.sz / 2); 65 mp.ctx.beginPath(); 66 if (gp.st[i1][i2] < 0) 67 mp.ctx.fillStyle = "rgb(0, 0, 0)"; 68 else 69 mp.ctx.fillStyle = "rgb(255, 255, 255)"; 70 mp.ctx.arc(x, y, Math.floor(gp.sz/2)-2, 0, 2*Math.PI); 71 mp.ctx.fill(); 72 } 73 } 74 } 75 }
let a = new Array(2); // let a = new Array(); でも可 for (let i1 = 0; i1 < 2; i1++) a[i1] = new Array(3);
let a = new Array(2); // let a = new Array(); でも可 a[0] = new Array(1, 2, 3); a[1] = new Array(4, 5, 6);
001 gp = null; // GamePanel オブジェクト 002 003 // 004 // GamePanel の開始 005 // 006 function gp_start() 007 { 008 // GamePanel オブジェクト 009 gp = new GamePanel(); 010 // 描画 011 gp.draw(); 012 // マウスクリックに対するイベントリスナ 013 mp.canvas.addEventListener("click", gp.mouseClick); 014 // ボタンの表示制御 015 document.getElementById('method').style.display = "none"; 016 document.getElementById('g_method0').style.display = "none"; 017 document.getElementById('g_method1').style.display = "none"; 018 document.getElementById('g_method2').style.display = "none"; 019 document.getElementById('ta').style.display = ""; 020 document.getElementById('ta').style.color = "black"; 021 document.getElementById('ta').innerHTML = "黒の番です."; 022 document.getElementById('first').style.display = ""; 023 document.getElementById('finish').style.display = ""; 024 } 025 // 026 // GamePanel オブジェクト(プロパティ) 027 // 028 function GamePanel() 029 { 030 this.sz = 51; // マス目の大きさ 031 this.gap = 3; // マス目間のギャップ 032 this.b_w = -1; // -1:黒の手番,1:白の手番 033 this.st = new Array(); // 盤面の状態(0:コマが置かれてない,-1:黒,1:白) 034 this.st[0] = new Array(0, 0, 0, 0, 0, 0, 0, 0); 035 this.st[1] = new Array(0, 0, 0, 0, 0, 0, 0, 0); 036 this.st[2] = new Array(0, 0, 0, 0, 0, 0, 0, 0); 037 this.st[3] = new Array(0, 0, 0, 1, -1, 0, 0, 0); 038 this.st[4] = new Array(0, 0, 0, -1, 1, 0, 0, 0); 039 this.st[5] = new Array(0, 0, 0, 0, 0, 0, 0, 0); 040 this.st[6] = new Array(0, 0, 0, 0, 0, 0, 0, 0); 041 this.st[7] = new Array(0, 0, 0, 0, 0, 0, 0, 0); 042 this.n = new Array(); // 指定された位置の各方向に対する反転できるコマの数 043 // [0] : 上方向 044 // [1] : 斜め右上方向 045 // [2] : 右方向 046 // [3] : 斜め右下方向 047 // [4] : 下方向 048 // [5] : 斜め左下方向 049 // [6] : 左方向 050 // [7] : 斜め左上方向 051 // [8] : 全体 052 return this; 053 } 054 // 055 // GamePanel オブジェクト(メソッド mouseClick) 056 // 057 GamePanel.prototype.mouseClick = function(event) 058 { 059 let x_base = mp.canvas.offsetLeft; // キャンバスの左上のx座標 060 let y_base = mp.canvas.offsetTop; // キャンバスの左上のy座標 061 let x = event.pageX - x_base; // キャンバス内のクリックされた位置(x座標) 062 let y = event.pageY - y_base; // キャンバス内のクリックされた位置(y座標) 063 // クリックされたマス目を特定 064 let k = new Array(-1, -1); 065 for (let i1 = 0; i1 < 8; i1++) { 066 if (y >= gp.gap+i1*(gp.gap+gp.sz) && y <= (i1+1)*(gp.gap+gp.sz)) { 067 k[0] = i1; 068 break; 069 } 070 } 071 for (let i1 = 0; i1 < 8; i1++) { 072 if (x >= gp.gap+i1*(gp.gap+gp.sz) && x <= (i1+1)*(gp.gap+gp.sz)) { 073 k[1] = i1; 074 break; 075 } 076 } 077 // 反転できるコマを探す 078 gp.r_check(k); 079 // 反転するコマがない場合 080 if (gp.n[8] <= 0) { 081 document.getElementById('ta').style.color = "red"; 082 let str = "の番ですが,\nそこへはコマを置けません."; 083 if (gp.b_w < 0) 084 document.getElementById('ta').innerHTML = "黒" + str; 085 else 086 document.getElementById('ta').innerHTML = "白" + str; 087 } 088 // 反転するコマがある場合 089 else 090 gp.set(k); 091 } 092 // 093 // k[0] 行 k[1] 列に黒または白( b_w )のコマを置いた場合,反転できるコマを探す( GamePanel オブジェクトのメソッド r_check ) 094 // 095 GamePanel.prototype.r_check = function(k) 096 { 097 let d = new Array(); 098 d[0] = new Array(-1, 0); 099 d[1] = new Array(-1, 1); 100 d[2] = new Array(0, 1); 101 d[3] = new Array(1, 1); 102 d[4] = new Array(1, 0); 103 d[5] = new Array(1, -1); 104 d[6] = new Array(0, -1); 105 d[7] = new Array(-1, -1); 106 gp.n[8] = 0; 107 if (k[0] >= 0 && k[1] >= 0 && gp.st[k[0]][k[1]] == 0) { 108 for (let i1 = 0; i1 < 8; i1++) { 109 let m1 = k[0]; 110 let m2 = k[1]; 111 gp.n[i1] = 0; 112 let s = 0; // 0:開始,1:カウント,2:カウント終了,3:反転不可能 113 let ct = 0; 114 while (s < 2) { 115 m1 += d[i1][0]; 116 m2 += d[i1][1]; 117 if (m1 >= 0 && m1 < 8 && m2 >= 0 && m2 < 8) { 118 if (gp.st[m1][m2] == 0) 119 s = 3; 120 else if (gp.st[m1][m2] == gp.b_w) { 121 if (s == 1) 122 s = 2; 123 else 124 s = 3; 125 } 126 else { 127 s = 1; 128 ct++; 129 } 130 } 131 else 132 s = 3; 133 } 134 if (s == 2) { 135 gp.n[8] += ct; 136 gp.n[i1] = ct; 137 } 138 } 139 } 140 } 141 // 142 // コマの操作( GamePanel オブジェクトのメソッド set ) 143 // 144 GamePanel.prototype.set = function(k) 145 { 146 // 反転 147 gp.reverse(k); 148 gp.b_w = -gp.b_w; 149 document.getElementById('ta').style.color = "black"; 150 if (gp.b_w < 0) 151 document.getElementById('ta').innerHTML = "黒の番です."; 152 else 153 document.getElementById('ta').innerHTML = "白の番です."; 154 } 155 // 156 // k[0] 行 k[1] 列に黒または白( b_w )のコマを置いた場合におけるコマの反転( GamePanel オブジェクトのメソッド reverse ) 157 // 158 GamePanel.prototype.reverse = function(k) 159 { 160 let d = new Array(); 161 d[0] = new Array(-1, 0); 162 d[1] = new Array(-1, 1); 163 d[2] = new Array(0, 1); 164 d[3] = new Array(1, 1); 165 d[4] = new Array(1, 0); 166 d[5] = new Array(1, -1); 167 d[6] = new Array(0, -1); 168 d[7] = new Array(-1, -1); 169 for (let i1 = 0; i1 < 8; i1++) { 170 let m1 = k[0]; 171 let m2 = k[1]; 172 for (let i2 = 0; i2 < gp.n[i1]; i2++) { 173 m1 += d[i1][0]; 174 m2 += d[i1][1]; 175 gp.st[m1][m2] = gp.b_w; 176 } 177 } 178 gp.st[k[0]][k[1]] = gp.b_w; 179 // 描画 180 gp.draw(); 181 } 182 // 183 // GamePanel オブジェクト(メソッド draw) 184 // 185 GamePanel.prototype.draw = function() 186 { 187 // キャンバスのクリア 188 mp.ctx.clearRect(0, 0, mp.canvas.width, mp.canvas.height); 189 // 描画 190 mp.ctx.beginPath(); 191 mp.ctx.fillStyle = "rgb(165, 42, 42)"; 192 mp.ctx.fillRect(0, 0, mp.canvas.width, mp.canvas.height); 193 mp.ctx.fill(); 194 195 for (let i1 = 0; i1 < 8; i1++) { 196 for (let i2 = 0; i2 < 8; i2++) { 197 let x = gp.gap + i2 * (gp.sz + gp.gap); 198 let y = gp.gap + i1 * (gp.sz + gp.gap); 199 mp.ctx.beginPath(); 200 mp.ctx.fillStyle = "rgb(0, 255, 0)"; 201 mp.ctx.fillRect(x, y, gp.sz, gp.sz); 202 mp.ctx.fill(); 203 if (gp.st[i1][i2] != 0) { 204 x += Math.floor(gp.sz / 2); 205 y += Math.floor(gp.sz / 2); 206 mp.ctx.beginPath(); 207 if (gp.st[i1][i2] < 0) 208 mp.ctx.fillStyle = "rgb(0, 0, 0)"; 209 else 210 mp.ctx.fillStyle = "rgb(255, 255, 255)"; 211 mp.ctx.arc(x, y, Math.floor(gp.sz/2)-2, 0, 2*Math.PI); 212 mp.ctx.fill(); 213 } 214 } 215 } 216 }
001 gp = null; // GamePanel オブジェクト
002
003 //
004 // GamePanel の開始
005 //
006 function gp_start()
007 {
008 // GamePanel オブジェクト
009 gp = new GamePanel();
010 // 描画
011 gp.draw();
012 // マウスクリックに対するイベントリスナ
013 mp.canvas.addEventListener("click", gp.mouseClick);
014 // ボタンの表示制御
015 document.getElementById('method').style.display = "none";
016 document.getElementById('g_method0').style.display = "none";
017 document.getElementById('g_method1').style.display = "none";
018 document.getElementById('g_method2').style.display = "none";
019 document.getElementById('ta').style.display = "";
020 document.getElementById('ta').style.color = "black";
021 document.getElementById('ta').innerHTML = "黒の番です.";
022 document.getElementById('first').style.display = "";
023 document.getElementById('finish').style.display = "";
024 }
025 //
026 // GamePanel オブジェクト(プロパティ)
027 //
028 function GamePanel()
029 {
030 this.sz = 51; // マス目の大きさ
031 this.gap = 3; // マス目間のギャップ
032 this.b_w = -1; // -1:黒の手番,1:白の手番
033 this.st = new Array(); // 盤面の状態(0:コマが置かれてない,-1:黒,1:白)
034 this.st[0] = new Array(0, 0, 0, 0, 0, 0, 0, 0);
035 this.st[1] = new Array(0, 0, 0, 0, 0, 0, 0, 0);
036 this.st[2] = new Array(0, 0, 0, 0, 0, 0, 0, 0);
037 this.st[3] = new Array(0, 0, 0, 1, -1, 0, 0, 0);
038 this.st[4] = new Array(0, 0, 0, -1, 1, 0, 0, 0);
039 this.st[5] = new Array(0, 0, 0, 0, 0, 0, 0, 0);
040 this.st[6] = new Array(0, 0, 0, 0, 0, 0, 0, 0);
041 this.st[7] = new Array(0, 0, 0, 0, 0, 0, 0, 0);
042 this.n = new Array(); // 指定された位置の各方向に対する反転できるコマの数
043 // [0] : 上方向
044 // [1] : 斜め右上方向
045 // [2] : 右方向
046 // [3] : 斜め右下方向
047 // [4] : 下方向
048 // [5] : 斜め左下方向
049 // [6] : 左方向
050 // [7] : 斜め左上方向
051 // [8] : 全体
052 return this;
053 }
054 //
055 // GamePanel オブジェクト(メソッド mouseClick)
056 //
057 GamePanel.prototype.mouseClick = function(event)
058 {
059 let x_base = mp.canvas.offsetLeft; // キャンバスの左上のx座標
060 let y_base = mp.canvas.offsetTop; // キャンバスの左上のy座標
061 let x = event.pageX - x_base; // キャンバス内のクリックされた位置(x座標)
062 let y = event.pageY - y_base; // キャンバス内のクリックされた位置(y座標)
063 // クリックされたマス目を特定
064 let k = new Array(-1, -1);
065 for (let i1 = 0; i1 < 8; i1++) {
066 if (y >= gp.gap+i1*(gp.gap+gp.sz) && y <= (i1+1)*(gp.gap+gp.sz)) {
067 k[0] = i1;
068 break;
069 }
070 }
071 for (let i1 = 0; i1 < 8; i1++) {
072 if (x >= gp.gap+i1*(gp.gap+gp.sz) && x <= (i1+1)*(gp.gap+gp.sz)) {
073 k[1] = i1;
074 break;
075 }
076 }
077 // 反転できるコマを探す
078 gp.r_check(k);
079 // 反転するコマがない場合
080 if (gp.n[8] <= 0) {
081 document.getElementById('ta').style.color = "red";
082 let str = "の番ですが,\nそこへはコマを置けません.";
083 if (gp.b_w < 0)
084 document.getElementById('ta').innerHTML = "黒" + str;
085 else
086 document.getElementById('ta').innerHTML = "白" + str;
087 }
088 // 反転するコマがある場合
089 else
090 gp.set(k);
091 }
092 //
093 // k[0] 行 k[1] 列に黒または白( b_w )のコマを置いた場合,反転できるコマを探す( GamePanel オブジェクトのメソッド r_check )
094 //
095 GamePanel.prototype.r_check = function(k)
096 {
097 let d = new Array();
098 d[0] = new Array(-1, 0);
099 d[1] = new Array(-1, 1);
100 d[2] = new Array(0, 1);
101 d[3] = new Array(1, 1);
102 d[4] = new Array(1, 0);
103 d[5] = new Array(1, -1);
104 d[6] = new Array(0, -1);
105 d[7] = new Array(-1, -1);
106 gp.n[8] = 0;
107 if (k[0] >= 0 && k[1] >= 0 && gp.st[k[0]][k[1]] == 0) {
108 for (let i1 = 0; i1 < 8; i1++) {
109 let m1 = k[0];
110 let m2 = k[1];
111 gp.n[i1] = 0;
112 let s = 0; // 0:開始,1:カウント,2:カウント終了,3:反転不可能
113 let ct = 0;
114 while (s < 2) {
115 m1 += d[i1][0];
116 m2 += d[i1][1];
117 if (m1 >= 0 && m1 < 8 && m2 >= 0 && m2 < 8) {
118 if (gp.st[m1][m2] == 0)
119 s = 3;
120 else if (gp.st[m1][m2] == gp.b_w) {
121 if (s == 1)
122 s = 2;
123 else
124 s = 3;
125 }
126 else {
127 s = 1;
128 ct++;
129 }
130 }
131 else
132 s = 3;
133 }
134 if (s == 2) {
135 gp.n[8] += ct;
136 gp.n[i1] = ct;
137 }
138 }
139 }
140 }
141 //
142 // コマの操作( GamePanel オブジェクトのメソッド set )
143 //
144 GamePanel.prototype.set = function(k)
145 {
146 // 反転
147 gp.reverse(k);
148 gp.b_w = -gp.b_w;
149 // コマの数を数え,勝敗決定のチェック
150 let b = 0;
151 let w = 0;
152 let total = 0;
153 for (let i1 = 0; i1 < 8; i1++) {
154 for (let i2 = 0; i2 < 8; i2++) {
155 if (gp.st[i1][i2] != 0) {
156 total++;
157 if (gp.st[i1][i2] < 0)
158 b++;
159 else
160 w++;
161 }
162 }
163 }
164 // 勝敗決定
165 if (total == 64) {
166 document.getElementById('ta').style.color = "black";
167 let str = "黒 " + b + " 個, 白 " + w + " 個\n";
168 if (b > w)
169 document.getElementById('ta').innerHTML = str + "黒の勝ちです.";
170 else if (b == w)
171 document.getElementById('ta').innerHTML = str + "引き分けです.";
172 else
173 document.getElementById('ta').innerHTML = str + "白の勝ちです.";
174 mp.canvas.removeEventListener("click", gp.mouseClick); // リスのの除去
175 }
176 // 勝負継続
177 else {
178 document.getElementById('ta').style.color = "black";
179 let str = "黒 " + b + " 個, 白 " + w + " 個\n";
180 // スキップのチェック
181 let sw = false;
182 for (let i1 = 0; i1 < 8 && !sw; i1++) {
183 for (let i2 = 0; i2 < 8 && !sw; i2++) {
184 k[0] = i1;
185 k[1] = i2;
186 gp.r_check(k);
187 if (gp.n[8] > 0)
188 sw = true;
189 }
190 }
191 // スキップの場合
192 if (!sw) {
193 gp.b_w = -gp.b_w;
194 str += "コマを置けないため,スキップし,\n";
195 }
196 // 次の手
197 if (gp.b_w < 0)
198 document.getElementById('ta').innerHTML = str + "黒の番です.";
199 else
200 document.getElementById('ta').innerHTML = str + "白の番です.";
201 }
202 }
203 //
204 // k[0] 行 k[1] 列に黒または白( b_w )のコマを置いた場合におけるコマの反転( GamePanel オブジェクトのメソッド reverse )
205 //
206 GamePanel.prototype.reverse = function(k)
207 {
208 let d = new Array();
209 d[0] = new Array(-1, 0);
210 d[1] = new Array(-1, 1);
211 d[2] = new Array(0, 1);
212 d[3] = new Array(1, 1);
213 d[4] = new Array(1, 0);
214 d[5] = new Array(1, -1);
215 d[6] = new Array(0, -1);
216 d[7] = new Array(-1, -1);
217 for (let i1 = 0; i1 < 8; i1++) {
218 let m1 = k[0];
219 let m2 = k[1];
220 for (let i2 = 0; i2 < gp.n[i1]; i2++) {
221 m1 += d[i1][0];
222 m2 += d[i1][1];
223 gp.st[m1][m2] = gp.b_w;
224 }
225 }
226 gp.st[k[0]][k[1]] = gp.b_w;
227 // 描画
228 gp.draw();
229 }
230 //
231 // GamePanel オブジェクト(メソッド draw)
232 //
233 GamePanel.prototype.draw = function()
234 {
235 // キャンバスのクリア
236 mp.ctx.clearRect(0, 0, mp.canvas.width, mp.canvas.height);
237 // 描画
238 mp.ctx.beginPath();
239 mp.ctx.fillStyle = "rgb(165, 42, 42)";
240 mp.ctx.fillRect(0, 0, mp.canvas.width, mp.canvas.height);
241 mp.ctx.fill();
242
243 for (let i1 = 0; i1 < 8; i1++) {
244 for (let i2 = 0; i2 < 8; i2++) {
245 let x = gp.gap + i2 * (gp.sz + gp.gap);
246 let y = gp.gap + i1 * (gp.sz + gp.gap);
247 mp.ctx.beginPath();
248 mp.ctx.fillStyle = "rgb(0, 255, 0)";
249 mp.ctx.fillRect(x, y, gp.sz, gp.sz);
250 mp.ctx.fill();
251 if (gp.st[i1][i2] != 0) {
252 x += Math.floor(gp.sz / 2);
253 y += Math.floor(gp.sz / 2);
254 mp.ctx.beginPath();
255 if (gp.st[i1][i2] < 0)
256 mp.ctx.fillStyle = "rgb(0, 0, 0)";
257 else
258 mp.ctx.fillStyle = "rgb(255, 255, 255)";
259 mp.ctx.arc(x, y, Math.floor(gp.sz/2)-2, 0, 2*Math.PI);
260 mp.ctx.fill();
261 }
262 }
263 }
264 }
001 gp = null; // GamePanel オブジェクト 002 003 // 004 // GamePanel の開始 005 // 006 function gp_start() 007 { 008 // GamePanel オブジェクト 009 gp = new GamePanel(); 010 // 描画 011 gp.draw(); 012 // マウスクリックに対するイベントリスナ 013 mp.canvas.addEventListener("click", gp.mouseClick); 014 // ボタンの表示制御 015 document.getElementById('method').style.display = "none"; 016 document.getElementById('g_method0').style.display = "none"; 017 document.getElementById('g_method1').style.display = "none"; 018 document.getElementById('g_method2').style.display = "none"; 019 document.getElementById('ta').style.display = ""; 020 document.getElementById('ta').style.color = "black"; 021 if (mp.method == 0) 022 document.getElementById('ta').innerHTML = "黒の番です."; 023 else if (mp.method == 1) 024 document.getElementById('ta').innerHTML = "あなた(黒)の番です."; 025 else 026 document.getElementById('ta').innerHTML = "コンピュータの番です."; 027 document.getElementById('first').style.display = ""; 028 document.getElementById('finish').style.display = ""; 029 // コンピュータの操作 030 if (mp.method == 2) { 031 let k = gp.computer(); // コマを置く場所の決定 032 gp.set(k); // コマを置く 033 } 034 } 035 // 036 // GamePanel オブジェクト(プロパティ) 037 // 038 function GamePanel() 039 { 040 this.sz = 51; // マス目の大きさ 041 this.gap = 3; // マス目間のギャップ 042 this.b_w = -1; // -1:黒の手番,1:白の手番 043 this.st = new Array(); // 盤面の状態(0:コマが置かれてない,-1:黒,1:白) 044 this.st[0] = new Array(0, 0, 0, 0, 0, 0, 0, 0); 045 this.st[1] = new Array(0, 0, 0, 0, 0, 0, 0, 0); 046 this.st[2] = new Array(0, 0, 0, 0, 0, 0, 0, 0); 047 this.st[3] = new Array(0, 0, 0, 1, -1, 0, 0, 0); 048 this.st[4] = new Array(0, 0, 0, -1, 1, 0, 0, 0); 049 this.st[5] = new Array(0, 0, 0, 0, 0, 0, 0, 0); 050 this.st[6] = new Array(0, 0, 0, 0, 0, 0, 0, 0); 051 this.st[7] = new Array(0, 0, 0, 0, 0, 0, 0, 0); 052 this.n = new Array(); // 指定された位置の各方向に対する反転できるコマの数 053 // [0] : 上方向 054 // [1] : 斜め右上方向 055 // [2] : 右方向 056 // [3] : 斜め右下方向 057 // [4] : 下方向 058 // [5] : 斜め左下方向 059 // [6] : 左方向 060 // [7] : 斜め左上方向 061 // [8] : 全体 062 return this; 063 } 064 // 065 // GamePanel オブジェクト(メソッド mouseClick) 066 // 067 GamePanel.prototype.mouseClick = function(event) 068 { 069 let x_base = mp.canvas.offsetLeft; // キャンバスの左上のx座標 070 let y_base = mp.canvas.offsetTop; // キャンバスの左上のy座標 071 let x = event.pageX - x_base; // キャンバス内のクリックされた位置(x座標) 072 let y = event.pageY - y_base; // キャンバス内のクリックされた位置(y座標) 073 // クリックされたマス目を特定 074 let k = new Array(-1, -1); 075 for (let i1 = 0; i1 < 8; i1++) { 076 if (y >= gp.gap+i1*(gp.gap+gp.sz) && y <= (i1+1)*(gp.gap+gp.sz)) { 077 k[0] = i1; 078 break; 079 } 080 } 081 for (let i1 = 0; i1 < 8; i1++) { 082 if (x >= gp.gap+i1*(gp.gap+gp.sz) && x <= (i1+1)*(gp.gap+gp.sz)) { 083 k[1] = i1; 084 break; 085 } 086 } 087 // 反転できるコマを探す 088 gp.r_check(k); 089 // 反転するコマがない場合 090 if (gp.n[8] <= 0) { 091 document.getElementById('ta').style.color = "red"; 092 let str = "の番ですが,\nそこへはコマを置けません."; 093 if (mp.method > 0) 094 document.getElementById('ta').innerHTML = "あなた" + str; 095 else { 096 if (gp.b_w < 0) 097 document.getElementById('ta').innerHTML = "黒" + str; 098 else 099 document.getElementById('ta').innerHTML = "白" + str; 100 } 101 } 102 // 反転するコマがある場合 103 else 104 gp.set(k); 105 } 106 // 107 // k[0] 行 k[1] 列に黒または白( b_w )のコマを置いた場合,反転できるコマを探す( GamePanel オブジェクトのメソッド r_check ) 108 // 109 GamePanel.prototype.r_check = function(k) 110 { 111 let d = new Array(); 112 d[0] = new Array(-1, 0); 113 d[1] = new Array(-1, 1); 114 d[2] = new Array(0, 1); 115 d[3] = new Array(1, 1); 116 d[4] = new Array(1, 0); 117 d[5] = new Array(1, -1); 118 d[6] = new Array(0, -1); 119 d[7] = new Array(-1, -1); 120 gp.n[8] = 0; 121 if (k[0] >= 0 && k[1] >= 0 && gp.st[k[0]][k[1]] == 0) { 122 for (let i1 = 0; i1 < 8; i1++) { 123 let m1 = k[0]; 124 let m2 = k[1]; 125 gp.n[i1] = 0; 126 let s = 0; // 0:開始,1:カウント,2:カウント終了,3:反転不可能 127 let ct = 0; 128 while (s < 2) { 129 m1 += d[i1][0]; 130 m2 += d[i1][1]; 131 if (m1 >= 0 && m1 < 8 && m2 >= 0 && m2 < 8) { 132 if (gp.st[m1][m2] == 0) 133 s = 3; 134 else if (gp.st[m1][m2] == gp.b_w) { 135 if (s == 1) 136 s = 2; 137 else 138 s = 3; 139 } 140 else { 141 s = 1; 142 ct++; 143 } 144 } 145 else 146 s = 3; 147 } 148 if (s == 2) { 149 gp.n[8] += ct; 150 gp.n[i1] = ct; 151 } 152 } 153 } 154 } 155 // 156 // コマの操作( GamePanel オブジェクトのメソッド set ) 157 // 158 GamePanel.prototype.set = function(k) 159 { 160 // 反転 161 gp.reverse(k); 162 gp.b_w = -gp.b_w; 163 // コマの数を数え,勝敗決定のチェック 164 let b = 0; 165 let w = 0; 166 let total = 0; 167 for (let i1 = 0; i1 < 8; i1++) { 168 for (let i2 = 0; i2 < 8; i2++) { 169 if (gp.st[i1][i2] != 0) { 170 total++; 171 if (gp.st[i1][i2] < 0) 172 b++; 173 else 174 w++; 175 } 176 } 177 } 178 // 勝敗決定 179 if (total == 64) { 180 document.getElementById('ta').style.color = "black"; 181 let str = "黒 " + b + " 個, 白 " + w + " 個\n"; 182 if (mp.method > 0) { 183 if (b == w) 184 document.getElementById('ta').innerHTML = str + "引き分けです."; 185 else if (b > w && mp.method == 1 || b < w && mp.method == 2) 186 document.getElementById('ta').innerHTML = str + "あなたの勝ちです."; 187 else 188 document.getElementById('ta').innerHTML = str + "コンピュータの勝ちです."; 189 } 190 else { 191 if (b > w) 192 document.getElementById('ta').innerHTML = str + "黒の勝ちです."; 193 else if (b == w) 194 document.getElementById('ta').innerHTML = str + "引き分けです."; 195 else 196 document.getElementById('ta').innerHTML = str + "白の勝ちです."; 197 } 198 mp.canvas.removeEventListener("click", gp.mouseClick); // リスナの除去 199 } 200 // 勝負継続 201 else { 202 document.getElementById('ta').style.color = "black"; 203 let str = "黒 " + b + " 個, 白 " + w + " 個\n"; 204 // スキップのチェック 205 let sw = false; 206 for (let i1 = 0; i1 < 8 && !sw; i1++) { 207 for (let i2 = 0; i2 < 8 && !sw; i2++) { 208 k[0] = i1; 209 k[1] = i2; 210 gp.r_check(k); 211 if (gp.n[8] > 0) 212 sw = true; 213 } 214 } 215 // 対コンピュータ 216 if (mp.method > 0) { 217 // スキップの場合 218 if (!sw) { 219 gp.b_w = -gp.b_w; 220 str += "コマを置けないため,スキップし,\n"; 221 if (mp.method == 1 && gp.b_w < 0) 222 document.getElementById('ta').innerHTML = str + "あなた(黒)の番です."; 223 else if (mp.method == 2 && gp.b_w > 0) 224 document.getElementById('ta').innerHTML = str + "あなた(白)の番です."; 225 else { 226 document.getElementById('ta').innerHTML = str + "コンピュータの番です."; 227 k = gp.computer(); // コマを置く場所の決定 228 gp.set(k); // コマを置く 229 } 230 } 231 // 次の手 232 else { 233 if (mp.method == 1 && gp.b_w < 0) 234 document.getElementById('ta').innerHTML = str + "あなた(黒)の番です."; 235 else if (mp.method == 2 && gp.b_w > 0) 236 document.getElementById('ta').innerHTML = str + "あなた(白)の番です."; 237 else { 238 document.getElementById('ta').innerHTML = str + "コンピュータの番です."; 239 k = gp.computer(); // コマを置く場所の決定 240 gp.set(k); // コマを置く 241 } 242 } 243 } 244 // 対人間 245 else { 246 // スキップの場合 247 if (!sw) { 248 gp.b_w = -gp.b_w; 249 str += "コマを置けないため,スキップし,\n"; 250 } 251 // 次の手 252 if (gp.b_w < 0) 253 document.getElementById('ta').innerHTML = str + "黒の番です."; 254 else 255 document.getElementById('ta').innerHTML = str + "白の番です."; 256 } 257 } 258 } 259 // 260 // k[0] 行 k[1] 列に黒または白( b_w )のコマを置いた場合におけるコマの反転( GamePanel オブジェクトのメソッド reverse ) 261 // 262 GamePanel.prototype.reverse = function(k) 263 { 264 let d = new Array(); 265 d[0] = new Array(-1, 0); 266 d[1] = new Array(-1, 1); 267 d[2] = new Array(0, 1); 268 d[3] = new Array(1, 1); 269 d[4] = new Array(1, 0); 270 d[5] = new Array(1, -1); 271 d[6] = new Array(0, -1); 272 d[7] = new Array(-1, -1); 273 for (let i1 = 0; i1 < 8; i1++) { 274 let m1 = k[0]; 275 let m2 = k[1]; 276 for (let i2 = 0; i2 < gp.n[i1]; i2++) { 277 m1 += d[i1][0]; 278 m2 += d[i1][1]; 279 gp.st[m1][m2] = gp.b_w; 280 } 281 } 282 gp.st[k[0]][k[1]] = gp.b_w; 283 // 描画 284 gp.draw(); 285 } 286 // 287 // コンピュータが置くコマの場所を決定( GamePanel オブジェクトのメソッド computer ) 288 // 289 GamePanel.prototype.computer = function() 290 { 291 let k = new Array(); 292 let kk = new Array(); 293 let mx = new Array(); 294 mx[8] = 0; 295 for (let i1 = 0; i1 < 8; i1++) { 296 for (let i2 = 0; i2 < 8; i2++) { 297 kk[0] = i1; 298 kk[1] = i2; 299 gp.r_check(kk); 300 if (gp.n[8] > mx[8]) { 301 k[0] = kk[0]; 302 k[1] = kk[1]; 303 for (let i3 = 0; i3 < 9; i3++) 304 mx[i3] = gp.n[i3]; 305 } 306 } 307 } 308 for (let i1 = 0; i1 < 9; i1++) 309 gp.n[i1] = mx[i1]; 310 return k; 311 } 312 // 313 // GamePanel オブジェクト(メソッド draw) 314 // 315 GamePanel.prototype.draw = function() 316 { 317 // キャンバスのクリア 318 mp.ctx.clearRect(0, 0, mp.canvas.width, mp.canvas.height); 319 // 描画 320 mp.ctx.beginPath(); 321 mp.ctx.fillStyle = "rgb(165, 42, 42)"; 322 mp.ctx.fillRect(0, 0, mp.canvas.width, mp.canvas.height); 323 mp.ctx.fill(); 324 325 for (let i1 = 0; i1 < 8; i1++) { 326 for (let i2 = 0; i2 < 8; i2++) { 327 let x = gp.gap + i2 * (gp.sz + gp.gap); 328 let y = gp.gap + i1 * (gp.sz + gp.gap); 329 mp.ctx.beginPath(); 330 mp.ctx.fillStyle = "rgb(0, 255, 0)"; 331 mp.ctx.fillRect(x, y, gp.sz, gp.sz); 332 mp.ctx.fill(); 333 if (gp.st[i1][i2] != 0) { 334 x += Math.floor(gp.sz / 2); 335 y += Math.floor(gp.sz / 2); 336 mp.ctx.beginPath(); 337 if (gp.st[i1][i2] < 0) 338 mp.ctx.fillStyle = "rgb(0, 0, 0)"; 339 else 340 mp.ctx.fillStyle = "rgb(255, 255, 255)"; 341 mp.ctx.arc(x, y, Math.floor(gp.sz/2)-2, 0, 2*Math.PI); 342 mp.ctx.fill(); 343 } 344 } 345 } 346 }
情報学部 | 菅沼ホーム | JavaScript 目次 | 索引 |