@gamepark/rules-api
Version:
API to implement the rules of a board game
82 lines (81 loc) • 4.27 kB
TypeScript
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;
}