ループモード実装

This commit is contained in:
syuilo 2018-03-10 21:23:00 +09:00
parent e4aabf9357
commit e6d2cbe6a3
6 changed files with 59 additions and 8 deletions

View file

@ -31,6 +31,7 @@ export interface IGame {
bw: string | number; bw: string | number;
is_llotheo: boolean; is_llotheo: boolean;
can_put_everywhere: boolean; can_put_everywhere: boolean;
looped_board: boolean;
}; };
} }

View file

@ -126,7 +126,8 @@ export default function(request: websocket.request, connection: websocket.connec
//#region 盤面に最初から石がないなどして始まった瞬間に勝敗が決定する場合があるのでその処理 //#region 盤面に最初から石がないなどして始まった瞬間に勝敗が決定する場合があるのでその処理
const o = new Othello(map, { const o = new Othello(map, {
isLlotheo: freshGame.settings.is_llotheo, 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) { if (o.isEnded) {
@ -168,7 +169,8 @@ export default function(request: websocket.request, connection: websocket.connec
const o = new Othello(game.settings.map, { const o = new Othello(game.settings.map, {
isLlotheo: game.settings.is_llotheo, 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 => { game.logs.forEach(log => {

View file

@ -4,6 +4,7 @@ export type MapPixel = 'null' | 'empty';
export type Options = { export type Options = {
isLlotheo: boolean; isLlotheo: boolean;
canPutEverywhere: boolean; canPutEverywhere: boolean;
loopedBoard: boolean;
}; };
/** /**
@ -31,6 +32,7 @@ export default class Othello {
this.opts = opts; this.opts = opts;
if (this.opts.isLlotheo == null) this.opts.isLlotheo = false; if (this.opts.isLlotheo == null) this.opts.isLlotheo = false;
if (this.opts.canPutEverywhere == null) this.opts.canPutEverywhere = false; if (this.opts.canPutEverywhere == null) this.opts.canPutEverywhere = false;
if (this.opts.loopedBoard == null) this.opts.loopedBoard = false;
//#endregion //#endregion
//#region Parse map data //#region Parse map data
@ -206,21 +208,50 @@ export default class Othello {
*/ */
private effects(color: Color, pos: number): number[] { private effects(color: Color, pos: number): number[] {
const enemyColor = color == 'black' ? 'white' : 'black'; const enemyColor = color == 'black' ? 'white' : 'black';
const [x, y] = this.transformPosToXy(pos);
// ひっくり返せる石(の位置)リスト
let stones = []; let stones = [];
const initPos = pos;
// 走査
const iterate = (fn: (i: number) => number[]) => { const iterate = (fn: (i: number) => number[]) => {
let i = 1; let i = 1;
const found = []; const found = [];
while (true) { while (true) {
const [x, y] = fn(i); let [x, y] = fn(i);
if (x < 0 || y < 0 || x >= this.mapWidth || y >= this.mapHeight) break;
// 座標が指し示す位置がボード外に出たとき
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); const pos = this.transformXyToPos(x, y);
//#region 「配置不能」マスに当たった場合走査終了
const pixel = this.mapDataGet(pos); const pixel = this.mapDataGet(pos);
if (pixel == 'null') break; if (pixel == 'null') break;
//#endregion
// 石取得
const stone = this.get(pos); const stone = this.get(pos);
// 石が置かれていないマスなら走査終了
if (stone == null) break; if (stone == null) break;
// 相手の石なら「ひっくり返せるかもリスト」に入れておく
if (stone == enemyColor) found.push(pos); if (stone == enemyColor) found.push(pos);
// 自分の石なら「ひっくり返せるかもリスト」を「ひっくり返せるリスト」に入れ、走査終了
if (stone == color) { if (stone == color) {
stones = stones.concat(found); stones = stones.concat(found);
break; break;
@ -229,6 +260,8 @@ export default class Othello {
} }
}; };
const [x, y] = this.transformPosToXy(pos);
iterate(i => [x , y - i]); // 上 iterate(i => [x , y - i]); // 上
iterate(i => [x + i, y - i]); // 右上 iterate(i => [x + i, y - i]); // 右上
iterate(i => [x + i, y ]); // 右 iterate(i => [x + i, y ]); // 右

View file

@ -793,7 +793,7 @@ export const twoBoard: Map = {
] ]
}; };
export const test: Map = { export const test1: Map = {
name: 'Test1', name: 'Test1',
category: 'Test', category: 'Test',
data: [ data: [
@ -803,3 +803,15 @@ export const test: Map = {
'--------' '--------'
] ]
}; };
export const test2: Map = {
name: 'Test2',
category: 'Test',
data: [
'------',
'------',
'-b--w-',
'-w--b-',
'-w--b-'
]
};

View file

@ -90,7 +90,8 @@ export default Vue.extend({
if (!this.game.is_ended) return; if (!this.game.is_ended) return;
this.o = new Othello(this.game.settings.map, { this.o = new Othello(this.game.settings.map, {
isLlotheo: this.game.settings.is_llotheo, 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) => { this.logs.forEach((log, i) => {
if (i < v) { if (i < v) {
@ -104,7 +105,8 @@ export default Vue.extend({
created() { created() {
this.o = new Othello(this.game.settings.map, { this.o = new Othello(this.game.settings.map, {
isLlotheo: this.game.settings.is_llotheo, 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 => { this.game.logs.forEach(log => {

View file

@ -26,6 +26,7 @@
<div class="rules"> <div class="rules">
<mk-switch v-model="game.settings.is_llotheo" @change="updateSettings" text="石の少ない方が勝ち(ロセオ)"/> <mk-switch v-model="game.settings.is_llotheo" @change="updateSettings" text="石の少ない方が勝ち(ロセオ)"/>
<mk-switch v-model="game.settings.looped_board" @change="updateSettings" text="ループマップ"/>
<mk-switch v-model="game.settings.can_put_everywhere" @change="updateSettings" text="どこでも置けるモード"/> <mk-switch v-model="game.settings.can_put_everywhere" @change="updateSettings" text="どこでも置けるモード"/>
<div> <div>
<el-radio v-model="game.settings.bw" label="random" @change="updateSettings">ランダム</el-radio> <el-radio v-model="game.settings.bw" label="random" @change="updateSettings">ランダム</el-radio>