@pompidup/kingdomino-engine 2.0.1 → 2.0.5

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/dist/index.js CHANGED
@@ -658,6 +658,61 @@ var jsonRules = () => {
658
658
  };
659
659
  var jsonRules_default = jsonRules;
660
660
 
661
+ // src/adapterServerside/shuffle.ts
662
+ var shuffleMethod = (array) => {
663
+ for (let i = array.length - 1; i > 0; i--) {
664
+ const j = Math.floor(Math.random() * (i + 1));
665
+ [array[i], array[j]] = [array[j], array[i]];
666
+ }
667
+ return array;
668
+ };
669
+
670
+ // src/adapterServerside/uuid.ts
671
+ import { randomUUID } from "crypto";
672
+ var uuidMethod = () => {
673
+ return randomUUID();
674
+ };
675
+
676
+ // src/core/domain/errors/domainErrors.ts
677
+ var InvalidStepError = class extends Error {
678
+ constructor(message) {
679
+ super(message);
680
+ this.name = "InvalidStepError";
681
+ }
682
+ };
683
+ var StepExecutionError = class extends Error {
684
+ constructor(message) {
685
+ super(message);
686
+ this.name = "StepExecutionError";
687
+ }
688
+ };
689
+ var ActionExecutionError = class extends Error {
690
+ constructor(message) {
691
+ super(message);
692
+ this.name = "ActionExecutionError";
693
+ }
694
+ };
695
+ var NotFoundError = class extends Error {
696
+ constructor(message) {
697
+ super(message);
698
+ this.name = "NotFoundError";
699
+ }
700
+ };
701
+
702
+ // src/core/domain/types/game.ts
703
+ var gameSteps = {
704
+ addPlayers: "addPlayers",
705
+ options: "options",
706
+ start: "start",
707
+ result: "result"
708
+ };
709
+ var isGameWithNextAction = (game) => {
710
+ return game.nextAction.type === "action";
711
+ };
712
+ var isGameWithNextStep = (game) => {
713
+ return game.nextAction.type === "step";
714
+ };
715
+
661
716
  // src/utils/result.ts
662
717
  var ok = (value) => ({ tag: "Ok", value });
663
718
  var err = (error) => ({ tag: "Err", error });
@@ -667,12 +722,15 @@ var isErr = (result) => result.tag === "Err";
667
722
  // src/application/handlers/addExtraRulesHandler.ts
668
723
  var addExtraRulesHandler = (useCase) => (command) => {
669
724
  const { game, extraRules } = command;
725
+ if (!isGameWithNextStep(game)) {
726
+ throw new InvalidStepError("Required game with nextAction type: 'step'");
727
+ }
670
728
  if (game.nextAction.step !== "options") {
671
- throw new Error("Invalid next action");
729
+ throw new InvalidStepError("Required game with options step");
672
730
  }
673
731
  const result = useCase(game, extraRules);
674
732
  if (isErr(result)) {
675
- throw new Error(result.error);
733
+ throw new StepExecutionError(result.error);
676
734
  }
677
735
  return result.value;
678
736
  };
