diff --git a/src/api/models/othello-game.ts b/src/api/models/othello-game.ts index b9d33007b..a8c302510 100644 --- a/src/api/models/othello-game.ts +++ b/src/api/models/othello-game.ts @@ -31,6 +31,7 @@ export interface IGame { bw: string | number; is_llotheo: boolean; can_put_everywhere: boolean; + looped_board: boolean; }; } diff --git a/src/api/stream/othello-game.ts b/src/api/stream/othello-game.ts index 05f244f76..5f61f0cc2 100644 --- a/src/api/stream/othello-game.ts +++ b/src/api/stream/othello-game.ts @@ -126,7 +126,8 @@ export default function(request: websocket.request, connection: websocket.connec //#region 盤面に最初から石がないなどして始まった瞬間に勝敗が決定する場合があるのでその処理 const o = new Othello(map, { isLlotheo: freshGame.settings.is_llotheo, - canPutEverywhere: freshGame.settings.can_put_everywhere + canPutEverywhere: freshGame.settings.can_put_everywhere, + loopedBoard: freshGame.settings.looped_board }); if (o.isEnded) { @@ -168,7 +169,8 @@ export default function(request: websocket.request, connection: websocket.connec const o = new Othello(game.settings.map, { isLlotheo: game.settings.is_llotheo, - canPutEverywhere: game.settings.can_put_everywhere + canPutEverywhere: game.settings.can_put_everywhere, + loopedBoard: game.settings.looped_board }); game.logs.forEach(log => { diff --git a/src/common/othello/core.ts b/src/common/othello/core.ts index 851f1b79c..418b461c6 100644 --- a/src/common/othello/core.ts +++ b/src/common/othello/core.ts @@ -4,6 +4,7 @@ export type MapPixel = 'null' | 'empty'; export type Options = { isLlotheo: boolean; canPutEverywhere: boolean; + loopedBoard: boolean; }; /** @@ -31,6 +32,7 @@ export default class Othello { this.opts = opts; if (this.opts.isLlotheo == null) this.opts.isLlotheo = false; if (this.opts.canPutEverywhere == null) this.opts.canPutEverywhere = false; + if (this.opts.loopedBoard == null) this.opts.loopedBoard = false; //#endregion //#region Parse map data @@ -206,21 +208,50 @@ export default class Othello { */ private effects(color: Color, pos: number): number[] { const enemyColor = color == 'black' ? 'white' : 'black'; - const [x, y] = this.transformPosToXy(pos); + + // ひっくり返せる石(の位置)リスト let stones = []; + const initPos = pos; + + // 走査 const iterate = (fn: (i: number) => number[]) => { let i = 1; const found = []; + while (true) { - const [x, y] = fn(i); - if (x < 0 || y < 0 || x >= this.mapWidth || y >= this.mapHeight) break; + let [x, y] = fn(i); + + // 座標が指し示す位置がボード外に出たとき + if (this.opts.loopedBoard) { + if (x < 0 ) x = this.mapWidth - (-x); + if (y < 0 ) y = this.mapHeight - (-y); + if (x >= this.mapWidth ) x = x - this.mapWidth; + if (y >= this.mapHeight) y = y - this.mapHeight; + + // 一周して自分に帰ってきたら + if (this.transformXyToPos(x, y) == initPos) break; + } else { + if (x == -1 || y == -1 || x == this.mapWidth || y == this.mapHeight) break; + } + const pos = this.transformXyToPos(x, y); + + //#region 「配置不能」マスに当たった場合走査終了 const pixel = this.mapDataGet(pos); if (pixel == 'null') break; + //#endregion + + // 石取得 const stone = this.get(pos); + + // 石が置かれていないマスなら走査終了 if (stone == null) break; + + // 相手の石なら「ひっくり返せるかもリスト」に入れておく if (stone == enemyColor) found.push(pos); + + // 自分の石なら「ひっくり返せるかもリスト」を「ひっくり返せるリスト」に入れ、走査終了 if (stone == color) { stones = stones.concat(found); break; @@ -229,6 +260,8 @@ export default class Othello { } }; + const [x, y] = this.transformPosToXy(pos); + iterate(i => [x , y - i]); // 上 iterate(i => [x + i, y - i]); // 右上 iterate(i => [x + i, y ]); // 右 diff --git a/src/common/othello/maps.ts b/src/common/othello/maps.ts index a6a1c4604..3518259bb 100644 --- a/src/common/othello/maps.ts +++ b/src/common/othello/maps.ts @@ -793,7 +793,7 @@ export const twoBoard: Map = { ] }; -export const test: Map = { +export const test1: Map = { name: 'Test1', category: 'Test', data: [ @@ -803,3 +803,15 @@ export const test: Map = { '--------' ] }; + +export const test2: Map = { + name: 'Test2', + category: 'Test', + data: [ + '------', + '------', + '-b--w-', + '-w--b-', + '-w--b-' + ] +}; diff --git a/src/web/app/common/views/components/othello.game.vue b/src/web/app/common/views/components/othello.game.vue index fa3ed8d9a..a84dcedd4 100644 --- a/src/web/app/common/views/components/othello.game.vue +++ b/src/web/app/common/views/components/othello.game.vue @@ -90,7 +90,8 @@ export default Vue.extend({ if (!this.game.is_ended) return; this.o = new Othello(this.game.settings.map, { isLlotheo: this.game.settings.is_llotheo, - canPutEverywhere: this.game.settings.can_put_everywhere + canPutEverywhere: this.game.settings.can_put_everywhere, + loopedBoard: this.game.settings.looped_board }); this.logs.forEach((log, i) => { if (i < v) { @@ -104,7 +105,8 @@ export default Vue.extend({ created() { this.o = new Othello(this.game.settings.map, { isLlotheo: this.game.settings.is_llotheo, - canPutEverywhere: this.game.settings.can_put_everywhere + canPutEverywhere: this.game.settings.can_put_everywhere, + loopedBoard: this.game.settings.looped_board }); this.game.logs.forEach(log => { diff --git a/src/web/app/common/views/components/othello.room.vue b/src/web/app/common/views/components/othello.room.vue index b7c28ae67..dfdc43ef9 100644 --- a/src/web/app/common/views/components/othello.room.vue +++ b/src/web/app/common/views/components/othello.room.vue @@ -26,6 +26,7 @@
+
ランダム