add shape modes any and flat
This commit is contained in:
parent
b88321bb1b
commit
2d83fd441f
9 changed files with 98 additions and 30 deletions
1
build/public/assets/index.3208e2e9.js
Normal file
1
build/public/assets/index.3208e2e9.js
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
|
@ -4,7 +4,7 @@
|
|||
<meta charset="UTF-8">
|
||||
|
||||
<title>🧩 jigsaw.hyottoko.club</title>
|
||||
<script type="module" crossorigin src="/assets/index.3ca85e0f.js"></script>
|
||||
<script type="module" crossorigin src="/assets/index.3208e2e9.js"></script>
|
||||
<link rel="modulepreload" href="/assets/vendor.18cd2d7e.js">
|
||||
<link rel="stylesheet" href="/assets/index.f7304069.css">
|
||||
</head>
|
||||
|
|
|
|||
|
|
@ -23,7 +23,13 @@ var ScoreMode;
|
|||
(function (ScoreMode) {
|
||||
ScoreMode[ScoreMode["FINAL"] = 0] = "FINAL";
|
||||
ScoreMode[ScoreMode["ANY"] = 1] = "ANY";
|
||||
})(ScoreMode || (ScoreMode = {}));
|
||||
})(ScoreMode || (ScoreMode = {}));
|
||||
var ShapeMode;
|
||||
(function (ShapeMode) {
|
||||
ShapeMode[ShapeMode["NORMAL"] = 0] = "NORMAL";
|
||||
ShapeMode[ShapeMode["ANY"] = 1] = "ANY";
|
||||
ShapeMode[ShapeMode["FLAT"] = 2] = "FLAT";
|
||||
})(ShapeMode || (ShapeMode = {}));
|
||||
|
||||
class Rng {
|
||||
constructor(seed) {
|
||||
|
|
@ -1433,7 +1439,7 @@ var Images = {
|
|||
// cut size of each puzzle tile in the
|
||||
// final resized version of the puzzle image
|
||||
const TILE_SIZE = 64;
|
||||
async function createPuzzle(rng, targetTiles, image, ts) {
|
||||
async function createPuzzle(rng, targetTiles, image, ts, shapeMode) {
|
||||
const imagePath = image.file;
|
||||
const imageUrl = image.url;
|
||||
// determine puzzle information from the image dimensions
|
||||
|
|
@ -1446,7 +1452,7 @@ async function createPuzzle(rng, targetTiles, image, ts) {
|
|||
for (let i = 0; i < rawPieces.length; i++) {
|
||||
rawPieces[i] = { idx: i };
|
||||
}
|
||||
const shapes = determinePuzzleTileShapes(rng, info);
|
||||
const shapes = determinePuzzleTileShapes(rng, info, shapeMode);
|
||||
let positions = new Array(info.tiles);
|
||||
for (const piece of rawPieces) {
|
||||
const coord = Util.coordByPieceIdx(info, piece.idx);
|
||||
|
|
@ -1555,8 +1561,19 @@ async function createPuzzle(rng, targetTiles, image, ts) {
|
|||
},
|
||||
};
|
||||
}
|
||||
function determinePuzzleTileShapes(rng, info) {
|
||||
const tabs = [-1, 1];
|
||||
function determineTabs(shapeMode) {
|
||||
switch (shapeMode) {
|
||||
case ShapeMode.ANY:
|
||||
return [-1, 0, 1];
|
||||
case ShapeMode.FLAT:
|
||||
return [0];
|
||||
case ShapeMode.NORMAL:
|
||||
default:
|
||||
return [-1, 1];
|
||||
}
|
||||
}
|
||||
function determinePuzzleTileShapes(rng, info, shapeMode) {
|
||||
const tabs = determineTabs(shapeMode);
|
||||
const shapes = new Array(info.tiles);
|
||||
for (let i = 0; i < info.tiles; i++) {
|
||||
const coord = Util.coordByPieceIdx(info, i);
|
||||
|
|
@ -1692,22 +1709,23 @@ var GameStorage = {
|
|||
setDirty,
|
||||
};
|
||||
|
||||
async function createGameObject(gameId, targetTiles, image, ts, scoreMode) {
|
||||
async function createGameObject(gameId, targetTiles, image, ts, scoreMode, shapeMode) {
|
||||
const seed = Util.hash(gameId + ' ' + ts);
|
||||
const rng = new Rng(seed);
|
||||
return {
|
||||
id: gameId,
|
||||
rng: { type: 'Rng', obj: rng },
|
||||
puzzle: await createPuzzle(rng, targetTiles, image, ts),
|
||||
puzzle: await createPuzzle(rng, targetTiles, image, ts, shapeMode),
|
||||
players: [],
|
||||
evtInfos: {},
|
||||
scoreMode,
|
||||
shapeMode,
|
||||
};
|
||||
}
|
||||
async function createGame(gameId, targetTiles, image, ts, scoreMode) {
|
||||
const gameObject = await createGameObject(gameId, targetTiles, image, ts, scoreMode);
|
||||
async function createGame(gameId, targetTiles, image, ts, scoreMode, shapeMode) {
|
||||
const gameObject = await createGameObject(gameId, targetTiles, image, ts, scoreMode, shapeMode);
|
||||
GameLog.create(gameId);
|
||||
GameLog.log(gameId, Protocol.LOG_HEADER, 1, targetTiles, image, ts, scoreMode);
|
||||
GameLog.log(gameId, Protocol.LOG_HEADER, 1, targetTiles, image, ts, scoreMode, shapeMode);
|
||||
GameCommon.setGame(gameObject.id, gameObject);
|
||||
GameStorage.setDirty(gameId);
|
||||
}
|
||||
|
|
@ -1981,7 +1999,7 @@ app.get('/api/replay-data', async (req, res) => {
|
|||
let game = null;
|
||||
if (offset === 0) {
|
||||
// also need the game
|
||||
game = await Game.createGameObject(gameId, log[0][2], log[0][3], log[0][4], log[0][5] || ScoreMode.FINAL);
|
||||
game = await Game.createGameObject(gameId, log[0][2], log[0][3], log[0][4], log[0][5] || ScoreMode.FINAL, log[0][6] || ShapeMode.NORMAL);
|
||||
}
|
||||
res.send({ log, game: game ? Util.encodeGame(game) : null });
|
||||
});
|
||||
|
|
@ -2069,7 +2087,7 @@ app.post('/api/newgame', express.json(), async (req, res) => {
|
|||
const gameId = Util.uniqId();
|
||||
if (!GameCommon.exists(gameId)) {
|
||||
const ts = Time.timestamp();
|
||||
await Game.createGame(gameId, gameSettings.tiles, gameSettings.image, ts, gameSettings.scoreMode);
|
||||
await Game.createGame(gameId, gameSettings.tiles, gameSettings.image, ts, gameSettings.scoreMode, gameSettings.shapeMode);
|
||||
}
|
||||
res.send({ id: gameId });
|
||||
});
|
||||
|
|
|
|||
|
|
@ -73,6 +73,7 @@ export interface Game {
|
|||
puzzle: Puzzle
|
||||
evtInfos: Record<string, EvtInfo>
|
||||
scoreMode?: ScoreMode
|
||||
shapeMode?: ShapeMode
|
||||
rng: GameRng
|
||||
}
|
||||
|
||||
|
|
@ -90,6 +91,7 @@ export interface GameSettings {
|
|||
tiles: number
|
||||
image: Image
|
||||
scoreMode: ScoreMode
|
||||
shapeMode: ShapeMode
|
||||
}
|
||||
|
||||
export interface Puzzle {
|
||||
|
|
@ -198,3 +200,9 @@ export enum ScoreMode {
|
|||
FINAL = 0,
|
||||
ANY = 1,
|
||||
}
|
||||
|
||||
export enum ShapeMode {
|
||||
NORMAL = 0,
|
||||
ANY = 1,
|
||||
FLAT = 2,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,6 +22,16 @@
|
|||
<label><input type="radio" v-model="scoreMode" value="0" /> Final (Score when pieces are put to their final location)</label>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><label>shapes: </label></td>
|
||||
<td>
|
||||
<label><input type="radio" v-model="shapeMode" value="0" /> Normal</label>
|
||||
<br />
|
||||
<label><input type="radio" v-model="shapeMode" value="1" /> Any (flat pieces can occur anywhere)</label>
|
||||
<br />
|
||||
<label><input type="radio" v-model="shapeMode" value="2" /> Flat (all pieces flat on all sides)</label>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
|
|
@ -36,7 +46,7 @@
|
|||
<script lang="ts">
|
||||
import { defineComponent } from 'vue'
|
||||
|
||||
import { GameSettings, ScoreMode } from './../../common/Types'
|
||||
import { GameSettings, ScoreMode, ShapeMode } from './../../common/Types'
|
||||
import ResponsiveImage from './ResponsiveImage.vue'
|
||||
|
||||
export default defineComponent({
|
||||
|
|
@ -58,6 +68,7 @@ export default defineComponent({
|
|||
return {
|
||||
tiles: 1000,
|
||||
scoreMode: ScoreMode.ANY,
|
||||
shapeMode: ShapeMode.NORMAL,
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
|
|
@ -66,6 +77,7 @@ export default defineComponent({
|
|||
tiles: this.tilesInt,
|
||||
image: this.image,
|
||||
scoreMode: this.scoreModeInt,
|
||||
shapeMode: this.shapeModeInt,
|
||||
} as GameSettings)
|
||||
},
|
||||
},
|
||||
|
|
@ -84,6 +96,9 @@ export default defineComponent({
|
|||
scoreModeInt (): number {
|
||||
return parseInt(`${this.scoreMode}`, 10)
|
||||
},
|
||||
shapeModeInt (): number {
|
||||
return parseInt(`${this.shapeMode}`, 10)
|
||||
},
|
||||
tilesInt (): number {
|
||||
return parseInt(`${this.tiles}`, 10)
|
||||
},
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import GameCommon from './../common/GameCommon'
|
||||
import { Change, Game, Input, ScoreMode, Timestamp } from './../common/Types'
|
||||
import { Change, Game, Input, ScoreMode, ShapeMode, Timestamp } from './../common/Types'
|
||||
import Util, { logger } from './../common/Util'
|
||||
import { Rng } from './../common/Rng'
|
||||
import GameLog from './GameLog'
|
||||
|
|
@ -14,17 +14,19 @@ async function createGameObject(
|
|||
targetTiles: number,
|
||||
image: PuzzleCreationImageInfo,
|
||||
ts: Timestamp,
|
||||
scoreMode: ScoreMode
|
||||
scoreMode: ScoreMode,
|
||||
shapeMode: ShapeMode
|
||||
): Promise<Game> {
|
||||
const seed = Util.hash(gameId + ' ' + ts)
|
||||
const rng = new Rng(seed)
|
||||
return {
|
||||
id: gameId,
|
||||
rng: { type: 'Rng', obj: rng },
|
||||
puzzle: await createPuzzle(rng, targetTiles, image, ts),
|
||||
puzzle: await createPuzzle(rng, targetTiles, image, ts, shapeMode),
|
||||
players: [],
|
||||
evtInfos: {},
|
||||
scoreMode,
|
||||
shapeMode,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -33,18 +35,29 @@ async function createGame(
|
|||
targetTiles: number,
|
||||
image: PuzzleCreationImageInfo,
|
||||
ts: Timestamp,
|
||||
scoreMode: ScoreMode
|
||||
scoreMode: ScoreMode,
|
||||
shapeMode: ShapeMode
|
||||
): Promise<void> {
|
||||
const gameObject = await createGameObject(
|
||||
gameId,
|
||||
targetTiles,
|
||||
image,
|
||||
ts,
|
||||
scoreMode
|
||||
scoreMode,
|
||||
shapeMode
|
||||
)
|
||||
|
||||
GameLog.create(gameId)
|
||||
GameLog.log(gameId, Protocol.LOG_HEADER, 1, targetTiles, image, ts, scoreMode)
|
||||
GameLog.log(
|
||||
gameId,
|
||||
Protocol.LOG_HEADER,
|
||||
1,
|
||||
targetTiles,
|
||||
image,
|
||||
ts,
|
||||
scoreMode,
|
||||
shapeMode
|
||||
)
|
||||
|
||||
GameCommon.setGame(gameObject.id, gameObject)
|
||||
GameStorage.setDirty(gameId)
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import Util from './../common/Util'
|
||||
import { Rng } from './../common/Rng'
|
||||
import Images from './Images'
|
||||
import { EncodedPiece, EncodedPieceShape, PieceShape, Puzzle } from '../common/Types'
|
||||
import { EncodedPiece, EncodedPieceShape, PieceShape, Puzzle, ShapeMode } from '../common/Types'
|
||||
import { Dim, Point } from '../common/Geometry'
|
||||
|
||||
export interface PuzzleCreationImageInfo {
|
||||
|
|
@ -28,7 +28,8 @@ async function createPuzzle(
|
|||
rng: Rng,
|
||||
targetTiles: number,
|
||||
image: PuzzleCreationImageInfo,
|
||||
ts: number
|
||||
ts: number,
|
||||
shapeMode: ShapeMode
|
||||
): Promise<Puzzle> {
|
||||
const imagePath = image.file
|
||||
const imageUrl = image.url
|
||||
|
|
@ -44,7 +45,7 @@ async function createPuzzle(
|
|||
for (let i = 0; i < rawPieces.length; i++) {
|
||||
rawPieces[i] = { idx: i }
|
||||
}
|
||||
const shapes = determinePuzzleTileShapes(rng, info)
|
||||
const shapes = determinePuzzleTileShapes(rng, info, shapeMode)
|
||||
|
||||
let positions: Point[] = new Array(info.tiles)
|
||||
for (const piece of rawPieces) {
|
||||
|
|
@ -162,13 +163,24 @@ async function createPuzzle(
|
|||
},
|
||||
}
|
||||
}
|
||||
function determineTabs (shapeMode: ShapeMode): number[] {
|
||||
switch(shapeMode) {
|
||||
case ShapeMode.ANY:
|
||||
return [-1, 0, 1]
|
||||
case ShapeMode.FLAT:
|
||||
return [0]
|
||||
case ShapeMode.NORMAL:
|
||||
default:
|
||||
return [-1, 1]
|
||||
}
|
||||
}
|
||||
|
||||
function determinePuzzleTileShapes(
|
||||
rng: Rng,
|
||||
info: PuzzleCreationInfo
|
||||
info: PuzzleCreationInfo,
|
||||
shapeMode: ShapeMode
|
||||
): Array<EncodedPieceShape> {
|
||||
const tabs = [-1, 1]
|
||||
|
||||
const tabs: number[] = determineTabs(shapeMode)
|
||||
const shapes: Array<PieceShape> = new Array(info.tiles)
|
||||
for (let i = 0; i < info.tiles; i++) {
|
||||
const coord = Util.coordByPieceIdx(info, i)
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ import {
|
|||
UPLOAD_DIR,
|
||||
} from './Dirs'
|
||||
import GameCommon from '../common/GameCommon'
|
||||
import { ServerEvent, Game as GameType, GameSettings, ScoreMode } from '../common/Types'
|
||||
import { ServerEvent, Game as GameType, GameSettings, ScoreMode, ShapeMode } from '../common/Types'
|
||||
import GameStorage from './GameStorage'
|
||||
import Db from './Db'
|
||||
|
||||
|
|
@ -89,7 +89,8 @@ app.get('/api/replay-data', async (req, res): Promise<void> => {
|
|||
log[0][2],
|
||||
log[0][3],
|
||||
log[0][4],
|
||||
log[0][5] || ScoreMode.FINAL
|
||||
log[0][5] || ScoreMode.FINAL,
|
||||
log[0][6] || ShapeMode.NORMAL
|
||||
)
|
||||
}
|
||||
res.send({ log, game: game ? Util.encodeGame(game) : null })
|
||||
|
|
@ -201,7 +202,8 @@ app.post('/api/newgame', express.json(), async (req, res): Promise<void> => {
|
|||
gameSettings.tiles,
|
||||
gameSettings.image,
|
||||
ts,
|
||||
gameSettings.scoreMode
|
||||
gameSettings.scoreMode,
|
||||
gameSettings.shapeMode
|
||||
)
|
||||
}
|
||||
res.send({ id: gameId })
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue