diff options
| author | syuilo <syuilotan@yahoo.co.jp> | 2018-03-07 21:57:06 +0900 |
|---|---|---|
| committer | syuilo <syuilotan@yahoo.co.jp> | 2018-03-07 21:57:06 +0900 |
| commit | 50e40ed61e8226ecbb7f1d7d53ba028fad1a9a01 (patch) | |
| tree | 92c564d99f45e3fd747cae5a4007d486ca6a3a67 /src/web/app/common | |
| parent | Fix bug (diff) | |
| download | misskey-50e40ed61e8226ecbb7f1d7d53ba028fad1a9a01.tar.gz misskey-50e40ed61e8226ecbb7f1d7d53ba028fad1a9a01.tar.bz2 misskey-50e40ed61e8226ecbb7f1d7d53ba028fad1a9a01.zip | |
:v:
Diffstat (limited to 'src/web/app/common')
| -rw-r--r-- | src/web/app/common/views/components/othello.game.vue | 97 |
1 files changed, 88 insertions, 9 deletions
diff --git a/src/web/app/common/views/components/othello.game.vue b/src/web/app/common/views/components/othello.game.vue index b7c23e704e..70c9965ee4 100644 --- a/src/web/app/common/views/components/othello.game.vue +++ b/src/web/app/common/views/components/othello.game.vue @@ -2,12 +2,13 @@ <div class="root"> <header><b>{{ game.black_user.name }}</b>(黒) vs <b>{{ game.white_user.name }}</b>(白)</header> <p class="turn" v-if="!iAmPlayer && !isEnded">{{ turn.name }}のターンです<mk-ellipsis/></p> + <p class="turn" v-if="logPos != logs.length">{{ turn.name }}のターン</p> <p class="turn" v-if="iAmPlayer && !isEnded">{{ isMyTurn ? 'あなたのターンです' : '相手のターンです' }}<mk-ellipsis v-if="!isMyTurn"/></p> - <p class="result" v-if="isEnded"> + <p class="result" v-if="isEnded && logPos == logs.length"> <template v-if="winner"><b>{{ winner.name }}</b>の勝ち</template> <template v-else>引き分け</template> </p> - <div> + <div class="board"> <div v-for="(stone, i) in o.board" :class="{ empty: stone == null, myTurn: isMyTurn, can: o.canReverse(turn.id == game.black_user.id ? 'black' : 'white', i) }" @click="set(i)" @@ -16,6 +17,22 @@ <img v-if="stone == 'white'" :src="`${game.white_user.avatar_url}?thumbnail&size=64`" alt=""> </div> </div> + <p>黒:{{ o.blackCount }} 白:{{ o.whiteCount }} 合計:{{ o.blackCount + o.whiteCount }}</p> + <div class="graph"> + <div v-for="n in 61 - o.stats.length"> + </div> + <div v-for="data in o.stats"> + <div :style="{ height: `${ Math.floor(data.b * 100) }%` }"></div> + <div :style="{ height: `${ Math.floor(data.w * 100) }%` }"></div> + </div> + </div> + <div class="player" v-if="isEnded"> + <el-button type="primary" @click="logPos = 0" :disabled="logPos == 0">%fa:fast-backward%</el-button> + <el-button type="primary" @click="logPos--" :disabled="logPos == 0">%fa:backward%</el-button> + <span>{{ logPos }} / {{ logs.length }}</span> + <el-button type="primary" @click="logPos++" :disabled="logPos == logs.length">%fa:forward%</el-button> + <el-button type="primary" @click="logPos = logs.length" :disabled="logPos == logs.length">%fa:fast-forward%</el-button> + </div> </div> </template> @@ -26,9 +43,12 @@ import Othello from '../../../../../common/othello'; export default Vue.extend({ props: ['game'], + data() { return { o: new Othello(), + logs: [], + logPos: 0, turn: null, isMyTurn: null, isEnded: false, @@ -36,6 +56,7 @@ export default Vue.extend({ 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; @@ -47,24 +68,57 @@ export default Vue.extend({ return this.myColor == 'black' ? 'white' : 'black'; } }, + + watch: { + logPos(v) { + if (!this.isEnded) return; + this.o = new Othello(); + this.turn = this.game.black_user; + this.logs.forEach((log, i) => { + if (i < v) { + this.o.set(log.color, log.pos); + + if (log.color == 'black' && this.o.getPattern('white').length > 0) { + this.turn = this.game.white_user; + } + if (log.color == 'black' && this.o.getPattern('white').length == 0) { + this.turn = this.game.black_user; + } + if (log.color == 'white' && this.o.getPattern('black').length > 0) { + this.turn = this.game.black_user; + } + if (log.color == 'white' && this.o.getPattern('black').length == 0) { + this.turn = this.game.white_user; + } + } + }); + this.$forceUpdate(); + } + }, + created() { this.game.logs.forEach(log => { this.o.set(log.color, log.pos); }); + this.logs = this.game.logs; + this.logPos = this.logs.length; 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); this.connection.on('set', this.onSet); }, + beforeDestroy() { this.connection.off('set', this.onSet); this.connection.close(); }, + methods: { set(pos) { if (!this.isMyTurn) return; @@ -75,9 +129,7 @@ export default Vue.extend({ 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.winner = this.o.blackCount == this.o.whiteCount ? null : this.o.blackCount > this.o.whiteCount ? this.game.black_user : this.game.white_user; } this.connection.send({ type: 'set', @@ -85,13 +137,15 @@ export default Vue.extend({ }); this.$forceUpdate(); }, + onSet(x) { + this.logs.push(x); + this.logPos++; this.o.set(x.color, x.pos); + 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; + this.winner = this.o.blackCount == this.o.whiteCount ? null : this.o.blackCount > this.o.whiteCount ? this.game.black_user : this.game.white_user; } else { if (this.iAmPlayer && this.o.getPattern(this.myColor).length > 0) { this.isMyTurn = true; @@ -126,7 +180,7 @@ export default Vue.extend({ padding 8px border-bottom dashed 1px #c4cdd4 - > div + > .board display grid grid-template-rows repeat(8, 1fr) grid-template-columns repeat(8, 1fr) @@ -168,4 +222,29 @@ export default Vue.extend({ display block width 100% height 100% + + > .graph + display grid + grid-template-columns repeat(61, 1fr) + width 300px + height 38px + margin 0 auto 16px auto + + > div + &:not(:empty) + background #ccc + + > div:first-child + background #333 + + > div:last-child + background #ccc + + > .player + margin-bottom 16px + + > span + display inline-block + margin 0 8px + min-width 70px </style> |