UNPKG

@gamepark/rules-api

Version:

API to implement the rules of a board game

82 lines (81 loc) 4.27 kB
import { Location } from '../location'; import { ItemMove } from '../moves'; import { ItemEntry, Material } from './index'; import { MaterialItem } from './MaterialItem'; /** * This subclass of {@link Material} is design to handle counting and moving Money with different units: coins of 5 and 1 for instance. * It also keeps track of how much money is left after spending moves are create so that it is easy to spend money multiple time at once, * without risking spending the same coins twice because the moves are no immediately executed. */ export declare class MaterialMoney<P extends number = number, M extends number = number, L extends number = number, Unit extends number = number> extends Material<P, M, L> { readonly type: M; units: Unit[]; protected items: MaterialItem<P, L>[]; protected readonly processMove?: ((move: ItemMove<P, M, L>) => void) | undefined; entries: ItemEntry<P, L>[]; private pendingMoves; /** * Construct a new Material Money helper instance * @param {number} type Type of items this instance will work on * @param {MaterialItem[]} items The complete list of items of this type in current game state. * @param {number[]} units The different units that exists in stock to count this money * @param {ItemEntry[]} entries The list of items to work on. Each entry consists of an array with the index of the item, and the item * @param {function} processMove if provided, this function will be executed on every move created with this instance */ constructor(type: M, units: Unit[], items?: MaterialItem<P, L>[], processMove?: ((move: ItemMove<P, M, L>) => void) | undefined, entries?: ItemEntry<P, L>[]); /** * Helper function to return a new instance of the same class (works also for children class) * @param {ItemEntry[]} entries Filtered entries for the new class * @returns {this} the new Material instance * @protected */ protected new(entries: ItemEntry<P, L>[]): this; /** * We need to apply the pending moves before any filtering is done to get the right count for instance. */ filter<Id extends string | number | Record<string, any> | undefined>(predicate: (item: MaterialItem<P, L, Id>, index: number) => boolean): this; /** * Count the total value of a material instance * @returns the sum of each item id multiplied by its quantity */ get count(): number; /** * Create an amount of Money and put it in given location * @param amount Amount to gain * @param location The location to filter material onto, and to create new items in * @returns the moves that need to be played to perform the operation */ addMoney(amount: number, location: Location<P, L>): ItemMove<P, M, L>[]; /** * Remove an amount of Money from given location * @param amount Amount to spend * @param location The location to filter material onto, and to create new items in * @returns the moves that need to be played to perform the operation */ removeMoney(amount: number, location: Location<P, L>): ItemMove<P, M, L>[]; /** * Move an amount of money from a place to another place. It searches after the easiest way to do it, making money with the bank only if necessary. * @param origin Location to remove money from * @param target Location to move money to * @param amount Amount of money to transfer * @returns the moves that need to be played to perform the operation */ moveMoney(origin: Location<P, L>, target: Location<P, L>, amount: number): ItemMove<P, M, L>[]; /** * Return the best way to gain an amount, prioritizing the highest unit values * @param amount Amount to gain, default 1 * @returns the record of coins to earn (only positive values) */ private getGainMap; /** * Return the best way to spend an amount of owned units, prioritizing the smallest unit values * @param amount Amount to gain, default 1 * @returns the record of coins to give away and eventually take (positive and negative values) */ private getSpendMap; /** * Mutate the entries to get the state after * @private */ private applyPendingMoves; }