<!DOCTYPE html><html><head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>マルチ オセロ</title> <link rel="stylesheet" type="text/css" href="styles.css"> <script defer src="settings.js"></script> <script defer src="utils.js"></script> <script defer src="Color.js"></script> <script defer src="Board.js"></script> <script defer src="Game.js"></script> <script defer src="Information.js"></script> <script defer src="Message.js"></script> <script defer src="Player.js"></script> <script defer src="Square.js"></script> <script defer src="State.js"></script> <script defer src="Stone.js"></script> <script defer src="Strategy.js"></script> <script defer src="main.js"></script></head><body> <div id="reversi"> <!-- 情報板 --> <div id="information"> <table> <thead> <tr> <th></th> <th></th> <th></th> <th class="num-area">石の数</th> <th class="num-area">勝ち数</th> </tr> </thead> <tbody id="information-body"> </tbody> </table> </div> <!-- 盤面 --> <div id="board"> </div> </div> <!-- メッセージ --> <div id="message"> </div></body></html>
class Color { constructor(colorCode) { this.colorCode = colorCode; this.members = []; this.stoneCount = 0; this.winCount = 0; } getCurrentPlayer () { // 現在が何巡目かを計算する。最初の巡目は0巡目となる // たとえば、石の色の数が3種類、ターン数が4の場合, // 7/3=1.33から小数点を切り捨てて、現在は1巡目となる const round = Math.trunc(state.turnCount / state.colors.length); // 巡目数をこの色のメンバー数で割った余りが現在のプレイヤーの配列番号となる // たとえば、メンバー数が2人で5巡目の場合、, // 5÷2の余りは1となりthis.members[1]が現在のプレイヤーとなる return this.members[round % this.members.length]; }}
class Square { constructor(rowIndex, columnIndex) { this.rowIndex = rowIndex; this.columnIndex = columnIndex; // 行番号と列番号をIDに持つdiv要素がすでに作成されているのでそれを取得する this.element = document.getElementById(`index-${rowIndex}-${columnIndex}`); this.element.classList.add('square'); this.element.addEventListener('click', this.click.bind(this)); this.stone = null; this.sandwichStones = []; // 角のマス目か否かを行番号と列番号から判別する this.isCorner = rowIndex === 0 && columnIndex === 0 || rowIndex === 0 && columnIndex === initialBoard[0].length - 1 || rowIndex === initialBoard.length - 1 && columnIndex === 0 || rowIndex === initialBoard.length - 1 && columnIndex === initialBoard[0].length - 1; // 空のマス目の個数を一つ増やす state.emptySquareCount++; } setNewStone (color) { this.stone = new Stone(color); // マス目のdiv要素に石のdiv要素を入れる this.element.append(this.stone.element); // 空のマス目の個数を一つ減らす state.emptySquareCount--; } isSelectable () { // このマス目に石が置いていない、かつ挟める石がある場合は石を置ける return this.stone === null && this.sandwichStones.length !== 0; } select () { this.setNewStone(state.currentPlayer.color); state.sandwichedStones = this.sandwichStones; // ゲームを進行する game.update(); } click () { // 現在のプレイヤーがヒトで、かつ石を置くことができるマス目であれば石を置く // こうすることで無関係なマス目をクリックしても何も起きないようにする if (state.currentPlayer.isHuman() && this.isSelectable()) { this.select(); } } setSandwichStones (sandwichStones) { this.sandwichStones = sandwichStones; // 現在のプレイヤーがヒトの場合、マス目の上に矢印を表示したりけしたりする if (state.currentPlayer.isHuman()) { if (this.isSelectable()) { this.element.classList.add('selectable'); } else { this.element.classList.remove('selectable'); } } } removeStone () { if (this.stone) { // 石のdiv要素を除去する this.stone.remove(); this.stone = null; // 空のマス目の個数を一つ増やす state.emptySquareCount++; } }}