| 情報学部 | 菅沼ホーム | 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 目次 | 索引 |