ループモード実装
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;
 | 
			
		||||
		is_llotheo: boolean;
 | 
			
		||||
		can_put_everywhere: boolean;
 | 
			
		||||
		looped_board: boolean;
 | 
			
		||||
	};
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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 => {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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    ]); // 右
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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-'
 | 
			
		||||
	]
 | 
			
		||||
};
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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 => {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -26,6 +26,7 @@
 | 
			
		|||
 | 
			
		||||
	<div class="rules">
 | 
			
		||||
		<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="どこでも置けるモード"/>
 | 
			
		||||
		<div>
 | 
			
		||||
			<el-radio v-model="game.settings.bw" label="random" @change="updateSettings">ランダム</el-radio>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue