@gamepark/rules-api 6.24.2 → 6.25.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (170) hide show
  1. package/dist/Action.d.ts +7 -0
  2. package/dist/Bot.d.ts +21 -0
  3. package/dist/Bot.js +18 -2
  4. package/dist/Bot.js.map +1 -1
  5. package/dist/Competitive.d.ts +45 -0
  6. package/dist/Competitive.js +15 -0
  7. package/dist/Competitive.js.map +1 -1
  8. package/dist/Eliminations.d.ts +17 -0
  9. package/dist/Eliminations.js +5 -0
  10. package/dist/Eliminations.js.map +1 -1
  11. package/dist/GameSetup.d.ts +14 -0
  12. package/dist/HiddenInformation.d.ts +22 -0
  13. package/dist/HiddenInformation.js +5 -0
  14. package/dist/HiddenInformation.js.map +1 -1
  15. package/dist/LocalMovePreview.d.ts +14 -0
  16. package/dist/LocalMovePreview.js +5 -0
  17. package/dist/LocalMovePreview.js.map +1 -1
  18. package/dist/RandomMove.d.ts +20 -2
  19. package/dist/Rules.d.ts +119 -0
  20. package/dist/Rules.js +102 -1
  21. package/dist/Rules.js.map +1 -1
  22. package/dist/SecretInformation.d.ts +39 -0
  23. package/dist/SecretInformation.js +5 -0
  24. package/dist/SecretInformation.js.map +1 -1
  25. package/dist/TimeLimit.d.ts +22 -0
  26. package/dist/TimeLimit.js +5 -0
  27. package/dist/TimeLimit.js.map +1 -1
  28. package/dist/Undo.d.ts +18 -0
  29. package/dist/Undo.js +6 -0
  30. package/dist/Undo.js.map +1 -1
  31. package/dist/UnpredictableMove.d.ts +19 -0
  32. package/dist/UnpredictableMove.js +5 -0
  33. package/dist/UnpredictableMove.js.map +1 -1
  34. package/dist/material/HiddenMaterialRules.d.ts +49 -1
  35. package/dist/material/HiddenMaterialRules.js +56 -13
  36. package/dist/material/HiddenMaterialRules.js.map +1 -1
  37. package/dist/material/MaterialGame.d.ts +12 -0
  38. package/dist/material/MaterialGameSetup.d.ts +74 -0
  39. package/dist/material/MaterialGameSetup.js +68 -5
  40. package/dist/material/MaterialGameSetup.js.map +1 -1
  41. package/dist/material/MaterialRules.d.ts +133 -1
  42. package/dist/material/MaterialRules.js +131 -5
  43. package/dist/material/MaterialRules.js.map +1 -1
  44. package/dist/material/SecretMaterialRules.d.ts +31 -0
  45. package/dist/material/SecretMaterialRules.js +23 -1
  46. package/dist/material/SecretMaterialRules.js.map +1 -1
  47. package/dist/material/items/Material.d.ts +265 -5
  48. package/dist/material/items/Material.js +266 -7
  49. package/dist/material/items/Material.js.map +1 -1
  50. package/dist/material/items/MaterialDeck.d.ts +34 -1
  51. package/dist/material/items/MaterialDeck.js +36 -3
  52. package/dist/material/items/MaterialDeck.js.map +1 -1
  53. package/dist/material/items/MaterialItem.d.ts +12 -0
  54. package/dist/material/items/MaterialMoney.d.ts +81 -0
  55. package/dist/material/items/MaterialMoney.js +288 -0
  56. package/dist/material/items/MaterialMoney.js.map +1 -0
  57. package/dist/material/items/MaterialMutator.d.ts +39 -0
  58. package/dist/material/items/MaterialMutator.js +44 -5
  59. package/dist/material/items/MaterialMutator.js.map +1 -1
  60. package/dist/material/items/index.d.ts +2 -1
  61. package/dist/material/items/index.js +3 -1
  62. package/dist/material/items/index.js.map +1 -1
  63. package/dist/material/location/Location.d.ts +28 -0
  64. package/dist/material/location/Location.js +5 -0
  65. package/dist/material/location/Location.js.map +1 -1
  66. package/dist/material/location/LocationBuilder.js +1 -1
  67. package/dist/material/location/strategy/FillGapStrategy.d.ts +4 -0
  68. package/dist/material/location/strategy/FillGapStrategy.js +5 -1
  69. package/dist/material/location/strategy/FillGapStrategy.js.map +1 -1
  70. package/dist/material/location/strategy/LocationStrategy.d.ts +20 -0
  71. package/dist/material/location/strategy/PositiveSequenceStrategy.d.ts +4 -0
  72. package/dist/material/location/strategy/PositiveSequenceStrategy.js +5 -1
  73. package/dist/material/location/strategy/PositiveSequenceStrategy.js.map +1 -1
  74. package/dist/material/memory/GameMemory.d.ts +21 -0
  75. package/dist/material/memory/GameMemory.js +22 -1
  76. package/dist/material/memory/GameMemory.js.map +1 -1
  77. package/dist/material/memory/PlayerMemory.d.ts +22 -0
  78. package/dist/material/memory/PlayerMemory.js +23 -1
  79. package/dist/material/memory/PlayerMemory.js.map +1 -1
  80. package/dist/material/moves/CustomMove.d.ts +18 -0
  81. package/dist/material/moves/CustomMove.js +13 -0
  82. package/dist/material/moves/CustomMove.js.map +1 -1
  83. package/dist/material/moves/MaterialMove.d.ts +9 -0
  84. package/dist/material/moves/MaterialMoveBuilder.d.ts +36 -0
  85. package/dist/material/moves/MaterialMoveBuilder.js +36 -0
  86. package/dist/material/moves/MaterialMoveBuilder.js.map +1 -1
  87. package/dist/material/moves/MoveKind.d.ts +3 -0
  88. package/dist/material/moves/MoveKind.js +3 -0
  89. package/dist/material/moves/MoveKind.js.map +1 -1
  90. package/dist/material/moves/items/CreateItem.d.ts +13 -0
  91. package/dist/material/moves/items/CreateItem.js +10 -0
  92. package/dist/material/moves/items/CreateItem.js.map +1 -1
  93. package/dist/material/moves/items/CreateItemsAtOnce.d.ts +14 -0
  94. package/dist/material/moves/items/CreateItemsAtOnce.js +10 -0
  95. package/dist/material/moves/items/CreateItemsAtOnce.js.map +1 -1
  96. package/dist/material/moves/items/DeleteItem.d.ts +18 -0
  97. package/dist/material/moves/items/DeleteItem.js +11 -0
  98. package/dist/material/moves/items/DeleteItem.js.map +1 -1
  99. package/dist/material/moves/items/DeleteItemsAtOnce.d.ts +17 -0
  100. package/dist/material/moves/items/DeleteItemsAtOnce.js +10 -0
  101. package/dist/material/moves/items/DeleteItemsAtOnce.js.map +1 -1
  102. package/dist/material/moves/items/ItemMove.d.ts +12 -0
  103. package/dist/material/moves/items/ItemMoveType.d.ts +3 -0
  104. package/dist/material/moves/items/ItemMoveType.js +3 -0
  105. package/dist/material/moves/items/ItemMoveType.js.map +1 -1
  106. package/dist/material/moves/items/MoveItem.d.ts +20 -0
  107. package/dist/material/moves/items/MoveItem.js +11 -0
  108. package/dist/material/moves/items/MoveItem.js.map +1 -1
  109. package/dist/material/moves/items/MoveItemsAtOnce.d.ts +20 -0
  110. package/dist/material/moves/items/MoveItemsAtOnce.js +10 -0
  111. package/dist/material/moves/items/MoveItemsAtOnce.js.map +1 -1
  112. package/dist/material/moves/items/RollItem.d.ts +19 -0
  113. package/dist/material/moves/items/RollItem.js +10 -0
  114. package/dist/material/moves/items/RollItem.js.map +1 -1
  115. package/dist/material/moves/items/SelectItem.d.ts +20 -0
  116. package/dist/material/moves/items/SelectItem.js +11 -0
  117. package/dist/material/moves/items/SelectItem.js.map +1 -1
  118. package/dist/material/moves/items/Shuffle.d.ts +26 -0
  119. package/dist/material/moves/items/Shuffle.js +15 -0
  120. package/dist/material/moves/items/Shuffle.js.map +1 -1
  121. package/dist/material/moves/local/CloseTutorialPopup.d.ts +8 -0
  122. package/dist/material/moves/local/CloseTutorialPopup.js +5 -0
  123. package/dist/material/moves/local/CloseTutorialPopup.js.map +1 -1
  124. package/dist/material/moves/local/DisplayHelp.d.ts +18 -0
  125. package/dist/material/moves/local/DisplayHelp.js +3 -0
  126. package/dist/material/moves/local/DisplayHelp.js.map +1 -1
  127. package/dist/material/moves/local/DropItem.d.ts +9 -0
  128. package/dist/material/moves/local/LocalMove.d.ts +6 -0
  129. package/dist/material/moves/local/LocalMove.js +3 -0
  130. package/dist/material/moves/local/LocalMove.js.map +1 -1
  131. package/dist/material/moves/local/SetTutorialStep.d.ts +8 -0
  132. package/dist/material/moves/local/SetTutorialStep.js +5 -0
  133. package/dist/material/moves/local/SetTutorialStep.js.map +1 -1
  134. package/dist/material/rules/MaterialRulesPart.d.ts +76 -0
  135. package/dist/material/rules/MaterialRulesPart.js +75 -3
  136. package/dist/material/rules/MaterialRulesPart.js.map +1 -1
  137. package/dist/material/rules/PlayerTurnRule.d.ts +19 -0
  138. package/dist/material/rules/PlayerTurnRule.js +20 -1
  139. package/dist/material/rules/PlayerTurnRule.js.map +1 -1
  140. package/dist/material/rules/RuleStep.d.ts +3 -0
  141. package/dist/material/rules/SimultaneousRule.d.ts +25 -0
  142. package/dist/material/rules/SimultaneousRule.js +21 -1
  143. package/dist/material/rules/SimultaneousRule.js.map +1 -1
  144. package/dist/material/tutorial/TutorialState.d.ts +7 -0
  145. package/dist/options/OptionsValidationError.js +1 -1
  146. package/dist/options/PlayerEnumOption.js +3 -0
  147. package/dist/options/PlayerEnumOption.js.map +1 -1
  148. package/dist/utils/action-view.util.js +3 -1
  149. package/dist/utils/action-view.util.js.map +1 -1
  150. package/dist/utils/action.util.js +1 -1
  151. package/dist/utils/action.util.js.map +1 -1
  152. package/dist/utils/enum.util.d.ts +27 -0
  153. package/dist/utils/enum.util.js +24 -0
  154. package/dist/utils/enum.util.js.map +1 -1
  155. package/dist/utils/grid.squares.util.d.ts +26 -0
  156. package/dist/utils/grid.squares.util.js +26 -0
  157. package/dist/utils/grid.squares.util.js.map +1 -1
  158. package/dist/utils/grid.util.d.ts +8 -0
  159. package/dist/utils/grid.util.js +5 -0
  160. package/dist/utils/grid.util.js.map +1 -1
  161. package/dist/utils/listing.util.d.ts +12 -0
  162. package/dist/utils/listing.util.js +12 -0
  163. package/dist/utils/listing.util.js.map +1 -1
  164. package/dist/utils/money.util.d.ts +42 -4
  165. package/dist/utils/money.util.js +39 -1
  166. package/dist/utils/money.util.js.map +1 -1
  167. package/dist/utils/random.util.d.ts +6 -2
  168. package/dist/utils/random.util.js +6 -10
  169. package/dist/utils/random.util.js.map +1 -1
  170. package/package.json +1 -1
