なんかもうめっちゃ変えた

This commit is contained in:
syuilo 2018-03-09 18:11:10 +09:00
parent caea9c91b9
commit 910ccf1804
7 changed files with 425 additions and 307 deletions

View file

@ -6,6 +6,23 @@ module.exports = (params, user) => new Promise(async (res, rej) => {
const [my = false, myErr] = $(params.my).optional.boolean().$;
if (myErr) return rej('invalid my param');
// Get 'limit' parameter
const [limit = 10, limitErr] = $(params.limit).optional.number().range(1, 100).$;
if (limitErr) return rej('invalid limit param');
// Get 'since_id' parameter
const [sinceId, sinceIdErr] = $(params.since_id).optional.id().$;
if (sinceIdErr) return rej('invalid since_id param');
// Get 'until_id' parameter
const [untilId, untilIdErr] = $(params.until_id).optional.id().$;
if (untilIdErr) return rej('invalid until_id param');
// Check if both of since_id and until_id is specified
if (sinceId && untilId) {
return rej('cannot set since_id and until_id');
}
const q = my ? {
is_started: true,
$or: [{
@ -17,13 +34,29 @@ module.exports = (params, user) => new Promise(async (res, rej) => {
is_started: true
};
const sort = {
_id: -1
};
if (sinceId) {
sort._id = 1;
q._id = {
$gt: sinceId
};
} else if (untilId) {
q._id = {
$lt: untilId
};
}
// Fetch games
const games = await Game.find(q, {
sort: {
_id: -1
}
sort
});
// Reponse
res(Promise.all(games.map(async (g) => await pack(g, user))));
res(Promise.all(games.map(async (g) => await pack(g, user, {
detail: false
}))));
});

View file

@ -38,7 +38,7 @@ module.exports = (params, user) => new Promise(async (res, rej) => {
is_ended: false,
logs: [],
settings: {
map: eighteight,
map: eighteight.data,
bw: 'random',
is_llotheo: false
}

View file

@ -28,7 +28,7 @@ export interface IGame {
winner_id: mongo.ObjectID;
logs: any[];
settings: {
map: Map;
map: string[];
bw: string | number;
is_llotheo: boolean;
};
@ -39,8 +39,15 @@ export interface IGame {
*/
export const pack = (
game: any,
me?: string | mongo.ObjectID | IUser
me?: string | mongo.ObjectID | IUser,
options?: {
detail?: boolean
}
) => new Promise<any>(async (resolve, reject) => {
const opts = Object.assign({
detail: true
}, options);
let _game: any;
// Populate the game if 'game' is ID
@ -69,6 +76,11 @@ export const pack = (
_game.id = _game._id;
delete _game._id;
if (opts.detail === false) {
delete _game.logs;
delete _game.settings.map;
}
// Populate user
_game.user1 = await packUser(_game.user1_id, meId);
_game.user2 = await packUser(_game.user2_id, meId);

View file

@ -1,5 +1,3 @@
import { Map } from './maps';
export type Color = 'black' | 'white';
export type MapPixel = 'null' | 'empty';
@ -11,12 +9,14 @@ export type Options = {
*
*/
export default class Othello {
public map: Map;
public mapData: MapPixel[];
public map: MapPixel[];
public mapWidth: number;
public mapHeight: number;
public board: Color[];
public turn: Color = 'black';
public opts: Options;
public prevPos = -1;
public stats: Array<{
b: number;
w: number;
@ -25,18 +25,21 @@ export default class Othello {
/**
*
*/
constructor(map: Map, opts: Options) {
this.map = map;
constructor(map: string[], opts: Options) {
this.opts = opts;
this.mapWidth = map[0].length;
this.mapHeight = map.length;
const mapData = map.join('');
// Parse map data
this.board = this.map.data.split('').map(d => {
this.board = mapData.split('').map(d => {
if (d == '-') return null;
if (d == 'b') return 'black';
if (d == 'w') return 'white';
return undefined;
});
this.mapData = this.map.data.split('').map(d => {
this.map = mapData.split('').map(d => {
if (d == '-' || d == 'b' || d == 'w') return 'empty';
return 'null';
});
@ -48,8 +51,6 @@ export default class Othello {
}];
}
public prevPos = -1;
/**
*
*/
@ -79,13 +80,13 @@ export default class Othello {
}
public transformPosToXy(pos: number): number[] {
const x = pos % this.map.size;
const y = Math.floor(pos / this.map.size);
const x = pos % this.mapWidth;
const y = Math.floor(pos / this.mapHeight);
return [x, y];
}
public transformXyToPos(x: number, y: number): number {
return x + (y * this.map.size);
return x + (y * this.mapHeight);
}
/**
@ -145,8 +146,8 @@ export default class Othello {
* @param pos
*/
public mapDataGet(pos: number): MapPixel {
if (pos < 0 || pos >= this.mapData.length) return 'null';
return this.mapData[pos];
if (pos < 0 || pos >= this.map.length) return 'null';
return this.map[pos];
}
/**
@ -188,7 +189,7 @@ export default class Othello {
const found = [];
while (true) {
const [x, y] = fn(i);
if (x < 0 || y < 0 || x >= this.map.size || y >= this.map.size) break;
if (x < 0 || y < 0 || x >= this.mapWidth || y >= this.mapHeight) break;
const pos = this.transformXyToPos(x, y);
const pixel = this.mapDataGet(pos);
if (pixel == 'null') break;

View file

@ -11,438 +11,502 @@
export type Map = {
name?: string;
category?: string;
size: number;
data: string;
author?: string;
data: string[];
};
export const fourfour: Map = {
name: '4x4',
category: '4x4',
size: 4,
data:
'----' +
'-wb-' +
'-bw-' +
data: [
'----',
'-wb-',
'-bw-',
'----'
]
};
export const sixsix: Map = {
name: '6x6',
category: '6x6',
size: 6,
data:
'------' +
'------' +
'--wb--' +
'--bw--' +
'------' +
data: [
'------',
'------',
'--wb--',
'--bw--',
'------',
'------'
]
};
export const roundedSixsix: Map = {
name: '6x6 rounded',
category: '6x6',
size: 6,
data:
' ---- ' +
'------' +
'--wb--' +
'--bw--' +
'------' +
author: 'syuilo',
data: [
' ---- ',
'------',
'--wb--',
'--bw--',
'------',
' ---- '
]
};
export const roundedSixsix2: Map = {
name: '6x6 rounded 2',
category: '6x6',
size: 6,
data:
' -- ' +
' ---- ' +
'--wb--' +
'--bw--' +
' ---- ' +
author: 'syuilo',
data: [
' -- ',
' ---- ',
'--wb--',
'--bw--',
' ---- ',
' -- '
]
};
export const eighteight: Map = {
name: '8x8',
category: '8x8',
size: 8,
data:
'--------' +
'--------' +
'--------' +
'---wb---' +
'---bw---' +
'--------' +
'--------' +
data: [
'--------',
'--------',
'--------',
'---wb---',
'---bw---',
'--------',
'--------',
'--------'
]
};
export const roundedEighteight: Map = {
name: '8x8 rounded',
category: '8x8',
size: 8,
data:
' ------ ' +
'--------' +
'--------' +
'---wb---' +
'---bw---' +
'--------' +
'--------' +
author: 'syuilo',
data: [
' ------ ',
'--------',
'--------',
'---wb---',
'---bw---',
'--------',
'--------',
' ------ '
]
};
export const roundedEighteight2: Map = {
name: '8x8 rounded 2',
category: '8x8',
size: 8,
data:
' ---- ' +
' ------ ' +
'--------' +
'---wb---' +
'---bw---' +
'--------' +
' ------ ' +
author: 'syuilo',
data: [
' ---- ',
' ------ ',
'--------',
'---wb---',
'---bw---',
'--------',
' ------ ',
' ---- '
]
};
export const roundedEighteight3: Map = {
name: '8x8 rounded 3',
category: '8x8',
size: 8,
data:
' -- ' +
' ---- ' +
' ------ ' +
'---wb---' +
'---bw---' +
' ------ ' +
' ---- ' +
author: 'syuilo',
data: [
' -- ',
' ---- ',
' ------ ',
'---wb---',
'---bw---',
' ------ ',
' ---- ',
' -- '
]
};
export const eighteightWithNotch: Map = {
name: '8x8 with notch',
category: '8x8',
size: 8,
data:
'--- ---' +
'--------' +
'--------' +
' --wb-- ' +
' --bw-- ' +
'--------' +
'--------' +
author: 'syuilo',
data: [
'--- ---',
'--------',
'--------',
' --wb-- ',
' --bw-- ',
'--------',
'--------',
'--- ---'
]
};
export const eighteightWithSomeHoles: Map = {
name: '8x8 with some holes',
category: '8x8',
size: 8,
data:
'--- ----' +
'----- --' +
'-- -----' +
'---wb---' +
'---bw- -' +
' -------' +
'--- ----' +
author: 'syuilo',
data: [
'--- ----',
'----- --',
'-- -----',
'---wb---',
'---bw- -',
' -------',
'--- ----',
'--------'
]
};
export const circle: Map = {
name: 'Circle',
category: '8x8',
size: 8,
data:
' -- ' +
' ------ ' +
' ------ ' +
'---wb---' +
'---bw---' +
' ------ ' +
' ------ ' +
author: 'syuilo',
data: [
' -- ',
' ------ ',
' ------ ',
'---wb---',
'---bw---',
' ------ ',
' ------ ',
' -- '
]
};
export const face: Map = {
name: 'Face',
export const smile: Map = {
name: 'Smile',
category: '8x8',
size: 8,
data:
' ------ ' +
'--------' +
'-- -- --' +
'---wb---' +
'-- bw --' +
'--- ---' +
'--------' +
author: 'syuilo',
data: [
' ------ ',
'--------',
'-- -- --',
'---wb---',
'-- bw --',
'--- ---',
'--------',
' ------ '
]
};
export const window: Map = {
name: 'Window',
category: '8x8',
size: 8,
data:
'--------' +
'- -- -' +
'- -- -' +
'---wb---' +
'---bw---' +
'- -- -' +
'- -- -' +
author: 'syuilo',
data: [
'--------',
'- -- -',
'- -- -',
'---wb---',
'---bw---',
'- -- -',
'- -- -',
'--------'
]
};
export const reserved: Map = {
name: 'Reserved',
category: '8x8',
size: 8,
data:
'w------b' +
'--------' +
'--------' +
'---wb---' +
'---bw---' +
'--------' +
'--------' +
author: 'Aya',
data: [
'w------b',
'--------',
'--------',
'---wb---',
'---bw---',
'--------',
'--------',
'b------w'
]
};
export const x: Map = {
name: 'X',
category: '8x8',
size: 8,
data:
'w------b' +
'-w----b-' +
'--w--b--' +
'---wb---' +
'---bw---' +
'--b--w--' +
'-b----w-' +
author: 'Aya',
data: [
'w------b',
'-w----b-',
'--w--b--',
'---wb---',
'---bw---',
'--b--w--',
'-b----w-',
'b------w'
]
};
export const minesweeper: Map = {
name: 'Minesweeper',
category: '8x8',
author: 'syuilo',
data: [
'b-b--w-w',
'-w-wb-b-',
'w-b--w-b',
'-b-wb-w-',
'-w-bw-b-',
'b-w--b-w',
'-b-bw-w-',
'w-w--b-b'
]
};
export const tenthtenth: Map = {
name: '10x10',
category: '10x10',
size: 10,
data:
'----------' +
'----------' +
'----------' +
'----------' +
'----wb----' +
'----bw----' +
'----------' +
'----------' +
'----------' +
data: [
'----------',
'----------',
'----------',
'----------',
'----wb----',
'----bw----',
'----------',
'----------',
'----------',
'----------'
]
};
export const hole: Map = {
name: 'The Hole',
category: '10x10',
size: 10,
data:
'----------' +
'----------' +
'--wb--wb--' +
'--bw--bw--' +
'---- ----' +
'---- ----' +
'--wb--wb--' +
'--bw--bw--' +
'----------' +
author: 'syuilo',
data: [
'----------',
'----------',
'--wb--wb--',
'--bw--bw--',
'---- ----',
'---- ----',
'--wb--wb--',
'--bw--bw--',
'----------',
'----------'
]
};
export const grid: Map = {
name: 'Grid',
category: '10x10',
size: 10,
data:
'----------' +
'- - -- - -' +
'----------' +
'- - -- - -' +
'----wb----' +
'----bw----' +
'- - -- - -' +
'----------' +
'- - -- - -' +
author: 'syuilo',
data: [
'----------',
'- - -- - -',
'----------',
'- - -- - -',
'----wb----',
'----bw----',
'- - -- - -',
'----------',
'- - -- - -',
'----------'
]
};
export const cross: Map = {
name: 'Cross',
category: '10x10',
size: 10,
data:
' ---- ' +
' ---- ' +
' ---- ' +
'----------' +
'----wb----' +
'----bw----' +
'----------' +
' ---- ' +
' ---- ' +
author: 'Aya',
data: [
' ---- ',
' ---- ',
' ---- ',
'----------',
'----wb----',
'----bw----',
'----------',
' ---- ',
' ---- ',
' ---- '
]
};
export const charX: Map = {
name: 'Char X',
category: '10x10',
author: 'syuilo',
data: [
'--- ---',
'---- ----',
'----------',
' -------- ',
' --wb-- ',
' --bw-- ',
' -------- ',
'----------',
'---- ----',
'--- ---'
]
};
export const charY: Map = {
name: 'Char Y',
category: '10x10',
author: 'syuilo',
data: [
'--- ---',
'---- ----',
'----------',
' -------- ',
' --wb-- ',
' --bw-- ',
' ------ ',
' ------ ',
' ------ ',
' ------ '
]
};
export const walls: Map = {
name: 'Walls',
category: '10x10',
size: 10,
data:
' bbbbbbbb ' +
'w--------w' +
'w--------w' +
'w--------w' +
'w---wb---w' +
'w---bw---w' +
'w--------w' +
'w--------w' +
'w--------w' +
author: 'Aya',
data: [
' bbbbbbbb ',
'w--------w',
'w--------w',
'w--------w',
'w---wb---w',
'w---bw---w',
'w--------w',
'w--------w',
'w--------w',
' bbbbbbbb '
]
};
export const checker: Map = {
name: 'Checker',
category: '10x10',
size: 10,
data:
'----------' +
'----------' +
'----------' +
'---wbwb---' +
'---bwbw---' +
'---wbwb---' +
'---bwbw---' +
'----------' +
'----------' +
author: 'Aya',
data: [
'----------',
'----------',
'----------',
'---wbwb---',
'---bwbw---',
'---wbwb---',
'---bwbw---',
'----------',
'----------',
'----------'
]
};
export const sixeight: Map = {
name: '6x8',
category: 'special',
size: 8,
data:
' ------ ' +
' ------ ' +
' ------ ' +
' --wb-- ' +
' --bw-- ' +
' ------ ' +
' ------ ' +
data: [
'------',
'------',
'------',
'--wb--',
'--bw--',
'------',
'------',
'------'
]
};
export const spark: Map = {
name: 'Spark',
category: 'special',
size: 10,
data:
' - - ' +
'----------' +
' -------- ' +
' -------- ' +
' ---wb--- ' +
' ---bw--- ' +
' -------- ' +
' -------- ' +
'----------' +
author: 'syuilo',
data: [
' - - ',
'----------',
' -------- ',
' -------- ',
' ---wb--- ',
' ---bw--- ',
' -------- ',
' -------- ',
'----------',
' - - '
]
};
export const islands: Map = {
name: 'Islands',
category: 'special',
size: 10,
data:
'-------- ' +
'---wb--- ' +
'---bw--- ' +
'-------- ' +
' - - ' +
' - - ' +
' --------' +
' --------' +
' --------' +
author: 'syuilo',
data: [
'-------- ',
'---wb--- ',
'---bw--- ',
'-------- ',
' - - ',
' - - ',
' --------',
' --------',
' --------',
' --------'
]
};
export const iphonex: Map = {
name: 'iPhone X',
category: 'special',
size: 12,
data:
' -- -- ' +
' -------- ' +
' -------- ' +
' -------- ' +
' -------- ' +
' ---wb--- ' +
' ---bw--- ' +
' -------- ' +
' -------- ' +
' -------- ' +
' -------- ' +
author: 'syuilo',
data: [
' -- -- ',
'--------',
'--------',
'--------',
'--------',
'---wb---',
'---bw---',
'--------',
'--------',
'--------',
'--------',
' ------ '
]
};
export const bigBoard: Map = {
name: 'Big board',
category: 'special',
size: 16,
data:
'----------------' +
'----------------' +
'----------------' +
'----------------' +
'----------------' +
'----------------' +
'----------------' +
'-------wb-------' +
'-------bw-------' +
'----------------' +
'----------------' +
'----------------' +
'----------------' +
'----------------' +
'----------------' +
data: [
'----------------',
'----------------',
'----------------',
'----------------',
'----------------',
'----------------',
'----------------',
'-------wb-------',
'-------bw-------',
'----------------',
'----------------',
'----------------',
'----------------',
'----------------',
'----------------',
'----------------'
]
};
export const twoBoard: Map = {
name: 'Two board',
category: 'special',
size: 17,
data:
'-------- --------' +
'-------- --------' +
'-------- --------' +
'---wb--- ---wb---' +
'---bw--- ---bw---' +
'-------- --------' +
'-------- --------' +
'-------- --------' +
' ' +
' ' +
' ' +
' ' +
' ' +
' ' +
' ' +
' ' +
' '
author: 'Aya',
data: [
'-------- --------',
'-------- --------',
'-------- --------',
'---wb--- ---wb---',
'---bw--- ---bw---',
'-------- --------',
'-------- --------',
'-------- --------'
]
};

View file

@ -10,9 +10,9 @@
<template v-else>引き分け</template>
</p>
<div class="board" :style="{ 'grid-template-rows': `repeat(${ game.settings.map.size }, 1fr)`, 'grid-template-columns': `repeat(${ game.settings.map.size }, 1fr)` }">
<div class="board" :style="{ 'grid-template-rows': `repeat(${ game.settings.map.length }, 1fr)`, 'grid-template-columns': `repeat(${ game.settings.map[0].length }, 1fr)` }">
<div v-for="(stone, i) in o.board"
:class="{ empty: stone == null, none: o.map.data[i] == ' ', isEnded: game.is_ended, myTurn: !game.is_ended && isMyTurn, can: turnUser ? o.canPut(turnUser.id == blackUser.id ? 'black' : 'white', i) : null, prev: o.prevPos == i }"
:class="{ empty: stone == null, none: o.map[i] == 'null', isEnded: game.is_ended, myTurn: !game.is_ended && isMyTurn, can: turnUser ? o.canPut(turnUser.id == blackUser.id ? 'black' : 'white', i) : null, prev: o.prevPos == i }"
@click="set(i)"
>
<img v-if="stone == 'black'" :src="`${blackUser.avatar_url}?thumbnail&size=128`" alt="">
@ -106,6 +106,8 @@ export default Vue.extend({
this.o.put(log.color, log.pos);
});
console.log(this.o);
this.logs = this.game.logs;
this.logPos = this.logs.length;
},

View file

@ -4,14 +4,17 @@
<p>ゲームの設定</p>
<el-select v-model="mapName" placeholder="マップを選択" @change="onMapChange">
<el-select class="map" v-model="mapName" placeholder="マップを選択" @change="onMapChange">
<el-option-group v-for="c in mapCategories" :key="c" :label="c">
<el-option v-for="m in maps" v-if="m.category == c" :key="m.name" :label="m.name" :value="m.name"/>
<el-option v-for="m in maps" v-if="m.category == c" :key="m.name" :label="m.name" :value="m.name">
<span style="float: left">{{ m.name }}</span>
<span style="float: right; color: #8492a6; font-size: 13px" v-if="m.author">(by <i>{{ m.author }}</i>)</span>
</el-option>
</el-option-group>
</el-select>
<div class="board" :style="{ 'grid-template-rows': `repeat(${ game.settings.map.size }, 1fr)`, 'grid-template-columns': `repeat(${ game.settings.map.size }, 1fr)` }">
<div v-for="(x, i) in game.settings.map.data"
<div class="board" :style="{ 'grid-template-rows': `repeat(${ game.settings.map.length }, 1fr)`, 'grid-template-columns': `repeat(${ game.settings.map[0].length }, 1fr)` }">
<div v-for="(x, i) in game.settings.map.join('')"
:class="{ none: x == ' ' }"
>
<template v-if="x == 'b'">%fa:circle%</template>
@ -112,7 +115,7 @@ export default Vue.extend({
},
onMapChange(v) {
this.game.settings.map = Object.entries(maps).find(x => x[1].name == v)[1];
this.game.settings.map = Object.entries(maps).find(x => x[1].name == v)[1].data;
this.connection.send({
type: 'update-settings',
settings: this.game.settings
@ -141,6 +144,9 @@ export default Vue.extend({
padding 8px
border-bottom dashed 1px #c4cdd4
> .map
width 300px
> .board
display grid
grid-gap 4px