initial commit
This commit is contained in:
317
src/mockProcess.ts
Normal file
317
src/mockProcess.ts
Normal file
@ -0,0 +1,317 @@
|
||||
import mockData from './mockdata';
|
||||
import * as cryptoRandomString from 'crypto-random-string';
|
||||
import { uniqueNamesGenerator, Config, adjectives, names, colors } from 'unique-names-generator';
|
||||
|
||||
// function calculateBusinessDay(player: any) {
|
||||
// let lineItems = [];
|
||||
// for (let i in player.vendingMachines) {
|
||||
// let machine = player.vendingMachines[i];
|
||||
//
|
||||
// }
|
||||
// }
|
||||
function handleEvent(eventLog: 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: string) {
|
||||
for (let i in mockData.players) {
|
||||
let player = mockData.players[i];
|
||||
for (let j in player.vendingMachines) {
|
||||
if (player.vendingMachines[i].id === id) {
|
||||
return player.vendingMachines[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function personPassesByVendingMachine(person: Person, machine): EventLog {
|
||||
let isThursty: boolean = Math.random() < person.thirst;
|
||||
let availableSelections = machine.selections.filter((selection) => {
|
||||
return !!selection.current;
|
||||
});
|
||||
|
||||
if (isThursty) {
|
||||
if (!availableSelections.length) {
|
||||
return wontBuy('NoneAvailable');
|
||||
}
|
||||
// pick a drink
|
||||
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): EventLog {
|
||||
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: Location): Person {
|
||||
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: string): string {
|
||||
return `${prefix}-${cryptoRandomString({length: 6, type: 'distinguishable'})}`;
|
||||
}
|
||||
|
||||
function genPersonName(): string {
|
||||
const config: Config = {
|
||||
dictionaries: [names, names],
|
||||
length: 2,
|
||||
separator: ' '
|
||||
};
|
||||
return uniqueNamesGenerator(config);
|
||||
}
|
||||
|
||||
function genDrinkName(): string {
|
||||
const config: Config = {
|
||||
dictionaries: [adjectives, colors],
|
||||
length: 2,
|
||||
separator: ' ',
|
||||
style: 'capital'
|
||||
};
|
||||
return uniqueNamesGenerator(config);
|
||||
}
|
||||
|
||||
function genStoreName(): string {
|
||||
const stores: string[] = [
|
||||
'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: Config = {
|
||||
dictionaries: [names, stores],
|
||||
length: 2,
|
||||
separator: '\'s ',
|
||||
style: 'capital'
|
||||
};
|
||||
return uniqueNamesGenerator(config);
|
||||
}
|
||||
|
||||
function genCityName(): string {
|
||||
const places: string[] = [
|
||||
'town',
|
||||
'city',
|
||||
'township',
|
||||
'borough',
|
||||
'seat',
|
||||
'metropolis',
|
||||
'burg',
|
||||
'municipality',
|
||||
'hamlet',
|
||||
];
|
||||
const config: Config = {
|
||||
dictionaries: [Math.random() > 0.5 ? colors : names, places],
|
||||
length: 2,
|
||||
separator: ' ',
|
||||
style: 'capital'
|
||||
};
|
||||
return uniqueNamesGenerator(config);
|
||||
}
|
||||
|
||||
function clamp(value: number, max: number = 1, min: number = 0) {
|
||||
if (value > max) {
|
||||
return max;
|
||||
}
|
||||
if (value < min) {
|
||||
return min;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
function genPreferences(): string[] {
|
||||
const availableDrinks: string[] = mockData.drinks;
|
||||
let prefCount = Math.floor(Math.random() * availableDrinks.length);
|
||||
prefCount = prefCount === 0 ? prefCount + 1 : prefCount; // have at least one preference
|
||||
let preferences: string[] = [];
|
||||
while (preferences.length < prefCount) {
|
||||
let newPref: Drink = pick(availableDrinks);
|
||||
if (preferences.indexOf(newPref.id) === -1) {
|
||||
preferences.push(newPref.id);
|
||||
}
|
||||
}
|
||||
return preferences;
|
||||
}
|
||||
|
||||
function getSelectionType(typeName: string) {
|
||||
return mockData.selectionTypes.find((type) => {
|
||||
return type.type === typeName;
|
||||
});
|
||||
}
|
||||
|
||||
function randomNumber(min: number, max: number): number {
|
||||
return Math.random() * (max - min) + min;
|
||||
}
|
||||
|
||||
function pick(arr: any[]) {
|
||||
return arr[Math.floor(Math.random() * arr.length)];
|
||||
}
|
||||
|
||||
function getStatsFromEvents(events: EventLog[]) {
|
||||
let purchaseCount: number = 0;
|
||||
let offerEventCount: number = 0;
|
||||
let amountEarned: number = 0;
|
||||
let ozSold: number = 0;
|
||||
let popularity: {[drink: string]: number} = {};
|
||||
let eventReasons: {[reason: string]: number} = {};
|
||||
|
||||
for (let i in events) {
|
||||
let eventLog: 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
|
||||
});
|
||||
}
|
||||
|
||||
interface Drink {
|
||||
id: string;
|
||||
name: string;
|
||||
costPerOz: number;
|
||||
}
|
||||
|
||||
interface DailyTraffic {
|
||||
max: number;
|
||||
min: number;
|
||||
thirstBonus: number;
|
||||
}
|
||||
|
||||
interface Placement {
|
||||
id: string;
|
||||
name: string;
|
||||
traffic: number;
|
||||
}
|
||||
|
||||
interface Location {
|
||||
id: string;
|
||||
name: string;
|
||||
city: string;
|
||||
dailyTraffic: DailyTraffic;
|
||||
placements: Placement[];
|
||||
}
|
||||
|
||||
interface Person {
|
||||
id: string;
|
||||
name: string;
|
||||
preferences: string[];
|
||||
highestPrice: number;
|
||||
money: number;
|
||||
thirst: number;
|
||||
}
|
||||
|
||||
interface EventLog {
|
||||
eventName: string;
|
||||
data: any;
|
||||
}
|
||||
|
||||
interface PersonEvent {
|
||||
reason: string;
|
||||
amount: number;
|
||||
drink: string;
|
||||
selection: string;
|
||||
selectionType: string;
|
||||
oz: number;
|
||||
person: string; // person involved in the event
|
||||
offer: string; // id of deal or vending machine
|
||||
}
|
||||
|
||||
let events: EventLog[] = [];
|
||||
let traffic: number = randomNumber(mockData.locations[0].dailyTraffic.min, mockData.locations[0].dailyTraffic.max)
|
||||
for (let i = 0; i < traffic; i++) {
|
||||
// console.log(generatePerson(mockData.locations[0]));
|
||||
let curEvent: EventLog = personPassesByVendingMachine(generatePerson(mockData.locations[0]), mockData.players[0].vendingMachines[0])
|
||||
// console.log(genDrinkName());
|
||||
// console.log(genStoreName());
|
||||
console.log(genCityName());
|
||||
events.push(curEvent);
|
||||
handleEvent(curEvent);
|
||||
}
|
||||
|
||||
getStatsFromEvents(events);
|
Reference in New Issue
Block a user