@pompidup/kingdomino-engine 1.0.4 → 1.1.1
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 +10 -6
- package/dist/index.d.ts +20 -16
- package/dist/index.js +157 -123
- package/dist/index.js.map +1 -1
- package/package.json +5 -5
package/README.md
CHANGED
|
@@ -4,6 +4,10 @@
|
|
|
4
4
|
|
|
5
5
|
This is under development. The goal is to create 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.
|
|
6
6
|
|
|
7
|
+
## Requirements
|
|
8
|
+
|
|
9
|
+
- Node v20.6.0 or higher
|
|
10
|
+
|
|
7
11
|
## Features
|
|
8
12
|
|
|
9
13
|
- **Game State Management**: Efficiently manage game states, including player turns, game rules, and game progression.
|
|
@@ -34,7 +38,7 @@ pnpm add @pompidup/kingdomino-engine
|
|
|
34
38
|
|
|
35
39
|
The Kingdomino Engine is designed to be easy to use and integrate into any application. Below are some examples of how you can use the engine to create a new game, add players, and start playing.
|
|
36
40
|
|
|
37
|
-
Each method returns an updated game state object, which contains the current state of the game, including the board, players, and dominoes. In return you will receive too the
|
|
41
|
+
Each method returns an updated game state object, which contains the current state of the game, including the board, players, and dominoes. In return you will receive too the nextLord (the next player to play) and the nextAction (the next action to be performed by the next player).
|
|
38
42
|
|
|
39
43
|
**It's your responsibility to save and pass the updated game state to the next method call.**
|
|
40
44
|
|
|
@@ -71,19 +75,19 @@ Incoming...
|
|
|
71
75
|
Players can perform actions like pick domino, placing domino, and passing turns.
|
|
72
76
|
|
|
73
77
|
- Pick Domino:
|
|
74
|
-
You can pick a domino by passing the
|
|
78
|
+
You can pick a domino by passing the lordId and the number of the domino you want to pick.
|
|
75
79
|
|
|
76
80
|
```typescript
|
|
77
|
-
gameState = engine.pickDomino(gameState, "
|
|
81
|
+
gameState = engine.pickDomino(gameState, "lordId", 12);
|
|
78
82
|
```
|
|
79
83
|
|
|
80
84
|
- Place Domino:
|
|
81
|
-
You can place a domino by passing the
|
|
85
|
+
You can place a domino by passing the lordId, the position where you want to place the domino, the orientation (horizontal or vertical), and the rotation (if you want to switch left and right tile you can pass 180 else 0).
|
|
82
86
|
|
|
83
87
|
```typescript
|
|
84
88
|
gameState = engine.placeDomino(
|
|
85
89
|
gameState,
|
|
86
|
-
"
|
|
90
|
+
"lordId",
|
|
87
91
|
{ x: 0, y: 0 },
|
|
88
92
|
"horizontal",
|
|
89
93
|
0
|
|
@@ -94,7 +98,7 @@ gameState = engine.placeDomino(
|
|
|
94
98
|
If you can not place a domino you can pass your turn.
|
|
95
99
|
|
|
96
100
|
```typescript
|
|
97
|
-
gameState = engine.passTurn(gameState, "
|
|
101
|
+
gameState = engine.passTurn(gameState, "lordId");
|
|
98
102
|
```
|
|
99
103
|
|
|
100
104
|
### Scoring
|
package/dist/index.d.ts
CHANGED
|
@@ -16,19 +16,11 @@ type Domino = {
|
|
|
16
16
|
type RevealsDomino = {
|
|
17
17
|
domino: Domino;
|
|
18
18
|
picked: boolean;
|
|
19
|
-
|
|
19
|
+
lordId: string | null;
|
|
20
20
|
position: number;
|
|
21
21
|
};
|
|
22
22
|
|
|
23
|
-
type
|
|
24
|
-
x: number;
|
|
25
|
-
y: number;
|
|
26
|
-
};
|
|
27
|
-
type Orientation = "vertical" | "horizontal";
|
|
28
|
-
type Rotation = 0 | 180;
|
|
29
|
-
type Kingdom = (Tile | EmptyTile)[][];
|
|
30
|
-
|
|
31
|
-
type King = {
|
|
23
|
+
type Lord = {
|
|
32
24
|
id: string;
|
|
33
25
|
playerId: string;
|
|
34
26
|
order: number;
|
|
@@ -37,25 +29,37 @@ type King = {
|
|
|
37
29
|
hasPlace: boolean;
|
|
38
30
|
dominoPicked?: Domino;
|
|
39
31
|
};
|
|
32
|
+
|
|
33
|
+
type Position = {
|
|
34
|
+
x: number;
|
|
35
|
+
y: number;
|
|
36
|
+
};
|
|
37
|
+
type Orientation = "vertical" | "horizontal";
|
|
38
|
+
type Rotation = 0 | 180;
|
|
39
|
+
type Kingdom = (Tile | EmptyTile)[][];
|
|
40
|
+
|
|
40
41
|
type Player = {
|
|
41
|
-
id
|
|
42
|
+
id: string;
|
|
42
43
|
name: string;
|
|
43
44
|
kingdom: Kingdom;
|
|
44
45
|
};
|
|
46
|
+
|
|
45
47
|
declare const availableMode: readonly ["Classic"];
|
|
46
48
|
type AvailableMode = (typeof availableMode)[number];
|
|
49
|
+
|
|
47
50
|
type Rule = {
|
|
48
51
|
name: string;
|
|
49
52
|
description: string;
|
|
50
53
|
mode: AvailableMode[];
|
|
51
54
|
playersLimit?: number;
|
|
52
55
|
};
|
|
56
|
+
|
|
53
57
|
type Game = {
|
|
54
58
|
id: string;
|
|
55
59
|
dominoes: Domino[];
|
|
56
60
|
currentDominoes: RevealsDomino[];
|
|
57
61
|
players: Player[];
|
|
58
|
-
|
|
62
|
+
lords: Lord[];
|
|
59
63
|
turn: number;
|
|
60
64
|
maxTurns: number;
|
|
61
65
|
maxDominoes: number;
|
|
@@ -80,7 +84,7 @@ type FinalResult = ScoreResult & {
|
|
|
80
84
|
};
|
|
81
85
|
|
|
82
86
|
type Resp = {
|
|
83
|
-
|
|
87
|
+
nextLord: string;
|
|
84
88
|
nextAction: "pick" | "place" | "end";
|
|
85
89
|
game: Game;
|
|
86
90
|
};
|
|
@@ -101,9 +105,9 @@ declare const gameEngine: () => {
|
|
|
101
105
|
start: (game: Game, players: {
|
|
102
106
|
name: string;
|
|
103
107
|
}[]) => Resp;
|
|
104
|
-
pass: (game: Game,
|
|
105
|
-
placeDomino: (game: Game,
|
|
106
|
-
pickDomino: (game: Game,
|
|
108
|
+
pass: (game: Game, lordId: string) => Resp;
|
|
109
|
+
placeDomino: (game: Game, lordId: string, position: Position, orientation: Orientation, rotation: Rotation) => Resp;
|
|
110
|
+
pickDomino: (game: Game, lordId: string, dominoPick: number) => Resp;
|
|
107
111
|
endGame: (game: Game) => GameResult;
|
|
108
112
|
};
|
|
109
113
|
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
|
-
// src/
|
|
1
|
+
// src/adapters/driver/index.ts
|
|
2
|
+
import { loadEnvFile } from "process";
|
|
3
|
+
|
|
4
|
+
// src/datasources/dominoes.json
|
|
2
5
|
var dominoes_default = [
|
|
3
6
|
{
|
|
4
7
|
left: {
|
|
@@ -530,7 +533,7 @@ var dominoes_default = [
|
|
|
530
533
|
}
|
|
531
534
|
];
|
|
532
535
|
|
|
533
|
-
// src/
|
|
536
|
+
// src/adapters/driven/inMemoryDominoes.ts
|
|
534
537
|
var inMemoryDominoes = () => {
|
|
535
538
|
const dominoes = [];
|
|
536
539
|
dominoes_default.forEach((domino) => {
|
|
@@ -554,10 +557,7 @@ var inMemoryDominoes = () => {
|
|
|
554
557
|
};
|
|
555
558
|
var inMemoryDominoes_default = inMemoryDominoes;
|
|
556
559
|
|
|
557
|
-
// src/
|
|
558
|
-
var availableMode = ["Classic"];
|
|
559
|
-
|
|
560
|
-
// src/domain/useCases/game/init.ts
|
|
560
|
+
// src/hexagon/internal/services/init.ts
|
|
561
561
|
var init = (dependencies) => () => {
|
|
562
562
|
const dominoes = dependencies.dominoesRepository.getAll();
|
|
563
563
|
const id = dependencies.uuidMethod();
|
|
@@ -566,7 +566,7 @@ var init = (dependencies) => () => {
|
|
|
566
566
|
dominoes,
|
|
567
567
|
currentDominoes: [],
|
|
568
568
|
players: [],
|
|
569
|
-
|
|
569
|
+
lords: [],
|
|
570
570
|
turn: 0,
|
|
571
571
|
maxTurns: 0,
|
|
572
572
|
maxDominoes: 0,
|
|
@@ -576,7 +576,7 @@ var init = (dependencies) => () => {
|
|
|
576
576
|
return state;
|
|
577
577
|
};
|
|
578
578
|
|
|
579
|
-
// src/
|
|
579
|
+
// src/hexagon/internal/entities/kingdom.ts
|
|
580
580
|
var createEmptyKingdom = () => {
|
|
581
581
|
const gridSize = 9;
|
|
582
582
|
const emptyTile = { type: "empty", crowns: 0 };
|
|
@@ -790,7 +790,7 @@ var kingdom = {
|
|
|
790
790
|
};
|
|
791
791
|
var kingdom_default = kingdom;
|
|
792
792
|
|
|
793
|
-
// src/
|
|
793
|
+
// src/hexagon/internal/services/setup.ts
|
|
794
794
|
var setup = (dependencies) => (payload) => {
|
|
795
795
|
const { state, players } = payload;
|
|
796
796
|
if (!players) {
|
|
@@ -803,22 +803,22 @@ var setup = (dependencies) => (payload) => {
|
|
|
803
803
|
throw new Error("There must be at least 2 players");
|
|
804
804
|
}
|
|
805
805
|
const { dominoes } = state;
|
|
806
|
-
const {
|
|
806
|
+
const { shuffleMethod: shuffleMethod2, uuidMethod: uuidMethod2 } = dependencies;
|
|
807
807
|
const { maxDominoes, dominoesPerTurn, maxTurns } = rules[players.length];
|
|
808
|
-
const shuffledDominoes =
|
|
808
|
+
const shuffledDominoes = shuffleMethod2(dominoes);
|
|
809
809
|
shuffledDominoes.splice(maxDominoes);
|
|
810
810
|
const newPlayers = players.map((player) => {
|
|
811
811
|
return {
|
|
812
812
|
...player,
|
|
813
813
|
kingdom: kingdom_default.createKingdomWithCastle(),
|
|
814
|
-
id:
|
|
814
|
+
id: uuidMethod2()
|
|
815
815
|
};
|
|
816
816
|
});
|
|
817
|
-
let
|
|
817
|
+
let newLords;
|
|
818
818
|
if (newPlayers.length === 2) {
|
|
819
|
-
|
|
819
|
+
newLords = [
|
|
820
820
|
{
|
|
821
|
-
id:
|
|
821
|
+
id: uuidMethod2(),
|
|
822
822
|
playerId: newPlayers[0].id,
|
|
823
823
|
order: 1,
|
|
824
824
|
turnEnded: false,
|
|
@@ -826,7 +826,7 @@ var setup = (dependencies) => (payload) => {
|
|
|
826
826
|
hasPlace: false
|
|
827
827
|
},
|
|
828
828
|
{
|
|
829
|
-
id:
|
|
829
|
+
id: uuidMethod2(),
|
|
830
830
|
playerId: newPlayers[0].id,
|
|
831
831
|
order: 2,
|
|
832
832
|
turnEnded: false,
|
|
@@ -834,7 +834,7 @@ var setup = (dependencies) => (payload) => {
|
|
|
834
834
|
hasPlace: false
|
|
835
835
|
},
|
|
836
836
|
{
|
|
837
|
-
id:
|
|
837
|
+
id: uuidMethod2(),
|
|
838
838
|
playerId: newPlayers[1].id,
|
|
839
839
|
order: 3,
|
|
840
840
|
turnEnded: false,
|
|
@@ -842,7 +842,7 @@ var setup = (dependencies) => (payload) => {
|
|
|
842
842
|
hasPlace: false
|
|
843
843
|
},
|
|
844
844
|
{
|
|
845
|
-
id:
|
|
845
|
+
id: uuidMethod2(),
|
|
846
846
|
playerId: newPlayers[1].id,
|
|
847
847
|
order: 4,
|
|
848
848
|
turnEnded: false,
|
|
@@ -851,9 +851,9 @@ var setup = (dependencies) => (payload) => {
|
|
|
851
851
|
}
|
|
852
852
|
];
|
|
853
853
|
} else {
|
|
854
|
-
|
|
854
|
+
newLords = newPlayers.map((player, index) => {
|
|
855
855
|
return {
|
|
856
|
-
id:
|
|
856
|
+
id: uuidMethod2(),
|
|
857
857
|
playerId: player.id,
|
|
858
858
|
order: index + 1,
|
|
859
859
|
turnEnded: false,
|
|
@@ -862,16 +862,16 @@ var setup = (dependencies) => (payload) => {
|
|
|
862
862
|
};
|
|
863
863
|
});
|
|
864
864
|
}
|
|
865
|
-
const
|
|
866
|
-
|
|
867
|
-
|
|
865
|
+
const lordsWithOrder = shuffleMethod2(newLords);
|
|
866
|
+
lordsWithOrder.forEach((lord, index) => {
|
|
867
|
+
lord.order = index + 1;
|
|
868
868
|
});
|
|
869
|
-
|
|
869
|
+
lordsWithOrder.sort((a, b) => a.order - b.order);
|
|
870
870
|
const newState = {
|
|
871
871
|
...state,
|
|
872
872
|
dominoes: shuffledDominoes,
|
|
873
873
|
players: newPlayers,
|
|
874
|
-
|
|
874
|
+
lords: lordsWithOrder,
|
|
875
875
|
maxTurns,
|
|
876
876
|
maxDominoes,
|
|
877
877
|
dominoesPerTurn,
|
|
@@ -880,34 +880,34 @@ var setup = (dependencies) => (payload) => {
|
|
|
880
880
|
return newState;
|
|
881
881
|
};
|
|
882
882
|
|
|
883
|
-
// src/
|
|
883
|
+
// src/hexagon/internal/services/startTurn.ts
|
|
884
884
|
var startTurn = (payload) => {
|
|
885
885
|
const { state } = payload;
|
|
886
886
|
const turn = state.turn + 1;
|
|
887
|
-
const
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
887
|
+
const lords = state.lords;
|
|
888
|
+
lords.forEach((lord) => {
|
|
889
|
+
lord.turnEnded = false;
|
|
890
|
+
lord.hasPick = false;
|
|
891
|
+
lord.hasPlace = false;
|
|
892
892
|
});
|
|
893
893
|
const updatedState = {
|
|
894
894
|
...state,
|
|
895
|
-
|
|
895
|
+
lords,
|
|
896
896
|
turn
|
|
897
897
|
};
|
|
898
898
|
return { game: updatedState };
|
|
899
899
|
};
|
|
900
900
|
|
|
901
|
-
// src/
|
|
901
|
+
// src/hexagon/internal/services/pick.ts
|
|
902
902
|
var pick = (payload) => {
|
|
903
|
-
const {
|
|
903
|
+
const { lordId, data } = payload;
|
|
904
904
|
const { state, dominoPick } = data;
|
|
905
|
-
const { currentDominoes,
|
|
906
|
-
if (!
|
|
905
|
+
const { currentDominoes, lords } = state;
|
|
906
|
+
if (!isLordTurn(state, lordId)) {
|
|
907
907
|
throw new Error("It is not your turn");
|
|
908
908
|
}
|
|
909
|
-
const
|
|
910
|
-
if (
|
|
909
|
+
const lord = lords.find((lord2) => lord2.id === lordId);
|
|
910
|
+
if (lord?.hasPick) {
|
|
911
911
|
throw new Error("You have already picked");
|
|
912
912
|
}
|
|
913
913
|
const domino = checkValidityDomino(state, dominoPick);
|
|
@@ -920,86 +920,86 @@ var pick = (payload) => {
|
|
|
920
920
|
const updatedCurrentDominoes = currentDominoes.map((domino2) => {
|
|
921
921
|
if (domino2.domino.number === dominoPick) {
|
|
922
922
|
domino2.picked = true;
|
|
923
|
-
domino2.
|
|
923
|
+
domino2.lordId = lordId;
|
|
924
924
|
}
|
|
925
925
|
return domino2;
|
|
926
926
|
});
|
|
927
|
-
const
|
|
928
|
-
if (
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
927
|
+
const updatedLords = lords.map((lord2) => {
|
|
928
|
+
if (lord2.id === lordId) {
|
|
929
|
+
lord2.hasPick = true;
|
|
930
|
+
lord2.turnEnded = true;
|
|
931
|
+
lord2.dominoPicked = domino.domino;
|
|
932
932
|
}
|
|
933
|
-
return
|
|
933
|
+
return lord2;
|
|
934
934
|
});
|
|
935
935
|
const updatedState = {
|
|
936
936
|
...state,
|
|
937
937
|
currentDominoes: updatedCurrentDominoes,
|
|
938
|
-
|
|
938
|
+
lords: updatedLords
|
|
939
939
|
};
|
|
940
940
|
return updatedState;
|
|
941
941
|
};
|
|
942
942
|
|
|
943
|
-
// src/
|
|
943
|
+
// src/hexagon/internal/services/place.ts
|
|
944
944
|
var place = (payload) => {
|
|
945
|
-
const {
|
|
945
|
+
const { lordId, data } = payload;
|
|
946
946
|
const { state, position, orientation, rotation } = data;
|
|
947
|
-
const
|
|
947
|
+
const currentLord = state.lords.find((lord) => lord.id === lordId);
|
|
948
948
|
const currentPlayer = state.players.find(
|
|
949
|
-
(player) => player.id ===
|
|
949
|
+
(player) => player.id === currentLord?.playerId
|
|
950
950
|
);
|
|
951
951
|
const currentKingdom = currentPlayer?.kingdom;
|
|
952
952
|
if (!currentKingdom) {
|
|
953
953
|
throw new Error("Kingdom not found");
|
|
954
954
|
}
|
|
955
|
-
const domino =
|
|
955
|
+
const domino = currentLord?.dominoPicked;
|
|
956
956
|
if (!domino) {
|
|
957
957
|
throw new Error("Domino not found");
|
|
958
958
|
}
|
|
959
959
|
kingdom_default.placeDomino(currentKingdom, position, orientation, rotation, domino);
|
|
960
960
|
currentPlayer.kingdom = currentKingdom;
|
|
961
|
-
|
|
961
|
+
currentLord.hasPlace = true;
|
|
962
962
|
const newState = {
|
|
963
963
|
...state,
|
|
964
|
-
|
|
965
|
-
if (
|
|
966
|
-
return
|
|
964
|
+
lords: state.lords.map((lord) => {
|
|
965
|
+
if (lord.id === lordId) {
|
|
966
|
+
return currentLord;
|
|
967
967
|
}
|
|
968
|
-
return
|
|
968
|
+
return lord;
|
|
969
969
|
})
|
|
970
970
|
};
|
|
971
971
|
return newState;
|
|
972
972
|
};
|
|
973
973
|
|
|
974
|
-
// src/
|
|
974
|
+
// src/hexagon/internal/services/order.ts
|
|
975
975
|
var definePlayerOrder = (payload) => {
|
|
976
976
|
const { state } = payload;
|
|
977
|
-
const {
|
|
978
|
-
const
|
|
979
|
-
if (!
|
|
980
|
-
throw new Error("Not all
|
|
977
|
+
const { lords, currentDominoes } = state;
|
|
978
|
+
const allLordsHavePlayed = lords.every((lord) => lord.turnEnded);
|
|
979
|
+
if (!allLordsHavePlayed) {
|
|
980
|
+
throw new Error("Not all lords have played");
|
|
981
981
|
}
|
|
982
|
-
const
|
|
982
|
+
const updatedLords = lords.map((lord) => {
|
|
983
983
|
return {
|
|
984
|
-
...
|
|
985
|
-
order: currentDominoes.find((domino) => domino.
|
|
984
|
+
...lord,
|
|
985
|
+
order: currentDominoes.find((domino) => domino.lordId === lord.id)?.position || 0
|
|
986
986
|
};
|
|
987
987
|
});
|
|
988
|
-
const order =
|
|
988
|
+
const order = updatedLords.reduce((acc, lord) => {
|
|
989
989
|
return {
|
|
990
990
|
...acc,
|
|
991
|
-
[
|
|
991
|
+
[lord.order]: lord.id
|
|
992
992
|
};
|
|
993
993
|
}, {});
|
|
994
994
|
const newState = {
|
|
995
995
|
...state,
|
|
996
|
-
|
|
996
|
+
lords: updatedLords,
|
|
997
997
|
order
|
|
998
998
|
};
|
|
999
999
|
return newState;
|
|
1000
1000
|
};
|
|
1001
1001
|
|
|
1002
|
-
// src/
|
|
1002
|
+
// src/hexagon/internal/services/draw.ts
|
|
1003
1003
|
var draw = (payload) => {
|
|
1004
1004
|
const { state } = payload;
|
|
1005
1005
|
const dominoesCopy = [...state.dominoes];
|
|
@@ -1012,7 +1012,7 @@ var draw = (payload) => {
|
|
|
1012
1012
|
return {
|
|
1013
1013
|
domino,
|
|
1014
1014
|
picked: false,
|
|
1015
|
-
|
|
1015
|
+
lordId: null,
|
|
1016
1016
|
position: index + 1
|
|
1017
1017
|
};
|
|
1018
1018
|
})
|
|
@@ -1020,7 +1020,7 @@ var draw = (payload) => {
|
|
|
1020
1020
|
return newState;
|
|
1021
1021
|
};
|
|
1022
1022
|
|
|
1023
|
-
// src/
|
|
1023
|
+
// src/hexagon/internal/services/scoring.ts
|
|
1024
1024
|
var calculateScore = (kingdom2) => {
|
|
1025
1025
|
const visited = kingdom2.map((row) => row.map(() => false));
|
|
1026
1026
|
const properties = [];
|
|
@@ -1092,28 +1092,28 @@ var calculateScore = (kingdom2) => {
|
|
|
1092
1092
|
};
|
|
1093
1093
|
};
|
|
1094
1094
|
|
|
1095
|
-
// src/
|
|
1095
|
+
// src/hexagon/internal/services/pass.ts
|
|
1096
1096
|
var pass = (payload) => {
|
|
1097
|
-
const {
|
|
1097
|
+
const { lordId, data } = payload;
|
|
1098
1098
|
const { state } = data;
|
|
1099
|
-
const
|
|
1100
|
-
if (!
|
|
1101
|
-
throw new Error("
|
|
1099
|
+
const currentLord = state.lords.find((lord) => lord.id === lordId);
|
|
1100
|
+
if (!currentLord) {
|
|
1101
|
+
throw new Error("Lord not found");
|
|
1102
1102
|
}
|
|
1103
|
-
|
|
1103
|
+
currentLord.hasPlace = true;
|
|
1104
1104
|
const newState = {
|
|
1105
1105
|
...state,
|
|
1106
|
-
|
|
1107
|
-
if (
|
|
1108
|
-
return
|
|
1106
|
+
lords: state.lords.map((lord) => {
|
|
1107
|
+
if (lord.id === lordId) {
|
|
1108
|
+
return currentLord;
|
|
1109
1109
|
}
|
|
1110
|
-
return
|
|
1110
|
+
return lord;
|
|
1111
1111
|
})
|
|
1112
1112
|
};
|
|
1113
1113
|
return newState;
|
|
1114
1114
|
};
|
|
1115
1115
|
|
|
1116
|
-
// src/
|
|
1116
|
+
// src/hexagon/internal/services/game.ts
|
|
1117
1117
|
var gameStep = (dependencies) => {
|
|
1118
1118
|
return {
|
|
1119
1119
|
init: init(dependencies),
|
|
@@ -1127,13 +1127,13 @@ var gameStep = (dependencies) => {
|
|
|
1127
1127
|
calculateScore
|
|
1128
1128
|
};
|
|
1129
1129
|
};
|
|
1130
|
-
var
|
|
1131
|
-
const {
|
|
1132
|
-
const
|
|
1130
|
+
var isLordTurn = (state, lordId) => {
|
|
1131
|
+
const { lords, currentDominoes } = state;
|
|
1132
|
+
const currentLordOrder = lords.find((lord) => lord.id === lordId)?.order;
|
|
1133
1133
|
const pickedDominoes = currentDominoes.filter(
|
|
1134
1134
|
(currentDomino) => currentDomino.picked
|
|
1135
1135
|
);
|
|
1136
|
-
if (
|
|
1136
|
+
if (currentLordOrder !== pickedDominoes.length + 1) {
|
|
1137
1137
|
return false;
|
|
1138
1138
|
}
|
|
1139
1139
|
return true;
|
|
@@ -1159,19 +1159,19 @@ var checkValidityDomino = (state, dominoPick) => {
|
|
|
1159
1159
|
};
|
|
1160
1160
|
var rules = {
|
|
1161
1161
|
2: {
|
|
1162
|
-
|
|
1162
|
+
lords: 2,
|
|
1163
1163
|
maxDominoes: 24,
|
|
1164
1164
|
dominoesPerTurn: 4,
|
|
1165
1165
|
maxTurns: 6
|
|
1166
1166
|
},
|
|
1167
1167
|
3: {
|
|
1168
|
-
|
|
1168
|
+
lords: 1,
|
|
1169
1169
|
maxDominoes: 36,
|
|
1170
1170
|
dominoesPerTurn: 3,
|
|
1171
1171
|
maxTurns: 12
|
|
1172
1172
|
},
|
|
1173
1173
|
4: {
|
|
1174
|
-
|
|
1174
|
+
lords: 1,
|
|
1175
1175
|
maxDominoes: 48,
|
|
1176
1176
|
dominoesPerTurn: 4,
|
|
1177
1177
|
maxTurns: 12
|
|
@@ -1179,7 +1179,7 @@ var rules = {
|
|
|
1179
1179
|
};
|
|
1180
1180
|
var game_default = gameStep;
|
|
1181
1181
|
|
|
1182
|
-
// src/
|
|
1182
|
+
// src/hexagon/internal/services/result.ts
|
|
1183
1183
|
var result = (scores) => {
|
|
1184
1184
|
scores.sort((a, b) => {
|
|
1185
1185
|
if (a.details.score !== b.details.score) {
|
|
@@ -1218,13 +1218,47 @@ var result = (scores) => {
|
|
|
1218
1218
|
return result2;
|
|
1219
1219
|
};
|
|
1220
1220
|
|
|
1221
|
-
// src/
|
|
1221
|
+
// src/hexagon/internal/entities/mode.ts
|
|
1222
|
+
var availableMode = ["Classic"];
|
|
1223
|
+
|
|
1224
|
+
// src/adapters/driven/uuid.ts
|
|
1225
|
+
import { randomUUID } from "crypto";
|
|
1226
|
+
var uuidMethod = () => {
|
|
1227
|
+
return randomUUID();
|
|
1228
|
+
};
|
|
1229
|
+
|
|
1230
|
+
// src/adapters/driven/shuffle.ts
|
|
1231
|
+
var shuffleMethod = (array) => {
|
|
1232
|
+
for (let i = array.length - 1; i > 0; i--) {
|
|
1233
|
+
const j = Math.floor(Math.random() * (i + 1));
|
|
1234
|
+
[array[i], array[j]] = [array[j], array[i]];
|
|
1235
|
+
}
|
|
1236
|
+
return array;
|
|
1237
|
+
};
|
|
1238
|
+
|
|
1239
|
+
// src/adapters/driver/index.ts
|
|
1222
1240
|
var gameEngine = () => {
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1241
|
+
let dependencies;
|
|
1242
|
+
try {
|
|
1243
|
+
loadEnvFile();
|
|
1244
|
+
} catch (error) {
|
|
1245
|
+
console.log("No .env file found. Using default configuration.");
|
|
1246
|
+
}
|
|
1247
|
+
if (process.env.NODE_ENV === "development" || process.env.NODE_ENV === "test") {
|
|
1248
|
+
console.log("Game engine is running in development mode");
|
|
1249
|
+
dependencies = {
|
|
1250
|
+
dominoesRepository: inMemoryDominoes_default(),
|
|
1251
|
+
uuidMethod: () => `uuid-${Math.random()}`,
|
|
1252
|
+
shuffleMethod: (array) => array
|
|
1253
|
+
};
|
|
1254
|
+
} else {
|
|
1255
|
+
console.log("Game engine is running in production mode");
|
|
1256
|
+
dependencies = {
|
|
1257
|
+
dominoesRepository: inMemoryDominoes_default(),
|
|
1258
|
+
uuidMethod,
|
|
1259
|
+
shuffleMethod
|
|
1260
|
+
};
|
|
1261
|
+
}
|
|
1228
1262
|
const {
|
|
1229
1263
|
init: init2,
|
|
1230
1264
|
setup: setup2,
|
|
@@ -1255,25 +1289,25 @@ var gameEngine = () => {
|
|
|
1255
1289
|
});
|
|
1256
1290
|
const drawState = draw2({ state: setupState });
|
|
1257
1291
|
return {
|
|
1258
|
-
|
|
1292
|
+
nextLord: drawState.lords[0].id,
|
|
1259
1293
|
nextAction: "pick",
|
|
1260
1294
|
game: drawState
|
|
1261
1295
|
};
|
|
1262
1296
|
};
|
|
1263
|
-
const passTurn = (game,
|
|
1297
|
+
const passTurn = (game, lordId) => {
|
|
1264
1298
|
const updatedGame = pass2({
|
|
1265
|
-
|
|
1299
|
+
lordId,
|
|
1266
1300
|
action: "pass",
|
|
1267
1301
|
data: {
|
|
1268
1302
|
state: game
|
|
1269
1303
|
}
|
|
1270
1304
|
});
|
|
1271
|
-
const resp = defineNextAction(updatedGame, "pass",
|
|
1305
|
+
const resp = defineNextAction(updatedGame, "pass", lordId);
|
|
1272
1306
|
return resp;
|
|
1273
1307
|
};
|
|
1274
|
-
const placeDomino2 = (game,
|
|
1308
|
+
const placeDomino2 = (game, lordId, position, orientation, rotation) => {
|
|
1275
1309
|
const updatedGame = place2({
|
|
1276
|
-
|
|
1310
|
+
lordId,
|
|
1277
1311
|
action: "place",
|
|
1278
1312
|
data: {
|
|
1279
1313
|
state: game,
|
|
@@ -1282,19 +1316,19 @@ var gameEngine = () => {
|
|
|
1282
1316
|
rotation
|
|
1283
1317
|
}
|
|
1284
1318
|
});
|
|
1285
|
-
const resp = defineNextAction(updatedGame, "place",
|
|
1319
|
+
const resp = defineNextAction(updatedGame, "place", lordId);
|
|
1286
1320
|
return resp;
|
|
1287
1321
|
};
|
|
1288
|
-
const pickDomino = (game,
|
|
1322
|
+
const pickDomino = (game, lordId, dominoPick) => {
|
|
1289
1323
|
const updatedGame = pick2({
|
|
1290
|
-
|
|
1324
|
+
lordId,
|
|
1291
1325
|
action: "pick",
|
|
1292
1326
|
data: {
|
|
1293
1327
|
state: game,
|
|
1294
1328
|
dominoPick
|
|
1295
1329
|
}
|
|
1296
1330
|
});
|
|
1297
|
-
const resp = defineNextAction(updatedGame, "pick",
|
|
1331
|
+
const resp = defineNextAction(updatedGame, "pick", lordId);
|
|
1298
1332
|
return resp;
|
|
1299
1333
|
};
|
|
1300
1334
|
const prepareNextTurn = (game) => {
|
|
@@ -1306,58 +1340,58 @@ var gameEngine = () => {
|
|
|
1306
1340
|
}
|
|
1307
1341
|
return updateTurn.game;
|
|
1308
1342
|
};
|
|
1309
|
-
const defineNextAction = (game, currentAction,
|
|
1310
|
-
const {
|
|
1343
|
+
const defineNextAction = (game, currentAction, currentLordId) => {
|
|
1344
|
+
const { lords, turn } = game;
|
|
1311
1345
|
if (turn === 0) {
|
|
1312
|
-
const
|
|
1313
|
-
if (!
|
|
1346
|
+
const nextLord2 = lords.find((lord) => !lord.hasPick);
|
|
1347
|
+
if (!nextLord2) {
|
|
1314
1348
|
const newState = prepareNextTurn(game);
|
|
1315
1349
|
return {
|
|
1316
|
-
|
|
1350
|
+
nextLord: newState.lords[0].id,
|
|
1317
1351
|
nextAction: "place",
|
|
1318
1352
|
game: newState
|
|
1319
1353
|
};
|
|
1320
1354
|
}
|
|
1321
1355
|
return {
|
|
1322
|
-
|
|
1356
|
+
nextLord: nextLord2.id,
|
|
1323
1357
|
nextAction: "pick",
|
|
1324
1358
|
game
|
|
1325
1359
|
};
|
|
1326
1360
|
}
|
|
1327
1361
|
if (currentAction === "place" || currentAction === "pass") {
|
|
1328
1362
|
if (game.turn === game.maxTurns) {
|
|
1329
|
-
const
|
|
1330
|
-
if (!
|
|
1363
|
+
const nextLord2 = lords.find((lord) => !lord.hasPlace);
|
|
1364
|
+
if (!nextLord2) {
|
|
1331
1365
|
return {
|
|
1332
|
-
|
|
1366
|
+
nextLord: "none",
|
|
1333
1367
|
nextAction: "end",
|
|
1334
1368
|
game
|
|
1335
1369
|
};
|
|
1336
1370
|
}
|
|
1337
1371
|
return {
|
|
1338
|
-
|
|
1372
|
+
nextLord: nextLord2.id,
|
|
1339
1373
|
nextAction: "place",
|
|
1340
1374
|
game
|
|
1341
1375
|
};
|
|
1342
1376
|
}
|
|
1343
1377
|
return {
|
|
1344
|
-
|
|
1378
|
+
nextLord: currentLordId,
|
|
1345
1379
|
nextAction: "pick",
|
|
1346
1380
|
game
|
|
1347
1381
|
};
|
|
1348
1382
|
}
|
|
1349
|
-
const
|
|
1350
|
-
if (
|
|
1383
|
+
const allLordsHavePicked = lords.every((lord) => lord.hasPick);
|
|
1384
|
+
if (allLordsHavePicked) {
|
|
1351
1385
|
const newState = prepareNextTurn(game);
|
|
1352
1386
|
return {
|
|
1353
|
-
|
|
1387
|
+
nextLord: newState.order["1"],
|
|
1354
1388
|
nextAction: "place",
|
|
1355
1389
|
game: newState
|
|
1356
1390
|
};
|
|
1357
1391
|
}
|
|
1358
|
-
const
|
|
1392
|
+
const nextLord = lords.find((lord) => !lord.hasPlace);
|
|
1359
1393
|
return {
|
|
1360
|
-
|
|
1394
|
+
nextLord: nextLord.id,
|
|
1361
1395
|
nextAction: "place",
|
|
1362
1396
|
game
|
|
1363
1397
|
};
|
|
@@ -1392,10 +1426,10 @@ var gameEngine = () => {
|
|
|
1392
1426
|
endGame
|
|
1393
1427
|
};
|
|
1394
1428
|
};
|
|
1395
|
-
var
|
|
1429
|
+
var driver_default = gameEngine;
|
|
1396
1430
|
|
|
1397
1431
|
// src/index.ts
|
|
1398
|
-
var src_default =
|
|
1432
|
+
var src_default = driver_default;
|
|
1399
1433
|
export {
|
|
1400
1434
|
src_default as default
|
|
1401
1435
|
};
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/infrastructure/data/dominoes.json","../src/infrastructure/repositories/inMemoryDominoes.ts","../src/domain/entities/game.ts","../src/domain/useCases/game/init.ts","../src/domain/entities/kingdom.ts","../src/domain/useCases/game/setup.ts","../src/domain/useCases/game/startTurn.ts","../src/domain/useCases/game/pick.ts","../src/domain/useCases/game/place.ts","../src/domain/useCases/game/order.ts","../src/domain/useCases/game/draw.ts","../src/domain/useCases/game/scoring.ts","../src/domain/useCases/game/pass.ts","../src/domain/useCases/game/game.ts","../src/domain/useCases/game/result.ts","../src/application/engine/index.ts","../src/index.ts"],"sourcesContent":["[\n {\n \"left\": {\n \"type\": \"wheat\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"wheat\",\n \"crowns\": 0\n },\n \"number\": 1\n },\n {\n \"left\": {\n \"type\": \"wheat\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"wheat\",\n \"crowns\": 0\n },\n \"number\": 2\n },\n {\n \"left\": {\n \"type\": \"forest\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"forest\",\n \"crowns\": 0\n },\n \"number\": 3\n },\n {\n \"left\": {\n \"type\": \"forest\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"forest\",\n \"crowns\": 0\n },\n \"number\": 4\n },\n {\n \"left\": {\n \"type\": \"forest\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"forest\",\n \"crowns\": 0\n },\n \"number\": 5\n },\n {\n \"left\": {\n \"type\": \"forest\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"forest\",\n \"crowns\": 0\n },\n \"number\": 6\n },\n {\n \"left\": {\n \"type\": \"water\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"water\",\n \"crowns\": 0\n },\n \"number\": 7\n },\n {\n \"left\": {\n \"type\": \"water\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"water\",\n \"crowns\": 0\n },\n \"number\": 8\n },\n {\n \"left\": {\n \"type\": \"water\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"water\",\n \"crowns\": 0\n },\n \"number\": 9\n },\n {\n \"left\": {\n \"type\": \"grass\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"grass\",\n \"crowns\": 0\n },\n \"number\": 10\n },\n {\n \"left\": {\n \"type\": \"grass\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"grass\",\n \"crowns\": 0\n },\n \"number\": 11\n },\n {\n \"left\": {\n \"type\": \"swamp\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"swamp\",\n \"crowns\": 0\n },\n \"number\": 12\n },\n {\n \"left\": {\n \"type\": \"wheat\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"forest\",\n \"crowns\": 0\n },\n \"number\": 13\n },\n {\n \"left\": {\n \"type\": \"wheat\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"water\",\n \"crowns\": 0\n },\n \"number\": 14\n },\n {\n \"left\": {\n \"type\": \"wheat\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"grass\",\n \"crowns\": 0\n },\n \"number\": 15\n },\n {\n \"left\": {\n \"type\": \"wheat\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"swamp\",\n \"crowns\": 0\n },\n \"number\": 16\n },\n {\n \"left\": {\n \"type\": \"forest\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"water\",\n \"crowns\": 0\n },\n \"number\": 17\n },\n {\n \"left\": {\n \"type\": \"forest\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"grass\",\n \"crowns\": 0\n },\n \"number\": 18\n },\n {\n \"left\": {\n \"type\": \"wheat\",\n \"crowns\": 1\n },\n \"right\": {\n \"type\": \"forest\",\n \"crowns\": 0\n },\n \"number\": 19\n },\n {\n \"left\": {\n \"type\": \"wheat\",\n \"crowns\": 1\n },\n \"right\": {\n \"type\": \"water\",\n \"crowns\": 0\n },\n \"number\": 20\n },\n {\n \"left\": {\n \"type\": \"wheat\",\n \"crowns\": 1\n },\n \"right\": {\n \"type\": \"grass\",\n \"crowns\": 0\n },\n \"number\": 21\n },\n {\n \"left\": {\n \"type\": \"wheat\",\n \"crowns\": 1\n },\n \"right\": {\n \"type\": \"swamp\",\n \"crowns\": 0\n },\n \"number\": 22\n },\n {\n \"left\": {\n \"type\": \"wheat\",\n \"crowns\": 1\n },\n \"right\": {\n \"type\": \"mine\",\n \"crowns\": 0\n },\n \"number\": 23\n },\n {\n \"left\": {\n \"type\": \"forest\",\n \"crowns\": 1\n },\n \"right\": {\n \"type\": \"wheat\",\n \"crowns\": 0\n },\n \"number\": 24\n },\n {\n \"left\": {\n \"type\": \"forest\",\n \"crowns\": 1\n },\n \"right\": {\n \"type\": \"wheat\",\n \"crowns\": 0\n },\n \"number\": 25\n },\n {\n \"left\": {\n \"type\": \"forest\",\n \"crowns\": 1\n },\n \"right\": {\n \"type\": \"wheat\",\n \"crowns\": 0\n },\n \"number\": 26\n },\n {\n \"left\": {\n \"type\": \"forest\",\n \"crowns\": 1\n },\n \"right\": {\n \"type\": \"wheat\",\n \"crowns\": 0\n },\n \"number\": 27\n },\n {\n \"left\": {\n \"type\": \"forest\",\n \"crowns\": 1\n },\n \"right\": {\n \"type\": \"water\",\n \"crowns\": 0\n },\n \"number\": 28\n },\n {\n \"left\": {\n \"type\": \"forest\",\n \"crowns\": 1\n },\n \"right\": {\n \"type\": \"grass\",\n \"crowns\": 0\n },\n \"number\": 29\n },\n {\n \"left\": {\n \"type\": \"water\",\n \"crowns\": 1\n },\n \"right\": {\n \"type\": \"wheat\",\n \"crowns\": 0\n },\n \"number\": 30\n },\n {\n \"left\": {\n \"type\": \"water\",\n \"crowns\": 1\n },\n \"right\": {\n \"type\": \"wheat\",\n \"crowns\": 0\n },\n \"number\": 31\n },\n {\n \"left\": {\n \"type\": \"water\",\n \"crowns\": 1\n },\n \"right\": {\n \"type\": \"forest\",\n \"crowns\": 0\n },\n \"number\": 32\n },\n {\n \"left\": {\n \"type\": \"water\",\n \"crowns\": 1\n },\n \"right\": {\n \"type\": \"forest\",\n \"crowns\": 0\n },\n \"number\": 33\n },\n {\n \"left\": {\n \"type\": \"water\",\n \"crowns\": 1\n },\n \"right\": {\n \"type\": \"forest\",\n \"crowns\": 0\n },\n \"number\": 34\n },\n {\n \"left\": {\n \"type\": \"water\",\n \"crowns\": 1\n },\n \"right\": {\n \"type\": \"forest\",\n \"crowns\": 0\n },\n \"number\": 35\n },\n {\n \"left\": {\n \"type\": \"wheat\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"grass\",\n \"crowns\": 1\n },\n \"number\": 36\n },\n {\n \"left\": {\n \"type\": \"water\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"grass\",\n \"crowns\": 1\n },\n \"number\": 37\n },\n {\n \"left\": {\n \"type\": \"wheat\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"swamp\",\n \"crowns\": 1\n },\n \"number\": 38\n },\n {\n \"left\": {\n \"type\": \"grass\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"swamp\",\n \"crowns\": 0\n },\n \"number\": 39\n },\n {\n \"left\": {\n \"type\": \"mine\",\n \"crowns\": 1\n },\n \"right\": {\n \"type\": \"wheat\",\n \"crowns\": 0\n },\n \"number\": 40\n },\n {\n \"left\": {\n \"type\": \"wheat\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"grass\",\n \"crowns\": 2\n },\n \"number\": 41\n },\n {\n \"left\": {\n \"type\": \"water\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"grass\",\n \"crowns\": 2\n },\n \"number\": 42\n },\n {\n \"left\": {\n \"type\": \"wheat\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"swamp\",\n \"crowns\": 2\n },\n \"number\": 43\n },\n {\n \"left\": {\n \"type\": \"grass\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"swamp\",\n \"crowns\": 2\n },\n \"number\": 44\n },\n {\n \"left\": {\n \"type\": \"mine\",\n \"crowns\": 2\n },\n \"right\": {\n \"type\": \"wheat\",\n \"crowns\": 0\n },\n \"number\": 45\n },\n {\n \"left\": {\n \"type\": \"swamp\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"mine\",\n \"crowns\": 2\n },\n \"number\": 46\n },\n {\n \"left\": {\n \"type\": \"swamp\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"mine\",\n \"crowns\": 2\n },\n \"number\": 47\n },\n {\n \"left\": {\n \"type\": \"wheat\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"mine\",\n \"crowns\": 3\n },\n \"number\": 48\n }\n]","import type { Domino, Ground } from \"../../domain/entities/domino\";\nimport dominoesJson from \"../data/dominoes.json\" assert { type: \"json\" };\nimport type { DominoesRepository } from \"../../domain/port/dominoesRepository\";\n\nconst inMemoryDominoes = (): DominoesRepository => {\n const dominoes: Domino[] = [];\n\n dominoesJson.forEach((domino) => {\n dominoes.push({\n left: {\n type: <Ground>domino.left.type,\n crowns: domino.left.crowns,\n },\n right: {\n type: <Ground>domino.right.type,\n crowns: domino.right.crowns,\n },\n number: domino.number,\n });\n });\n\n return {\n getAll: () => {\n return dominoes;\n },\n };\n};\n\nexport default inMemoryDominoes;\n","import type { Domino, RevealsDomino } from \"./domino\";\nimport type { Kingdom } from \"./kingdom\";\n\nexport type King = {\n id: string;\n playerId: string;\n order: number;\n turnEnded: boolean;\n hasPick: boolean;\n hasPlace: boolean;\n dominoPicked?: Domino;\n};\n\nexport type Player = {\n id?: string;\n name: string;\n kingdom: Kingdom;\n};\n\nexport const availableMode = [\"Classic\"] as const;\nexport type AvailableMode = (typeof availableMode)[number];\nexport const isValidMode = (mode: string): mode is AvailableMode => {\n return availableMode.includes(mode as AvailableMode);\n};\n\nexport type Rule = {\n name: string;\n description: string;\n mode: AvailableMode[];\n playersLimit?: number;\n};\n\nexport type Game = {\n id: string;\n dominoes: Domino[];\n currentDominoes: RevealsDomino[];\n players: Player[];\n kings: King[];\n turn: number;\n maxTurns: number;\n maxDominoes: number;\n dominoesPerTurn: number;\n order: Record<number, string>;\n rules?: Rule[];\n};\n","import type { Game } from \"../../entities/game.js\";\nimport type { GameDependencies } from \"./game.js\";\n\nconst init = (dependencies: GameDependencies) => (): Game => {\n const dominoes = dependencies.dominoesRepository.getAll();\n const id = dependencies.uuidMethod();\n\n const state = {\n id,\n dominoes,\n currentDominoes: [],\n players: [],\n kings: [],\n turn: 0,\n maxTurns: 0,\n maxDominoes: 0,\n dominoesPerTurn: 0,\n order: {},\n };\n\n return state;\n};\n\nexport { init };\n","import type { Domino, Tile, EmptyTile } from \"domain/entities/domino\";\n\nexport type Position = {\n x: number; // cols\n y: number; // rows\n};\n\nexport type Orientation = \"vertical\" | \"horizontal\";\n\nexport type Rotation = 0 | 180;\n\nexport type Kingdom = (Tile | EmptyTile)[][];\n\nconst createEmptyKingdom = (): Kingdom => {\n const gridSize = 9;\n const emptyTile: EmptyTile = { type: \"empty\", crowns: 0 };\n\n return Array.from({ length: gridSize }, () =>\n Array.from({ length: gridSize }, () => emptyTile)\n );\n};\n\nconst createKingdomWithCastle = (): Kingdom => {\n const kingdom = createEmptyKingdom();\n return placeTile(kingdom, { x: 4, y: 4 }, { type: \"castle\", crowns: 0 });\n};\n\nconst placeTile = (\n kingdom: Kingdom,\n position: Position,\n tile: Tile\n): Kingdom => {\n const newRow = [...kingdom[position.y]!];\n newRow[position.x] = tile;\n return [\n ...kingdom.slice(0, position.y),\n newRow,\n ...kingdom.slice(position.y + 1),\n ];\n};\n\nconst getTile = (grid: Kingdom, position: Position): Tile | EmptyTile => {\n const tile = grid[position.y]?.[position.x];\n if (tile === undefined) {\n throw new Error(\"Invalid placement (not fit into the grid)\");\n }\n return tile;\n};\n\nconst calculateDominoPosition = (\n position: Position,\n orientation: Orientation,\n rotation: Rotation,\n domino: Domino\n): [{ tile: Tile; position: Position }, { tile: Tile; position: Position }] => {\n let firstTile: {\n tile: Tile;\n position: Position;\n };\n let secondTile: {\n tile: Tile;\n position: Position;\n };\n\n if (orientation === \"horizontal\") {\n if (rotation === 0) {\n firstTile = {\n tile: domino.left,\n position: {\n x: position.x,\n y: position.y,\n },\n };\n secondTile = {\n tile: domino.right,\n position: {\n x: position.x + 1,\n y: position.y,\n },\n };\n } else {\n firstTile = {\n tile: domino.right,\n position: {\n x: position.x,\n y: position.y,\n },\n };\n secondTile = {\n tile: domino.left,\n position: {\n x: position.x + 1,\n y: position.y,\n },\n };\n }\n } else {\n if (rotation === 0) {\n firstTile = {\n tile: domino.left,\n position: {\n x: position.x,\n y: position.y,\n },\n };\n secondTile = {\n tile: domino.right,\n position: {\n x: position.x,\n y: position.y + 1,\n },\n };\n } else {\n firstTile = {\n tile: domino.right,\n position: {\n x: position.x,\n y: position.y,\n },\n };\n secondTile = {\n tile: domino.left,\n position: {\n x: position.x,\n y: position.y + 1,\n },\n };\n }\n }\n\n return [firstTile, secondTile];\n};\n\nconst placeDomino = (\n kingdom: Kingdom,\n position: Position,\n orientation: \"vertical\" | \"horizontal\",\n rotation: 0 | 180,\n domino: Domino\n): Kingdom => {\n const [firstTile, secondTile] = calculateDominoPosition(\n position,\n orientation,\n rotation,\n domino\n );\n\n if (!isFreePlace(kingdom, firstTile.position, secondTile.position)) {\n throw new Error(\"Invalid placement (not free place)\");\n }\n\n if (!isFitIntoTheGrid(kingdom, [firstTile, secondTile])) {\n throw new Error(\"Invalid placement (not fit into the grid)\");\n }\n\n const adjacentTiles = isAdjacent(\n kingdom,\n firstTile.position,\n secondTile.position\n );\n\n if (adjacentTiles.length === 0) {\n throw new Error(\"Invalid placement (no adjacent)\");\n }\n\n const hasValidAdjacentTiles = hasValidAdjacent(adjacentTiles, [\n firstTile.tile,\n secondTile.tile,\n ]);\n\n if (!hasValidAdjacentTiles) {\n throw new Error(\"Invalid placement (no valid adjacent)\");\n }\n\n return placeTiles(kingdom, [firstTile, secondTile]);\n};\n\nconst placeTiles = (\n kingdom: Kingdom,\n tiles: { tile: Tile; position: Position }[]\n): Kingdom => {\n return tiles.reduce(\n (newKingdom, { tile, position }) => placeTile(newKingdom, position, tile),\n kingdom\n );\n};\n\nconst isFreePlace = (\n kingdom: Kingdom,\n firstPosition: Position,\n secondPosition: Position\n): boolean => {\n const firstTile = getTile(kingdom, firstPosition);\n const secondTile = getTile(kingdom, secondPosition);\n\n if (firstTile.type !== \"empty\" || secondTile.type !== \"empty\") {\n return false;\n }\n\n return true;\n};\n\nconst isAdjacent = (\n kingdom: Kingdom,\n firstPosition: Position,\n secondPosition: Position\n): (Tile | EmptyTile)[] => {\n const xFirstPosition = firstPosition.x;\n const yFirstPosition = firstPosition.y;\n const xSecondPosition = secondPosition.x;\n const ySecondPosition = secondPosition.y;\n\n const adjacentTiles: (Tile | EmptyTile)[] = [];\n const adjacentTilesKeys = [\n { x: xFirstPosition - 1, y: yFirstPosition },\n { x: xFirstPosition, y: yFirstPosition - 1 },\n { x: xFirstPosition + 1, y: yFirstPosition },\n { x: xFirstPosition, y: yFirstPosition + 1 },\n { x: xSecondPosition - 1, y: ySecondPosition },\n { x: xSecondPosition, y: ySecondPosition - 1 },\n { x: xSecondPosition + 1, y: ySecondPosition },\n { x: xSecondPosition, y: ySecondPosition + 1 },\n ];\n\n // Remove firstPosition and secondPosition from adjacentTilesKeys\n adjacentTilesKeys.splice(\n adjacentTilesKeys.findIndex((pos) => {\n return pos.x === xFirstPosition && pos.y === yFirstPosition;\n }),\n 1\n );\n\n adjacentTilesKeys.splice(\n adjacentTilesKeys.findIndex((pos) => {\n return pos.x === xSecondPosition && pos.y === ySecondPosition;\n }),\n 1\n );\n\n adjacentTilesKeys.forEach((key) => {\n const tile = getTile(kingdom, key);\n if (tile) {\n adjacentTiles.push(tile);\n }\n });\n\n return adjacentTiles;\n};\n\nconst hasValidAdjacent = (\n adjacentTiles: (Tile | EmptyTile)[],\n tiles: Tile[]\n): boolean => {\n return adjacentTiles.some((adjacentTile) => {\n return tiles.some((tile) => {\n return tile.type === adjacentTile.type || adjacentTile.type === \"castle\";\n });\n });\n};\n\nconst isFitIntoTheGrid = (\n grid: Kingdom,\n positions: {\n tile: Tile;\n position: Position;\n }[]\n): boolean => {\n const maxSize = 5;\n\n const simulateNewGrid = [...grid];\n\n simulateNewGrid[positions[0]!.position.y]![positions[0]!.position.x] =\n positions[0]!.tile;\n simulateNewGrid[positions[1]!.position.y]![positions[1]!.position.x] =\n positions[1]!.tile;\n\n const lines = simulateNewGrid.map((line) =>\n line.filter((tile) => tile.type !== \"empty\")\n );\n const columns = simulateNewGrid[0]!.map((_, index) =>\n simulateNewGrid\n .map((line) => line[index])\n .filter((tile) => tile?.type !== \"empty\")\n );\n\n const linesLength = lines.map((line) => line.length);\n const columnsLength = columns.map((line) => line.length);\n\n const maxLineLength = Math.max(...linesLength);\n const maxColumnLength = Math.max(...columnsLength);\n\n if (maxLineLength > maxSize || maxColumnLength > maxSize) {\n return false;\n }\n\n return true;\n};\n\nconst kingdom = {\n createEmptyKingdom,\n createKingdomWithCastle,\n getTile,\n placeDomino,\n};\n\nexport default kingdom;\n","import type { Game, King, Player } from \"../../entities/game.js\";\nimport kingdom from \"../../entities/kingdom.js\";\nimport { type GameDependencies, rules } from \"./game.js\";\n\ntype SetupPayload = {\n state: Game;\n players: { name: string }[];\n};\n\nconst setup =\n (dependencies: GameDependencies) =>\n (payload: SetupPayload): Game => {\n const { state, players } = payload;\n\n if (!players) {\n throw new Error(\"There must be at least 2 players\");\n }\n\n if (players.length > 4) {\n throw new Error(\"There must be no more than 4 players\");\n }\n\n if (players.length < 2) {\n throw new Error(\"There must be at least 2 players\");\n }\n\n const { dominoes } = state;\n const { randomMethod, uuidMethod } = dependencies;\n const { maxDominoes, dominoesPerTurn, maxTurns } = rules[players.length]!;\n const shuffledDominoes = randomMethod(dominoes);\n shuffledDominoes.splice(maxDominoes);\n\n const newPlayers: Player[] = players.map((player) => {\n return {\n ...player,\n kingdom: kingdom.createKingdomWithCastle(),\n id: uuidMethod(),\n };\n });\n\n let newKings: King[];\n if (newPlayers.length === 2) {\n newKings = [\n {\n id: uuidMethod(),\n playerId: newPlayers[0]!.id!,\n order: 1,\n turnEnded: false,\n hasPick: false,\n hasPlace: false,\n },\n {\n id: uuidMethod(),\n playerId: newPlayers[0]!.id!,\n order: 2,\n turnEnded: false,\n hasPick: false,\n hasPlace: false,\n },\n {\n id: uuidMethod(),\n playerId: newPlayers[1]!.id!,\n order: 3,\n turnEnded: false,\n hasPick: false,\n hasPlace: false,\n },\n {\n id: uuidMethod(),\n playerId: newPlayers[1]!.id!,\n order: 4,\n turnEnded: false,\n hasPick: false,\n hasPlace: false,\n },\n ];\n } else {\n newKings = newPlayers.map((player, index) => {\n return {\n id: uuidMethod(),\n playerId: player.id!,\n order: index + 1,\n turnEnded: false,\n hasPick: false,\n hasPlace: false,\n };\n });\n }\n\n const kingsWithOrder = randomMethod(newKings);\n\n kingsWithOrder.forEach((king, index) => {\n king.order = index + 1;\n });\n\n kingsWithOrder.sort((a, b) => a.order - b.order);\n\n const newState = {\n ...state,\n dominoes: shuffledDominoes,\n players: newPlayers,\n kings: kingsWithOrder,\n maxTurns,\n maxDominoes,\n dominoesPerTurn,\n turn: 0,\n };\n\n return newState;\n };\n\nexport { setup };\n","import type { Game } from \"../../entities/game.js\";\n\ntype StartTurnPayload = {\n state: Game;\n};\n\nconst startTurn = (payload: StartTurnPayload): { game: Game } => {\n const { state } = payload;\n\n const turn = state.turn + 1;\n const kings = state.kings;\n\n kings.forEach((king) => {\n king.turnEnded = false;\n king.hasPick = false;\n king.hasPlace = false;\n });\n\n const updatedState = {\n ...state,\n kings,\n turn,\n };\n\n return { game: updatedState };\n};\n\nexport { startTurn };\n","import type { Game } from \"../../entities/game.js\";\nimport type { RevealsDomino } from \"../../entities/domino.js\";\nimport {\n type PlayerActionPayload,\n type CustomError,\n checkValidityDomino,\n isKingTurn,\n} from \"./game.js\";\n\nconst pick = (payload: PlayerActionPayload<\"pick\">): Game => {\n const { kingId, data } = payload;\n const { state, dominoPick } = data;\n const { currentDominoes, kings } = state;\n\n // Check if it is the king's turn\n if (!isKingTurn(state, kingId)) {\n throw new Error(\"It is not your turn\");\n }\n\n // Check if king has already picked\n const king = kings.find((king) => king.id === kingId);\n if (king?.hasPick) {\n throw new Error(\"You have already picked\");\n }\n\n // Check if dominoPick is valid choice\n const domino = checkValidityDomino(state, dominoPick);\n\n // typeguard to check if domino is a CustomError\n const isError = (\n domino: CustomError | RevealsDomino\n ): domino is CustomError => {\n return (domino as CustomError).error !== undefined;\n };\n\n if (isError(domino)) {\n throw new Error(domino.error);\n }\n\n // update currentDominoes\n const updatedCurrentDominoes = currentDominoes.map((domino) => {\n if (domino.domino.number === dominoPick) {\n domino.picked = true;\n domino.kingId = kingId;\n }\n\n return domino;\n });\n\n // update kings\n const updatedKings = kings.map((king) => {\n if (king.id === kingId) {\n king.hasPick = true;\n king.turnEnded = true;\n king.dominoPicked = domino.domino;\n }\n\n return king;\n });\n\n // update state\n const updatedState = {\n ...state,\n currentDominoes: updatedCurrentDominoes,\n kings: updatedKings,\n };\n\n return updatedState;\n};\n\nexport { pick };\n","import type { Game } from \"../../entities/game.js\";\nimport kingdom from \"../../entities/kingdom.js\";\nimport type { PlayerActionPayload } from \"./game.js\";\n\nconst place = (payload: PlayerActionPayload<\"place\">): Game => {\n const { kingId, data } = payload;\n const { state, position, orientation, rotation } = data;\n\n const currentKing = state.kings.find((king) => king.id === kingId);\n const currentPlayer = state.players.find(\n (player) => player.id === currentKing?.playerId\n );\n const currentKingdom = currentPlayer?.kingdom;\n\n if (!currentKingdom) {\n throw new Error(\"Kingdom not found\");\n }\n\n const domino = currentKing?.dominoPicked;\n\n if (!domino) {\n throw new Error(\"Domino not found\");\n }\n\n kingdom.placeDomino(currentKingdom, position, orientation, rotation, domino);\n\n currentPlayer.kingdom = currentKingdom;\n currentKing.hasPlace = true;\n\n const newState = {\n ...state,\n kings: state.kings.map((king) => {\n if (king.id === kingId) {\n return currentKing;\n }\n\n return king;\n }),\n };\n\n return newState;\n};\n\nexport { place };\n","import type { Game } from \"../../entities/game.js\";\n\ntype DefinePlayerOrderPayload = {\n state: Game;\n};\n\nconst definePlayerOrder = (payload: DefinePlayerOrderPayload): Game => {\n const { state } = payload;\n const { kings, currentDominoes } = state;\n\n const allKingsHavePlayed = kings.every((king) => king.turnEnded);\n\n if (!allKingsHavePlayed) {\n throw new Error(\"Not all kings have played\");\n }\n\n const updatedKings = kings.map((king) => {\n return {\n ...king,\n order:\n currentDominoes.find((domino) => domino.kingId === king.id)?.position ||\n 0,\n };\n });\n\n const order = updatedKings.reduce((acc, king) => {\n return {\n ...acc,\n [king.order!]: king.id,\n };\n }, {});\n\n const newState = {\n ...state,\n kings: updatedKings,\n order,\n };\n\n return newState;\n};\n\nexport { definePlayerOrder };\n","import type { Game } from \"../../entities/game.js\";\n\ntype DrawPayload = {\n state: Game;\n};\n\nconst draw = (payload: DrawPayload): Game => {\n const { state } = payload;\n\n const dominoesCopy = [...state.dominoes];\n const dominoesDrawn = dominoesCopy.splice(0, state.dominoesPerTurn);\n dominoesDrawn.sort((a, b) => a.number - b.number);\n\n const newState = {\n ...state,\n dominoes: dominoesCopy,\n currentDominoes: dominoesDrawn.map((domino, index) => {\n return {\n domino,\n picked: false,\n kingId: null,\n position: index + 1,\n };\n }),\n };\n\n return newState;\n};\n\nexport { draw };\n","import type { Kingdom } from \"../../entities/kingdom.js\";\n\ntype Property = {\n type: string;\n crowns: number;\n size: number;\n tiles: number[][];\n};\n\nexport type Score = {\n score: number;\n maxPropertiesSize: number;\n totalCrowns: number;\n};\n\nconst calculateScore = (kingdom: Kingdom): Score => {\n const visited: boolean[][] = kingdom.map((row) => row.map(() => false));\n const properties: Property[] = [];\n\n const directions = [\n [-1, 0],\n [1, 0],\n [0, -1],\n [0, 1],\n ]; // Up, Down, Left, Right\n\n const markZone = (\n x: number,\n y: number,\n type: string,\n crowns: number\n ): void => {\n if (\n x < 0 ||\n y < 0 ||\n x >= kingdom[0]!.length ||\n y >= kingdom.length ||\n visited[y]![x] ||\n kingdom[y]![x]!.type !== type ||\n kingdom[y]![x]!.type === \"empty\" ||\n kingdom[y]![x]!.type === \"castle\"\n ) {\n return;\n }\n\n visited[y]![x] = true;\n const currentZone = properties.find(\n (property) =>\n property.type === type &&\n property.tiles.some(([tx, ty]) => {\n for (let [dx, dy] of directions) {\n if (\n (tx as number) + (dx as number) === x &&\n (ty as number) + (dy as number) === y\n ) {\n return true;\n }\n }\n return false;\n })\n );\n\n if (currentZone) {\n currentZone.crowns += crowns;\n currentZone.size++;\n currentZone.tiles.push([x, y]);\n } else {\n properties.push({ type, crowns, size: 1, tiles: [[x, y]] });\n }\n\n directions.forEach(([dx, dy]) => {\n const nx = x + (dx as number);\n const ny = y + (dy as number);\n if (\n nx >= 0 &&\n ny >= 0 &&\n nx < kingdom[0]!.length &&\n ny < kingdom.length &&\n kingdom[ny]![nx]!.type === type\n ) {\n markZone(nx, ny, kingdom[ny]![nx]!.type, kingdom[ny]![nx]!.crowns);\n }\n });\n };\n\n kingdom.forEach((row, y) => {\n row.forEach((tile, x) => {\n if (!visited[y]![x]) {\n markZone(x, y, tile.type, tile.crowns);\n }\n });\n });\n\n if (properties.length === 0) {\n return {\n score: 0,\n maxPropertiesSize: 0,\n totalCrowns: 0,\n };\n }\n\n const score = properties.reduce(\n (score, property) => score + property.crowns * property.size,\n 0\n );\n const maxPropertiesSize = Math.max(\n ...properties.map((property) => property.size ?? 0)\n );\n\n const totalCrowns = properties.reduce(\n (total, property) => total + property.crowns,\n 0\n );\n\n return {\n score,\n maxPropertiesSize,\n totalCrowns,\n };\n};\n\nexport { calculateScore };\n","import type { Game } from \"../../entities/game.js\";\nimport type { PlayerActionPayload } from \"./game.js\";\n\nconst pass = (payload: PlayerActionPayload<\"pass\">): Game => {\n const { kingId, data } = payload;\n const { state } = data;\n\n const currentKing = state.kings.find((king) => king.id === kingId);\n\n if (!currentKing) {\n throw new Error(\"King not found\");\n }\n\n currentKing.hasPlace = true;\n\n const newState = {\n ...state,\n kings: state.kings.map((king) => {\n if (king.id === kingId) {\n return currentKing;\n }\n\n return king;\n }),\n };\n\n return newState;\n};\n\nexport { pass };\n","import type { DominoesRepository } from \"../../port/dominoesRepository.js\";\nimport type { Position } from \"../../entities/kingdom.js\";\nimport type { Game } from \"../../entities/game.js\";\nimport { init } from \"./init.js\";\nimport { setup } from \"./setup.js\";\nimport { startTurn } from \"./startTurn.js\";\nimport { pick } from \"./pick.js\";\nimport { place } from \"./place.js\";\nimport { definePlayerOrder } from \"./order.js\";\nimport { draw } from \"./draw.js\";\nimport { calculateScore } from \"./scoring.js\";\nimport { pass } from \"./pass.js\";\n\nexport type GameDependencies = {\n dominoesRepository: DominoesRepository;\n uuidMethod: () => string;\n randomMethod<T>(array: T[]): T[];\n};\n\nexport const playerAction = {\n pick: \"pick\",\n place: \"place\",\n pass: \"pass\",\n} as const;\n\ntype ObjectValues<T> = T[keyof T];\n\nexport type PlayerAction = ObjectValues<typeof playerAction>;\n\ntype PickData = {\n state: Game;\n dominoPick: number;\n};\n\ntype PlaceData = {\n state: Game;\n position: Position;\n orientation: \"vertical\" | \"horizontal\";\n rotation: 0 | 180;\n};\n\ntype PassData = {\n state: Game;\n};\n\ntype ActionToDataMap = {\n pick: PickData;\n place: PlaceData;\n pass: PassData;\n};\n\nexport type PlayerActionPayload<T extends PlayerAction> = {\n kingId: string;\n action: T;\n data: ActionToDataMap[T];\n};\n\nconst gameStep = (dependencies: GameDependencies) => {\n return {\n init: init(dependencies),\n setup: setup(dependencies),\n startTurn,\n pick,\n place,\n pass,\n definePlayerOrder,\n draw,\n calculateScore,\n };\n};\n\nexport const isKingTurn = (state: Game, kingId: string): boolean => {\n const { kings, currentDominoes } = state;\n const currentKingOrder = kings.find((king) => king.id === kingId)?.order;\n\n const pickedDominoes = currentDominoes.filter(\n (currentDomino) => currentDomino.picked\n );\n\n if (currentKingOrder !== pickedDominoes.length + 1) {\n return false;\n }\n\n return true;\n};\n\nexport type CustomError = {\n error: string;\n};\n\nexport const checkValidityDomino = (state: Game, dominoPick: number) => {\n const { currentDominoes } = state;\n const domino = currentDominoes.find(\n (currentDomino) => currentDomino.domino.number === dominoPick\n );\n\n if (!domino) {\n const error: CustomError = {\n error: \"Domino not found\",\n };\n\n return error;\n }\n\n if (domino.picked) {\n const error: CustomError = {\n error: \"Domino already picked\",\n };\n return error;\n }\n\n return domino;\n};\n\n// 2 players => 24 dominoes, 2 kings, 4 dominoes per turn, 6 turns\n// 3 players => 36 dominoes, 1 king, 3 dominoes per turn, 12 turns\n// 4 players => 48 dominoes, 1 king, 4 dominoes per turn, 12 turns\nexport const rules: {\n [key: number]: {\n kings: number;\n maxDominoes: number;\n dominoesPerTurn: number;\n maxTurns: number;\n };\n} = {\n 2: {\n kings: 2,\n maxDominoes: 24,\n dominoesPerTurn: 4,\n maxTurns: 6,\n },\n 3: {\n kings: 1,\n maxDominoes: 36,\n dominoesPerTurn: 3,\n maxTurns: 12,\n },\n 4: {\n kings: 1,\n maxDominoes: 48,\n dominoesPerTurn: 4,\n maxTurns: 12,\n },\n};\n\nexport default gameStep;\n","import type { Score } from \"./scoring.js\";\n\nexport type ScoreResult = {\n playerId: string;\n playerName: string;\n details: Score;\n};\n\nexport type FinalResult = ScoreResult & {\n position: number;\n};\n\nconst result = (scores: ScoreResult[]): FinalResult[] => {\n // 1 order players by score, then by maxPropertiesSize, then by totalCrowns all descending\n scores.sort((a, b) => {\n if (a.details.score !== b.details.score) {\n return b.details.score - a.details.score;\n }\n if (a.details.maxPropertiesSize !== b.details.maxPropertiesSize) {\n return b.details.maxPropertiesSize - a.details.maxPropertiesSize;\n }\n return b.details.totalCrowns - a.details.totalCrowns;\n });\n\n const result: FinalResult[] = [];\n let isTie = false;\n result.push({\n ...scores[0]!,\n position: 1,\n });\n\n for (let i = 1; i < scores.length; i++) {\n const currentScore = scores[i];\n const previousScore = scores[i - 1];\n if (\n previousScore &&\n currentScore &&\n currentScore.details.score === previousScore.details.score &&\n currentScore.details.maxPropertiesSize ===\n previousScore.details.maxPropertiesSize &&\n currentScore.details.totalCrowns === previousScore.details.totalCrowns\n ) {\n isTie = true;\n }\n\n if (isTie) {\n result.push({\n ...currentScore!,\n position: result[i - 1]!.position,\n });\n } else {\n result.push({\n ...currentScore!,\n position: i + 1,\n });\n }\n\n isTie = false;\n }\n\n return result;\n};\n\nexport { result };\n","import inMemoryDominoes from \"../../infrastructure/repositories/inMemoryDominoes.js\";\nimport { availableMode, type Game } from \"../../domain/entities/game.js\";\nimport type {\n Orientation,\n Position,\n Rotation,\n} from \"../../domain/entities/kingdom.js\";\nimport gameStep, {\n type GameDependencies,\n} from \"../../domain/useCases/game/game.js\";\nimport {\n result,\n type FinalResult,\n type ScoreResult,\n} from \"../../domain/useCases/game/result.js\";\n\nexport type Resp = {\n nextKing: string;\n nextAction: \"pick\" | \"place\" | \"end\";\n game: Game;\n};\n\nexport type GameResult = {\n result: FinalResult[];\n game: Game;\n};\n\n/** Todo\n * Add rules step\n *\n **/\n\nconst gameEngine = () => {\n const dependencies: GameDependencies = {\n dominoesRepository: inMemoryDominoes(),\n uuidMethod: () => `uuid-${Math.random()}`,\n randomMethod: (array) => array,\n };\n\n const {\n init,\n setup,\n startTurn,\n pick,\n place,\n pass,\n definePlayerOrder,\n draw,\n calculateScore,\n } = gameStep(dependencies);\n\n /**\n * WIP\n **/\n const getMode = () => {\n return availableMode;\n };\n\n const setMode = (mode: string, game: Game) => {\n return game;\n };\n\n const getRules = (mode: string) => {\n return [];\n };\n\n const setRules = (rules: string[], game: Game) => {\n return game;\n };\n\n const start = (game: Game, players: { name: string }[]): Resp => {\n const setupState = setup({\n state: game,\n players,\n });\n const drawState = draw({ state: setupState });\n\n return {\n nextKing: drawState.kings[0]!.id,\n nextAction: \"pick\",\n game: drawState,\n };\n };\n\n const passTurn = (game: Game, kingId: string): Resp => {\n const updatedGame = pass({\n kingId,\n action: \"pass\",\n data: {\n state: game,\n },\n });\n\n const resp = defineNextAction(updatedGame, \"pass\", kingId);\n\n return resp;\n };\n\n const placeDomino = (\n game: Game,\n kingId: string,\n position: Position,\n orientation: Orientation,\n rotation: Rotation\n ): Resp => {\n const updatedGame = place({\n kingId,\n action: \"place\",\n data: {\n state: game,\n position,\n orientation,\n rotation,\n },\n });\n\n const resp = defineNextAction(updatedGame, \"place\", kingId);\n\n return resp;\n };\n\n const pickDomino = (game: Game, kingId: string, dominoPick: number): Resp => {\n const updatedGame = pick({\n kingId,\n action: \"pick\",\n data: {\n state: game,\n dominoPick,\n },\n });\n\n const resp = defineNextAction(updatedGame, \"pick\", kingId);\n\n return resp;\n };\n\n const prepareNextTurn = (game: Game): Game => {\n const updatedOrder = definePlayerOrder({ state: game });\n const updateDraw = draw({ state: updatedOrder });\n const updateTurn = startTurn({ state: updateDraw });\n\n if (updateTurn.game.turn > updateTurn.game.maxTurns) {\n throw new Error(\"Game is over\");\n }\n\n return updateTurn.game;\n };\n\n const defineNextAction = (\n game: Game,\n currentAction: string,\n currentKingId: string\n ): Resp => {\n const { kings, turn } = game;\n\n if (turn === 0) {\n const nextKing = kings.find((king) => !king.hasPick);\n if (!nextKing) {\n const newState = prepareNextTurn(game);\n return {\n nextKing: newState.kings[0]!.id,\n nextAction: \"place\",\n game: newState,\n };\n }\n return {\n nextKing: nextKing.id,\n nextAction: \"pick\",\n game,\n };\n }\n\n if (currentAction === \"place\" || currentAction === \"pass\") {\n if (game.turn === game.maxTurns) {\n const nextKing = kings.find((king) => !king.hasPlace);\n if (!nextKing) {\n return {\n nextKing: \"none\",\n nextAction: \"end\",\n game,\n };\n }\n return {\n nextKing: nextKing!.id,\n nextAction: \"place\",\n game,\n };\n }\n return {\n nextKing: currentKingId,\n nextAction: \"pick\",\n game,\n };\n }\n\n const allKingsHavePicked = kings.every((king) => king.hasPick);\n\n if (allKingsHavePicked) {\n const newState = prepareNextTurn(game);\n return {\n nextKing: newState.order[\"1\"]!,\n nextAction: \"place\",\n game: newState,\n };\n }\n\n const nextKing = kings.find((king) => !king.hasPlace);\n\n return {\n nextKing: nextKing!.id,\n nextAction: \"place\",\n game,\n };\n };\n\n const endGame = (game: Game): GameResult => {\n const players = game.players;\n const scores: ScoreResult[] = [];\n\n for (let player of players) {\n const score = calculateScore(player.kingdom);\n scores.push({\n playerId: player.id!,\n playerName: player.name,\n details: score,\n });\n }\n\n const finalResult = result(scores);\n\n return {\n result: finalResult,\n game,\n };\n };\n\n return {\n init,\n getMode,\n setMode,\n getRules,\n setRules,\n start,\n pass: passTurn,\n placeDomino,\n pickDomino,\n endGame,\n };\n};\n\nexport default gameEngine;\n\n// TODO\n// Add rules step\n// Add error handling\n// Refactor game.js\n// Manage env for injection of dependencies (uuid, random, etc.)\n// Add variant available (queendomino, giant extension, dragonomino, etc.)\n","import gameEngine from \"./application/engine/index.js\";\n\nexport default gameEngine;\n"],"mappings":"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","names":["kingdom","king","domino","kingdom","score","result","init","setup","startTurn","pick","place","pass","definePlayerOrder","draw","calculateScore","rules","placeDomino","nextKing"]}
|
|
1
|
+
{"version":3,"sources":["../src/adapters/driver/index.ts","../src/datasources/dominoes.json","../src/adapters/driven/inMemoryDominoes.ts","../src/hexagon/internal/services/init.ts","../src/hexagon/internal/entities/kingdom.ts","../src/hexagon/internal/services/setup.ts","../src/hexagon/internal/services/startTurn.ts","../src/hexagon/internal/services/pick.ts","../src/hexagon/internal/services/place.ts","../src/hexagon/internal/services/order.ts","../src/hexagon/internal/services/draw.ts","../src/hexagon/internal/services/scoring.ts","../src/hexagon/internal/services/pass.ts","../src/hexagon/internal/services/game.ts","../src/hexagon/internal/services/result.ts","../src/hexagon/internal/entities/mode.ts","../src/adapters/driven/uuid.ts","../src/adapters/driven/shuffle.ts","../src/index.ts"],"sourcesContent":["import { loadEnvFile } from \"node:process\";\nimport inMemoryDominoes from \"../driven/inMemoryDominoes.js\";\nimport type { Game } from \"../../hexagon/internal/entities/game.js\";\nimport type {\n Orientation,\n Position,\n Rotation,\n} from \"../../hexagon/internal/entities/kingdom.js\";\nimport gameStep, {\n type GameDependencies,\n} from \"../../hexagon/internal/services/game.js\";\nimport {\n result,\n type FinalResult,\n type ScoreResult,\n} from \"../../hexagon/internal/services/result.js\";\nimport { availableMode } from \"../../hexagon/internal/entities/mode.js\";\nimport { uuidMethod } from \"../../adapters/driven/uuid.js\";\nimport { shuffleMethod } from \"../../adapters/driven/shuffle.js\";\n\nexport type Resp = {\n nextLord: string;\n nextAction: \"pick\" | \"place\" | \"end\";\n game: Game;\n};\n\nexport type GameResult = {\n result: FinalResult[];\n game: Game;\n};\n\n/** Todo\n * Add rules step\n *\n **/\n\nconst gameEngine = () => {\n let dependencies: GameDependencies;\n try {\n loadEnvFile();\n } catch (error) {\n console.log(\"No .env file found. Using default configuration.\");\n }\n\n if (\n process.env.NODE_ENV === \"development\" ||\n process.env.NODE_ENV === \"test\"\n ) {\n console.log(\"Game engine is running in development mode\");\n dependencies = {\n dominoesRepository: inMemoryDominoes(),\n uuidMethod: () => `uuid-${Math.random()}`,\n shuffleMethod: (array) => array,\n };\n } else {\n console.log(\"Game engine is running in production mode\");\n dependencies = {\n dominoesRepository: inMemoryDominoes(),\n uuidMethod,\n shuffleMethod,\n };\n }\n\n const {\n init,\n setup,\n startTurn,\n pick,\n place,\n pass,\n definePlayerOrder,\n draw,\n calculateScore,\n } = gameStep(dependencies);\n\n /**\n * WIP\n **/\n const getMode = () => {\n return availableMode;\n };\n\n const setMode = (mode: string, game: Game) => {\n return game;\n };\n\n const getRules = (mode: string) => {\n return [];\n };\n\n const setRules = (rules: string[], game: Game) => {\n return game;\n };\n\n const start = (game: Game, players: { name: string }[]): Resp => {\n const setupState = setup({\n state: game,\n players,\n });\n const drawState = draw({ state: setupState });\n\n return {\n nextLord: drawState.lords[0]!.id,\n nextAction: \"pick\",\n game: drawState,\n };\n };\n\n const passTurn = (game: Game, lordId: string): Resp => {\n const updatedGame = pass({\n lordId,\n action: \"pass\",\n data: {\n state: game,\n },\n });\n\n const resp = defineNextAction(updatedGame, \"pass\", lordId);\n\n return resp;\n };\n\n const placeDomino = (\n game: Game,\n lordId: string,\n position: Position,\n orientation: Orientation,\n rotation: Rotation\n ): Resp => {\n const updatedGame = place({\n lordId,\n action: \"place\",\n data: {\n state: game,\n position,\n orientation,\n rotation,\n },\n });\n\n const resp = defineNextAction(updatedGame, \"place\", lordId);\n\n return resp;\n };\n\n const pickDomino = (game: Game, lordId: string, dominoPick: number): Resp => {\n const updatedGame = pick({\n lordId,\n action: \"pick\",\n data: {\n state: game,\n dominoPick,\n },\n });\n\n const resp = defineNextAction(updatedGame, \"pick\", lordId);\n\n return resp;\n };\n\n const prepareNextTurn = (game: Game): Game => {\n const updatedOrder = definePlayerOrder({ state: game });\n const updateDraw = draw({ state: updatedOrder });\n const updateTurn = startTurn({ state: updateDraw });\n\n if (updateTurn.game.turn > updateTurn.game.maxTurns) {\n throw new Error(\"Game is over\");\n }\n\n return updateTurn.game;\n };\n\n const defineNextAction = (\n game: Game,\n currentAction: string,\n currentLordId: string\n ): Resp => {\n const { lords, turn } = game;\n\n if (turn === 0) {\n const nextLord = lords.find((lord) => !lord.hasPick);\n if (!nextLord) {\n const newState = prepareNextTurn(game);\n return {\n nextLord: newState.lords[0]!.id,\n nextAction: \"place\",\n game: newState,\n };\n }\n return {\n nextLord: nextLord.id,\n nextAction: \"pick\",\n game,\n };\n }\n\n if (currentAction === \"place\" || currentAction === \"pass\") {\n if (game.turn === game.maxTurns) {\n const nextLord = lords.find((lord) => !lord.hasPlace);\n if (!nextLord) {\n return {\n nextLord: \"none\",\n nextAction: \"end\",\n game,\n };\n }\n return {\n nextLord: nextLord!.id,\n nextAction: \"place\",\n game,\n };\n }\n return {\n nextLord: currentLordId,\n nextAction: \"pick\",\n game,\n };\n }\n\n const allLordsHavePicked = lords.every((lord) => lord.hasPick);\n\n if (allLordsHavePicked) {\n const newState = prepareNextTurn(game);\n return {\n nextLord: newState.order[\"1\"]!,\n nextAction: \"place\",\n game: newState,\n };\n }\n\n const nextLord = lords.find((lord) => !lord.hasPlace);\n\n return {\n nextLord: nextLord!.id,\n nextAction: \"place\",\n game,\n };\n };\n\n const endGame = (game: Game): GameResult => {\n const players = game.players;\n const scores: ScoreResult[] = [];\n\n for (let player of players) {\n const score = calculateScore(player.kingdom);\n scores.push({\n playerId: player.id!,\n playerName: player.name,\n details: score,\n });\n }\n\n const finalResult = result(scores);\n\n return {\n result: finalResult,\n game,\n };\n };\n\n return {\n init,\n getMode,\n setMode,\n getRules,\n setRules,\n start,\n pass: passTurn,\n placeDomino,\n pickDomino,\n endGame,\n };\n};\n\nexport default gameEngine;\n\n// TODO\n// Add rules step\n// Add error handling\n// Refactor game.js\n// Manage env for injection of dependencies (uuid, random, etc.)\n// Add variant available (queendomino, giant extension, dragonomino, etc.)\n","[\n {\n \"left\": {\n \"type\": \"wheat\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"wheat\",\n \"crowns\": 0\n },\n \"number\": 1\n },\n {\n \"left\": {\n \"type\": \"wheat\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"wheat\",\n \"crowns\": 0\n },\n \"number\": 2\n },\n {\n \"left\": {\n \"type\": \"forest\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"forest\",\n \"crowns\": 0\n },\n \"number\": 3\n },\n {\n \"left\": {\n \"type\": \"forest\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"forest\",\n \"crowns\": 0\n },\n \"number\": 4\n },\n {\n \"left\": {\n \"type\": \"forest\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"forest\",\n \"crowns\": 0\n },\n \"number\": 5\n },\n {\n \"left\": {\n \"type\": \"forest\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"forest\",\n \"crowns\": 0\n },\n \"number\": 6\n },\n {\n \"left\": {\n \"type\": \"water\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"water\",\n \"crowns\": 0\n },\n \"number\": 7\n },\n {\n \"left\": {\n \"type\": \"water\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"water\",\n \"crowns\": 0\n },\n \"number\": 8\n },\n {\n \"left\": {\n \"type\": \"water\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"water\",\n \"crowns\": 0\n },\n \"number\": 9\n },\n {\n \"left\": {\n \"type\": \"grass\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"grass\",\n \"crowns\": 0\n },\n \"number\": 10\n },\n {\n \"left\": {\n \"type\": \"grass\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"grass\",\n \"crowns\": 0\n },\n \"number\": 11\n },\n {\n \"left\": {\n \"type\": \"swamp\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"swamp\",\n \"crowns\": 0\n },\n \"number\": 12\n },\n {\n \"left\": {\n \"type\": \"wheat\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"forest\",\n \"crowns\": 0\n },\n \"number\": 13\n },\n {\n \"left\": {\n \"type\": \"wheat\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"water\",\n \"crowns\": 0\n },\n \"number\": 14\n },\n {\n \"left\": {\n \"type\": \"wheat\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"grass\",\n \"crowns\": 0\n },\n \"number\": 15\n },\n {\n \"left\": {\n \"type\": \"wheat\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"swamp\",\n \"crowns\": 0\n },\n \"number\": 16\n },\n {\n \"left\": {\n \"type\": \"forest\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"water\",\n \"crowns\": 0\n },\n \"number\": 17\n },\n {\n \"left\": {\n \"type\": \"forest\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"grass\",\n \"crowns\": 0\n },\n \"number\": 18\n },\n {\n \"left\": {\n \"type\": \"wheat\",\n \"crowns\": 1\n },\n \"right\": {\n \"type\": \"forest\",\n \"crowns\": 0\n },\n \"number\": 19\n },\n {\n \"left\": {\n \"type\": \"wheat\",\n \"crowns\": 1\n },\n \"right\": {\n \"type\": \"water\",\n \"crowns\": 0\n },\n \"number\": 20\n },\n {\n \"left\": {\n \"type\": \"wheat\",\n \"crowns\": 1\n },\n \"right\": {\n \"type\": \"grass\",\n \"crowns\": 0\n },\n \"number\": 21\n },\n {\n \"left\": {\n \"type\": \"wheat\",\n \"crowns\": 1\n },\n \"right\": {\n \"type\": \"swamp\",\n \"crowns\": 0\n },\n \"number\": 22\n },\n {\n \"left\": {\n \"type\": \"wheat\",\n \"crowns\": 1\n },\n \"right\": {\n \"type\": \"mine\",\n \"crowns\": 0\n },\n \"number\": 23\n },\n {\n \"left\": {\n \"type\": \"forest\",\n \"crowns\": 1\n },\n \"right\": {\n \"type\": \"wheat\",\n \"crowns\": 0\n },\n \"number\": 24\n },\n {\n \"left\": {\n \"type\": \"forest\",\n \"crowns\": 1\n },\n \"right\": {\n \"type\": \"wheat\",\n \"crowns\": 0\n },\n \"number\": 25\n },\n {\n \"left\": {\n \"type\": \"forest\",\n \"crowns\": 1\n },\n \"right\": {\n \"type\": \"wheat\",\n \"crowns\": 0\n },\n \"number\": 26\n },\n {\n \"left\": {\n \"type\": \"forest\",\n \"crowns\": 1\n },\n \"right\": {\n \"type\": \"wheat\",\n \"crowns\": 0\n },\n \"number\": 27\n },\n {\n \"left\": {\n \"type\": \"forest\",\n \"crowns\": 1\n },\n \"right\": {\n \"type\": \"water\",\n \"crowns\": 0\n },\n \"number\": 28\n },\n {\n \"left\": {\n \"type\": \"forest\",\n \"crowns\": 1\n },\n \"right\": {\n \"type\": \"grass\",\n \"crowns\": 0\n },\n \"number\": 29\n },\n {\n \"left\": {\n \"type\": \"water\",\n \"crowns\": 1\n },\n \"right\": {\n \"type\": \"wheat\",\n \"crowns\": 0\n },\n \"number\": 30\n },\n {\n \"left\": {\n \"type\": \"water\",\n \"crowns\": 1\n },\n \"right\": {\n \"type\": \"wheat\",\n \"crowns\": 0\n },\n \"number\": 31\n },\n {\n \"left\": {\n \"type\": \"water\",\n \"crowns\": 1\n },\n \"right\": {\n \"type\": \"forest\",\n \"crowns\": 0\n },\n \"number\": 32\n },\n {\n \"left\": {\n \"type\": \"water\",\n \"crowns\": 1\n },\n \"right\": {\n \"type\": \"forest\",\n \"crowns\": 0\n },\n \"number\": 33\n },\n {\n \"left\": {\n \"type\": \"water\",\n \"crowns\": 1\n },\n \"right\": {\n \"type\": \"forest\",\n \"crowns\": 0\n },\n \"number\": 34\n },\n {\n \"left\": {\n \"type\": \"water\",\n \"crowns\": 1\n },\n \"right\": {\n \"type\": \"forest\",\n \"crowns\": 0\n },\n \"number\": 35\n },\n {\n \"left\": {\n \"type\": \"wheat\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"grass\",\n \"crowns\": 1\n },\n \"number\": 36\n },\n {\n \"left\": {\n \"type\": \"water\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"grass\",\n \"crowns\": 1\n },\n \"number\": 37\n },\n {\n \"left\": {\n \"type\": \"wheat\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"swamp\",\n \"crowns\": 1\n },\n \"number\": 38\n },\n {\n \"left\": {\n \"type\": \"grass\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"swamp\",\n \"crowns\": 0\n },\n \"number\": 39\n },\n {\n \"left\": {\n \"type\": \"mine\",\n \"crowns\": 1\n },\n \"right\": {\n \"type\": \"wheat\",\n \"crowns\": 0\n },\n \"number\": 40\n },\n {\n \"left\": {\n \"type\": \"wheat\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"grass\",\n \"crowns\": 2\n },\n \"number\": 41\n },\n {\n \"left\": {\n \"type\": \"water\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"grass\",\n \"crowns\": 2\n },\n \"number\": 42\n },\n {\n \"left\": {\n \"type\": \"wheat\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"swamp\",\n \"crowns\": 2\n },\n \"number\": 43\n },\n {\n \"left\": {\n \"type\": \"grass\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"swamp\",\n \"crowns\": 2\n },\n \"number\": 44\n },\n {\n \"left\": {\n \"type\": \"mine\",\n \"crowns\": 2\n },\n \"right\": {\n \"type\": \"wheat\",\n \"crowns\": 0\n },\n \"number\": 45\n },\n {\n \"left\": {\n \"type\": \"swamp\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"mine\",\n \"crowns\": 2\n },\n \"number\": 46\n },\n {\n \"left\": {\n \"type\": \"swamp\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"mine\",\n \"crowns\": 2\n },\n \"number\": 47\n },\n {\n \"left\": {\n \"type\": \"wheat\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"mine\",\n \"crowns\": 3\n },\n \"number\": 48\n }\n]","import type { Domino, Ground } from \"../../hexagon/internal/entities/domino.js\";\nimport dominoesJson from \"../../datasources/dominoes.json\" assert { type: \"json\" };\nimport type { DominoesRepository } from \"../../hexagon/ports/driven/dominoesRepository.js\";\n\nconst inMemoryDominoes = (): DominoesRepository => {\n const dominoes: Domino[] = [];\n\n dominoesJson.forEach((domino) => {\n dominoes.push({\n left: {\n type: <Ground>domino.left.type,\n crowns: domino.left.crowns,\n },\n right: {\n type: <Ground>domino.right.type,\n crowns: domino.right.crowns,\n },\n number: domino.number,\n });\n });\n\n return {\n getAll: () => {\n return dominoes;\n },\n };\n};\n\nexport default inMemoryDominoes;\n","import type { Game } from \"../entities/game.js\";\nimport type { GameDependencies } from \"./game.js\";\n\nconst init = (dependencies: GameDependencies) => (): Game => {\n const dominoes = dependencies.dominoesRepository.getAll();\n const id = dependencies.uuidMethod();\n\n const state = {\n id,\n dominoes,\n currentDominoes: [],\n players: [],\n lords: [],\n turn: 0,\n maxTurns: 0,\n maxDominoes: 0,\n dominoesPerTurn: 0,\n order: {},\n };\n\n return state;\n};\n\nexport { init };\n","import type { Domino, Tile, EmptyTile } from \"./domino.js\";\n\nexport type Position = {\n x: number; // cols\n y: number; // rows\n};\n\nexport type Orientation = \"vertical\" | \"horizontal\";\n\nexport type Rotation = 0 | 180;\n\nexport type Kingdom = (Tile | EmptyTile)[][];\n\nconst createEmptyKingdom = (): Kingdom => {\n const gridSize = 9;\n const emptyTile: EmptyTile = { type: \"empty\", crowns: 0 };\n\n return Array.from({ length: gridSize }, () =>\n Array.from({ length: gridSize }, () => emptyTile)\n );\n};\n\nconst createKingdomWithCastle = (): Kingdom => {\n const kingdom = createEmptyKingdom();\n return placeTile(kingdom, { x: 4, y: 4 }, { type: \"castle\", crowns: 0 });\n};\n\nconst placeTile = (\n kingdom: Kingdom,\n position: Position,\n tile: Tile\n): Kingdom => {\n const newRow = [...kingdom[position.y]!];\n newRow[position.x] = tile;\n return [\n ...kingdom.slice(0, position.y),\n newRow,\n ...kingdom.slice(position.y + 1),\n ];\n};\n\nconst getTile = (grid: Kingdom, position: Position): Tile | EmptyTile => {\n const tile = grid[position.y]?.[position.x];\n if (tile === undefined) {\n throw new Error(\"Invalid placement (not fit into the grid)\");\n }\n return tile;\n};\n\nconst calculateDominoPosition = (\n position: Position,\n orientation: Orientation,\n rotation: Rotation,\n domino: Domino\n): [{ tile: Tile; position: Position }, { tile: Tile; position: Position }] => {\n let firstTile: {\n tile: Tile;\n position: Position;\n };\n let secondTile: {\n tile: Tile;\n position: Position;\n };\n\n if (orientation === \"horizontal\") {\n if (rotation === 0) {\n firstTile = {\n tile: domino.left,\n position: {\n x: position.x,\n y: position.y,\n },\n };\n secondTile = {\n tile: domino.right,\n position: {\n x: position.x + 1,\n y: position.y,\n },\n };\n } else {\n firstTile = {\n tile: domino.right,\n position: {\n x: position.x,\n y: position.y,\n },\n };\n secondTile = {\n tile: domino.left,\n position: {\n x: position.x + 1,\n y: position.y,\n },\n };\n }\n } else {\n if (rotation === 0) {\n firstTile = {\n tile: domino.left,\n position: {\n x: position.x,\n y: position.y,\n },\n };\n secondTile = {\n tile: domino.right,\n position: {\n x: position.x,\n y: position.y + 1,\n },\n };\n } else {\n firstTile = {\n tile: domino.right,\n position: {\n x: position.x,\n y: position.y,\n },\n };\n secondTile = {\n tile: domino.left,\n position: {\n x: position.x,\n y: position.y + 1,\n },\n };\n }\n }\n\n return [firstTile, secondTile];\n};\n\nconst placeDomino = (\n kingdom: Kingdom,\n position: Position,\n orientation: \"vertical\" | \"horizontal\",\n rotation: 0 | 180,\n domino: Domino\n): Kingdom => {\n const [firstTile, secondTile] = calculateDominoPosition(\n position,\n orientation,\n rotation,\n domino\n );\n\n if (!isFreePlace(kingdom, firstTile.position, secondTile.position)) {\n throw new Error(\"Invalid placement (not free place)\");\n }\n\n if (!isFitIntoTheGrid(kingdom, [firstTile, secondTile])) {\n throw new Error(\"Invalid placement (not fit into the grid)\");\n }\n\n const adjacentTiles = isAdjacent(\n kingdom,\n firstTile.position,\n secondTile.position\n );\n\n if (adjacentTiles.length === 0) {\n throw new Error(\"Invalid placement (no adjacent)\");\n }\n\n const hasValidAdjacentTiles = hasValidAdjacent(adjacentTiles, [\n firstTile.tile,\n secondTile.tile,\n ]);\n\n if (!hasValidAdjacentTiles) {\n throw new Error(\"Invalid placement (no valid adjacent)\");\n }\n\n return placeTiles(kingdom, [firstTile, secondTile]);\n};\n\nconst placeTiles = (\n kingdom: Kingdom,\n tiles: { tile: Tile; position: Position }[]\n): Kingdom => {\n return tiles.reduce(\n (newKingdom, { tile, position }) => placeTile(newKingdom, position, tile),\n kingdom\n );\n};\n\nconst isFreePlace = (\n kingdom: Kingdom,\n firstPosition: Position,\n secondPosition: Position\n): boolean => {\n const firstTile = getTile(kingdom, firstPosition);\n const secondTile = getTile(kingdom, secondPosition);\n\n if (firstTile.type !== \"empty\" || secondTile.type !== \"empty\") {\n return false;\n }\n\n return true;\n};\n\nconst isAdjacent = (\n kingdom: Kingdom,\n firstPosition: Position,\n secondPosition: Position\n): (Tile | EmptyTile)[] => {\n const xFirstPosition = firstPosition.x;\n const yFirstPosition = firstPosition.y;\n const xSecondPosition = secondPosition.x;\n const ySecondPosition = secondPosition.y;\n\n const adjacentTiles: (Tile | EmptyTile)[] = [];\n const adjacentTilesKeys = [\n { x: xFirstPosition - 1, y: yFirstPosition },\n { x: xFirstPosition, y: yFirstPosition - 1 },\n { x: xFirstPosition + 1, y: yFirstPosition },\n { x: xFirstPosition, y: yFirstPosition + 1 },\n { x: xSecondPosition - 1, y: ySecondPosition },\n { x: xSecondPosition, y: ySecondPosition - 1 },\n { x: xSecondPosition + 1, y: ySecondPosition },\n { x: xSecondPosition, y: ySecondPosition + 1 },\n ];\n\n // Remove firstPosition and secondPosition from adjacentTilesKeys\n adjacentTilesKeys.splice(\n adjacentTilesKeys.findIndex((pos) => {\n return pos.x === xFirstPosition && pos.y === yFirstPosition;\n }),\n 1\n );\n\n adjacentTilesKeys.splice(\n adjacentTilesKeys.findIndex((pos) => {\n return pos.x === xSecondPosition && pos.y === ySecondPosition;\n }),\n 1\n );\n\n adjacentTilesKeys.forEach((key) => {\n const tile = getTile(kingdom, key);\n if (tile) {\n adjacentTiles.push(tile);\n }\n });\n\n return adjacentTiles;\n};\n\nconst hasValidAdjacent = (\n adjacentTiles: (Tile | EmptyTile)[],\n tiles: Tile[]\n): boolean => {\n return adjacentTiles.some((adjacentTile) => {\n return tiles.some((tile) => {\n return tile.type === adjacentTile.type || adjacentTile.type === \"castle\";\n });\n });\n};\n\nconst isFitIntoTheGrid = (\n grid: Kingdom,\n positions: {\n tile: Tile;\n position: Position;\n }[]\n): boolean => {\n const maxSize = 5;\n\n const simulateNewGrid = [...grid];\n\n simulateNewGrid[positions[0]!.position.y]![positions[0]!.position.x] =\n positions[0]!.tile;\n simulateNewGrid[positions[1]!.position.y]![positions[1]!.position.x] =\n positions[1]!.tile;\n\n const lines = simulateNewGrid.map((line) =>\n line.filter((tile) => tile.type !== \"empty\")\n );\n const columns = simulateNewGrid[0]!.map((_, index) =>\n simulateNewGrid\n .map((line) => line[index])\n .filter((tile) => tile?.type !== \"empty\")\n );\n\n const linesLength = lines.map((line) => line.length);\n const columnsLength = columns.map((line) => line.length);\n\n const maxLineLength = Math.max(...linesLength);\n const maxColumnLength = Math.max(...columnsLength);\n\n if (maxLineLength > maxSize || maxColumnLength > maxSize) {\n return false;\n }\n\n return true;\n};\n\nconst kingdom = {\n createEmptyKingdom,\n createKingdomWithCastle,\n getTile,\n placeDomino,\n};\n\nexport default kingdom;\n","import type { Game } from \"../entities/game.js\";\nimport type { Lord } from \"../entities/lord.js\";\nimport type { Player } from \"../entities/player.js\";\nimport kingdom from \"../entities/kingdom.js\";\nimport { type GameDependencies, rules } from \"./game.js\";\n\ntype SetupPayload = {\n state: Game;\n players: { name: string }[];\n};\n\nconst setup =\n (dependencies: GameDependencies) =>\n (payload: SetupPayload): Game => {\n const { state, players } = payload;\n\n if (!players) {\n throw new Error(\"There must be at least 2 players\");\n }\n\n if (players.length > 4) {\n throw new Error(\"There must be no more than 4 players\");\n }\n\n if (players.length < 2) {\n throw new Error(\"There must be at least 2 players\");\n }\n\n const { dominoes } = state;\n const { shuffleMethod, uuidMethod } = dependencies;\n const { maxDominoes, dominoesPerTurn, maxTurns } = rules[players.length]!;\n const shuffledDominoes = shuffleMethod(dominoes);\n shuffledDominoes.splice(maxDominoes);\n\n const newPlayers: Player[] = players.map((player) => {\n return {\n ...player,\n kingdom: kingdom.createKingdomWithCastle(),\n id: uuidMethod(),\n };\n });\n\n let newLords: Lord[];\n if (newPlayers.length === 2) {\n newLords = [\n {\n id: uuidMethod(),\n playerId: newPlayers[0]!.id!,\n order: 1,\n turnEnded: false,\n hasPick: false,\n hasPlace: false,\n },\n {\n id: uuidMethod(),\n playerId: newPlayers[0]!.id!,\n order: 2,\n turnEnded: false,\n hasPick: false,\n hasPlace: false,\n },\n {\n id: uuidMethod(),\n playerId: newPlayers[1]!.id!,\n order: 3,\n turnEnded: false,\n hasPick: false,\n hasPlace: false,\n },\n {\n id: uuidMethod(),\n playerId: newPlayers[1]!.id!,\n order: 4,\n turnEnded: false,\n hasPick: false,\n hasPlace: false,\n },\n ];\n } else {\n newLords = newPlayers.map((player, index) => {\n return {\n id: uuidMethod(),\n playerId: player.id!,\n order: index + 1,\n turnEnded: false,\n hasPick: false,\n hasPlace: false,\n };\n });\n }\n\n const lordsWithOrder = shuffleMethod(newLords);\n\n lordsWithOrder.forEach((lord, index) => {\n lord.order = index + 1;\n });\n\n lordsWithOrder.sort((a, b) => a.order - b.order);\n\n const newState = {\n ...state,\n dominoes: shuffledDominoes,\n players: newPlayers,\n lords: lordsWithOrder,\n maxTurns,\n maxDominoes,\n dominoesPerTurn,\n turn: 0,\n };\n\n return newState;\n };\n\nexport { setup };\n","import type { Game } from \"../entities/game.js\";\n\ntype StartTurnPayload = {\n state: Game;\n};\n\nconst startTurn = (payload: StartTurnPayload): { game: Game } => {\n const { state } = payload;\n\n const turn = state.turn + 1;\n const lords = state.lords;\n\n lords.forEach((lord) => {\n lord.turnEnded = false;\n lord.hasPick = false;\n lord.hasPlace = false;\n });\n\n const updatedState = {\n ...state,\n lords,\n turn,\n };\n\n return { game: updatedState };\n};\n\nexport { startTurn };\n","import type { Game } from \"../entities/game.js\";\nimport type { RevealsDomino } from \"../entities/domino.js\";\nimport {\n type PlayerActionPayload,\n type CustomError,\n checkValidityDomino,\n isLordTurn,\n} from \"./game.js\";\n\nconst pick = (payload: PlayerActionPayload<\"pick\">): Game => {\n const { lordId, data } = payload;\n const { state, dominoPick } = data;\n const { currentDominoes, lords } = state;\n\n // Check if it is the lord's turn\n if (!isLordTurn(state, lordId)) {\n throw new Error(\"It is not your turn\");\n }\n\n // Check if lord has already picked\n const lord = lords.find((lord) => lord.id === lordId);\n if (lord?.hasPick) {\n throw new Error(\"You have already picked\");\n }\n\n // Check if dominoPick is valid choice\n const domino = checkValidityDomino(state, dominoPick);\n\n // typeguard to check if domino is a CustomError\n const isError = (\n domino: CustomError | RevealsDomino\n ): domino is CustomError => {\n return (domino as CustomError).error !== undefined;\n };\n\n if (isError(domino)) {\n throw new Error(domino.error);\n }\n\n // update currentDominoes\n const updatedCurrentDominoes = currentDominoes.map((domino) => {\n if (domino.domino.number === dominoPick) {\n domino.picked = true;\n domino.lordId = lordId;\n }\n\n return domino;\n });\n\n // update lords\n const updatedLords = lords.map((lord) => {\n if (lord.id === lordId) {\n lord.hasPick = true;\n lord.turnEnded = true;\n lord.dominoPicked = domino.domino;\n }\n\n return lord;\n });\n\n // update state\n const updatedState = {\n ...state,\n currentDominoes: updatedCurrentDominoes,\n lords: updatedLords,\n };\n\n return updatedState;\n};\n\nexport { pick };\n","import type { Game } from \"../entities/game.js\";\nimport kingdom from \"../entities/kingdom.js\";\nimport type { PlayerActionPayload } from \"./game.js\";\n\nconst place = (payload: PlayerActionPayload<\"place\">): Game => {\n const { lordId, data } = payload;\n const { state, position, orientation, rotation } = data;\n\n const currentLord = state.lords.find((lord) => lord.id === lordId);\n const currentPlayer = state.players.find(\n (player) => player.id === currentLord?.playerId\n );\n const currentKingdom = currentPlayer?.kingdom;\n\n if (!currentKingdom) {\n throw new Error(\"Kingdom not found\");\n }\n\n const domino = currentLord?.dominoPicked;\n\n if (!domino) {\n throw new Error(\"Domino not found\");\n }\n\n kingdom.placeDomino(currentKingdom, position, orientation, rotation, domino);\n\n currentPlayer.kingdom = currentKingdom;\n currentLord.hasPlace = true;\n\n const newState = {\n ...state,\n lords: state.lords.map((lord) => {\n if (lord.id === lordId) {\n return currentLord;\n }\n\n return lord;\n }),\n };\n\n return newState;\n};\n\nexport { place };\n","import type { Game } from \"../entities/game.js\";\n\ntype DefinePlayerOrderPayload = {\n state: Game;\n};\n\nconst definePlayerOrder = (payload: DefinePlayerOrderPayload): Game => {\n const { state } = payload;\n const { lords, currentDominoes } = state;\n\n const allLordsHavePlayed = lords.every((lord) => lord.turnEnded);\n\n if (!allLordsHavePlayed) {\n throw new Error(\"Not all lords have played\");\n }\n\n const updatedLords = lords.map((lord) => {\n return {\n ...lord,\n order:\n currentDominoes.find((domino) => domino.lordId === lord.id)?.position ||\n 0,\n };\n });\n\n const order = updatedLords.reduce((acc, lord) => {\n return {\n ...acc,\n [lord.order!]: lord.id,\n };\n }, {});\n\n const newState = {\n ...state,\n lords: updatedLords,\n order,\n };\n\n return newState;\n};\n\nexport { definePlayerOrder };\n","import type { Game } from \"../entities/game.js\";\n\ntype DrawPayload = {\n state: Game;\n};\n\nconst draw = (payload: DrawPayload): Game => {\n const { state } = payload;\n\n const dominoesCopy = [...state.dominoes];\n const dominoesDrawn = dominoesCopy.splice(0, state.dominoesPerTurn);\n dominoesDrawn.sort((a, b) => a.number - b.number);\n\n const newState = {\n ...state,\n dominoes: dominoesCopy,\n currentDominoes: dominoesDrawn.map((domino, index) => {\n return {\n domino,\n picked: false,\n lordId: null,\n position: index + 1,\n };\n }),\n };\n\n return newState;\n};\n\nexport { draw };\n","import type { Kingdom } from \"../entities/kingdom.js\";\n\ntype Property = {\n type: string;\n crowns: number;\n size: number;\n tiles: number[][];\n};\n\nexport type Score = {\n score: number;\n maxPropertiesSize: number;\n totalCrowns: number;\n};\n\nconst calculateScore = (kingdom: Kingdom): Score => {\n const visited: boolean[][] = kingdom.map((row) => row.map(() => false));\n const properties: Property[] = [];\n\n const directions = [\n [-1, 0],\n [1, 0],\n [0, -1],\n [0, 1],\n ]; // Up, Down, Left, Right\n\n const markZone = (\n x: number,\n y: number,\n type: string,\n crowns: number\n ): void => {\n if (\n x < 0 ||\n y < 0 ||\n x >= kingdom[0]!.length ||\n y >= kingdom.length ||\n visited[y]![x] ||\n kingdom[y]![x]!.type !== type ||\n kingdom[y]![x]!.type === \"empty\" ||\n kingdom[y]![x]!.type === \"castle\"\n ) {\n return;\n }\n\n visited[y]![x] = true;\n const currentZone = properties.find(\n (property) =>\n property.type === type &&\n property.tiles.some(([tx, ty]) => {\n for (let [dx, dy] of directions) {\n if (\n (tx as number) + (dx as number) === x &&\n (ty as number) + (dy as number) === y\n ) {\n return true;\n }\n }\n return false;\n })\n );\n\n if (currentZone) {\n currentZone.crowns += crowns;\n currentZone.size++;\n currentZone.tiles.push([x, y]);\n } else {\n properties.push({ type, crowns, size: 1, tiles: [[x, y]] });\n }\n\n directions.forEach(([dx, dy]) => {\n const nx = x + (dx as number);\n const ny = y + (dy as number);\n if (\n nx >= 0 &&\n ny >= 0 &&\n nx < kingdom[0]!.length &&\n ny < kingdom.length &&\n kingdom[ny]![nx]!.type === type\n ) {\n markZone(nx, ny, kingdom[ny]![nx]!.type, kingdom[ny]![nx]!.crowns);\n }\n });\n };\n\n kingdom.forEach((row, y) => {\n row.forEach((tile, x) => {\n if (!visited[y]![x]) {\n markZone(x, y, tile.type, tile.crowns);\n }\n });\n });\n\n if (properties.length === 0) {\n return {\n score: 0,\n maxPropertiesSize: 0,\n totalCrowns: 0,\n };\n }\n\n const score = properties.reduce(\n (score, property) => score + property.crowns * property.size,\n 0\n );\n const maxPropertiesSize = Math.max(\n ...properties.map((property) => property.size ?? 0)\n );\n\n const totalCrowns = properties.reduce(\n (total, property) => total + property.crowns,\n 0\n );\n\n return {\n score,\n maxPropertiesSize,\n totalCrowns,\n };\n};\n\nexport { calculateScore };\n","import type { Game } from \"../entities/game.js\";\nimport type { PlayerActionPayload } from \"./game.js\";\n\nconst pass = (payload: PlayerActionPayload<\"pass\">): Game => {\n const { lordId, data } = payload;\n const { state } = data;\n\n const currentLord = state.lords.find((lord) => lord.id === lordId);\n\n if (!currentLord) {\n throw new Error(\"Lord not found\");\n }\n\n currentLord.hasPlace = true;\n\n const newState = {\n ...state,\n lords: state.lords.map((lord) => {\n if (lord.id === lordId) {\n return currentLord;\n }\n\n return lord;\n }),\n };\n\n return newState;\n};\n\nexport { pass };\n","import type { DominoesRepository } from \"../../ports/driven/dominoesRepository.js\";\nimport type { Position } from \"../entities/kingdom.js\";\nimport type { Game } from \"../entities/game.js\";\nimport { init } from \"./init.js\";\nimport { setup } from \"./setup.js\";\nimport { startTurn } from \"./startTurn.js\";\nimport { pick } from \"./pick.js\";\nimport { place } from \"./place.js\";\nimport { definePlayerOrder } from \"./order.js\";\nimport { draw } from \"./draw.js\";\nimport { calculateScore } from \"./scoring.js\";\nimport { pass } from \"./pass.js\";\nimport type { UuidMethod } from \"../../ports/driven/uuidMethod.js\";\nimport type { ShuffleMethod } from \"../../ports/driven/shuffleMethod.js\";\n\nexport type GameDependencies = {\n dominoesRepository: DominoesRepository;\n uuidMethod: UuidMethod;\n shuffleMethod: ShuffleMethod;\n};\n\nexport const playerAction = {\n pick: \"pick\",\n place: \"place\",\n pass: \"pass\",\n} as const;\n\ntype ObjectValues<T> = T[keyof T];\n\nexport type PlayerAction = ObjectValues<typeof playerAction>;\n\ntype PickData = {\n state: Game;\n dominoPick: number;\n};\n\ntype PlaceData = {\n state: Game;\n position: Position;\n orientation: \"vertical\" | \"horizontal\";\n rotation: 0 | 180;\n};\n\ntype PassData = {\n state: Game;\n};\n\ntype ActionToDataMap = {\n pick: PickData;\n place: PlaceData;\n pass: PassData;\n};\n\nexport type PlayerActionPayload<T extends PlayerAction> = {\n lordId: string;\n action: T;\n data: ActionToDataMap[T];\n};\n\nconst gameStep = (dependencies: GameDependencies) => {\n return {\n init: init(dependencies),\n setup: setup(dependencies),\n startTurn,\n pick,\n place,\n pass,\n definePlayerOrder,\n draw,\n calculateScore,\n };\n};\n\nexport const isLordTurn = (state: Game, lordId: string): boolean => {\n const { lords, currentDominoes } = state;\n const currentLordOrder = lords.find((lord) => lord.id === lordId)?.order;\n\n const pickedDominoes = currentDominoes.filter(\n (currentDomino) => currentDomino.picked\n );\n\n if (currentLordOrder !== pickedDominoes.length + 1) {\n return false;\n }\n\n return true;\n};\n\nexport type CustomError = {\n error: string;\n};\n\nexport const checkValidityDomino = (state: Game, dominoPick: number) => {\n const { currentDominoes } = state;\n const domino = currentDominoes.find(\n (currentDomino) => currentDomino.domino.number === dominoPick\n );\n\n if (!domino) {\n const error: CustomError = {\n error: \"Domino not found\",\n };\n\n return error;\n }\n\n if (domino.picked) {\n const error: CustomError = {\n error: \"Domino already picked\",\n };\n return error;\n }\n\n return domino;\n};\n\n// 2 players => 24 dominoes, 2 lords, 4 dominoes per turn, 6 turns\n// 3 players => 36 dominoes, 1 lord, 3 dominoes per turn, 12 turns\n// 4 players => 48 dominoes, 1 lord, 4 dominoes per turn, 12 turns\nexport const rules: {\n [key: number]: {\n lords: number;\n maxDominoes: number;\n dominoesPerTurn: number;\n maxTurns: number;\n };\n} = {\n 2: {\n lords: 2,\n maxDominoes: 24,\n dominoesPerTurn: 4,\n maxTurns: 6,\n },\n 3: {\n lords: 1,\n maxDominoes: 36,\n dominoesPerTurn: 3,\n maxTurns: 12,\n },\n 4: {\n lords: 1,\n maxDominoes: 48,\n dominoesPerTurn: 4,\n maxTurns: 12,\n },\n};\n\nexport default gameStep;\n","import type { Score } from \"./scoring.js\";\n\nexport type ScoreResult = {\n playerId: string;\n playerName: string;\n details: Score;\n};\n\nexport type FinalResult = ScoreResult & {\n position: number;\n};\n\nconst result = (scores: ScoreResult[]): FinalResult[] => {\n // 1 order players by score, then by maxPropertiesSize, then by totalCrowns all descending\n scores.sort((a, b) => {\n if (a.details.score !== b.details.score) {\n return b.details.score - a.details.score;\n }\n if (a.details.maxPropertiesSize !== b.details.maxPropertiesSize) {\n return b.details.maxPropertiesSize - a.details.maxPropertiesSize;\n }\n return b.details.totalCrowns - a.details.totalCrowns;\n });\n\n const result: FinalResult[] = [];\n let isTie = false;\n result.push({\n ...scores[0]!,\n position: 1,\n });\n\n for (let i = 1; i < scores.length; i++) {\n const currentScore = scores[i];\n const previousScore = scores[i - 1];\n if (\n previousScore &&\n currentScore &&\n currentScore.details.score === previousScore.details.score &&\n currentScore.details.maxPropertiesSize ===\n previousScore.details.maxPropertiesSize &&\n currentScore.details.totalCrowns === previousScore.details.totalCrowns\n ) {\n isTie = true;\n }\n\n if (isTie) {\n result.push({\n ...currentScore!,\n position: result[i - 1]!.position,\n });\n } else {\n result.push({\n ...currentScore!,\n position: i + 1,\n });\n }\n\n isTie = false;\n }\n\n return result;\n};\n\nexport { result };\n","export const availableMode = [\"Classic\"] as const;\n\nexport type AvailableMode = (typeof availableMode)[number];\n\nexport const isValidMode = (mode: string): mode is AvailableMode => {\n return availableMode.includes(mode as AvailableMode);\n};\n","import type { UuidMethod } from \"../../hexagon/ports/driven/uuidMethod.js\";\nimport { randomUUID } from \"crypto\";\n\nexport const uuidMethod: UuidMethod = () => {\n return randomUUID();\n};\n","import type { ShuffleMethod } from \"../../hexagon/ports/driven/shuffleMethod\";\n\nexport const shuffleMethod: ShuffleMethod = <T>(array: T[]) => {\n for (let i = array.length - 1; i > 0; i--) {\n const j = Math.floor(Math.random() * (i + 1));\n [array[i], array[j]] = [array[j] as T, array[i] as T];\n }\n return array;\n};\n","import gameEngine from \"./adapters/driver/index.js\";\n\nexport default gameEngine;\n"],"mappings":"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","names":["kingdom","shuffleMethod","uuidMethod","lord","domino","kingdom","score","result","init","setup","startTurn","pick","place","pass","definePlayerOrder","draw","calculateScore","rules","placeDomino","nextLord"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pompidup/kingdomino-engine",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.1.1",
|
|
4
4
|
"description": "A simple engine for the game Kingdomino",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -35,11 +35,11 @@
|
|
|
35
35
|
},
|
|
36
36
|
"homepage": "https://github.com/Pompidup/KDomino#readme",
|
|
37
37
|
"devDependencies": {
|
|
38
|
-
"@types/node": "^20.
|
|
39
|
-
"@vitest/coverage-v8": "^1.
|
|
38
|
+
"@types/node": "^20.12.6",
|
|
39
|
+
"@vitest/coverage-v8": "^1.4.0",
|
|
40
40
|
"ts-node": "^10.9.2",
|
|
41
41
|
"tsup": "^8.0.2",
|
|
42
|
-
"typescript": "^5.
|
|
43
|
-
"vitest": "^1.
|
|
42
|
+
"typescript": "^5.4.4",
|
|
43
|
+
"vitest": "^1.4.0"
|
|
44
44
|
}
|
|
45
45
|
}
|