mirror of
https://activitypub.software/TransFem-org/Sharkey
synced 2024-11-27 00:13:03 +00:00
ループモード実装
This commit is contained in:
parent
e4aabf9357
commit
e6d2cbe6a3
6 changed files with 59 additions and 8 deletions
|
@ -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;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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 => {
|
||||||
|
|
|
@ -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 ]); // 右
|
||||||
|
|
|
@ -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-'
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
|
@ -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 => {
|
||||||
|
|
|
@ -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>
|
||||||
|
|
Loading…
Reference in a new issue