@@ -680,12 +738,15 @@ var addExtraRulesHandler = (useCase) => (command) => {
680
738
  // src/application/handlers/addPlayersHandler.ts
681
739
  var addPlayersHandler = (useCase) => (command) => {
682
740
  const { game, players } = command;
741
+ if (!isGameWithNextStep(game)) {
742
+ throw new InvalidStepError("Required game with nextAction type: 'step'");
743
+ }
683
744
  if (game.nextAction.step !== "addPlayers") {
684
- throw new Error("Invalid next action");
745
+ throw new InvalidStepError("Required game with addPlayers step");
685
746
  }
686
747
  const result = useCase(game, players);
687
748
  if (isErr(result)) {
688
- throw new Error(result.error);
749
+ throw new StepExecutionError(result.error);
689
750
  }
690
751
  return result.value;
691
752
  };
@@ -693,12 +754,17 @@ var addPlayersHandler = (useCase) => (command) => {
693
754
  // src/application/handlers/chooseDominoHandler.ts
694
755
  var chooseDominoHandler = (useCase) => (command) => {
695
756
  const { game, lordId, dominoPick } = command;
757
+ if (!isGameWithNextAction(game)) {
758
+ throw new InvalidStepError(
759
+ "Required game with nextAction type: 'action'"
760
+ );
761
+ }
696
762
  if (game.nextAction.nextAction !== "pickDomino") {
697
- throw new Error("Invalid next action");
763
+ throw new InvalidStepError("Required game with pickDomino action");
698
764
  }
699
765
  const result = useCase(game, lordId, dominoPick);
700
766
  if (isErr(result)) {
701
- throw new Error(result.error);
767
+ throw new ActionExecutionError(result.error);
702
768
  }
703
769
  return result.value;
704
770
  };
@@ -707,31 +773,25 @@ var chooseDominoHandler = (useCase) => (command) => {
707
773
  var createGameHandler = (useCase) => (command) => {
708
774
  const result = useCase(command.mode);
709
775
  if (isErr(result)) {
710
- throw new Error(result.error);
776
+ throw new StepExecutionError(result.error);
711
777
  }
712
778
  return result.value;
713
779
  };
714
780
 
715
- // src/core/domain/types/game.ts
716
- var gameSteps = {
717
- addPlayers: "addPlayers",
718
- options: "options",
719
- start: "start",
720
- result: "result"
721
- };
722
- var isGameWithNextAction = (game) => {
723
- return game.nextAction.type === "action";
724
- };
725
-
726
781
  // src/application/handlers/discardDominoHandler.ts
727
782
  var discardDominoHandler = (useCase) => (command) => {
728
783
  const { game, lordId } = command;
784
+ if (!isGameWithNextAction(game)) {
785
+ throw new InvalidStepError(
786
+ "Required game with nextAction type: 'action'"
787
+ );
788
+ }
729
789
  if (game.nextAction.nextAction !== "placeDomino") {
730
- throw new Error("Invalid next action");
790
+ throw new InvalidStepError("Required game with placeDomino action");
731
791
  }
732
792
  const result = useCase(game, lordId);
733
793
  if (isErr(result)) {
734
- throw new Error(result.error);
794
+ throw new ActionExecutionError(result.error);
735
795
  }
736
796
  if (isGameWithNextAction(result.value)) {
737
797
  return result.value;
@@ -744,7 +804,7 @@ var getExtraRulesHandler = (getExtraRulesUseCase2) => (command) => {
744
804
  const { mode, players } = command;
745
805
  const result = getExtraRulesUseCase2(mode, players);
746
806
  if (isErr(result)) {
747
- throw new Error(result.error);
807
+ throw new NotFoundError(result.error);
748
808
  }
749
809
  return result.value;
750
810
  };
@@ -753,7 +813,7 @@ var getExtraRulesHandler = (getExtraRulesUseCase2) => (command) => {
753
813
  var getModesHandler = (getModeUseCase) => (_command) => {
754
814
  const result = getModeUseCase();
755
815
  if (isErr(result)) {
756
- throw new Error(result.error);
816
+ throw new NotFoundError(result.error);
757
817
  }
758
818
  return result.value;
759
819
  };
@@ -761,12 +821,15 @@ var getModesHandler = (getModeUseCase) => (_command) => {
761
821
  // src/application/handlers/getResultHandler.ts
762
822
  var getResultHandler = (useCase) => (command) => {
763
823
  const { game } = command;
824
+ if (!isGameWithNextStep(game)) {
825
+ throw new InvalidStepError("Required game with nextAction type: 'step'");
826
+ }
764
827
  if (game.nextAction.step !== "result") {
765
- throw new Error("Invalid next step");
828
+ throw new InvalidStepError("Required game with result step");
766
829
  }
767
830
  const result = useCase(game);
768
831
  if (isErr(result)) {
769
- throw new Error(result.error);
832
+ throw new NotFoundError(result.error);
770
833
  }
771
834
  return result.value;
772
835
  };
@@ -774,12 +837,17 @@ var getResultHandler = (useCase) => (command) => {
774
837
  // src/application/handlers/placeDominoHandler.ts
775
838
  var placeDominoHandler = (useCase) => (command) => {
776
839
  const { game, lordId, position, orientation, rotation } = command;
840
+ if (!isGameWithNextAction(game)) {
841
+ throw new InvalidStepError(
842
+ "Required game with nextAction type: 'action'"
843
+ );
844
+ }
777
845
  if (game.nextAction.nextAction !== "placeDomino") {
778
- throw new Error("Invalid next action");
846
+ throw new InvalidStepError("Required game with placeDomino step");
779
847
  }
780
848
  const result = useCase(game, lordId, position, orientation, rotation);
781
849
  if (isErr(result)) {
782
- throw new Error(result.error);
850
+ throw new ActionExecutionError(result.error);
783
851
  }
784
852
  if (isGameWithNextAction(result.value)) {
785
853
  return result.value;
@@ -790,12 +858,17 @@ var placeDominoHandler = (useCase) => (command) => {
790
858
  // src/application/handlers/startGameHandler.ts
791
859
  var startGameHandler = (useCase) => (command) => {
792
860
  const { game } = command;
793
- if (game.nextAction.step !== "start") {
794
- throw new Error("Invalid next action");
861
+ if (!isGameWithNextStep(game)) {
862
+ throw new InvalidStepError("Required game with nextAction type: 'step'");
863
+ }
864
+ if (game.nextAction.step !== "start" && game.nextAction.step !== "options") {
865
+ throw new InvalidStepError(
866
+ "Required game with start step or options step"
867
+ );
795
868
  }
796
869
  const result = useCase(game);
797
870
  if (isErr(result)) {
798
- throw new Error(result.error);
871
+ throw new StepExecutionError(result.error);
799
872
  }
800
873
  return result.value;
801
874
  };
@@ -867,26 +940,6 @@ var addExtraRulesUseCase = (deps) => (game, rules) => {
867
940
  return ok(updatedGame);
868
941
  };
869
942
 
870
- // src/core/domain/entities/player.ts
871
- var MINPLAYERSNAMELENGTH = 3;
872
- var validatePlayer = (name) => {
873
- if (!name || name.trim().length < MINPLAYERSNAMELENGTH) {
874
- return err(`Invalid player name: ${name}`);
875
- }
876
- return ok(name);
877
- };
878
- var createPlayer = (playerName, id, kingdom) => {
879
- const name = validatePlayer(playerName);
880
- if (isErr(name)) {
881
- return name;
882
- }
883
- return ok({
884
- name: name.value,
885
- id,
886
- kingdom
887
- });
888
- };
889
-
890
943
  // src/core/domain/entities/domino.ts
891
944
  var isGround = (ground) => {
892
945
  return GROUND.includes(ground);
@@ -1120,6 +1173,26 @@ var deepCopyKingdom = (kingdom) => {
1120
1173
  return kingdom.map((line) => line.map((tile) => ({ ...tile })));
1121
1174
  };
1122
1175
 
1176
+ // src/core/domain/entities/player.ts
1177
+ var MINPLAYERSNAMELENGTH = 3;
1178
+ var validatePlayer = (name) => {
1179
+ if (!name || name.trim().length < MINPLAYERSNAMELENGTH) {
1180
+ return err(`Invalid player name: ${name}`);
1181
+ }
1182
+ return ok(name);
1183
+ };
1184
+ var createPlayer = (playerName, id, kingdom) => {
1185
+ const name = validatePlayer(playerName);
1186
+ if (isErr(name)) {
1187
+ return name;
1188
+ }
1189
+ return ok({
1190
+ name: name.value,
1191
+ id,
1192
+ kingdom
1193
+ });
1194
+ };
1195
+
1123
1196
  // src/core/useCases/addPlayers.ts
1124
1197
  var addPlayersUseCase = (deps) => (game, players) => {
1125
1198
  const { uuidMethod: uuidMethod2, shuffleMethod: shuffleMethod2, ruleRepository } = deps;
@@ -1186,8 +1259,8 @@ var canPlaceAndDominoPickedIsDefined = (lord) => {
1186
1259
  return !hasPick(lord) && !hasPlace(lord) && !hasTurnEnded(lord) && lord.dominoPicked !== void 0;
1187
1260
  };
1188
1261
  var updateLordOrder = (lords) => {
1189
- return lords.sort((a2, b2) => {
1190
- return a2.dominoPicked.number - b2.dominoPicked.number;
1262
+ return lords.sort((a, b) => {
1263
+ return a.dominoPicked.number - b.dominoPicked.number;
1191
1264
  });
1192
1265
  };
1193
1266
  var resetLordsActions = (lord) => {
@@ -1266,7 +1339,7 @@ var chooseDominoUseCase = (game, lordId, dominoPick) => {
1266
1339
  0,
1267
1340
  game.rules.basic.dominoesPerTurn
1268
1341
  );
1269
- dominoesDrawn.sort((a2, b2) => a2.number - b2.number);
1342
+ dominoesDrawn.sort((a, b) => a.number - b.number);
1270
1343
  const updatedCurrentDominoes2 = dominoesDrawn.map((domino, index) => {
1271
1344
  return {
1272
1345
  domino,
@@ -1533,14 +1606,14 @@ var getResultUseCase = (game) => {
1533
1606
  }
1534
1607
  };
1535
1608
  });
1536
- scores.sort((a2, b2) => {
1537
- if (a2.details.points !== b2.details.points) {
1538
- return b2.details.points - a2.details.points;
1609
+ scores.sort((a, b) => {
1610
+ if (a.details.points !== b.details.points) {
1611
+ return b.details.points - a.details.points;
1539
1612
  }
1540
- if (a2.details.maxPropertiesSize !== b2.details.maxPropertiesSize) {
1541
- return b2.details.maxPropertiesSize - a2.details.maxPropertiesSize;
1613
+ if (a.details.maxPropertiesSize !== b.details.maxPropertiesSize) {
1614
+ return b.details.maxPropertiesSize - a.details.maxPropertiesSize;
1542
1615
  }
1543
- return b2.details.totalCrowns - a2.details.totalCrowns;
1616
+ return b.details.totalCrowns - a.details.totalCrowns;
1544
1617
  });
1545
1618
  const result = [];
1546
1619
  let isTie = false;
@@ -1550,21 +1623,21 @@ var getResultUseCase = (game) => {
1550
1623
  details: scores[0].details,
1551
1624
  position: 1
1552
1625
  });
1553
- for (let i2 = 1; i2 < scores.length; i2++) {
1554
- const currentScore = scores[i2];
1555
- const previousScore = scores[i2 - 1];
1626
+ for (let i = 1; i < scores.length; i++) {
1627
+ const currentScore = scores[i];
1628
+ const previousScore = scores[i - 1];
1556
1629
  if (previousScore && currentScore && currentScore.details.points === previousScore.details.points && currentScore.details.maxPropertiesSize === previousScore.details.maxPropertiesSize && currentScore.details.totalCrowns === previousScore.details.totalCrowns) {
1557
1630
  isTie = true;
1558
1631
  }
1559
1632
  if (isTie) {
1560
1633
  result.push({
1561
1634
  ...currentScore,
1562
- position: result[i2 - 1].position
1635
+ position: result[i - 1].position
1563
1636
  });
1564
1637
  } else {
1565
1638
  result.push({
1566
1639
  ...currentScore,
1567
- position: i2 + 1
1640
+ position: i + 1
1568
1641
  });
1569
1642
  }
1570
1643
  isTie = false;
@@ -1641,13 +1714,15 @@ var placeDominoUseCase = (game, lordId, position, orientation, rotation) => {
1641
1714
  updatedGame = {
1642
1715
  ...game,
1643
1716
  lords: updatedLords,
1644
- nextAction: resultStep
1717
+ nextAction: resultStep,
1718
+ players: updatedPlayers
1645
1719
  };
1646
1720
  } else {
1647
1721
  updatedGame = {
1648
1722
  ...game,
1649
1723
  lords: updatedLords,
1650
- nextAction: nextLordWithAction(updatedLords)
1724
+ nextAction: nextLordWithAction(updatedLords),
1725
+ players: updatedPlayers
1651
1726
  };
1652
1727
  }
1653
1728
  return ok(updatedGame);
@@ -1665,16 +1740,16 @@ var startGameUseCase = (deps) => (game) => {
1665
1740
  } = game;
1666
1741
  const numberOfPlayers = players.length;
1667
1742
  const newLords = [];
1668
- for (let i2 = 0; i2 < numberOfPlayers; i2++) {
1743
+ for (let i = 0; i < numberOfPlayers; i++) {
1669
1744
  for (let j = 0; j < maxLords; j++) {
1670
- const lord = createLord(uuidMethod2(), players[i2].id);
1745
+ const lord = createLord(uuidMethod2(), players[i].id);
1671
1746
  newLords.push(lord);
1672
1747
  }
1673
1748
  }
1674
1749
  const shuffledLords = shuffleMethod2(newLords);
1675
1750
  const dominoesCopy = [...dominoes];
1676
1751
  const dominoesDrawn = dominoesCopy.splice(0, dominoesPerTurn);
1677
- dominoesDrawn.sort((a2, b2) => a2.number - b2.number);
1752
+ dominoesDrawn.sort((a, b) => a.number - b.number);
1678
1753
  const nextAction = {
1679
1754
  type: "action",
1680
1755
  nextLord: shuffledLords[0].id,
@@ -1697,26 +1772,11 @@ var startGameUseCase = (deps) => (game) => {
1697
1772
  return ok(newState);
1698
1773
  };
1699
1774
 
1700
- // src/adapterServerside/shuffle.ts
1701
- var shuffleMethod = (array) => {
1702
- for (let i2 = array.length - 1; i2 > 0; i2--) {
1703
- const j = Math.floor(Math.random() * (i2 + 1));
1704
- [array[i2], array[j]] = [array[j], array[i2]];
1705
- }
1706
- return array;
1707
- };
1708
-
1709
- // src/adapterServerside/uuid.ts
1710
- import { randomUUID } from "crypto";
1711
- var uuidMethod = () => {
1712
- return randomUUID();
1713
- };
1714
-
1715
1775
  // src/config.ts
1716
1776
  var configureEngine = (config) => {
1717
- const modeRepository = config.modeRepository || jsonModes_default();
1718
- const dominoesRepository = config.dominoesRepository || jsonDominoes_default();
1719
- const ruleRepository = config.ruleRepository || jsonRules_default();
1777
+ const modeRepository = jsonModes_default();
1778
+ const dominoesRepository = jsonDominoes_default();
1779
+ const ruleRepository = jsonRules_default();
1720
1780
  const uuid = config.uuidMethod || uuidMethod;
1721
1781
  const shuffle = config.shuffleMethod || shuffleMethod;
1722
1782
  return {
@@ -1778,36 +1838,6 @@ var createGameEngine = (config) => {
1778
1838
  getResults: (command) => getResultHandler2(command)
1779
1839
  };
1780
1840
  };
1781
- var engine = createGameEngine({});
1782
- var a = engine.createGame({ mode: "standard" });
1783
- var b = engine.getModes({});
1784
- var c = engine.getExtraRules({ mode: "standard", players: 2 });
1785
- var d = engine.addPlayers({ game: a, players: ["player1"] });
1786
- var e = engine.addExtraRules({ game: d, extraRules: ["rule1"] });
1787
- var f = engine.startGame({ game: e });
1788
- var g = engine.chooseDomino({
1789
- game: f,
1790
- lordId: "player1",
1791
- dominoPick: 1
1792
- });
1793
- var h = engine.discardDomino({ game: g, lordId: "player1" });
1794
- var i = engine.placeDomino({
1795
- game: g,
1796
- lordId: "player1",
1797
- position: { x: 1, y: 1 },
1798
- orientation: "horizontal",
1799
- rotation: 0
1800
- });
1801
- if (isGameWithNextAction(i)) {
1802
- const j = engine.chooseDomino({
1803
- game: i,
1804
- lordId: "player1",
1805
- dominoPick: 1
1806
- });
1807
- }
1808
- if (!isGameWithNextAction(i)) {
1809
- const j = engine.getResults({ game: i });
1810
- }
1811
1841
  export {
1812
1842
  createGameEngine
1813
1843
  };