wip
This commit is contained in:
		
							parent
							
								
									161fd4afab
								
							
						
					
					
						commit
						0bca0e8a02
					
				|  | @ -475,8 +475,8 @@ class OthelloContext extends Context { | |||
| 		othelloAi('white', this.othello); | ||||
| 		if (this.othello.getPattern('black').length === 0) { | ||||
| 			this.bot.clearContext(); | ||||
| 			const blackCount = this.othello.board.map(row => row.filter(s => s == 'black').length).reduce((a, b) => a + b); | ||||
| 			const whiteCount = this.othello.board.map(row => row.filter(s => s == 'white').length).reduce((a, b) => a + b); | ||||
| 			const blackCount = this.othello.board.filter(s => s == 'black').length; | ||||
| 			const whiteCount = this.othello.board.filter(s => s == 'white').length; | ||||
| 			const winner = blackCount == whiteCount ? '引き分け' : blackCount > whiteCount ? '黒の勝ち' : '白の勝ち'; | ||||
| 			return this.othello.toString() + `\n\n~終了~\n\n黒${blackCount}、白${whiteCount}で${winner}です。`; | ||||
| 		} else { | ||||
|  |  | |||
|  | @ -3,7 +3,7 @@ import Game, { pack } from '../../models/othello-game'; | |||
| 
 | ||||
| module.exports = (params, user) => new Promise(async (res, rej) => { | ||||
| 	// Get 'my' parameter
 | ||||
| 	const [my = false, myErr] = $(params.my).boolean().$; | ||||
| 	const [my = false, myErr] = $(params.my).optional.boolean().$; | ||||
| 	if (myErr) return rej('invalid my param'); | ||||
| 
 | ||||
| 	const q = my ? { | ||||
|  |  | |||
|  | @ -34,6 +34,7 @@ module.exports = (params, user) => new Promise(async (res, rej) => { | |||
| 			black_user_id: parentIsBlack ? exist.parent_id : user._id, | ||||
| 			white_user_id: parentIsBlack ? user._id : exist.parent_id, | ||||
| 			turn_user_id: parentIsBlack ? exist.parent_id : user._id, | ||||
| 			is_ended: false, | ||||
| 			logs: [] | ||||
| 		}); | ||||
| 
 | ||||
|  |  | |||
|  | @ -11,6 +11,9 @@ export interface IGame { | |||
| 	created_at: Date; | ||||
| 	black_user_id: mongo.ObjectID; | ||||
| 	white_user_id: mongo.ObjectID; | ||||
| 	turn_user_id: mongo.ObjectID; | ||||
| 	is_ended: boolean; | ||||
| 	winner_id: mongo.ObjectID; | ||||
| 	logs: any[]; | ||||
| } | ||||
| 
 | ||||
|  | @ -40,6 +43,7 @@ export const pack = ( | |||
| 	// Populate user
 | ||||
| 	_game.black_user = await packUser(_game.black_user_id, meId); | ||||
| 	_game.white_user = await packUser(_game.white_user_id, meId); | ||||
| 	_game.winner = await packUser(_game.winner_id, meId); | ||||
| 
 | ||||
| 	resolve(_game); | ||||
| }); | ||||
|  |  | |||
|  | @ -19,51 +19,68 @@ export default function(request: websocket.request, connection: websocket.connec | |||
| 		switch (msg.type) { | ||||
| 			case 'set': | ||||
| 				if (msg.pos == null) return; | ||||
| 				const pos = msg.pos; | ||||
| 
 | ||||
| 				const game = await Game.findOne({ _id: gameId }); | ||||
| 
 | ||||
| 				const o = new Othello(); | ||||
| 
 | ||||
| 				game.logs.forEach(log => { | ||||
| 					o.set(log.color, log.pos); | ||||
| 				}); | ||||
| 
 | ||||
| 				const myColor = game.black_user_id.equals(user._id) ? 'black' : 'white'; | ||||
| 				const opColor = myColor == 'black' ? 'white' : 'black'; | ||||
| 
 | ||||
| 				if (!o.canReverse(myColor, pos)) return; | ||||
| 				o.set(myColor, pos); | ||||
| 
 | ||||
| 				let turn; | ||||
| 				if (o.getPattern(opColor).length > 0) { | ||||
| 					turn = myColor == 'black' ? game.white_user_id : game.black_user_id; | ||||
| 				} else { | ||||
| 					turn = myColor == 'black' ? game.black_user_id : game.white_user_id; | ||||
| 				} | ||||
| 
 | ||||
| 				const log = { | ||||
| 					at: new Date(), | ||||
| 					color: myColor, | ||||
| 					pos | ||||
| 				}; | ||||
| 
 | ||||
| 				await Game.update({ | ||||
| 					_id: gameId | ||||
| 				}, { | ||||
| 					$set: { | ||||
| 						turn_user_id: turn | ||||
| 					}, | ||||
| 					$push: { | ||||
| 						logs: log | ||||
| 					} | ||||
| 				}); | ||||
| 
 | ||||
| 				publishOthelloGameStream(gameId, 'set', { | ||||
| 					color: myColor, | ||||
| 					pos | ||||
| 				}); | ||||
| 				set(msg.pos); | ||||
| 				break; | ||||
| 		} | ||||
| 	}); | ||||
| 
 | ||||
| 	async function set(pos) { | ||||
| 		const game = await Game.findOne({ _id: gameId }); | ||||
| 
 | ||||
| 		if (game.is_ended) return; | ||||
| 
 | ||||
| 		const o = new Othello(); | ||||
| 
 | ||||
| 		game.logs.forEach(log => { | ||||
| 			o.set(log.color, log.pos); | ||||
| 		}); | ||||
| 
 | ||||
| 		const myColor = game.black_user_id.equals(user._id) ? 'black' : 'white'; | ||||
| 		const opColor = myColor == 'black' ? 'white' : 'black'; | ||||
| 
 | ||||
| 		if (!o.canReverse(myColor, pos)) return; | ||||
| 		o.set(myColor, pos); | ||||
| 
 | ||||
| 		let turn; | ||||
| 		if (o.getPattern(opColor).length > 0) { | ||||
| 			turn = myColor == 'black' ? game.white_user_id : game.black_user_id; | ||||
| 		} else if (o.getPattern(myColor).length > 0) { | ||||
| 			turn = myColor == 'black' ? game.black_user_id : game.white_user_id; | ||||
| 		} else { | ||||
| 			turn = null; | ||||
| 		} | ||||
| 
 | ||||
| 		const isEnded = turn === null; | ||||
| 
 | ||||
| 		let winner; | ||||
| 		if (isEnded) { | ||||
| 			const blackCount = o.board.filter(s => s == 'black').length; | ||||
| 			const whiteCount = o.board.filter(s => s == 'white').length; | ||||
| 			winner = blackCount == whiteCount ? null : blackCount > whiteCount ? game.black_user_id : game.white_user_id; | ||||
| 		} | ||||
| 
 | ||||
| 		const log = { | ||||
| 			at: new Date(), | ||||
| 			color: myColor, | ||||
| 			pos | ||||
| 		}; | ||||
| 
 | ||||
| 		await Game.update({ | ||||
| 			_id: gameId | ||||
| 		}, { | ||||
| 			$set: { | ||||
| 				turn_user_id: turn, | ||||
| 				is_ended: isEnded, | ||||
| 				winner_id: winner | ||||
| 			}, | ||||
| 			$push: { | ||||
| 				logs: log | ||||
| 			} | ||||
| 		}); | ||||
| 
 | ||||
| 		publishOthelloGameStream(gameId, 'set', { | ||||
| 			color: myColor, | ||||
| 			pos | ||||
| 		}); | ||||
| 	} | ||||
| } | ||||
|  |  | |||
|  | @ -1,10 +1,15 @@ | |||
| <template> | ||||
| <div class="root"> | ||||
| 	<header><b>{{ game.black_user.name }}</b>(黒) vs <b>{{ game.white_user.name }}</b>(白)</header> | ||||
| 	<p class="turn">{{ turn ? 'あなたのターンです' : '相手のターンです' }}<mk-ellipsis v-if="!turn"/></p> | ||||
| 	<p class="turn" v-if="!iAmPlayer && !isEnded">{{ turn.name }}のターンです<mk-ellipsis/></p> | ||||
| 	<p class="turn" v-if="iAmPlayer && !isEnded">{{ isMyTurn ? 'あなたのターンです' : '相手のターンです' }}<mk-ellipsis v-if="!isMyTurn"/></p> | ||||
| 	<p class="result" v-if="isEnded"> | ||||
| 		<template v-if="winner"><b>{{ winner.name }}</b>の勝ち</template> | ||||
| 		<template v-else>引き分け</template> | ||||
| 	</p> | ||||
| 	<div> | ||||
| 		<div v-for="(stone, i) in o.board" | ||||
| 			:class="{ empty: stone == null, myTurn: turn, can: o.canReverse(turn ? myColor : opColor, i) }" | ||||
| 			:class="{ empty: stone == null, myTurn: isMyTurn, can: o.canReverse(turn.id == game.black_user.id ? 'black' : 'white', i) }" | ||||
| 			@click="set(i)" | ||||
| 		> | ||||
| 			<img v-if="stone == 'black'" :src="`${game.black_user.avatar_url}?thumbnail&size=64`" alt=""> | ||||
|  | @ -25,10 +30,16 @@ export default Vue.extend({ | |||
| 		return { | ||||
| 			o: new Othello(), | ||||
| 			turn: null, | ||||
| 			isMyTurn: null, | ||||
| 			isEnded: false, | ||||
| 			winner: null, | ||||
| 			connection: null | ||||
| 		}; | ||||
| 	}, | ||||
| 	computed: { | ||||
| 		iAmPlayer(): boolean { | ||||
| 			return this.game.black_user_id == (this as any).os.i.id || this.game.white_user_id == (this as any).os.i.id; | ||||
| 		}, | ||||
| 		myColor(): string { | ||||
| 			return this.game.black_user_id == (this as any).os.i.id ? 'black' : 'white'; | ||||
| 		}, | ||||
|  | @ -41,7 +52,10 @@ export default Vue.extend({ | |||
| 			this.o.set(log.color, log.pos); | ||||
| 		}); | ||||
| 
 | ||||
| 		this.turn = this.game.turn_user_id == (this as any).os.i.id; | ||||
| 		this.turn = this.game.turn_user_id == this.game.black_user_id ? this.game.black_user : this.game.white_user; | ||||
| 		this.isMyTurn = this.game.turn_user_id == (this as any).os.i.id; | ||||
| 		this.isEnded = this.game.is_ended; | ||||
| 		this.winner = this.game.winner; | ||||
| 	}, | ||||
| 	mounted() { | ||||
| 		this.connection = new OthelloGameStream((this as any).os.i, this.game); | ||||
|  | @ -53,11 +67,17 @@ export default Vue.extend({ | |||
| 	}, | ||||
| 	methods: { | ||||
| 		set(pos) { | ||||
| 			if (!this.turn) return; | ||||
| 			if (!this.isMyTurn) return; | ||||
| 			if (!this.o.canReverse(this.myColor, pos)) return; | ||||
| 			this.o.set(this.myColor, pos); | ||||
| 			if (this.o.getPattern(this.opColor).length > 0) { | ||||
| 				this.turn = !this.turn; | ||||
| 				this.isMyTurn = !this.isMyTurn; | ||||
| 				this.turn = this.myColor == 'black' ? this.game.white_user : this.game.black_user; | ||||
| 			} else if (this.o.getPattern(this.myColor).length == 0) { | ||||
| 				this.isEnded = true; | ||||
| 				const blackCount = this.o.board.filter(s => s == 'black').length; | ||||
| 				const whiteCount = this.o.board.filter(s => s == 'white').length; | ||||
| 				this.winner = blackCount == whiteCount ? null : blackCount > whiteCount ? this.game.black_user : this.game.white_user; | ||||
| 			} | ||||
| 			this.connection.send({ | ||||
| 				type: 'set', | ||||
|  | @ -67,8 +87,28 @@ export default Vue.extend({ | |||
| 		}, | ||||
| 		onSet(x) { | ||||
| 			this.o.set(x.color, x.pos); | ||||
| 			if (this.o.getPattern(this.myColor).length > 0) { | ||||
| 				this.turn = true; | ||||
| 			if (this.o.getPattern('black').length == 0 && this.o.getPattern('white').length == 0) { | ||||
| 				this.isEnded = true; | ||||
| 				const blackCount = this.o.board.filter(s => s == 'black').length; | ||||
| 				const whiteCount = this.o.board.filter(s => s == 'white').length; | ||||
| 				this.winner = blackCount == whiteCount ? null : blackCount > whiteCount ? this.game.black_user : this.game.white_user; | ||||
| 			} else { | ||||
| 				if (this.iAmPlayer && this.o.getPattern(this.myColor).length > 0) { | ||||
| 					this.isMyTurn = true; | ||||
| 				} | ||||
| 
 | ||||
| 				if (x.color == 'black' && this.o.getPattern('white').length > 0) { | ||||
| 					this.turn = this.game.white_user; | ||||
| 				} | ||||
| 				if (x.color == 'black' && this.o.getPattern('white').length == 0) { | ||||
| 					this.turn = this.game.black_user; | ||||
| 				} | ||||
| 				if (x.color == 'white' && this.o.getPattern('black').length > 0) { | ||||
| 					this.turn = this.game.black_user; | ||||
| 				} | ||||
| 				if (x.color == 'white' && this.o.getPattern('black').length == 0) { | ||||
| 					this.turn = this.game.white_user; | ||||
| 				} | ||||
| 			} | ||||
| 			this.$forceUpdate(); | ||||
| 		} | ||||
|  |  | |||
|  | @ -43,11 +43,17 @@ | |||
| 				<img :src="`${g.black_user.avatar_url}?thumbnail&size=32`" alt=""> | ||||
| 				<img :src="`${g.white_user.avatar_url}?thumbnail&size=32`" alt=""> | ||||
| 				<span><b>{{ g.black_user.name }}</b> vs <b>{{ g.white_user.name }}</b></span> | ||||
| 				<span class="state">{{ g.winner ? '終了' : '進行中' }}</span> | ||||
| 				<span class="state">{{ g.is_ended ? '終了' : '進行中' }}</span> | ||||
| 			</div> | ||||
| 		</section> | ||||
| 		<section> | ||||
| 		<section v-if="games.length > 0"> | ||||
| 			<h2>みんなの対局</h2> | ||||
| 			<div class="game" v-for="g in games" tabindex="-1" @click="game = g"> | ||||
| 				<img :src="`${g.black_user.avatar_url}?thumbnail&size=32`" alt=""> | ||||
| 				<img :src="`${g.white_user.avatar_url}?thumbnail&size=32`" alt=""> | ||||
| 				<span><b>{{ g.black_user.name }}</b> vs <b>{{ g.white_user.name }}</b></span> | ||||
| 				<span class="state">{{ g.is_ended ? '終了' : '進行中' }}</span> | ||||
| 			</div> | ||||
| 		</section> | ||||
| 	</div> | ||||
| </div> | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue