Finished implementing the stats updating, just need to implement the new model methods. Added a notes file.
This commit is contained in:
7
notes.txt
Normal file
7
notes.txt
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
- Make a whole new class for each model called "Player", "DbUser", etc. and wrap mongoose completely.
|
||||||
|
- Create a corresponding namespace "PlayerCollection", "DbUserCollection", etc. for the database model itself and its
|
||||||
|
corresponding methods.
|
||||||
|
- Decide on whether to always use the namespace to call methods and pass an id, with the returned objects "Player",
|
||||||
|
"DbUser", etc. all being immutable object copies with limited attributes and no methods, or actually create extra
|
||||||
|
classes that have methods that can be called (right now thinking the first idea is better).
|
||||||
|
-> This way will be completely decoupled from Mongoose and MongoDB and will have full control.
|
||||||
@@ -40,5 +40,9 @@
|
|||||||
"ts-loader": "^7.0.5",
|
"ts-loader": "^7.0.5",
|
||||||
"tslint": "^6.1.1",
|
"tslint": "^6.1.1",
|
||||||
"typescript": "^3.9.3"
|
"typescript": "^3.9.3"
|
||||||
|
},
|
||||||
|
"prettier": {
|
||||||
|
"tabWidth": 4,
|
||||||
|
"jsxBracketSameLine": true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,24 +3,32 @@ import { RequestHandler } from "express";
|
|||||||
import Player, { IPlayer } from "../models/player";
|
import Player, { IPlayer } from "../models/player";
|
||||||
|
|
||||||
const DEFAULT_RULESET = "DEFAULT_RULESET";
|
const DEFAULT_RULESET = "DEFAULT_RULESET";
|
||||||
|
const UPPER_BONUS_THRESHOLD = 63;
|
||||||
|
const UPPER_BONUS = 35;
|
||||||
|
const FULL_HOUSE_SCORE = 25;
|
||||||
|
const SML_STRAIGHT_SCORE = 30;
|
||||||
|
const LG_STRAIGHT_SCORE = 40;
|
||||||
|
const YAHTZEE_SCORE = 50;
|
||||||
|
|
||||||
export interface GameSubmission {
|
export interface GameSubmission {
|
||||||
ruleset: string;
|
ruleset: string;
|
||||||
players: { id: string; nick: string }[];
|
players: { id: string; nick: string }[];
|
||||||
results: GameResults[];
|
results: PlayerGameResult[];
|
||||||
}
|
}
|
||||||
|
|
||||||
interface GameResults {
|
interface ScoredResult extends ScoreTotalFields, PlayerGameResult {}
|
||||||
playerId: string;
|
|
||||||
blocks: Record<BlockName, Block>;
|
interface ScoreTotalFields {
|
||||||
|
topBonus: boolean;
|
||||||
|
topSubtotal: number;
|
||||||
|
top: number;
|
||||||
|
bottom: number;
|
||||||
|
total: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type PlayerGameResult = { playerId: string; blocks: Record<BlockName, Block> };
|
||||||
type BlockName = "top" | "bottom";
|
type BlockName = "top" | "bottom";
|
||||||
|
type Block = { cells: Record<CellName, StandardCell> };
|
||||||
interface Block {
|
|
||||||
cells: Record<CellName, StandardCell>;
|
|
||||||
}
|
|
||||||
|
|
||||||
type CellName =
|
type CellName =
|
||||||
| "aces"
|
| "aces"
|
||||||
| "twos"
|
| "twos"
|
||||||
@@ -35,13 +43,15 @@ type CellName =
|
|||||||
| "lg_straight"
|
| "lg_straight"
|
||||||
| "yahtzee"
|
| "yahtzee"
|
||||||
| "chance";
|
| "chance";
|
||||||
|
type StandardCell = { value: CellValue };
|
||||||
interface StandardCell {
|
export type CellValue = number | boolean | "cellFlagStrike";
|
||||||
value: CellValue;
|
enum ResultType {
|
||||||
|
winner,
|
||||||
|
drawn,
|
||||||
|
runnerUp,
|
||||||
|
loser,
|
||||||
}
|
}
|
||||||
|
|
||||||
type CellValue = number | boolean | "cellFlagStrike";
|
|
||||||
|
|
||||||
export const listGames: RequestHandler = async (req, res) => {
|
export const listGames: RequestHandler = async (req, res) => {
|
||||||
const user = req.user as IDbUser;
|
const user = req.user as IDbUser;
|
||||||
const dbUser = await DbUser.findById(user.id, {
|
const dbUser = await DbUser.findById(user.id, {
|
||||||
@@ -51,7 +61,8 @@ export const listGames: RequestHandler = async (req, res) => {
|
|||||||
});
|
});
|
||||||
if (dbUser) {
|
if (dbUser) {
|
||||||
res.json({ games: dbUser.savedGames });
|
res.json({ games: dbUser.savedGames });
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
res.sendStatus(404);
|
res.sendStatus(404);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -59,62 +70,162 @@ export const listGames: RequestHandler = async (req, res) => {
|
|||||||
export const saveGame: RequestHandler = async (req, res) => {
|
export const saveGame: RequestHandler = async (req, res) => {
|
||||||
const user = req.user as IDbUser;
|
const user = req.user as IDbUser;
|
||||||
const submission = req.body as GameSubmission;
|
const submission = req.body as GameSubmission;
|
||||||
await addNewGuestsFromSubmissionAndFillInIds(submission, user);
|
const newGuests: IPlayer[] = await addNewGuests(submission, user);
|
||||||
|
if (newGuests.length > 0) {
|
||||||
|
fillOutSubmissionWithNewIds(submission, newGuests);
|
||||||
|
}
|
||||||
const newGame = await user.addGame(submission);
|
const newGame = await user.addGame(submission);
|
||||||
if (submission.ruleset === DEFAULT_RULESET) {
|
if (submission.ruleset === DEFAULT_RULESET) {
|
||||||
processStandardStatistics(submission.results, user);
|
processStandardStatistics(submission.results, user);
|
||||||
}
|
}
|
||||||
console.log(JSON.stringify(req.body));
|
|
||||||
res.send({ message: "Game submitted successfully!", newGame: newGame });
|
res.send({ message: "Game submitted successfully!", newGame: newGame });
|
||||||
};
|
};
|
||||||
|
|
||||||
async function addNewGuestsFromSubmissionAndFillInIds(
|
async function addNewGuests(submission: GameSubmission, user: IDbUser): Promise<IPlayer[]> {
|
||||||
submission: GameSubmission,
|
const newGuestIds: IPlayer[] = [];
|
||||||
user: IDbUser
|
for (const playerDetails of submission.players) {
|
||||||
): Promise<void> {
|
const isNewPlayer = playerDetails.id === playerDetails.nick;
|
||||||
for (const playerInParticipantList of submission.players) {
|
if (isNewPlayer) {
|
||||||
if (playerInParticipantList.id === playerInParticipantList.nick) {
|
const newGuest: IPlayer = await user.addGuest(playerDetails.nick);
|
||||||
const newGuest = await user.addGuest(playerInParticipantList.nick);
|
newGuestIds.push(newGuest);
|
||||||
const gameResultsFromNewGuest = submission.results.find(
|
|
||||||
(result) => result.playerId === playerInParticipantList.nick
|
|
||||||
);
|
|
||||||
gameResultsFromNewGuest!.playerId = newGuest.id;
|
|
||||||
playerInParticipantList.id = newGuest.id;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return newGuestIds;
|
||||||
}
|
}
|
||||||
|
|
||||||
function processStandardStatistics(results: GameResults[], account: IDbUser) {
|
function fillOutSubmissionWithNewIds(submission: GameSubmission, newGuestList: IPlayer[]): GameSubmission {
|
||||||
let runnerUp: IPlayer;
|
for (const newGuest of newGuestList) {
|
||||||
const drawnPlayers: IPlayer[] = [];
|
const gameResultsFromNewGuest = submission.results.find((result) => result.playerId === newGuest.nick);
|
||||||
const scoredResults: { pid: string; score: number }[] = [];
|
if (gameResultsFromNewGuest) {
|
||||||
|
gameResultsFromNewGuest.playerId = newGuest.id;
|
||||||
|
}
|
||||||
|
const playerEntryForNewGuest = submission.players.find((player) => player.id === newGuest.nick);
|
||||||
|
if (playerEntryForNewGuest) {
|
||||||
|
playerEntryForNewGuest.id = newGuest.id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return submission;
|
||||||
|
}
|
||||||
|
|
||||||
|
function processStandardStatistics(results: PlayerGameResult[], account: IDbUser) {
|
||||||
|
let scoredResults: ScoredResult[] = [];
|
||||||
for (const result of results) {
|
for (const result of results) {
|
||||||
Player.updatePlayerStats(result.playerId, result);
|
const scoredResult = {
|
||||||
scoredResults.push({pid: result.playerId, score: calculateStandardScore(result)});
|
...result,
|
||||||
|
...getStandardScoreFields(result),
|
||||||
|
};
|
||||||
|
scoredResults.push(scoredResult);
|
||||||
|
updatePlayerStats(result.playerId, scoredResult);
|
||||||
}
|
}
|
||||||
const winner = Math.max(...scoredResults.map(result => result.score));
|
const { wasDraw } = incrementPlayerPlacings(scoredResults);
|
||||||
//winner.incrementWin();
|
if (wasDraw) {
|
||||||
//runnerUp.incrementRunnerUp();
|
DbUser.incrementTimesNoWinner(account.id);
|
||||||
//drawnPlayers.forEach(player => player.incrementDraw();
|
}
|
||||||
|
DbUser.incrementGamesPlayed(account.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
function calculateStandardScore(result: GameResults): number {
|
async function updatePlayerStats(playerId: string, result: ScoredResult) {
|
||||||
const top = result.blocks.top.cells;
|
const player: IPlayer = await Player.findById(playerId) as IPlayer;
|
||||||
const bottom = result.blocks.bottom.cells;
|
for (const blockId in result.blocks) {
|
||||||
|
const cells = result.blocks[blockId as BlockName].cells;
|
||||||
|
for (const cellId in cells) {
|
||||||
|
Player.updateCellStats(player.id, {id: cellId, value: cells[cellId as CellName].value});
|
||||||
|
}
|
||||||
|
if (result.topBonus) {
|
||||||
|
Player.incrementBonus(player.id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Player.incrementGamesPlayed(player.id);
|
||||||
|
}
|
||||||
|
|
||||||
|
function incrementPlayerPlacings(scoredResults: ScoredResult[]) {
|
||||||
|
scoredResults = sortDescendingByScore(scoredResults);
|
||||||
|
const placingFacts: { wasDraw: boolean } = { wasDraw: false };
|
||||||
|
let runnerUpsStart: number;
|
||||||
|
if (scoredResults[0].total !== scoredResults[1].total) {
|
||||||
|
Player.incrementWinFor(scoredResults[0].playerId);
|
||||||
|
runnerUpsStart = 1;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
runnerUpsStart = icrmtPlayerDrawsTilScoreChange(scoredResults);
|
||||||
|
placingFacts.wasDraw = true;
|
||||||
|
}
|
||||||
|
const losersStart = icrmtPlayerRunnerUpsTilScoreChange(
|
||||||
|
scoredResults.slice(runnerUpsStart)
|
||||||
|
);
|
||||||
|
icrmtPlayerLosses(scoredResults.slice(losersStart));
|
||||||
|
return placingFacts;
|
||||||
|
}
|
||||||
|
|
||||||
|
function icrmtPlayerDrawsTilScoreChange(scoredResults: ScoredResult[]): number {
|
||||||
|
for (let i = 0; i < scoredResults.length; i++) {
|
||||||
|
if (scoredResults[i].total === scoredResults[0].total) {
|
||||||
|
Player.incrementDrawFor(scoredResults[i].playerId);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return scoredResults.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
function icrmtPlayerRunnerUpsTilScoreChange(scoredResults: ScoredResult[]): number {
|
||||||
|
for (let i = 0; i < scoredResults.length; i++) {
|
||||||
|
if (scoredResults[i].total === scoredResults[0].total) {
|
||||||
|
Player.incrementRunnerUpFor(scoredResults[i].playerId);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return scoredResults.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
function icrmtPlayerLosses(scoredResults: ScoredResult[]): void {
|
||||||
|
for (const scoredResult of scoredResults) {
|
||||||
|
Player.incrementLossFor(scoredResult.playerId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function sortDescendingByScore(scoredResults: ScoredResult[]) {
|
||||||
|
return scoredResults.sort((a, b) => b.total - a.total);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function getStandardScoreFields(result: PlayerGameResult): ScoreTotalFields {
|
||||||
|
const scoreFields: ScoreTotalFields = { topBonus: false, topSubtotal: 0, top: 0, bottom: 0, total: 0 };
|
||||||
|
scoreFields.topSubtotal = topSubtotal(result.blocks.top.cells);
|
||||||
|
scoreFields.top = scoreFields.topSubtotal;
|
||||||
|
if (scoreFields.topSubtotal >= UPPER_BONUS_THRESHOLD) {
|
||||||
|
scoreFields.topBonus = true;
|
||||||
|
scoreFields.top += UPPER_BONUS;
|
||||||
|
}
|
||||||
|
scoreFields.bottom = bottomTotal(result.blocks.bottom.cells);
|
||||||
|
scoreFields.total = scoreFields.top + scoreFields.bottom;
|
||||||
|
return scoreFields;
|
||||||
|
}
|
||||||
|
|
||||||
|
function topSubtotal(topResult: Record<CellName, StandardCell>) {
|
||||||
return (
|
return (
|
||||||
cellScore(top.aces) +
|
cellScore(topResult.aces) +
|
||||||
cellScore(top.twos) * 2 +
|
cellScore(topResult.twos) * 2 +
|
||||||
cellScore(top.threes) * 3 +
|
cellScore(topResult.threes) * 3 +
|
||||||
cellScore(top.fours) * 4 +
|
cellScore(topResult.fours) * 4 +
|
||||||
cellScore(top.fives) * 5 +
|
cellScore(topResult.fives) * 5 +
|
||||||
cellScore(top.sixes) * 6 +
|
cellScore(topResult.sixes) * 6
|
||||||
cellScore(bottom.three_kind) +
|
);
|
||||||
cellScore(bottom.four_kind) +
|
}
|
||||||
cellScore(bottom.full_house) * 25 +
|
|
||||||
cellScore(bottom.sml_straight) * 30 +
|
|
||||||
cellScore(bottom.lg_straight) * 40 +
|
function bottomTotal(bottomResult: Record<CellName, StandardCell>) {
|
||||||
cellScore(bottom.yahtzee) * 50 +
|
return (
|
||||||
cellScore(bottom.chance)
|
cellScore(bottomResult.three_kind) +
|
||||||
|
cellScore(bottomResult.four_kind) +
|
||||||
|
cellScore(bottomResult.full_house) * FULL_HOUSE_SCORE +
|
||||||
|
cellScore(bottomResult.sml_straight) * SML_STRAIGHT_SCORE +
|
||||||
|
cellScore(bottomResult.lg_straight) * LG_STRAIGHT_SCORE +
|
||||||
|
cellScore(bottomResult.yahtzee) * YAHTZEE_SCORE +
|
||||||
|
cellScore(bottomResult.chance)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -126,42 +237,3 @@ function cellScore(cell: StandardCell) {
|
|||||||
}
|
}
|
||||||
return cell.value;
|
return cell.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
const example = {
|
|
||||||
players: [
|
|
||||||
{
|
|
||||||
id: "5ecbf33a9d246114c0c9d9bb",
|
|
||||||
nick: "Ledda",
|
|
||||||
},
|
|
||||||
],
|
|
||||||
results: [
|
|
||||||
{
|
|
||||||
playerId: "5ecbf33a9d246114c0c9d9bb",
|
|
||||||
blocks: [
|
|
||||||
{
|
|
||||||
id: "top",
|
|
||||||
cells: [
|
|
||||||
{ id: "aces", value: 1 },
|
|
||||||
{ id: "twos", value: 1 },
|
|
||||||
{ id: "threes", value: 1 },
|
|
||||||
{ id: "fours", value: 1 },
|
|
||||||
{ id: "fives", value: 1 },
|
|
||||||
{ id: "sixes", value: 1 },
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: "bottom",
|
|
||||||
cells: [
|
|
||||||
{ id: "three_kind", value: "cellFlagStrike" },
|
|
||||||
{ id: "four_kind", value: "cellFlagStrike" },
|
|
||||||
{ id: "full_house", value: true },
|
|
||||||
{ id: "sml_straight", value: true },
|
|
||||||
{ id: "lg_straight", value: true },
|
|
||||||
{ id: "yahtzee", value: 1 },
|
|
||||||
{ id: "chance", value: "cellFlagStrike" },
|
|
||||||
],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
};
|
|
||||||
|
|||||||
@@ -71,6 +71,8 @@ export interface IDbUserModel extends mongoose.Model<IDbUserDoc> {
|
|||||||
userWithEmailExists(email: string): Promise<boolean>;
|
userWithEmailExists(email: string): Promise<boolean>;
|
||||||
userWithUsernameExists(username: string): Promise<boolean>;
|
userWithUsernameExists(username: string): Promise<boolean>;
|
||||||
getSerializedAuthUser(id: string): Promise<IDbUser>;
|
getSerializedAuthUser(id: string): Promise<IDbUser>;
|
||||||
|
incrementTimesNoWinner(id: string): Promise<void>;
|
||||||
|
incrementGamesPlayed(id: string): Promise<void>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const DbUserSchema = new mongoose.Schema({
|
export const DbUserSchema = new mongoose.Schema({
|
||||||
@@ -132,6 +134,14 @@ DbUserSchema.statics.getSerializedAuthUser = async function (id: string): Promis
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
DbUserSchema.statics.incrementTimesNoWinner = async function (id: string): Promise<void> {
|
||||||
|
...
|
||||||
|
};
|
||||||
|
|
||||||
|
DbUserSchema.statics.incrementGamesPlayed = async function (id: string): Promise<void> {
|
||||||
|
...
|
||||||
|
};
|
||||||
|
|
||||||
DbUserSchema.methods.getGuests = async function (this: IDbUser): Promise<IPlayer[]> {
|
DbUserSchema.methods.getGuests = async function (this: IDbUser): Promise<IPlayer[]> {
|
||||||
const user: IDbUserDoc = await tryQuery(async () => {
|
const user: IDbUserDoc = await tryQuery(async () => {
|
||||||
return DbUser.findById(this.id, {"guests.nick": 1, "guests._id": 1}).exec();
|
return DbUser.findById(this.id, {"guests.nick": 1, "guests._id": 1}).exec();
|
||||||
|
|||||||
@@ -1,6 +1,12 @@
|
|||||||
import mongoose from "mongoose";
|
import mongoose from "mongoose";
|
||||||
import {IPlayerStats, IPlayerStatsDoc, PlayerStatsSchema} from "./stats";
|
import {IPlayerStats, IPlayerStatsDoc, PlayerStatsSchema} from "./stats";
|
||||||
import {globalSchemaOptions} from "./utils";
|
import {globalSchemaOptions} from "./utils";
|
||||||
|
import {CellValue} from "../controllers/statsController";
|
||||||
|
|
||||||
|
interface CellDetails {
|
||||||
|
id: string;
|
||||||
|
value: CellValue;
|
||||||
|
}
|
||||||
|
|
||||||
export interface IPlayer {
|
export interface IPlayer {
|
||||||
id: string;
|
id: string;
|
||||||
@@ -15,7 +21,13 @@ export interface IPlayerDoc extends mongoose.Document {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface IPlayerModel extends mongoose.Model<IPlayerDoc> {
|
export interface IPlayerModel extends mongoose.Model<IPlayerDoc> {
|
||||||
// virtual static methods
|
incrementGamesPlayed(playerId: string): void;
|
||||||
|
incrementWinFor(playerId: string): void;
|
||||||
|
incrementDrawFor(playerId: string): void;
|
||||||
|
incrementRunnerUpFor(playerId: string): void;
|
||||||
|
incrementLossFor(playerId: string): void;
|
||||||
|
updateCellStats(playerId: string, cellDetails: CellDetails): void;
|
||||||
|
incrementBonus(playerId: string): Promise<void>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const PlayerSchema = new mongoose.Schema({
|
export const PlayerSchema = new mongoose.Schema({
|
||||||
@@ -23,5 +35,34 @@ export const PlayerSchema = new mongoose.Schema({
|
|||||||
stats: { type: PlayerStatsSchema, required: true, default: () => ({}) },
|
stats: { type: PlayerStatsSchema, required: true, default: () => ({}) },
|
||||||
}, {...globalSchemaOptions});
|
}, {...globalSchemaOptions});
|
||||||
|
|
||||||
|
PlayerSchema.statics.incrementGamesPlayed = async function (playerId: string): Promise<void> {
|
||||||
|
...
|
||||||
|
};
|
||||||
|
|
||||||
|
PlayerSchema.statics.incrementWinFor = async function (playerId: string): Promise<void> {
|
||||||
|
...
|
||||||
|
};
|
||||||
|
|
||||||
|
PlayerSchema.statics.incrementDrawFor = async function (playerId: string): Promise<void> {
|
||||||
|
...
|
||||||
|
};
|
||||||
|
|
||||||
|
PlayerSchema.statics.incrementRunnerUpFor = async function (playerId: string): Promise<void> {
|
||||||
|
...
|
||||||
|
};
|
||||||
|
|
||||||
|
PlayerSchema.statics.incrementLossFor = async function (playerId: string): Promise<void> {
|
||||||
|
...
|
||||||
|
};
|
||||||
|
|
||||||
|
PlayerSchema.statics.updateCellStats = async function (playerId: string, cellDetails: CellDetails): void {
|
||||||
|
...
|
||||||
|
};
|
||||||
|
|
||||||
|
PlayerSchema.statics.incrementBonus = async function (playerId: string): Promise<void> {
|
||||||
|
...
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
const Player = mongoose.model<IPlayerDoc, IPlayerModel>("Player", PlayerSchema);
|
const Player = mongoose.model<IPlayerDoc, IPlayerModel>("Player", PlayerSchema);
|
||||||
export default Player;
|
export default Player;
|
||||||
@@ -17,7 +17,6 @@ export interface IBaseStats {
|
|||||||
four: IMultiplierFieldStats;
|
four: IMultiplierFieldStats;
|
||||||
five: IMultiplierFieldStats;
|
five: IMultiplierFieldStats;
|
||||||
six: IMultiplierFieldStats;
|
six: IMultiplierFieldStats;
|
||||||
upperBonus: IBonusFieldStats;
|
|
||||||
upperTotal: ITotalFieldStats;
|
upperTotal: ITotalFieldStats;
|
||||||
threeKind: INumberFieldStats;
|
threeKind: INumberFieldStats;
|
||||||
fourKind: INumberFieldStats;
|
fourKind: INumberFieldStats;
|
||||||
@@ -30,9 +29,6 @@ export interface IBaseStats {
|
|||||||
lowerTotal: ITotalFieldStats;
|
lowerTotal: ITotalFieldStats;
|
||||||
gamesPlayed: number;
|
gamesPlayed: number;
|
||||||
}
|
}
|
||||||
interface IBonusFieldStats {
|
|
||||||
total: number;
|
|
||||||
}
|
|
||||||
interface ITotalFieldStats {
|
interface ITotalFieldStats {
|
||||||
average: number;
|
average: number;
|
||||||
best: number;
|
best: number;
|
||||||
@@ -69,7 +65,6 @@ interface IBaseStatsDoc extends mongoose.Document {
|
|||||||
four: IMultiplierFieldStatsDoc;
|
four: IMultiplierFieldStatsDoc;
|
||||||
five: IMultiplierFieldStatsDoc;
|
five: IMultiplierFieldStatsDoc;
|
||||||
six: IMultiplierFieldStatsDoc;
|
six: IMultiplierFieldStatsDoc;
|
||||||
upperBonus: IBonusFieldStatsDoc;
|
|
||||||
upperTotal: ITotalFieldStatsDoc;
|
upperTotal: ITotalFieldStatsDoc;
|
||||||
threeKind: INumberFieldStatsDoc;
|
threeKind: INumberFieldStatsDoc;
|
||||||
fourKind: INumberFieldStatsDoc;
|
fourKind: INumberFieldStatsDoc;
|
||||||
@@ -83,7 +78,6 @@ interface IBaseStatsDoc extends mongoose.Document {
|
|||||||
gamesPlayed: number;
|
gamesPlayed: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
type IBonusFieldStatsDoc = mongoose.Document & IBonusFieldStats;
|
|
||||||
type ITotalFieldStatsDoc = mongoose.Document & ITotalFieldStats;
|
type ITotalFieldStatsDoc = mongoose.Document & ITotalFieldStats;
|
||||||
type IBoolFieldStatsDoc = mongoose.Document & IBoolFieldStats;
|
type IBoolFieldStatsDoc = mongoose.Document & IBoolFieldStats;
|
||||||
type INumberFieldStatsDoc = mongoose.Document & INumberFieldStats;
|
type INumberFieldStatsDoc = mongoose.Document & INumberFieldStats;
|
||||||
@@ -106,10 +100,6 @@ class Int extends mongoose.SchemaType {
|
|||||||
}
|
}
|
||||||
(mongoose.Schema.Types as any).Int = Int;
|
(mongoose.Schema.Types as any).Int = Int;
|
||||||
|
|
||||||
const BonusFieldStatsSchema = new mongoose.Schema( {
|
|
||||||
average: {type: Number, required: true, default: 0, min: 0},
|
|
||||||
total: {type: Int, required: true, default: 0, min: 0}
|
|
||||||
}, { _id: false });
|
|
||||||
const TotalFieldStatsSchema = new mongoose.Schema( {
|
const TotalFieldStatsSchema = new mongoose.Schema( {
|
||||||
average: {type: Number, required: true, default: 0, min: 0},
|
average: {type: Number, required: true, default: 0, min: 0},
|
||||||
best: {type: Int, required: true, default: 0, min: 0},
|
best: {type: Int, required: true, default: 0, min: 0},
|
||||||
@@ -145,7 +135,6 @@ export const PlayerStatsSchema = new mongoose.Schema( {
|
|||||||
four: { type: MultiplierFieldStatsSchema, required: true, default: () => ({}) },
|
four: { type: MultiplierFieldStatsSchema, required: true, default: () => ({}) },
|
||||||
five: { type: MultiplierFieldStatsSchema, required: true, default: () => ({}) },
|
five: { type: MultiplierFieldStatsSchema, required: true, default: () => ({}) },
|
||||||
six: { type: MultiplierFieldStatsSchema, required: true, default: () => ({}) },
|
six: { type: MultiplierFieldStatsSchema, required: true, default: () => ({}) },
|
||||||
upperBonus: { type: BonusFieldStatsSchema, required: true, default: () => ({}) },
|
|
||||||
upperTotal: { type: TotalFieldStatsSchema, required: true, default: () => ({}) },
|
upperTotal: { type: TotalFieldStatsSchema, required: true, default: () => ({}) },
|
||||||
threeKind: { type: NumberFieldStatsSchema, required: true, default: () => ({}) },
|
threeKind: { type: NumberFieldStatsSchema, required: true, default: () => ({}) },
|
||||||
fourKind: { type: NumberFieldStatsSchema, required: true, default: () => ({}) },
|
fourKind: { type: NumberFieldStatsSchema, required: true, default: () => ({}) },
|
||||||
@@ -156,6 +145,7 @@ export const PlayerStatsSchema = new mongoose.Schema( {
|
|||||||
chance: { type: NumberFieldStatsSchema, required: true, default: () => ({}) },
|
chance: { type: NumberFieldStatsSchema, required: true, default: () => ({}) },
|
||||||
grandTotal: { type: TotalFieldStatsSchema, required: true, default: () => ({}) },
|
grandTotal: { type: TotalFieldStatsSchema, required: true, default: () => ({}) },
|
||||||
lowerTotal: { type: TotalFieldStatsSchema, required: true, default: () => ({}) },
|
lowerTotal: { type: TotalFieldStatsSchema, required: true, default: () => ({}) },
|
||||||
|
timesHadBonus: {type: Int, required: true, default: 0, min: 0},
|
||||||
gamesPlayed: { type: Int, required: true, default: 0, min: 0 },
|
gamesPlayed: { type: Int, required: true, default: 0, min: 0 },
|
||||||
wins: { type: Int, required: true, default: 0, min: 0 },
|
wins: { type: Int, required: true, default: 0, min: 0 },
|
||||||
runnerUps: { type: Int, required: true, default: 0, min: 0 },
|
runnerUps: { type: Int, required: true, default: 0, min: 0 },
|
||||||
@@ -169,7 +159,6 @@ export const AccountStatsSchema = new mongoose.Schema( {
|
|||||||
four: { type: MultiplierFieldStatsSchema, required: true, default: () => ({}) },
|
four: { type: MultiplierFieldStatsSchema, required: true, default: () => ({}) },
|
||||||
five: { type: MultiplierFieldStatsSchema, required: true, default: () => ({}) },
|
five: { type: MultiplierFieldStatsSchema, required: true, default: () => ({}) },
|
||||||
six: { type: MultiplierFieldStatsSchema, required: true, default: () => ({}) },
|
six: { type: MultiplierFieldStatsSchema, required: true, default: () => ({}) },
|
||||||
upperBonus: { type: BonusFieldStatsSchema, required: true, default: () => ({}) },
|
|
||||||
upperTotal: { type: TotalFieldStatsSchema, required: true, default: () => ({}) },
|
upperTotal: { type: TotalFieldStatsSchema, required: true, default: () => ({}) },
|
||||||
threeKind: { type: NumberFieldStatsSchema, required: true, default: () => ({}) },
|
threeKind: { type: NumberFieldStatsSchema, required: true, default: () => ({}) },
|
||||||
fourKind: { type: NumberFieldStatsSchema, required: true, default: () => ({}) },
|
fourKind: { type: NumberFieldStatsSchema, required: true, default: () => ({}) },
|
||||||
|
|||||||
Reference in New Issue
Block a user