238 lines
7.3 KiB
JavaScript
238 lines
7.3 KiB
JavaScript
"use strict";
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
const mockdata_1 = require("./mockdata");
|
|
const cryptoRandomString = require("crypto-random-string");
|
|
const unique_names_generator_1 = require("unique-names-generator");
|
|
function handleEvent(eventLog) {
|
|
if (eventLog.eventName === 'bought') {
|
|
let vendingMachine = findVendingMachine(eventLog.data.offer);
|
|
let selection = vendingMachine.selections.find((sel) => {
|
|
return sel.id === eventLog.data.selection;
|
|
});
|
|
selection.current = selection.current - 1;
|
|
}
|
|
}
|
|
function findVendingMachine(id) {
|
|
for (let i in mockdata_1.default.players) {
|
|
let player = mockdata_1.default.players[i];
|
|
for (let j in player.vendingMachines) {
|
|
if (player.vendingMachines[i].id === id) {
|
|
return player.vendingMachines[i];
|
|
}
|
|
}
|
|
}
|
|
}
|
|
function personPassesByVendingMachine(person, machine) {
|
|
let isThursty = Math.random() < person.thirst;
|
|
let availableSelections = machine.selections.filter((selection) => {
|
|
return !!selection.current;
|
|
});
|
|
if (isThursty) {
|
|
if (!availableSelections.length) {
|
|
return wontBuy('NoneAvailable');
|
|
}
|
|
let acceptableOptions = availableSelections.filter((option) => {
|
|
return person.preferences.indexOf(option.drink) !== -1;
|
|
});
|
|
if (!acceptableOptions.length) {
|
|
return wontBuy('NoPreferredDrinks');
|
|
}
|
|
let options = acceptableOptions.filter((selection) => {
|
|
return selection.price <= person.highestPrice;
|
|
});
|
|
if (!options.length) {
|
|
return wontBuy('HighPrice');
|
|
}
|
|
let picked = pick(acceptableOptions);
|
|
let selectionTypeData = getSelectionType(picked.type);
|
|
return {
|
|
eventName: 'bought',
|
|
data: {
|
|
reason: 'Thirsty',
|
|
amount: picked.price,
|
|
drink: picked.drink,
|
|
selection: picked.id,
|
|
selectionType: picked.type,
|
|
oz: selectionTypeData ? selectionTypeData.oz : 12,
|
|
person: person.id,
|
|
offer: machine.id,
|
|
}
|
|
};
|
|
}
|
|
else {
|
|
return wontBuy('NotThirsty');
|
|
}
|
|
function wontBuy(reason) {
|
|
return {
|
|
eventName: 'wontBuy',
|
|
data: {
|
|
reason: reason,
|
|
amount: 0,
|
|
drink: 'none',
|
|
selection: 'none',
|
|
selectionType: 'none',
|
|
oz: 0,
|
|
person: person.id,
|
|
offer: machine.id,
|
|
}
|
|
};
|
|
}
|
|
}
|
|
function generatePerson(location) {
|
|
let money = Math.random() * 100;
|
|
return {
|
|
id: genId('person'),
|
|
name: genPersonName(),
|
|
preferences: genPreferences(),
|
|
highestPrice: (money / 20),
|
|
money: money,
|
|
thirst: clamp(location.dailyTraffic.thirstBonus + (Math.random() / 10))
|
|
};
|
|
}
|
|
function genId(prefix) {
|
|
return `${prefix}-${cryptoRandomString({ length: 6, type: 'distinguishable' })}`;
|
|
}
|
|
function genPersonName() {
|
|
const config = {
|
|
dictionaries: [unique_names_generator_1.names, unique_names_generator_1.names],
|
|
length: 2,
|
|
separator: ' '
|
|
};
|
|
return unique_names_generator_1.uniqueNamesGenerator(config);
|
|
}
|
|
function genDrinkName() {
|
|
const config = {
|
|
dictionaries: [unique_names_generator_1.adjectives, unique_names_generator_1.colors],
|
|
length: 2,
|
|
separator: ' ',
|
|
style: 'capital'
|
|
};
|
|
return unique_names_generator_1.uniqueNamesGenerator(config);
|
|
}
|
|
function genStoreName() {
|
|
const stores = [
|
|
'shop',
|
|
'reseller',
|
|
'department Store',
|
|
'chain Store',
|
|
'emporium',
|
|
'supermarket',
|
|
'hypermarket',
|
|
'superstore',
|
|
'mart',
|
|
'shed',
|
|
'big Box',
|
|
'convenience Store',
|
|
'corner Store',
|
|
'food Store',
|
|
'market',
|
|
'food Mart',
|
|
'bodega',
|
|
];
|
|
const config = {
|
|
dictionaries: [unique_names_generator_1.names, stores],
|
|
length: 2,
|
|
separator: '\'s ',
|
|
style: 'capital'
|
|
};
|
|
return unique_names_generator_1.uniqueNamesGenerator(config);
|
|
}
|
|
function genCityName() {
|
|
const places = [
|
|
'town',
|
|
'city',
|
|
'township',
|
|
'borough',
|
|
'seat',
|
|
'metropolis',
|
|
'burg',
|
|
'municipality',
|
|
'hamlet',
|
|
];
|
|
const config = {
|
|
dictionaries: [Math.random() > 0.5 ? unique_names_generator_1.colors : unique_names_generator_1.names, places],
|
|
length: 2,
|
|
separator: ' ',
|
|
style: 'capital'
|
|
};
|
|
return unique_names_generator_1.uniqueNamesGenerator(config);
|
|
}
|
|
function clamp(value, max = 1, min = 0) {
|
|
if (value > max) {
|
|
return max;
|
|
}
|
|
if (value < min) {
|
|
return min;
|
|
}
|
|
return value;
|
|
}
|
|
function genPreferences() {
|
|
const availableDrinks = mockdata_1.default.drinks;
|
|
let prefCount = Math.floor(Math.random() * availableDrinks.length);
|
|
prefCount = prefCount === 0 ? prefCount + 1 : prefCount;
|
|
let preferences = [];
|
|
while (preferences.length < prefCount) {
|
|
let newPref = pick(availableDrinks);
|
|
if (preferences.indexOf(newPref.id) === -1) {
|
|
preferences.push(newPref.id);
|
|
}
|
|
}
|
|
return preferences;
|
|
}
|
|
function getSelectionType(typeName) {
|
|
return mockdata_1.default.selectionTypes.find((type) => {
|
|
return type.type === typeName;
|
|
});
|
|
}
|
|
function randomNumber(min, max) {
|
|
return Math.random() * (max - min) + min;
|
|
}
|
|
function pick(arr) {
|
|
return arr[Math.floor(Math.random() * arr.length)];
|
|
}
|
|
function getStatsFromEvents(events) {
|
|
let purchaseCount = 0;
|
|
let offerEventCount = 0;
|
|
let amountEarned = 0;
|
|
let ozSold = 0;
|
|
let popularity = {};
|
|
let eventReasons = {};
|
|
for (let i in events) {
|
|
let eventLog = events[i];
|
|
if (!eventReasons[eventLog.data.reason]) {
|
|
eventReasons[eventLog.data.reason] = 0;
|
|
}
|
|
eventReasons[eventLog.data.reason] = eventReasons[eventLog.data.reason] + 1;
|
|
if (eventLog.eventName === 'bought' || eventLog.eventName === 'wontBuy') {
|
|
offerEventCount = offerEventCount + 1;
|
|
if (eventLog.eventName === 'bought') {
|
|
purchaseCount = purchaseCount + 1;
|
|
if (!popularity[eventLog.data.drink]) {
|
|
popularity[eventLog.data.drink] = 0;
|
|
}
|
|
popularity[eventLog.data.drink] = popularity[eventLog.data.drink] + 1;
|
|
amountEarned = amountEarned + eventLog.data.amount;
|
|
ozSold = ozSold + eventLog.data.oz;
|
|
}
|
|
}
|
|
}
|
|
console.log({
|
|
purchaseCount,
|
|
purchaseRate: purchaseCount / offerEventCount,
|
|
offerEventCount,
|
|
amountEarned,
|
|
ozSold,
|
|
popularity,
|
|
eventReasons
|
|
});
|
|
}
|
|
let events = [];
|
|
let traffic = randomNumber(mockdata_1.default.locations[0].dailyTraffic.min, mockdata_1.default.locations[0].dailyTraffic.max);
|
|
for (let i = 0; i < traffic; i++) {
|
|
let curEvent = personPassesByVendingMachine(generatePerson(mockdata_1.default.locations[0]), mockdata_1.default.players[0].vendingMachines[0]);
|
|
console.log(genCityName());
|
|
events.push(curEvent);
|
|
handleEvent(curEvent);
|
|
}
|
|
getStatsFromEvents(events);
|