@pompidup/kingdomino-engine 2.0.3 → 2.1.2

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.
package/README.md CHANGED
@@ -1,5 +1,12 @@
1
1
  # Kingdomino Engine
2
2
 
3
+ [![Node.js CI](https://github.com/Pompidup/KDomino/actions/workflows/node.js.yml/badge.svg?branch=main)](https://github.com/Pompidup/KDomino/actions/workflows/node.js.yml)
4
+ ![Branches](./badges/coverage-branches.svg)
5
+ ![Functions](./badges/coverage-functions.svg)
6
+ ![Lines](./badges/coverage-lines.svg)
7
+ ![Statements](./badges/coverage-statements.svg)
8
+ ![Coverage total](./badges/coverage-total.svg)
9
+
3
10
  ## Overview
4
11
 
5
12
  This is a simple and lightweight TypeScript engine designed to facilitate the gameplay of Kingdomino. It provides the core logic for managing game states, rules, and player interactions, making it easy to integrate into any application that requires a Kingdomino game engine.
@@ -39,11 +46,34 @@ Each method returns an updated game state object, which contains the current sta
39
46
  To start using the Kingdomino Engine, import it and initialize a new game instance:
40
47
 
41
48
  ```typescript
42
- import gameEngine from "@pompidup/kingdomino-engine";
49
+ import createGameEngine from "@pompidup/kingdomino-engine";
43
50
 
44
- const engine = gameEngine();
51
+ const engine = createGameEngine({});
45
52
  let gameState = engine.createGame({ mode: "Classic" });
53
+ ```
54
+
55
+ ### Options for GameEngine
56
+
57
+ You can pass options to the `createGameEngine` function to customize the engine's behavior. The available options are:
58
+
59
+ - `logging`: Enable or disable logging for debugging purposes. Default is `false`.
60
+ - `shuffleMethod`: Specify the method used to shuffle dominoes. If not specified, a default shuffle method will be used.
61
+ - `uuidMethod`: Specify the method used to generate UUIDs. If not specified, a default UUID method will be used.
62
+
63
+ Here's an example of how to pass options to the engine:
64
+
65
+ ```typescript
66
+ // Full custom options
67
+ const options: EngineConfig = {
68
+ logging: true,
69
+ shuffleMethod: myCustomShuffleMethod,
70
+ uuidMethod: myCustomUuidMethod,
71
+ };
72
+
73
+ const engine = createGameEngine(options);
46
74
 
75
+ // If you want default options
76
+ const engine = createGameEngine({});
47
77
  ```
48
78
 
49
79
  ### Adding Players
@@ -51,30 +81,45 @@ let gameState = engine.createGame({ mode: "Classic" });
51
81
  Add players to the game by passing an array of player names:
52
82
 
53
83
  ```typescript
54
- gameState = engine.addPlayers(gameState, ["Player 1", "Player 2", "Player 3"]);
84
+ gameState = engine.addPlayers({gameState, ["Player 1", "Player 2", "Player 3"]});
55
85
  ```
56
86
 
57
- ### Setting Up Extra Rules
87
+ ### Getting Available Game Modes
58
88
 
59
- You can get available extra rules and add them to the game:
89
+ You can get available game modes and select one for the game:
90
+
91
+ ```typescript
92
+ const modes = engine.getModes({});
93
+ gameState = engine.createGame({ mode: modes[0].name });
94
+ ```
95
+
96
+ ### Getting Available Extra Rules
97
+
98
+ You can get available extra rules for a specific game mode and number of players:
60
99
 
61
100
  ```typescript
62
101
  const extraRules = engine.getExtraRules({ mode: "Classic", players: 2 });
102
+ ```
103
+
104
+ ### Setting Up Extra Rules
105
+
106
+ You can add extra rules to the game to modify gameplay. For example, you can add the "The Middle Kingdom" rule:
107
+
108
+ ```typescript
63
109
  gameState = engine.addExtraRules({
64
- game: gameState,
65
- extraRules: ["The middle Kingdom"],
110
+ game: gameState,
111
+ extraRules: ["The middle Kingdom"],
66
112
  });
67
113
  ```
68
114
 
69
115
  ### Starting the Game
70
116
 
71
- After setting up players and rules, start the game:
117
+ After setting up players and rules, start the game, the engine will automatically set up the initial game state and determine the first player (lord) to play in nextAction.
72
118
 
73
119
  ```typescript
74
120
  gameState = engine.startGame({ game: gameState });
75
121
  ```
76
122
 
77
-
78
123
  ### Player Actions
79
124
 
80
125
  Players can perform actions like picking a domino, placing a domino, and discarding a domino.
@@ -85,7 +130,7 @@ Players can perform actions like picking a domino, placing a domino, and discard
85
130
  gameState = engine.chooseDomino({
86
131
  game: gameState,
87
132
  lordId: "lordId",
88
- dominoPick: 12
133
+ dominoPick: 12,
89
134
  });
90
135
  ```
91
136
 
@@ -97,7 +142,7 @@ gameState = engine.placeDomino({
97
142
  lordId: "lordId",
98
143
  position: { x: 0, y: 0 },
99
144
  orientation: "horizontal",
100
- rotation: 0
145
+ rotation: 0,
101
146
  });
102
147
  ```
103
148
 
@@ -110,14 +155,30 @@ gameState = engine.discardDomino({
110
155
  });
111
156
  ```
112
157
 
113
-
114
158
  ### Game Flow
115
159
 
116
160
  The game progresses through various steps and actions. The `nextAction` property in the game state indicates what action should be taken next. This could be a step (like "addPlayers", "options", "start", or "result") or an action (like "pickDomino" or "placeDomino").
161
+ Once the game is started you will receive the nextAction and nextLord, when you receive a nextStep the game isOver.
162
+ You can use utility functions to check the game state and determine the next action to take.
163
+
164
+ ```typescript
165
+ while (isGameWithNextAction(gameState)) {
166
+ // Manage player actions
167
+ }
168
+
169
+ if (isGameWithNextStep(gameState)) {
170
+ // Manage game steps, like adding players or showing results
171
+ }
172
+ ```
117
173
 
118
174
  ### Scoring
119
175
 
120
- When the last turn is played, the game will automatically calculate and provide the final score for each player and their position.
176
+ When the last turn is played, the game will automatically calculate the final score for each player and their position.
177
+ You can get the results by calling the `getResults` method:
178
+
179
+ ```typescript
180
+ gameState = engine.getResults({ game: gameState });
181
+ ```
121
182
 
122
183
  ## Extra Rules
123
184
 
@@ -143,13 +204,12 @@ type GameEngine = {
143
204
  addExtraRules: (command: AddExtraRulesCommand) => GameWithNextStep;
144
205
  startGame: (command: StartGameCommand) => GameWithNextAction;
145
206
  chooseDomino: (command: ChooseDominoCommand) => GameWithNextAction;
146
- placeDomino: (command: PlaceDominoCommand) => GameWithNextAction | GameWithNextStep;
147
- discardDomino: (command: DiscardDominoCommand) => GameWithNextAction | GameWithNextStep;
207
+ placeDomino: (command: PlaceDominoCommand) => GameState;
208
+ discardDomino: (command: DiscardDominoCommand) => GameState;
148
209
  getResults: (command: GetResultCommand) => GameWithResults;
149
210
  };
150
211
  ```
151
212
 
152
-
153
213
  #### Game
154
214
 
155
215
  Represents the current state of a Kingdomino game.
@@ -162,12 +222,12 @@ type Game = {
162
222
  players: Player[];
163
223
  lords: Lord[];
164
224
  turn: number;
225
+ nextAction: NextAction | NextStep;
165
226
  rules: SelectedRules;
166
227
  mode: GameMode;
167
228
  };
168
229
  ```
169
230
 
170
-
171
231
  #### NextStep and NextAction
172
232
 
173
233
  Represent the next step or action in the game flow.
@@ -177,14 +237,14 @@ type NextStep = {
177
237
  type: "step";
178
238
  step: "addPlayers" | "options" | "start" | "result";
179
239
  };
240
+
180
241
  type NextAction = {
181
242
  type: "action";
182
243
  nextLord: string;
183
- nextAction: "pickDomino" | "placeDomino";
244
+ nextAction: "pickDomino" | "placeDomino" | "pass";
184
245
  };
185
246
  ```
186
247
 
187
-
188
248
  #### ExtraRule
189
249
 
190
250
  Represents an additional rule that can be applied to the game.
@@ -198,7 +258,6 @@ type ExtraRule = {
198
258
  };
199
259
  ```
200
260
 
201
-
202
261
  ### Methods
203
262
 
204
263
  #### createGame(command: CreateGameCommand): GameWithNextStep
@@ -221,11 +280,11 @@ Starts the game, setting up the initial game state.
221
280
 
222
281
  Allows a player to choose a domino.
223
282
 
224
- #### placeDomino(command: PlaceDominoCommand): GameWithNextAction | GameWithNextStep
283
+ #### placeDomino(command: PlaceDominoCommand): GameState
225
284
 
226
285
  Allows a player to place a domino on their kingdom.
227
286
 
228
- #### discardDomino(command: DiscardDominoCommand): GameWithNextAction | GameWithNextStep
287
+ #### discardDomino(command: DiscardDominoCommand): GameState
229
288
 
230
289
  Allows a player to discard a domino if they cannot place it.
231
290
 
@@ -236,4 +295,3 @@ Calculates and returns the final game results.
236
295
  ## Advanced Usage
237
296
 
238
297
  For more advanced usage and detailed API documentation, please refer to the source code and inline comments.
239
-
package/dist/index.d.ts CHANGED
@@ -70,10 +70,6 @@ type ExtraRule = {
70
70
  mode: GameMode[];
71
71
  playersLimit?: number;
72
72
  };
73
- type Rules = {
74
- basic: Record<number, BasicRules>;
75
- extraRules: ExtraRule[];
76
- };
77
73
  type SelectedRules = {
78
74
  basic: BasicRules;
79
75
  extra: ExtraRule[];
@@ -112,6 +108,7 @@ type GameWithNextAction = Game & {
112
108
  type GameWithNextStep = Game & {
113
109
  nextAction: NextStep;
114
110
  };
111
+ type GameState = GameWithNextAction | GameWithNextStep;
115
112
  type Score = {
116
113
  points: number;
117
114
  maxPropertiesSize: number;
@@ -141,33 +138,27 @@ type CreateGameCommand = {
141
138
  };
142
139
 
143
140
  type AddPlayersCommand = {
144
- game: Game & {
145
- nextAction: NextStep;
146
- };
141
+ game: GameState;
147
142
  players: string[];
148
143
  };
149
144
 
150
145
  type AddExtraRulesCommand = {
151
- game: Game & {
152
- nextAction: NextStep;
153
- };
146
+ game: GameState;
154
147
  extraRules: string[];
155
148
  };
156
149
 
157
150
  type StartGameCommand = {
158
- game: Game & {
159
- nextAction: NextStep;
160
- };
151
+ game: GameState;
161
152
  };
162
153
 
163
154
  type ChooseDominoCommand = {
164
- game: GameWithNextAction;
155
+ game: GameState;
165
156
  dominoPick: number;
166
157
  lordId: string;
167
158
  };
168
159
 
169
160
  type PlaceDominoCommand = {
170
- game: GameWithNextAction;
161
+ game: GameState;
171
162
  lordId: string;
172
163
  position: Position;
173
164
  orientation: Orientation;
@@ -175,12 +166,12 @@ type PlaceDominoCommand = {
175
166
  };
176
167
 
177
168
  type DiscardDominoCommand = {
178
- game: GameWithNextAction;
169
+ game: GameState;
179
170
  lordId: string;
180
171
  };
181
172
 
182
173
  type GetResultCommand = {
183
- game: GameWithNextStep;
174
+ game: GameState;
184
175
  };
185
176
 
186
177
  type GameEngine = {
@@ -191,34 +182,19 @@ type GameEngine = {
191
182
  addExtraRules: (command: AddExtraRulesCommand) => GameWithNextStep;
192
183
  startGame: (command: StartGameCommand) => GameWithNextAction;
193
184
  chooseDomino: (command: ChooseDominoCommand) => GameWithNextAction;
194
- placeDomino: (command: PlaceDominoCommand) => GameWithNextAction | GameWithNextStep;
195
- discardDomino: (command: DiscardDominoCommand) => GameWithNextAction | GameWithNextStep;
185
+ placeDomino: (command: PlaceDominoCommand) => GameState;
186
+ discardDomino: (command: DiscardDominoCommand) => GameState;
196
187
  getResults: (command: GetResultCommand) => GameWithResults;
197
188
  };
198
189
 
199
- type DominoesRepository = {
200
- getForMode: (mode: GameMode) => Domino[] | [];
201
- };
202
-
203
- type ModeRepository = {
204
- getAvailables: () => GameMode[];
205
- };
206
-
207
- type RuleRepository = {
208
- getAll: () => Rules;
209
- getAllExtra: () => ExtraRule[];
210
- };
211
-
212
190
  type ShuffleMethod = <T>(array: T[]) => T[];
213
191
 
214
192
  type UuidMethod = () => string;
215
193
 
216
194
  type EngineConfig = {
217
- modeRepository?: ModeRepository;
218
- dominoesRepository?: DominoesRepository;
219
- ruleRepository?: RuleRepository;
220
195
  uuidMethod?: UuidMethod;
221
196
  shuffleMethod?: ShuffleMethod;
197
+ logging?: boolean;
222
198
  };
223
199
 
224
200
  declare const createGameEngine: (config: Partial<EngineConfig>) => GameEngine;