package/dist/Rules.js CHANGED
@@ -6,24 +6,61 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.Rules = void 0;
7
7
  var isEqual_1 = __importDefault(require("lodash/isEqual"));
8
8
  var Eliminations_1 = require("./Eliminations");
9
- var Rules = (function () {
9
+ /**
10
+ * The Rules class is the basic minimal API to implement when adapting a board game on Game Park.
11
+ * It has the ability to tell whether it is a player's turn to play, what moves are legal, what happens when a move is played, and when the game is over.
12
+ *
13
+ * @typeparam Game - Data structure of the game state
14
+ * @typeparam Move - Data structure of a game move
15
+ * @typeparam PlayerId - type of the player's identifiers. Usually a number or a numeric enum.
16
+ */
17
+ var Rules = /** @class */ (function () {
18
+ /**
19
+ * Construct a new instance of the Rules to work on a game state
20
+ * @param game the state of the game to work on
21
+ */
10
22
  function Rules(game) {
11
23
  this.game = game;
12
24
  }
13
25
  Object.defineProperty(Rules.prototype, "state", {
26
+ /**
27
+ * A shortcut for this.game for backward compatibility
28
+ */
14
29
  get: function () {
15
30
  return this.game;
16
31
  },
17
32
  enumerable: false,
18
33
  configurable: true
19
34
  });
35
+ /**
36
+ * The delegation allows to split the rules in smaller and simpler parts.
37
+ * Override this method to delegate the behavior of the other method to another Rules class.
38
+ *
39
+ * @return the Rule you want to delegate the current game behavior to
40
+ */
20
41
  Rules.prototype.delegate = function () {
21
42
  return;
22
43
  };
44
+ /**
45
+ * The delegation allows to split the rules in smaller and simpler parts.
46
+ * Default behavior call {@link delegate} and returns either an empty array, or an array with the delegate if any.
47
+ * Override this method to delegate the behavior of the other method to multiple Rules class.
48
+ *
49
+ * @return an array of Rules to delegate the current game behavior to
50
+ */
23
51
  Rules.prototype.delegates = function () {
24
52
  var delegate = this.delegate();
25
53
  return delegate ? [delegate] : [];
26
54
  };
55
+ /**
56
+ * Implement this to tell at any point in the game which player is active or not.
57
+ * When it's a player's turn, his thinking time decreases.
58
+ * A player whose turn it's not can have authorised moves, so this method is not sufficient to prevent a player from playing.
59
+ * Supports delegation: it returns true if any {@link delegates} return true.
60
+ *
61
+ * @param playerId - Identifier of a player
62
+ * @returns true if it is this player's turn to play
63
+ */
27
64
  Rules.prototype.isTurnToPlay = function (playerId) {
28
65
  var rules = this.delegates();
29
66
  if (rules.some(function (rules) { return rules.isTurnToPlay(playerId); })) {
@@ -31,6 +68,12 @@ var Rules = (function () {
31
68
  }
32
69
  return playerId === this.getActivePlayer();
33
70
  };
71
+ /**
72
+ * When only one player is active at a time, you can implement this method instead of "isTurnToPlay" to tell which player is active.
73
+ * Supports delegation: if any {@link delegates} returns an active player, it will return it.
74
+ *
75
+ * @return @typeParam PlayerId - The identifier of the active player
76
+ */
34
77
  Rules.prototype.getActivePlayer = function () {
35
78
  for (var _i = 0, _a = this.delegates(); _i < _a.length; _i++) {
36
79
  var delegate = _a[_i];
@@ -40,6 +83,15 @@ var Rules = (function () {
40
83
  }
41
84
  return;
42
85
  };
86
+ /**
87
+ * This method allows the Game Park server to authorise only valid moves in accordance with the game rules.
88
+ * The default behavior calls {@link getLegalMoves}, and returns true when at least one move is equal.
89
+ * Supports delegation with {@link delegates}. A move is legal if it is legal for at least one delegate.
90
+ *
91
+ * @param playerId - Identifier of a player
92
+ * @param move - a Move to control
93
+ * @returns true if the move can be played by this player
94
+ */
43
95
  Rules.prototype.isLegalMove = function (playerId, move) {
44
96
  var rules = this.delegates();
45
97
  if (rules.some(function (rules) { return rules.isLegalMove(playerId, move); })) {
@@ -53,15 +105,64 @@ var Rules = (function () {
53
105
  }
54
106
  return false;
55
107
  };
108
+ /**
109
+ * This method lists all the moves that are legal for a given player.
110
+ * This is optional but convenient: it is used by {@link isLegalMove}, {@link Bot} and many UI features from @gamepark/react-game to automatically
111
+ * highlight what can be done on the screen.
112
+ * Beware of the size of the list however: if the game offers to many legal moves, you might have to fall back to implementing {@link isLegalMove} and a
113
+ * custom {@link Bot}.
114
+ *
115
+ * Supports delegation with {@link delegates}: by default it will return all the legal moves of each delegate.
116
+ *
117
+ * @param playerId - Identifier of a player
118
+ * @returns the list of the moves
119
+ */
56
120
  Rules.prototype.getLegalMoves = function (playerId) {
57
121
  return this.delegates().flatMap(function (rules) { return rules.getLegalMoves(playerId); });
58
122
  };
123
+ /**
124
+ * When some game state require automatic actions to be taken by the players, you can return a list of moves to play played automatically.
125
+ * It can be a sequences in the rules where everything is scripted for instance (no choices left for players).
126
+ *
127
+ * @deprecated because of the lifecycle of this method, the game state must never be modified inside it. However, it is a very common mistake, so
128
+ * this method should not be used at all: use {@link play} method to return the automatic moves.
129
+ *
130
+ * Supports delegation with {@link delegates}: by default it will return all the automatic moves of each delegate.
131
+ *
132
+ * @returns the list of the moves that must be played automatically
133
+ */
59
134
  Rules.prototype.getAutomaticMoves = function () {
60
135
  return this.delegates().flatMap(function (rules) { return rules.getAutomaticMoves(); });
61
136
  };
137
+ /**
138
+ * Executes a move on current game state.
139
+ * This method is the only one that should mutate the state of the game.
140
+ * When a move is played by a player, or automatically played as a consequence of another move, it will be played by this method, independently on Game Park
141
+ * server and on every player or spectator clients. It can also be replayed in replay or undo features.
142
+ *
143
+ * A move should not change a lot the game state: instead, this method should return new moves to play as consequences.
144
+ * Dividing moves into small parts with consequences is key to producing step-by-step animations in the UI.
145
+ *
146
+ * see {@link https://en.wikipedia.org/wiki/Command_pattern}
147
+ *
148
+ * Supports delegation with {@link delegates}: by default it will play the move on each delegate, and return all the consequences.
149
+ *
150
+ * @param move - the Move to execute on the game state
151
+ * @param context - context of execution: see {@link PlayMoveContext}
152
+ * @returns A list of moves that should be immediately played as consequences of this move
153
+ */
62
154
  Rules.prototype.play = function (move, context) {
63
155
  return this.delegates().flatMap(function (rules) { return rules.play(move, context); });
64
156
  };
157
+ /**
158
+ * This method must return true when the game is over.
159
+ *
160
+ * Supports delegation with {@link delegates}: by default it will return true if there is at least one delegate, and every delegate returns true.
161
+ * Default behavior returns true if playersIds is provided, and it is not {@link isTurnToPlay} for any player - however this behavior is deprecated.
162
+ *
163
+ * @param playerIds - All the player ids in the game. Do not use (deprecated).
164
+ * @returns true if game is over
165
+ */
65
166
  Rules.prototype.isOver = function (playerIds) {
66
167
  var _this = this;
67
168
  var delegates = this.delegates();
package/dist/Rules.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"Rules.js","sourceRoot":"","sources":["../src/Rules.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"Rules.js","sourceRoot":"","sources":["../src/Rules.ts"],"names":[],"mappings":"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"}
@@ -1,9 +1,48 @@
1
1
  import { HiddenInformation } from './HiddenInformation';
2
+ /**
3
+ * Some game hide information to the player, and the information is not equally accessible by each player.
4
+ * For example, when a player knows the cards in their hand, but this information is not available to other players.
5
+ * The rules of the game need to implement this interface in that case to secure the information.
6
+ *
7
+ * It is important not to implement SecretInformation if {@link HiddenInformation} is sufficient, because implementing SecretInformation will create a
8
+ * distinct notification channel for each player, thus more notifications that necessary if all players have access to the same information.
9
+ */
2
10
  export interface SecretInformation<GameView = any, Move = any, MoveView = any, PlayerId = any> extends HiddenInformation<GameView, Move, MoveView> {
11
+ /**
12
+ * In a game with Secret Information, getView is called for spectators only. See {@link HiddenInformation.getView}.
13
+ */
3
14
  getView(): GameView;
15
+ /**
16
+ * In a game with Secret Information, getMoveView is called for spectators only. See {@link HiddenInformation.getMoveView}.
17
+ */
4
18
  getMoveView(move: Move): MoveView;
19
+ /**
20
+ * Same as {@link HiddenInformation.getView}, but for one player.
21
+ * @param playerId The player this view will be sent to
22
+ * @returns the state of the game this player can see
23
+ */
5
24
  getPlayerView(playerId: PlayerId): GameView;
25
+ /**
26
+ * Same as {@link HiddenInformation.getMoveView}, but for one player.
27
+ * @param move A move that happened in the game
28
+ * @param playerId The player this move view will be sent to
29
+ * @returns the move with less or more data depending on what to hide or reveal
30
+ */
6
31
  getPlayerMoveView?(move: Move, playerId: PlayerId): MoveView;
32
+ /**
33
+ * If some moves played must be entirely keep secret to other players, you can implement this function to prevent the move from being transmitted to
34
+ * another player as long as necessary.
35
+ * Useful for game with secret planning for instance.
36
+ *
37
+ * @param move A move played by a player
38
+ * @param playerId Identifier of another player
39
+ * @return true as long as the move must be kept secret from that player
40
+ */
7
41
  keepMoveSecret?(move: Move, playerId: PlayerId): boolean;
8
42
  }
43
+ /**
44
+ * Type guard for games with secret information
45
+ * @param rules Rules of the game
46
+ * @returns true if the game implements {@link SecretInformation}
47
+ */
9
48
  export declare function hasSecretInformation<GameView = any, Move = any, MoveView = any, PlayerId = any>(rules: Object): rules is SecretInformation<GameView, Move, MoveView, PlayerId>;
@@ -1,6 +1,11 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.hasSecretInformation = void 0;
4
+ /**
5
+ * Type guard for games with secret information
6
+ * @param rules Rules of the game
7
+ * @returns true if the game implements {@link SecretInformation}
8
+ */
4
9
  function hasSecretInformation(rules) {
5
10
  var test = rules;
6
11
  return typeof test.getPlayerView === 'function';
@@ -1 +1 @@
1
- {"version":3,"file":"SecretInformation.js","sourceRoot":"","sources":["../src/SecretInformation.ts"],"names":[],"mappings":";;;AAqDA,SAAgB,oBAAoB,CAA6D,KAAa;IAC5G,IAAM,IAAI,GAAG,KAA8D,CAAA;IAC3E,OAAO,OAAO,IAAI,CAAC,aAAa,KAAK,UAAU,CAAA;AACjD,CAAC;AAHD,oDAGC"}
1
+ {"version":3,"file":"SecretInformation.js","sourceRoot":"","sources":["../src/SecretInformation.ts"],"names":[],"mappings":";;;AAgDA;;;;GAIG;AACH,SAAgB,oBAAoB,CAA6D,KAAa;IAC5G,IAAM,IAAI,GAAG,KAA8D,CAAA;IAC3E,OAAO,OAAO,IAAI,CAAC,aAAa,KAAK,UAAU,CAAA;AACjD,CAAC;AAHD,oDAGC"}
@@ -1,6 +1,28 @@
1
1
  import { Rules } from './Rules';
2
+ /**
3
+ * In games played in real time with a time limit, players start with an amount of time, and more time is added every time it is their turn to play.
4
+ * Players can be expelled after some time (-1 minute).
5
+ * This interface allows to control how much extra time is given to players every time it is their turn to play.
6
+ *
7
+ * Beginner have up to x1.5 more thinking time, so the time given here must be for "experienced" players.
8
+ */
2
9
  export interface TimeLimit<Game, Move = string, PlayerId = number> extends Rules<Game, Move, PlayerId> {
10
+ /**
11
+ * Amount of time given to a player everytime it is their turn to play.
12
+ * @param playerId Id of the player, if you want to give different time depending on the id for asymmetric games.
13
+ * @return number of seconds to add to the player's clock
14
+ */
3
15
  giveTime(playerId: PlayerId): number;
16
+ /**
17
+ * Amount of time given to a player before the game begins. Default value is 2 minutes.
18
+ * @param playerId Id of the player, if you want to give different time depending on the id for asymmetric games.
19
+ * @return starting amount of seconds for each player when the game starts
20
+ */
4
21
  startingTime?(playerId: PlayerId): number;
5
22
  }
23
+ /**
24
+ * Type guard for {@link TimeLimit} interface
25
+ * @param rules Rules of the game
26
+ * @returns true if rules implements {@link TimeLimit}
27
+ */
6
28
  export declare function hasTimeLimit<Game, Move, PlayerId>(rules: Rules<Game, Move, PlayerId>): rules is TimeLimit<Game, Move, PlayerId>;
package/dist/TimeLimit.js CHANGED
@@ -1,6 +1,11 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.hasTimeLimit = void 0;
4
+ /**
5
+ * Type guard for {@link TimeLimit} interface
6
+ * @param rules Rules of the game
7
+ * @returns true if rules implements {@link TimeLimit}
8
+ */
4
9
  function hasTimeLimit(rules) {
5
10
  return typeof rules.giveTime === 'function';
6
11
  }
@@ -1 +1 @@
1
- {"version":3,"file":"TimeLimit.js","sourceRoot":"","sources":["../src/TimeLimit.ts"],"names":[],"mappings":";;;AA8BA,SAAgB,YAAY,CAAuB,KAAkC;IACnF,OAAO,OAAQ,KAAyC,CAAC,QAAQ,KAAK,UAAU,CAAA;AAClF,CAAC;AAFD,oCAEC"}
1
+ {"version":3,"file":"TimeLimit.js","sourceRoot":"","sources":["../src/TimeLimit.ts"],"names":[],"mappings":";;;AAyBA;;;;GAIG;AACH,SAAgB,YAAY,CAAuB,KAAkC;IACnF,OAAO,OAAQ,KAAyC,CAAC,QAAQ,KAAK,UAAU,CAAA;AAClF,CAAC;AAFD,oCAEC"}
package/dist/Undo.d.ts CHANGED
@@ -1,5 +1,23 @@
1
1
  import { Action } from './Action';
2
+ /**
3
+ * The undo feature allow a player to undo some move played during the game.
4
+ * The move undone is removed from the game history: the new game state results from applying all the remaining moves from the game setup.
5
+ * Any direct consequences of the move (see {@link Action.consequences}) are also removed.
6
+ */
2
7
  export interface Undo<Move = string, PlayerId = number> {
8
+ /**
9
+ * This function allow an action to be undone, by the player that did it.
10
+ *
11
+ * @param action The {@link Action} to allow or not to undo.
12
+ * @param consecutiveActions All the actions that has been played meanwhile by the players
13
+ * @returns true if the action can be undone
14
+ */
3
15
  canUndo(action: Action<Move, PlayerId>, consecutiveActions: Action<Move, PlayerId>[]): boolean;
4
16
  }
17
+ /**
18
+ * Type guard to know if a game implements the Undo feature.
19
+ *
20
+ * @param rules Rules of the game
21
+ * @returns true if rules implements {@link Undo}
22
+ */
5
23
  export declare function hasUndo<Move, PlayerId>(rules: Object): rules is Undo<Move, PlayerId>;
package/dist/Undo.js CHANGED
@@ -1,6 +1,12 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.hasUndo = void 0;
4
+ /**
5
+ * Type guard to know if a game implements the Undo feature.
6
+ *
7
+ * @param rules Rules of the game
8
+ * @returns true if rules implements {@link Undo}
9
+ */
4
10
  function hasUndo(rules) {
5
11
  var test = rules;
6
12
  return typeof test.canUndo === 'function';
package/dist/Undo.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"Undo.js","sourceRoot":"","sources":["../src/Undo.ts"],"names":[],"mappings":";;;AAwBA,SAAgB,OAAO,CAAiB,KAAa;IACnD,IAAM,IAAI,GAAG,KAA6B,CAAA;IAC1C,OAAO,OAAO,IAAI,CAAC,OAAO,KAAK,UAAU,CAAA;AAC3C,CAAC;AAHD,0BAGC"}
1
+ {"version":3,"file":"Undo.js","sourceRoot":"","sources":["../src/Undo.ts"],"names":[],"mappings":";;;AAkBA;;;;;GAKG;AACH,SAAgB,OAAO,CAAiB,KAAa;IACnD,IAAM,IAAI,GAAG,KAA6B,CAAA;IAC1C,OAAO,OAAO,IAAI,CAAC,OAAO,KAAK,UAAU,CAAA;AAC3C,CAAC;AAHD,0BAGC"}
@@ -1,6 +1,25 @@
1
1
  import { Rules } from './Rules';
2
+ /**
3
+ * A move is unpredictable for the player when the outcome is not known, ie when the state of the game after applying the move cannot be processed without
4
+ * the server response.
5
+ * It is the case for moves with random output (like rolling a die), or revealing hidden information (like drawing a card).
6
+ *
7
+ * Game Park offers a smooth experience by executing any move played immediately, without waiting for the server's response, as well as the consequences.
8
+ * However, it cannot be done for unpredictable moves, so this interface allows to identify which move can be played immediately, or not.
9
+ */
2
10
  export interface UnpredictableMoves<M = any, P = any> {
11
+ /**
12
+ * Tell if a move is unpredictable
13
+ * @param move A move
14
+ * @param player The player that should predict the move
15
+ * @returns true if the move outcome is predictable
16
+ */
3
17
  isUnpredictableMove(move: M, player: P): boolean;
4
18
  canIgnoreServerDifference?(clientMove: M, serverMove: M): boolean;
5
19
  }
20
+ /**
21
+ * Type guard for {@link UnpredictableMoves} interface
22
+ * @param rules Rules of the game
23
+ * @returns true is rules implements {@link UnpredictableMoves}
24
+ */
6
25
  export declare const hasUnpredictableMoves: <G = any, M = any, P = any>(rules: Rules<G, M, P>) => rules is Rules<G, M, P> & UnpredictableMoves<M, P>;
@@ -1,6 +1,11 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.hasUnpredictableMoves = void 0;
4
+ /**
5
+ * Type guard for {@link UnpredictableMoves} interface
6
+ * @param rules Rules of the game
7
+ * @returns true is rules implements {@link UnpredictableMoves}
8
+ */
4
9
  var hasUnpredictableMoves = function (rules) { return typeof rules.isUnpredictableMove === 'function'; };
5
10
  exports.hasUnpredictableMoves = hasUnpredictableMoves;
6
11
  //# sourceMappingURL=UnpredictableMove.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"UnpredictableMove.js","sourceRoot":"","sources":["../src/UnpredictableMove.ts"],"names":[],"mappings":";;;AA2BO,IAAM,qBAAqB,GAAG,UACnC,KAAqB,IACkC,OAAA,OAAO,KAAK,CAAC,mBAAmB,KAAK,UAAU,EAA/C,CAA+C,CAAA;AAF3F,QAAA,qBAAqB,yBAEsE"}
1
+ {"version":3,"file":"UnpredictableMove.js","sourceRoot":"","sources":["../src/UnpredictableMove.ts"],"names":[],"mappings":";;;AAsBA;;;;GAIG;AACI,IAAM,qBAAqB,GAAG,UACnC,KAAqB,IACkC,OAAA,OAAO,KAAK,CAAC,mBAAmB,KAAK,UAAU,EAA/C,CAA+C,CAAA;AAF3F,QAAA,qBAAqB,yBAEsE"}
@@ -4,23 +4,58 @@ import { MaterialItem } from './items';
4
4
  import { MaterialGame } from './MaterialGame';
5
5
  import { MaterialRules } from './MaterialRules';
6
6
  import { MaterialMove, MaterialMoveRandomized, MaterialMoveView } from './moves';
7
+ /**
8
+ * Implement HiddenMaterialRules when you want to use the {@link MaterialRules} approach with {@link HiddenInformation}.
9
+ * Using some {@link HidingStrategy} allows to enforce the security of a game with hidden information easily.
10
+ * If the game has secret information (some players have information not available to others, link cards in their hand), then you
11
+ * must implement {@link SecretMaterialRules} instead.
12
+ */
7
13
  export declare abstract class HiddenMaterialRules<P extends number = number, M extends number = number, L extends number = number> extends MaterialRules<P, M, L> implements HiddenInformation<MaterialGame<P, M, L>, MaterialMove<P, M, L>, MaterialMove<P, M, L>> {
8
14
  private readonly client?;
9
15
  constructor(game: MaterialGame<P, M, L>, client?: {
10
16
  player?: P | undefined;
11
17
  } | undefined);
18
+ /**
19
+ * A hiding strategy allows to hide automatically some information about an item when it is at a specific location type.
20
+ * Usually, we hide the item id (or a part of it).
21
+ * Example: {[MaterialType.Card]: {[LocationType.Deck]: hideItemId}} will hide the id of the cards in the deck to everybody.
22
+ * See {@link HidingStrategy}
23
+ */
12
24
  abstract readonly hidingStrategies: Partial<Record<M, Partial<Record<L, HidingStrategy<P, L>>>>>;
13
- randomize(move: MaterialMove<P, M, L>): MaterialMove<P, M, L> & MaterialMoveRandomized<P, M, L>;
25
+ randomize(move: MaterialMove<P, M, L>, player?: P): MaterialMove<P, M, L> & MaterialMoveRandomized<P, M, L>;
14
26
  private isRevealingItemMove;
27
+ /**
28
+ * Items that can be hidden cannot merge by default, to prevent hidden items to merge only because they have no id.
29
+ */
15
30
  itemsCanMerge(type: M): boolean;
31
+ /**
32
+ * Moves that reveal some information (like drawing a card) cannot be predicted by the player.
33
+ */
16
34
  isUnpredictableMove(move: MaterialMove<P, M, L>, player: P): boolean;
35
+ /**
36
+ * Moves than reveals an information to someone cannot be undone by default
37
+ */
17
38
  protected moveBlocksUndo(move: MaterialMove<P, M, L>): boolean;
39
+ /**
40
+ * @param move A move to test
41
+ * @returns true if the move revealed something to some player
42
+ */
18
43
  protected moveRevealedSomething(move: MaterialMove<P, M, L>): boolean;
44
+ /**
45
+ * With the material approach, we can offer a default working implementation for {@link HiddenInformation.getView}
46
+ */
19
47
  getView(player?: P): MaterialGame<P, M, L>;
20
48
  private hideItem;
21
49
  private getItemHiddenPaths;
22
50
  private itemHasHiddenInformation;
51
+ /**
52
+ * To be able to know if a MoveItem cannot be undone, the server flags the moves with a "reveal" property.
53
+ * This difference must be integrated without error during the callback.
54
+ */
23
55
  canIgnoreServerDifference(clientMove: MaterialMove<P, M, L>, serverMove: MaterialMove<P, M, L>): boolean;
56
+ /**
57
+ * With the material approach, we can offer a default working implementation for {@link HiddenInformation.getMoveView}
58
+ */
24
59
  getMoveView(move: MaterialMoveRandomized<P, M, L>, player?: P): MaterialMove<P, M, L>;
25
60
  private getMoveItemView;
26
61
  private getMoveAtOnceView;
@@ -30,8 +65,21 @@ export declare abstract class HiddenMaterialRules<P extends number = number, M e
30
65
  private moveAtOnceWillRevealSomething;
31
66
  private getShuffleItemsView;
32
67
  private canSeeShuffleResult;
68
+ /**
69
+ * Override of {@link MaterialRules.play} that also removes the hidden information from items, for example when a card is flipped face down
70
+ */
33
71
  play(move: MaterialMoveRandomized<P, M, L> | MaterialMoveView<P, M, L>, context?: PlayMoveContext): MaterialMove<P, M, L>[];
34
72
  }
73
+ /**
74
+ * A Hiding Strategy is a function that takes an item and returns a list of path to hide in the item object.
75
+ * See {@link hideItemId} and {@link hideFront} for 2 hiding strategy frequently used.
76
+ */
35
77
  export type HidingStrategy<P extends number = number, L extends number = number> = (item: MaterialItem<P, L>) => string[];
78
+ /**
79
+ * Hiding strategy that removes the item id
80
+ */
36
81
  export declare const hideItemId: HidingStrategy;
82
+ /**
83
+ * Hiding strategy that removes "id.front" from the item (when we have cards with composite ids, back & front)
84
+ */
37
85
  export declare const hideFront: HidingStrategy;
@@ -49,27 +49,43 @@ var set_1 = __importDefault(require("lodash/set"));
49
49
  var unset_1 = __importDefault(require("lodash/unset"));
50
50
  var MaterialRules_1 = require("./MaterialRules");
51
51
  var moves_1 = require("./moves");
52
- var HiddenMaterialRules = (function (_super) {
52
+ /**
53
+ * Implement HiddenMaterialRules when you want to use the {@link MaterialRules} approach with {@link HiddenInformation}.
54
+ * Using some {@link HidingStrategy} allows to enforce the security of a game with hidden information easily.
55
+ * If the game has secret information (some players have information not available to others, link cards in their hand), then you
56
+ * must implement {@link SecretMaterialRules} instead.
57
+ */
58
+ var HiddenMaterialRules = /** @class */ (function (_super) {
53
59
  __extends(HiddenMaterialRules, _super);
54
60
  function HiddenMaterialRules(game, client) {
55
61
  var _this = _super.call(this, game) || this;
56
62
  _this.client = client;
57
63
  return _this;
58
64
  }
59
- HiddenMaterialRules.prototype.randomize = function (move) {
60
- if (this.isRevealingItemMove(move)) {
65
+ HiddenMaterialRules.prototype.randomize = function (move, player) {
66
+ if (player !== undefined && this.isRevealingItemMove(move, player)) {
67
+ // We need to know if a MoveItem has revealed something to the player to prevent the undo in that case.
68
+ // To know that, we need the position of the item before the move.
69
+ // To prevent having to recalculate the game state before the move, we flag the move in the database with "reveal: {}".
70
+ // This flag indicate that something was revealed to someone.
71
+ // We use the "randomize" function because is the where we can "preprocess" the move and transform it after checking it is legal and before it is saved.
61
72
  return __assign(__assign({}, move), { reveal: {} });
62
73
  }
63
74
  return _super.prototype.randomize.call(this, move);
64
75
  };
65
- HiddenMaterialRules.prototype.isRevealingItemMove = function (move) {
66
- var _this = this;
67
- return ((0, moves_1.isMoveItem)(move) && this.game.players.some(function (player) { return _this.moveItemWillRevealSomething(move, player); })) ||
68
- ((0, moves_1.isMoveItemsAtOnce)(move) && this.game.players.some(function (player) { return _this.moveAtOnceWillRevealSomething(move, player); }));
76
+ HiddenMaterialRules.prototype.isRevealingItemMove = function (move, player) {
77
+ return ((0, moves_1.isMoveItem)(move) && this.moveItemWillRevealSomething(move, player))
78
+ || ((0, moves_1.isMoveItemsAtOnce)(move) && this.moveAtOnceWillRevealSomething(move, player));
69
79
  };
80
+ /**
81
+ * Items that can be hidden cannot merge by default, to prevent hidden items to merge only because they have no id.
82
+ */
70
83
  HiddenMaterialRules.prototype.itemsCanMerge = function (type) {
71
84
  return !this.hidingStrategies[type];
72
85
  };
86
+ /**
87
+ * Moves that reveal some information (like drawing a card) cannot be predicted by the player.
88
+ */
73
89
  HiddenMaterialRules.prototype.isUnpredictableMove = function (move, player) {
74
90
  var _this = this;
75
91
  if ((0, moves_1.isMoveItem)(move)) {
@@ -91,12 +107,22 @@ var HiddenMaterialRules = (function (_super) {
91
107
  return _super.prototype.isUnpredictableMove.call(this, move, player);
92
108
  }
93
109
  };
110
+ /**
111
+ * Moves than reveals an information to someone cannot be undone by default
112
+ */
94
113
  HiddenMaterialRules.prototype.moveBlocksUndo = function (move) {
95
114
  return _super.prototype.moveBlocksUndo.call(this, move) || this.moveRevealedSomething(move);
96
115
  };
116
+ /**
117
+ * @param move A move to test
118
+ * @returns true if the move revealed something to some player
119
+ */
97
120
  HiddenMaterialRules.prototype.moveRevealedSomething = function (move) {
98
121
  return ((0, moves_1.isMoveItem)(move) || (0, moves_1.isMoveItemsAtOnce)(move)) && !!move.reveal;
99
122
  };
123
+ /**
124
+ * With the material approach, we can offer a default working implementation for {@link HiddenInformation.getView}
125
+ */
100
126
  HiddenMaterialRules.prototype.getView = function (player) {
101
127
  var _this = this;
102
128
  return __assign(__assign({}, this.game), { items: (0, mapValues_1.default)(this.game.items, function (items, stringType) {
@@ -126,6 +152,10 @@ var HiddenMaterialRules = (function (_super) {
126
152
  HiddenMaterialRules.prototype.itemHasHiddenInformation = function (type, item, player) {
127
153
  return this.getItemHiddenPaths(type, item, player).length > 0;
128
154
  };
155
+ /**
156
+ * To be able to know if a MoveItem cannot be undone, the server flags the moves with a "reveal" property.
157
+ * This difference must be integrated without error during the callback.
158
+ */
129
159
  HiddenMaterialRules.prototype.canIgnoreServerDifference = function (clientMove, serverMove) {
130
160
  if ((0, moves_1.isMoveItem)(clientMove) && (0, moves_1.isMoveItem)(serverMove)) {
131
161
  var reveal = serverMove.reveal, serverMoveWithoutReveal = __rest(serverMove, ["reveal"]);
@@ -133,6 +163,9 @@ var HiddenMaterialRules = (function (_super) {
133
163
  }
134
164
  return false;
135
165
  };
166
+ /**
167
+ * With the material approach, we can offer a default working implementation for {@link HiddenInformation.getMoveView}
168
+ */
136
169
  HiddenMaterialRules.prototype.getMoveView = function (move, player) {
137
170
  var _this = this;
138
171
  if (move.kind === moves_1.MoveKind.ItemMove && move.itemType in this.hidingStrategies) {
@@ -152,8 +185,6 @@ var HiddenMaterialRules = (function (_super) {
152
185
  return move;
153
186
  };
154
187
  HiddenMaterialRules.prototype.getMoveItemView = function (move, player) {
155
- if (!move.reveal)
156
- return move;
157
188
  var revealedPaths = this.getMoveItemRevealedPath(move, player);
158
189
  if (!revealedPaths.length)
159
190
  return move;
@@ -166,16 +197,16 @@ var HiddenMaterialRules = (function (_super) {
166
197
  return moveView;
167
198
  };
168
199
  HiddenMaterialRules.prototype.getMoveAtOnceView = function (move, player) {
169
- if (!move.reveal)
170
- return move;
171
- var moveView = __assign(__assign({}, move), { reveal: {} });
200
+ var moveView = __assign({}, move);
172
201
  for (var _i = 0, _a = move.indexes; _i < _a.length; _i++) {
173
202
  var index = _a[_i];
174
203
  var revealedPaths = this.getMoveAtOnceRevealedPath(move, index, player);
175
204
  if (!revealedPaths.length)
176
205
  continue;
177
- var item = this.material(move.itemType).getItem(index);
206
+ if (!moveView.reveal)
207
+ moveView.reveal = {};
178
208
  moveView.reveal[index] = {};
209
+ var item = this.material(move.itemType).getItem(index);
179
210
  for (var _b = 0, revealedPaths_2 = revealedPaths; _b < revealedPaths_2.length; _b++) {
180
211
  var path = revealedPaths_2[_b];
181
212
  (0, set_1.default)(moveView.reveal[index], path, (0, get_1.default)(item, path));
@@ -219,8 +250,14 @@ var HiddenMaterialRules = (function (_super) {
219
250
  })) {
220
251
  throw new RangeError("You cannot shuffle items with different hiding strategies: ".concat(JSON.stringify(move.indexes.map(function (index) { return _this.getItemHiddenPaths(move.itemType, material.getItem(index), player); }))));
221
252
  }
253
+ // TODO: if we shuffle a hand of items partially hidden, we should send the partially visible information to the client.
254
+ // Example: It's a Wonderful World with the Extension: the back face of the player's hand are different
255
+ // => when the hand is shuffled we should see where the expansion cards land.
222
256
  return !hiddenPaths.length;
223
257
  };
258
+ /**
259
+ * Override of {@link MaterialRules.play} that also removes the hidden information from items, for example when a card is flipped face down
260
+ */
224
261
  HiddenMaterialRules.prototype.play = function (move, context) {
225
262
  var result = _super.prototype.play.call(this, move, context);
226
263
  if (this.client && (0, moves_1.isMoveItem)(move) && this.hidingStrategies[move.itemType]) {
@@ -243,8 +280,14 @@ var HiddenMaterialRules = (function (_super) {
243
280
  return HiddenMaterialRules;
244
281
  }(MaterialRules_1.MaterialRules));
245
282
  exports.HiddenMaterialRules = HiddenMaterialRules;
283
+ /**
284
+ * Hiding strategy that removes the item id
285
+ */
246
286
  var hideItemId = function () { return ['id']; };
247
287
  exports.hideItemId = hideItemId;
288
+ /**
289
+ * Hiding strategy that removes "id.front" from the item (when we have cards with composite ids, back & front)
290
+ */
248
291
  var hideFront = function () { return ['id.front']; };
249
292
  exports.hideFront = hideFront;
250
293
  //# sourceMappingURL=HiddenMaterialRules.js.map