@fgv/ts-sudoku-lib 2.0.2-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (95) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +5 -0
  3. package/cspell.json +13 -0
  4. package/dist/ts-sudoku-lib.d.ts +763 -0
  5. package/dist/tsdoc-metadata.json +11 -0
  6. package/lib/index.d.ts +6 -0
  7. package/lib/index.d.ts.map +1 -0
  8. package/lib/index.js +59 -0
  9. package/lib/index.js.map +1 -0
  10. package/lib/packlets/collections/collections.d.ts +55 -0
  11. package/lib/packlets/collections/collections.d.ts.map +1 -0
  12. package/lib/packlets/collections/collections.js +137 -0
  13. package/lib/packlets/collections/collections.js.map +1 -0
  14. package/lib/packlets/collections/data/puzzles.json +61 -0
  15. package/lib/packlets/collections/index.d.ts +2 -0
  16. package/lib/packlets/collections/index.d.ts.map +1 -0
  17. package/lib/packlets/collections/index.js +41 -0
  18. package/lib/packlets/collections/index.js.map +1 -0
  19. package/lib/packlets/common/cage.d.ts +23 -0
  20. package/lib/packlets/common/cage.d.ts.map +1 -0
  21. package/lib/packlets/common/cage.js +87 -0
  22. package/lib/packlets/common/cage.js.map +1 -0
  23. package/lib/packlets/common/cell.d.ts +34 -0
  24. package/lib/packlets/common/cell.d.ts.map +1 -0
  25. package/lib/packlets/common/cell.js +92 -0
  26. package/lib/packlets/common/cell.js.map +1 -0
  27. package/lib/packlets/common/common.d.ts +77 -0
  28. package/lib/packlets/common/common.d.ts.map +1 -0
  29. package/lib/packlets/common/common.js +49 -0
  30. package/lib/packlets/common/common.js.map +1 -0
  31. package/lib/packlets/common/converters.d.ts +24 -0
  32. package/lib/packlets/common/converters.d.ts.map +1 -0
  33. package/lib/packlets/common/converters.js +73 -0
  34. package/lib/packlets/common/converters.js.map +1 -0
  35. package/lib/packlets/common/ids.d.ts +15 -0
  36. package/lib/packlets/common/ids.d.ts.map +1 -0
  37. package/lib/packlets/common/ids.js +107 -0
  38. package/lib/packlets/common/ids.js.map +1 -0
  39. package/lib/packlets/common/index.d.ts +12 -0
  40. package/lib/packlets/common/index.d.ts.map +1 -0
  41. package/lib/packlets/common/index.js +65 -0
  42. package/lib/packlets/common/index.js.map +1 -0
  43. package/lib/packlets/common/model.d.ts +15 -0
  44. package/lib/packlets/common/model.d.ts.map +1 -0
  45. package/lib/packlets/common/model.js +26 -0
  46. package/lib/packlets/common/model.js.map +1 -0
  47. package/lib/packlets/common/public.d.ts +65 -0
  48. package/lib/packlets/common/public.d.ts.map +1 -0
  49. package/lib/packlets/common/public.js +26 -0
  50. package/lib/packlets/common/public.js.map +1 -0
  51. package/lib/packlets/common/puzzle.d.ts +99 -0
  52. package/lib/packlets/common/puzzle.d.ts.map +1 -0
  53. package/lib/packlets/common/puzzle.js +389 -0
  54. package/lib/packlets/common/puzzle.js.map +1 -0
  55. package/lib/packlets/common/puzzleSession.d.ts +214 -0
  56. package/lib/packlets/common/puzzleSession.d.ts.map +1 -0
  57. package/lib/packlets/common/puzzleSession.js +361 -0
  58. package/lib/packlets/common/puzzleSession.js.map +1 -0
  59. package/lib/packlets/common/puzzleState.d.ts +52 -0
  60. package/lib/packlets/common/puzzleState.d.ts.map +1 -0
  61. package/lib/packlets/common/puzzleState.js +100 -0
  62. package/lib/packlets/common/puzzleState.js.map +1 -0
  63. package/lib/packlets/file/converters.d.ts +17 -0
  64. package/lib/packlets/file/converters.d.ts.map +1 -0
  65. package/lib/packlets/file/converters.js +49 -0
  66. package/lib/packlets/file/converters.js.map +1 -0
  67. package/lib/packlets/file/index.d.ts +4 -0
  68. package/lib/packlets/file/index.d.ts.map +1 -0
  69. package/lib/packlets/file/index.js +54 -0
  70. package/lib/packlets/file/index.js.map +1 -0
  71. package/lib/packlets/file/model.d.ts +9 -0
  72. package/lib/packlets/file/model.d.ts.map +1 -0
  73. package/lib/packlets/file/model.js +26 -0
  74. package/lib/packlets/file/model.js.map +1 -0
  75. package/lib/packlets/puzzles/anyPuzzle.d.ts +10 -0
  76. package/lib/packlets/puzzles/anyPuzzle.d.ts.map +1 -0
  77. package/lib/packlets/puzzles/anyPuzzle.js +51 -0
  78. package/lib/packlets/puzzles/anyPuzzle.js.map +1 -0
  79. package/lib/packlets/puzzles/index.d.ts +6 -0
  80. package/lib/packlets/puzzles/index.d.ts.map +1 -0
  81. package/lib/packlets/puzzles/index.js +35 -0
  82. package/lib/packlets/puzzles/index.js.map +1 -0
  83. package/lib/packlets/puzzles/killerSudokuPuzzle.d.ts +14 -0
  84. package/lib/packlets/puzzles/killerSudokuPuzzle.d.ts.map +1 -0
  85. package/lib/packlets/puzzles/killerSudokuPuzzle.js +136 -0
  86. package/lib/packlets/puzzles/killerSudokuPuzzle.js.map +1 -0
  87. package/lib/packlets/puzzles/sudokuPuzzle.d.ts +10 -0
  88. package/lib/packlets/puzzles/sudokuPuzzle.d.ts.map +1 -0
  89. package/lib/packlets/puzzles/sudokuPuzzle.js +47 -0
  90. package/lib/packlets/puzzles/sudokuPuzzle.js.map +1 -0
  91. package/lib/packlets/puzzles/sudokuXPuzzle.d.ts +11 -0
  92. package/lib/packlets/puzzles/sudokuXPuzzle.d.ts.map +1 -0
  93. package/lib/packlets/puzzles/sudokuXPuzzle.js +65 -0
  94. package/lib/packlets/puzzles/sudokuXPuzzle.js.map +1 -0
  95. package/package.json +70 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"puzzle.js","sourceRoot":"","sources":["../../../src/packlets/common/puzzle.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;;;AAEH,4CAAkE;AAWlE,iCAA8B;AAC9B,iCAA8B;AAC9B,+BAA4B;AAG5B,+CAA4C;AAE5C,MAAM,cAAc,GAAW,EAAE,CAAC;AAmBlC;;GAEG;AACH,MAAa,MAAM;IA8BjB;;;;OAIG;IACH,YAAsB,MAA0B,EAAE,UAA6B;QAC7E,6CAA6C;QAC7C,UAAU,GAAG,UAAU,aAAV,UAAU,cAAV,UAAU,GAAI,EAAE,CAAC;QAE9B,IAAI,MAAM,CAAC,IAAI,KAAK,CAAC,EAAE;YACrB,MAAM,IAAI,KAAK,CAAC,WAAW,MAAM,CAAC,WAAW,2BAA2B,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;SACxF;QACD,IAAI,MAAM,CAAC,IAAI,KAAK,CAAC,EAAE;YACrB,MAAM,IAAI,KAAK,CAAC,WAAW,MAAM,CAAC,WAAW,8BAA8B,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;SAC3F;QACD,IAAI,MAAM,CAAC,KAAK,CAAC,MAAM,KAAK,MAAM,CAAC,IAAI,GAAG,MAAM,CAAC,IAAI,EAAE;YACrD,MAAM,IAAI,KAAK,CACb,WAAW,MAAM,CAAC,WAAW,cAAc,MAAM,CAAC,IAAI,GAAG,MAAM,CAAC,IAAI,iBAClE,MAAM,CAAC,KAAK,CAAC,MACf,EAAE,CACH,CAAC;SACH;QAED,IAAI,CAAC,EAAE,GAAG,MAAM,CAAC,EAAE,CAAC;QACpB,IAAI,CAAC,WAAW,GAAG,MAAM,CAAC,WAAW,CAAC;QAEtC,MAAM,IAAI,GAAG,MAAM,CAAC,eAAe,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,CAAC;QACxE,MAAM,OAAO,GAAG,MAAM,CAAC,kBAAkB,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,CAAC;QAC9E,MAAM,QAAQ,GAAG,MAAM,CAAC,mBAAmB,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,CAAC;QAChF,MAAM,KAAK,GAAG,CAAC,GAAG,IAAI,EAAE,GAAG,OAAO,EAAE,GAAG,QAAQ,EAAE,GAAG,UAAU,CAAC,CAAC;QAChE,IAAI,CAAC,KAAK,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,CAAC;QAC3B,IAAI,CAAC,QAAQ,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,CAAC;QACjC,IAAI,CAAC,SAAS,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,CAAC;QACnC,IAAI,CAAC,MAAM,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,CAAC;QAC7B,IAAI,CAAC,MAAM,GAAG,IAAI,GAAG,EAAE,CAAC;QAExB,MAAM,QAAQ,GAAG,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;QACnC,KAAK,IAAI,GAAG,GAAG,CAAC,EAAE,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE;YAC9C,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,CAAC;YAC3C,KAAK,IAAI,GAAG,GAAG,CAAC,EAAE,GAAG,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE;gBACjD,MAAM,EAAE,GAAG,SAAG,CAAC,MAAM,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC;gBAC9C,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,CAAC;gBAC9C,MAAM,WAAW,GAAG,IAAI,CAAC,UAAU,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC;gBAC5D,MAAM,UAAU,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC,CAAC;gBAE/E,MAAM,IAAI,GAAG,QAAQ,CAAC,KAAK,EAAE,CAAC;gBAC9B,iGAAiG;gBACjG,MAAM,cAAc,GAAG,IAAI,KAAK,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,aAAJ,IAAI,cAAJ,IAAI,GAAI,GAAG,CAAC,CAAC;gBAC/E,IACE,cAAc,KAAK,SAAS;oBAC5B,CAAC,MAAM,CAAC,KAAK,CAAC,cAAc,CAAC,IAAI,cAAc,GAAG,CAAC,IAAI,cAAc,GAAG,CAAC,CAAC,EAC1E;oBACA,MAAM,IAAI,KAAK,CAAC,UAAU,MAAM,CAAC,WAAW,mBAAmB,IAAI,cAAc,EAAE,EAAE,CAAC,CAAC;iBACxF;gBACD,MAAM,KAAK,GAAG,CAAC,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC;gBAC5F,MAAM,IAAI,GAAG,IAAI,WAAI,CAAC,EAAE,EAAE,EAAE,cAAc,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE,KAAK,CAAC,CAAC;gBAC/D,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;aAC3B;SACF;QAED,IAAI,CAAC,YAAY,GAAG,yBAAW,CAAC,MAAM,CACpC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,KAAK,CAAC,EAAc,EAAE;YAChE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,CAAC,cAAc,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC;QACxD,CAAC,CAAC,CACH,CAAC,OAAO,EAAE,CAAC;IACd,CAAC;IAED,IAAW,OAAO;QAChB,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC;IACzB,CAAC;IAED,IAAW,UAAU;QACnB,OAAO,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC;IAC5B,CAAC;IAED,IAAW,IAAI;QACb,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC;IACzC,CAAC;IAED,IAAW,IAAI;QACb,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;IAC5C,CAAC;IAED,IAAW,QAAQ;QACjB,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC;IAC7C,CAAC;IAED,IAAW,KAAK;QACd,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;IAC1C,CAAC;IAED,IAAW,KAAK;QACd,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;IAC1C,CAAC;IAED;;OAEG;IACO,MAAM,CAAC,eAAe,CAAC,OAAe,EAAE,OAAe;QAC/D,MAAM,KAAK,GAAqB,EAAE,CAAC;QACnC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,OAAO,EAAE,CAAC,EAAE,EAAE;YAChC,MAAM,EAAE,GAAG,SAAG,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;YAC5B,MAAM,OAAO,GAAG,SAAG,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,OAAO,CAAC,CAAC;YAC9C,6DAA6D;YAC7D,IAAI,OAAO,CAAC,SAAS,EAAE,EAAE;gBACvB,OAAO,IAAA,eAAI,EAAC,OAAO,CAAC,OAAO,CAAC,CAAC;aAC9B;YAED,MAAM,MAAM,GAAG,WAAI,CAAC,MAAM,CAAC,EAAE,EAAE,KAAK,EAAE,cAAc,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,CAAC,IAAI,EAAE,EAAE;gBACtF,KAAK,CAAC,IAAI,CAAC,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC,CAAC;gBACvB,OAAO,IAAA,kBAAO,EAAC,IAAI,CAAC,CAAC;YACvB,CAAC,CAAC,CAAC;YACH,6DAA6D;YAC7D,IAAI,MAAM,CAAC,SAAS,EAAE,EAAE;gBACtB,OAAO,IAAA,eAAI,EAAC,MAAM,CAAC,OAAO,CAAC,CAAC;aAC7B;SACF;QACD,OAAO,IAAA,kBAAO,EAAC,KAAK,CAAC,CAAC;IACxB,CAAC;IAED;;OAEG;IACO,MAAM,CAAC,kBAAkB,CAAC,OAAe,EAAE,OAAe;QAClE,MAAM,KAAK,GAAqB,EAAE,CAAC;QACnC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,OAAO,EAAE,CAAC,EAAE,EAAE;YAChC,MAAM,EAAE,GAAG,SAAG,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;YAC/B,MAAM,OAAO,GAAG,SAAG,CAAC,OAAO,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;YAC9C,6DAA6D;YAC7D,IAAI,OAAO,CAAC,SAAS,EAAE,EAAE;gBACvB,OAAO,IAAA,eAAI,EAAC,OAAO,CAAC,OAAO,CAAC,CAAC;aAC9B;YAED,MAAM,MAAM,GAAG,WAAI,CAAC,MAAM,CAAC,EAAE,EAAE,QAAQ,EAAE,cAAc,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,CAAC,IAAI,EAAE,EAAE;gBACzF,KAAK,CAAC,IAAI,CAAC,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC,CAAC;gBACvB,OAAO,IAAA,kBAAO,EAAC,IAAI,CAAC,CAAC;YACvB,CAAC,CAAC,CAAC;YACH,6DAA6D;YAC7D,IAAI,MAAM,CAAC,SAAS,EAAE,EAAE;gBACtB,OAAO,IAAA,eAAI,EAAC,MAAM,CAAC,OAAO,CAAC,CAAC;aAC7B;SACF;QACD,OAAO,IAAA,kBAAO,EAAC,KAAK,CAAC,CAAC;IACxB,CAAC;IAED;;OAEG;IACK,MAAM,CAAC,mBAAmB,CAAC,OAAe,EAAE,OAAe;QACjE,MAAM,KAAK,GAAqB,EAAE,CAAC;QACnC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,OAAO,EAAE,CAAC,IAAI,CAAC,EAAE;YACnC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,OAAO,EAAE,CAAC,IAAI,CAAC,EAAE;gBACnC,MAAM,EAAE,GAAG,SAAG,CAAC,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;gBACnC,MAAM,OAAO,GAAG,SAAG,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;gBACxC,6DAA6D;gBAC7D,IAAI,OAAO,CAAC,SAAS,EAAE,EAAE;oBACvB,OAAO,IAAA,eAAI,EAAC,OAAO,CAAC,OAAO,CAAC,CAAC;iBAC9B;gBAED,MAAM,MAAM,GAAG,WAAI,CAAC,MAAM,CAAC,EAAE,EAAE,SAAS,EAAE,cAAc,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,CAAC,IAAI,EAAE,EAAE;oBAC1F,KAAK,CAAC,IAAI,CAAC,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC,CAAC;oBACvB,OAAO,IAAA,kBAAO,EAAC,IAAI,CAAC,CAAC;gBACvB,CAAC,CAAC,CAAC;gBACH,6DAA6D;gBAC7D,IAAI,MAAM,CAAC,SAAS,EAAE,EAAE;oBACtB,OAAO,IAAA,eAAI,EAAC,MAAM,CAAC,OAAO,CAAC,CAAC;iBAC7B;aACF;SACF;QACD,OAAO,IAAA,kBAAO,EAAC,KAAK,CAAC,CAAC;IACxB,CAAC;IAEM,aAAa,CAAC,KAAkB;QACrC,KAAK,MAAM,EAAE,IAAI,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE;YACnC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE;gBACvB,OAAO,KAAK,CAAC;aACd;SACF;QACD,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,EAAE;YACvC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE;gBACxB,OAAO,KAAK,CAAC;aACd;SACF;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAEM,YAAY,CAAC,KAAkB;QACpC,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,EAAE;YACvC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE;gBACxB,OAAO,KAAK,CAAC;aACd;SACF;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAEM,aAAa,CAAC,KAAkB;QACrC,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAC/E,CAAC;IAEM,eAAe,CAAC,KAAkB;QACvC,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC;IAC3E,CAAC;IAEM,eAAe,CACpB,IAAyB,EACzB,KAAkB;QAElB,OAAO,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,CAAC,IAAI,EAAE,EAAE;YAC3C,IAAI,IAAI,CAAC,SAAS,EAAE;gBAClB,MAAM,QAAQ,GAAkB,EAAE,KAAK,EAAE,IAAI,CAAC,cAAc,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC;gBAC1E,OAAO,IAAA,kBAAO,EAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAC;aACpC;YACD,OAAO,KAAK,CAAC,eAAe,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC,QAAuB,EAAE,EAAE;gBAC1E,OAAO,IAAA,kBAAO,EAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAC;YACrC,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC;IAEM,OAAO,CAAC,IAAiC;QAC9C,MAAM,IAAI,GAAG,SAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QAC9B,IAAI,IAAI,CAAC,SAAS,EAAE,EAAE;YACpB,OAAO,IAAA,eAAI,EAAC,IAAI,CAAC,OAAO,CAAC,CAAC;SAC3B;QAED,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACzC,OAAO,IAAI,CAAC,CAAC,CAAC,IAAA,kBAAO,EAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAA,eAAI,EAAC,QAAQ,IAAI,CAAC,KAAK,YAAY,CAAC,CAAC;IACrE,CAAC;IAEM,eAAe,CACpB,IAAiC,EACjC,SAA8B,EAC9B,IAAoB;QAEpB,OAAO,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,CAAC,IAAI,EAAE,EAAE;YAC3C,MAAM,IAAI,GACR,SAAS,KAAK,MAAM,IAAI,SAAS,KAAK,OAAO;gBAC3C,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,SAAS,EAAE,IAAI,CAAC;gBACzC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,SAAS,EAAE,IAAI,CAAC,CAAC;YAC3C,OAAO,IAAI,CAAC,SAAS,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;QACtD,CAAC,CAAC,CAAC;IACL,CAAC;IAEM,cAAc,CAAC,WAAsC,EAAE,KAAkB;QAC9E,WAAW,GAAG,KAAK,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC;QACvE,OAAO,IAAA,qBAAU,EACf,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CACpB,IAAI,CAAC,eAAe,CAAC,CAAC,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC,SAAS,CAAC,CAAC,QAAQ,EAAE,EAAE,CACvD,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE,EAAE,EAAE;YACtD,MAAM,IAAI,mBAAiB,EAAE,EAAE,CAAC,CAAC,EAAE,IAAK,QAAQ,CAAC,QAAQ,CAAE,CAAC;YAC5D,OAAO,IAAA,kBAAO,EAAC,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC;QAC/B,CAAC,CAAC,CACH,CACF,CACF,CAAC,SAAS,CAAC,CAAC,WAAW,EAAE,EAAE;YAC1B,OAAO,KAAK,CAAC,MAAM,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,YAAyB,EAAE,EAAE;gBAC3F,OAAO,IAAA,kBAAO,EAAC;oBACb,IAAI,EAAE,KAAK;oBACX,EAAE,EAAE,YAAY;oBAChB,KAAK,EAAE,WAAW;iBACnB,CAAC,CAAC;YACL,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC;IAEM,YAAY,CAAC,WAAsC,EAAE,KAAkB;QAC5E,WAAW,GAAG,KAAK,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC;QACvE,OAAO,IAAA,qBAAU,EACf,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CACpB,IAAI,CAAC,eAAe,CAAC,CAAC,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC,SAAS,CAAC,CAAC,QAAQ,EAAE,EAAE,CACvD,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,EAAE,QAAQ,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE,EAAE,EAAE;YACtE,MAAM,IAAI,mBAAiB,EAAE,EAAE,CAAC,CAAC,EAAE,IAAK,QAAQ,CAAC,QAAQ,CAAE,CAAC;YAC5D,OAAO,IAAA,kBAAO,EAAC,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC;QAC/B,CAAC,CAAC,CACH,CACF,CACF,CAAC,SAAS,CAAC,CAAC,WAAW,EAAE,EAAE;YAC1B,OAAO,KAAK,CAAC,MAAM,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,YAAyB,EAAE,EAAE;gBAC3F,OAAO,IAAA,kBAAO,EAAC;oBACb,IAAI,EAAE,KAAK;oBACX,EAAE,EAAE,YAAY;oBAChB,KAAK,EAAE,WAAW;iBACnB,CAAC,CAAC;YACL,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC;IAEM,WAAW,CAAC,WAAsC,EAAE,KAAkB;QAC3E,WAAW,GAAG,KAAK,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC;QACvE,OAAO,IAAA,qBAAU,EACf,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CACpB,IAAI,CAAC,eAAe,CAAC,CAAC,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC,SAAS,CAAC,CAAC,QAAQ,EAAE,EAAE,CACvD,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE,EAAE,EAAE;YACtE,MAAM,IAAI,mBAAiB,EAAE,EAAE,CAAC,CAAC,EAAE,IAAK,QAAQ,CAAC,QAAQ,CAAE,CAAC;YAC5D,OAAO,IAAA,kBAAO,EAAC,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC;QAC/B,CAAC,CAAC,CACH,CACF,CACF,CAAC,SAAS,CAAC,CAAC,WAAW,EAAE,EAAE;YAC1B,OAAO,KAAK,CAAC,MAAM,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,YAAyB,EAAE,EAAE;gBAC3F,OAAO,IAAA,kBAAO,EAAC;oBACb,IAAI,EAAE,KAAK;oBACX,EAAE,EAAE,YAAY;oBAChB,KAAK,EAAE,WAAW;iBACnB,CAAC,CAAC;YACL,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC;IAEM,eAAe,CACpB,IAAyB,EACzB,KAAyB,EACzB,KAAkB;QAElB,MAAM,QAAQ,GAAG,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,SAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QAChF,MAAM,KAAK,GAAa,EAAE,CAAC;QAC3B,OAAO,QAAQ,CAAC,SAAS,CAAC,CAAC,EAAE,EAAE,EAAE;YAC/B,MAAM,MAAM,GAAe,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;YAChD,OAAO,IAAI,CAAC,YAAY,CAAC,CAAC,MAAM,CAAC,EAAE,KAAK,CAAC,CAAC;QAC5C,CAAC,CAAC,CAAC;IACL,CAAC;IAEM,eAAe,CACpB,IAAyB,EACzB,KAAe,EACf,KAAkB;QAElB,MAAM,QAAQ,GAAG,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,SAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QAChF,MAAM,KAAK,GAAG,SAAS,CAAC;QACxB,OAAO,QAAQ,CAAC,SAAS,CAAC,CAAC,EAAE,EAAE,EAAE;YAC/B,MAAM,MAAM,GAAe,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;YAChD,OAAO,IAAI,CAAC,WAAW,CAAC,CAAC,MAAM,CAAC,EAAE,KAAK,CAAC,CAAC;QAC3C,CAAC,CAAC,CAAC;IACL,CAAC;IAEM,MAAM,CAAC,GAAoB;QAChC,MAAM,EAAE,GAAG,OAAO,GAAG,KAAK,QAAQ,CAAC,CAAC,CAAC,SAAG,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;QAC9D,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAChC,OAAO,IAAI,CAAC,CAAC,CAAC,IAAA,kBAAO,EAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAA,eAAI,EAAC,OAAO,EAAE,YAAY,CAAC,CAAC;IAC5D,CAAC;IAEM,SAAS,CAAC,GAAoB;QACnC,MAAM,EAAE,GAAG,OAAO,GAAG,KAAK,QAAQ,CAAC,CAAC,CAAC,SAAG,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;QACjE,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACnC,OAAO,IAAI,CAAC,CAAC,CAAC,IAAA,kBAAO,EAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAA,eAAI,EAAC,UAAU,EAAE,YAAY,CAAC,CAAC;IAC/D,CAAC;IAEM,UAAU,CAAC,IAAyB;QACzC,MAAM,EAAE,GAAG,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,SAAG,CAAC,aAAa,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;QACnF,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACpC,OAAO,IAAI,CAAC,CAAC,CAAC,IAAA,kBAAO,EAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAA,eAAI,EAAC,WAAW,EAAE,YAAY,CAAC,CAAC;IAChE,CAAC;IAEM,OAAO,CAAC,EAAU;QACvB,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACjC,OAAO,IAAI,CAAC,CAAC,CAAC,IAAA,kBAAO,EAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAA,eAAI,EAAC,QAAQ,EAAE,YAAY,CAAC,CAAC;IAC7D,CAAC;IAEM,SAAS,CAAC,KAAkB;QACjC,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC;IAC3E,CAAC;IAEM,QAAQ,CAAC,KAAkB;QAChC,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC1C,CAAC;IAEO,WAAW,CACjB,OAAmB,EACnB,SAA2B,EAC3B,IAAoB;QAEpB,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC;QAExB,IAAI,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC;QACtB,IAAI,SAAS,KAAK,MAAM,EAAE;YACxB,IAAI,GAAG,GAAG,CAAC,EAAE;gBACX,GAAG,GAAG,GAAG,GAAG,CAAC,CAAC;aACf;iBAAM,IAAI,IAAI,KAAK,MAAM,EAAE;gBAC1B,GAAG,GAAG,IAAI,CAAC,UAAU,GAAG,CAAC,CAAC;gBAC1B,IAAI,IAAI,KAAK,WAAW,EAAE;oBACxB,OAAO,IAAI,CAAC,QAAQ,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE,IAAI,EAAE,aAAa,CAAC,CAAC;iBACzD;aACF;iBAAM;gBACL,OAAO,IAAA,eAAI,EAAC,gCAAgC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;aAC5D;SACF;aAAM,IAAI,SAAS,KAAK,OAAO,EAAE;YAChC,IAAI,GAAG,GAAG,IAAI,CAAC,UAAU,GAAG,CAAC,EAAE;gBAC7B,GAAG,GAAG,GAAG,GAAG,CAAC,CAAC;aACf;iBAAM,IAAI,IAAI,KAAK,MAAM,EAAE;gBAC1B,GAAG,GAAG,CAAC,CAAC;gBACR,IAAI,IAAI,KAAK,WAAW,EAAE;oBACxB,OAAO,IAAI,CAAC,QAAQ,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE,MAAM,EAAE,aAAa,CAAC,CAAC;iBAC3D;aACF;iBAAM;gBACL,OAAO,IAAA,eAAI,EAAC,iCAAiC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;aAC7D;SACF;QACD,OAAO,IAAA,kBAAO,EAAC,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC;IAC/B,CAAC;IAEO,QAAQ,CAAC,OAAmB,EAAE,SAAwB,EAAE,IAAoB;QAClF,IAAI,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC;QACtB,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC;QAExB,IAAI,SAAS,KAAK,IAAI,EAAE;YACtB,IAAI,GAAG,GAAG,CAAC,EAAE;gBACX,GAAG,GAAG,GAAG,GAAG,CAAC,CAAC;aACf;iBAAM,IAAI,IAAI,KAAK,MAAM,EAAE;gBAC1B,GAAG,GAAG,IAAI,CAAC,OAAO,GAAG,CAAC,CAAC;gBACvB,IAAI,IAAI,KAAK,WAAW,EAAE;oBACxB,OAAO,IAAI,CAAC,WAAW,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE,MAAM,EAAE,aAAa,CAAC,CAAC;iBAC9D;aACF;iBAAM;gBACL,OAAO,IAAA,eAAI,EAAC,2BAA2B,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;aACvD;SACF;aAAM,IAAI,SAAS,KAAK,MAAM,EAAE;YAC/B,IAAI,GAAG,GAAG,IAAI,CAAC,OAAO,GAAG,CAAC,EAAE;gBAC1B,GAAG,GAAG,GAAG,GAAG,CAAC,CAAC;aACf;iBAAM,IAAI,IAAI,KAAK,MAAM,EAAE;gBAC1B,GAAG,GAAG,CAAC,CAAC;gBACR,IAAI,IAAI,KAAK,WAAW,EAAE;oBACxB,OAAO,IAAI,CAAC,WAAW,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE,OAAO,EAAE,aAAa,CAAC,CAAC;iBAC/D;aACF;iBAAM;gBACL,OAAO,IAAA,eAAI,EAAC,6BAA6B,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;aACzD;SACF;QACD,OAAO,IAAA,kBAAO,EAAC,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC;IAC/B,CAAC;CACF;AA1cD,wBA0cC","sourcesContent":["/*\n * MIT License\n *\n * Copyright (c) 2023 Erik Fortune\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\nimport { Result, fail, mapResults, succeed } from '@fgv/ts-utils';\nimport {\n CageId,\n CellId,\n ICellContents,\n ICellState,\n IRowColumn,\n NavigationDirection,\n NavigationWrap\n} from './common';\n\nimport { Cage } from './cage';\nimport { Cell } from './cell';\nimport { Ids } from './ids';\nimport { IPuzzleDescription } from './model';\nimport { ICell } from './public';\nimport { PuzzleState } from './puzzleState';\n\nconst basicCageTotal: number = 45;\n\n/**\n * @internal\n */\nexport interface ICellUpdate {\n from: ICellState;\n to: ICellState;\n}\n\n/**\n * @internal\n */\nexport interface IPuzzleUpdate {\n from: PuzzleState;\n to: PuzzleState;\n cells: ICellUpdate[];\n}\n\n/**\n * @internal\n */\nexport class Puzzle {\n public readonly id?: string;\n public readonly description: string;\n public readonly initialState: PuzzleState;\n\n /**\n * @internal\n */\n protected readonly _rows: Map<CageId, Cage>;\n\n /**\n * @internal\n */\n protected readonly _columns: Map<CageId, Cage>;\n\n /**\n * @internal\n */\n protected readonly _sections: Map<CageId, Cage>;\n\n /**\n * @internal\n */\n protected readonly _cages: Map<CageId, Cage>;\n\n /**\n * @internal\n */\n protected readonly _cells: Map<CellId, Cell>;\n\n /**\n * Constructs a new puzzle state.\n * @param puzzle - {@Link Data.Model.PuzzleDescription | Puzzle description} from which this puzzle state\n * is to be initialized.\n */\n protected constructor(puzzle: IPuzzleDescription, extraCages?: [CageId, Cage][]) {\n /* c8 ignore next - ?? is defense in depth */\n extraCages = extraCages ?? [];\n\n if (puzzle.rows !== 9) {\n throw new Error(`Puzzle '${puzzle.description}' unsupported row count ${puzzle.rows}`);\n }\n if (puzzle.cols !== 9) {\n throw new Error(`Puzzle '${puzzle.description}' unsupported column count ${puzzle.cols}`);\n }\n if (puzzle.cells.length !== puzzle.rows * puzzle.cols) {\n throw new Error(\n `Puzzle '${puzzle.description}\" expected ${puzzle.rows * puzzle.cols} cells, found ${\n puzzle.cells.length\n }`\n );\n }\n\n this.id = puzzle.id;\n this.description = puzzle.description;\n\n const rows = Puzzle._createRowCages(puzzle.rows, puzzle.cols).orThrow();\n const columns = Puzzle._createColumnCages(puzzle.rows, puzzle.cols).orThrow();\n const sections = Puzzle._createSectionCages(puzzle.rows, puzzle.cols).orThrow();\n const cages = [...rows, ...columns, ...sections, ...extraCages];\n this._rows = new Map(rows);\n this._columns = new Map(columns);\n this._sections = new Map(sections);\n this._cages = new Map(cages);\n this._cells = new Map();\n\n const cellInit = [...puzzle.cells];\n for (let row = 0; row < this._rows.size; row++) {\n const rowCage = this.getRow(row).orThrow();\n for (let col = 0; col < this._columns.size; col++) {\n const id = Ids.cellId({ row, col }).orThrow();\n const colCage = this.getColumn(col).orThrow();\n const sectionCage = this.getSection({ row, col }).orThrow();\n const otherCages = extraCages.filter(([__key, cage]) => cage.containsCell(id));\n\n const init = cellInit.shift();\n /* c8 ignore next - defense in depth/make type check happy. undefined init should never happen */\n const immutableValue = init === '.' ? undefined : Number.parseInt(init ?? '0');\n if (\n immutableValue !== undefined &&\n (Number.isNaN(immutableValue) || immutableValue < 1 || immutableValue > 9)\n ) {\n throw new Error(`Puzzle ${puzzle.description} illegal value \"${init}\" for cell ${id}`);\n }\n const cages = [rowCage, colCage, sectionCage, ...otherCages.map(([__key, state]) => state)];\n const cell = new Cell({ id, immutableValue, row, col }, cages);\n this._cells.set(id, cell);\n }\n }\n\n this.initialState = PuzzleState.create(\n Array.from(this._cells.entries()).map(([id, state]): ICellState => {\n return { id, value: state.immutableValue, notes: [] };\n })\n ).orThrow();\n }\n\n public get numRows(): number {\n return this._rows.size;\n }\n\n public get numColumns(): number {\n return this._columns.size;\n }\n\n public get rows(): Cage[] {\n return Array.from(this._rows.values());\n }\n\n public get cols(): Cage[] {\n return Array.from(this._columns.values());\n }\n\n public get sections(): Cage[] {\n return Array.from(this._sections.values());\n }\n\n public get cages(): Cage[] {\n return Array.from(this._cages.values());\n }\n\n public get cells(): Cell[] {\n return Array.from(this._cells.values());\n }\n\n /**\n * @internal\n */\n protected static _createRowCages(numRows: number, numCols: number): Result<[CageId, Cage][]> {\n const cages: [CageId, Cage][] = [];\n for (let r = 0; r < numRows; r++) {\n const id = Ids.rowCageId(r);\n const cellIds = Ids.cellIds(r, 1, 0, numCols);\n /* c8 ignore next 3 - defense in depth should never happen */\n if (cellIds.isFailure()) {\n return fail(cellIds.message);\n }\n\n const result = Cage.create(id, 'row', basicCageTotal, cellIds.value).onSuccess((cage) => {\n cages.push([id, cage]);\n return succeed(cage);\n });\n /* c8 ignore next 3 - defense in depth should never happen */\n if (result.isFailure()) {\n return fail(result.message);\n }\n }\n return succeed(cages);\n }\n\n /**\n * @internal\n */\n protected static _createColumnCages(numRows: number, numCols: number): Result<[CageId, Cage][]> {\n const cages: [CageId, Cage][] = [];\n for (let c = 0; c < numCols; c++) {\n const id = Ids.columnCageId(c);\n const cellIds = Ids.cellIds(0, numRows, c, 1);\n /* c8 ignore next 3 - defense in depth should never happen */\n if (cellIds.isFailure()) {\n return fail(cellIds.message);\n }\n\n const result = Cage.create(id, 'column', basicCageTotal, cellIds.value).onSuccess((cage) => {\n cages.push([id, cage]);\n return succeed(cage);\n });\n /* c8 ignore next 3 - defense in depth should never happen */\n if (result.isFailure()) {\n return fail(result.message);\n }\n }\n return succeed(cages);\n }\n\n /**\n * @internal\n */\n private static _createSectionCages(numRows: number, numCols: number): Result<[CageId, Cage][]> {\n const cages: [CageId, Cage][] = [];\n for (let r = 0; r < numRows; r += 3) {\n for (let c = 0; c < numCols; c += 3) {\n const id = Ids.sectionCageId(r, c);\n const cellIds = Ids.cellIds(r, 3, c, 3);\n /* c8 ignore next 3 - defense in depth should never happen */\n if (cellIds.isFailure()) {\n return fail(cellIds.message);\n }\n\n const result = Cage.create(id, 'section', basicCageTotal, cellIds.value).onSuccess((cage) => {\n cages.push([id, cage]);\n return succeed(cage);\n });\n /* c8 ignore next 3 - defense in depth should never happen */\n if (result.isFailure()) {\n return fail(result.message);\n }\n }\n }\n return succeed(cages);\n }\n\n public checkIsSolved(state: PuzzleState): boolean {\n for (const id of this._cells.keys()) {\n if (!state.hasValue(id)) {\n return false;\n }\n }\n for (const cell of this._cells.values()) {\n if (!cell.isValid(state)) {\n return false;\n }\n }\n return true;\n }\n\n public checkIsValid(state: PuzzleState): boolean {\n for (const cell of this._cells.values()) {\n if (!cell.isValid(state)) {\n return false;\n }\n }\n return true;\n }\n\n public getEmptyCells(state: PuzzleState): Cell[] {\n return Array.from(this._cells.values()).filter((c) => !state.hasValue(c.id));\n }\n\n public getInvalidCells(state: PuzzleState): Cell[] {\n return Array.from(this._cells.values()).filter((c) => !c.isValid(state));\n }\n\n public getCellContents(\n spec: string | IRowColumn,\n state: PuzzleState\n ): Result<{ cell: Cell; contents: ICellContents }> {\n return this.getCell(spec).onSuccess((cell) => {\n if (cell.immutable) {\n const contents: ICellContents = { value: cell.immutableValue, notes: [] };\n return succeed({ cell, contents });\n }\n return state.getCellContents(cell.id).onSuccess((contents: ICellContents) => {\n return succeed({ cell, contents });\n });\n });\n }\n\n public getCell(spec: string | IRowColumn | ICell): Result<Cell> {\n const want = Ids.cellId(spec);\n if (want.isFailure()) {\n return fail(want.message);\n }\n\n const cell = this._cells.get(want.value);\n return cell ? succeed(cell) : fail(`Cell ${want.value} not found`);\n }\n\n public getCellNeighbor(\n spec: string | IRowColumn | ICell,\n direction: NavigationDirection,\n wrap: NavigationWrap\n ): Result<ICell> {\n return this.getCell(spec).onSuccess((cell) => {\n const move =\n direction === 'left' || direction === 'right'\n ? this._moveColumn(cell, direction, wrap)\n : this._moveRow(cell, direction, wrap);\n return move.onSuccess((next) => this.getCell(next));\n });\n }\n\n public updateContents(wantUpdates: ICellState[] | ICellState, state: PuzzleState): Result<IPuzzleUpdate> {\n wantUpdates = Array.isArray(wantUpdates) ? wantUpdates : [wantUpdates];\n return mapResults(\n wantUpdates.map((u) =>\n this.getCellContents(u.id, state).onSuccess((existing) =>\n existing.cell.update(u.value, u.notes).onSuccess((to) => {\n const from: ICellState = { id: u.id, ...existing.contents };\n return succeed({ from, to });\n })\n )\n )\n ).onSuccess((cellUpdates) => {\n return state.update(cellUpdates.map(({ to }) => to)).onSuccess((updatedState: PuzzleState) => {\n return succeed({\n from: state,\n to: updatedState,\n cells: cellUpdates\n });\n });\n });\n }\n\n public updateValues(wantUpdates: ICellState[] | ICellState, state: PuzzleState): Result<IPuzzleUpdate> {\n wantUpdates = Array.isArray(wantUpdates) ? wantUpdates : [wantUpdates];\n return mapResults(\n wantUpdates.map((u) =>\n this.getCellContents(u.id, state).onSuccess((existing) =>\n existing.cell.update(u.value, existing.contents.notes).onSuccess((to) => {\n const from: ICellState = { id: u.id, ...existing.contents };\n return succeed({ from, to });\n })\n )\n )\n ).onSuccess((cellUpdates) => {\n return state.update(cellUpdates.map(({ to }) => to)).onSuccess((updatedState: PuzzleState) => {\n return succeed({\n from: state,\n to: updatedState,\n cells: cellUpdates\n });\n });\n });\n }\n\n public updateNotes(wantUpdates: ICellState[] | ICellState, state: PuzzleState): Result<IPuzzleUpdate> {\n wantUpdates = Array.isArray(wantUpdates) ? wantUpdates : [wantUpdates];\n return mapResults(\n wantUpdates.map((u) =>\n this.getCellContents(u.id, state).onSuccess((existing) =>\n existing.cell.update(existing.contents.value, u.notes).onSuccess((to) => {\n const from: ICellState = { id: u.id, ...existing.contents };\n return succeed({ from, to });\n })\n )\n )\n ).onSuccess((cellUpdates) => {\n return state.update(cellUpdates.map(({ to }) => to)).onSuccess((updatedState: PuzzleState) => {\n return succeed({\n from: state,\n to: updatedState,\n cells: cellUpdates\n });\n });\n });\n }\n\n public updateCellValue(\n want: string | IRowColumn,\n value: number | undefined,\n state: PuzzleState\n ): Result<IPuzzleUpdate> {\n const idResult = typeof want === 'string' ? Ids.cellId(want) : Ids.cellId(want);\n const notes: number[] = [];\n return idResult.onSuccess((id) => {\n const update: ICellState = { id, value, notes };\n return this.updateValues([update], state);\n });\n }\n\n public updateCellNotes(\n want: string | IRowColumn,\n notes: number[],\n state: PuzzleState\n ): Result<IPuzzleUpdate> {\n const idResult = typeof want === 'string' ? Ids.cellId(want) : Ids.cellId(want);\n const value = undefined;\n return idResult.onSuccess((id) => {\n const update: ICellState = { id, value, notes };\n return this.updateNotes([update], state);\n });\n }\n\n public getRow(row: CageId | number): Result<Cage> {\n const id = typeof row === 'number' ? Ids.rowCageId(row) : row;\n const cage = this._rows.get(id);\n return cage ? succeed(cage) : fail(`Row ${id} not found`);\n }\n\n public getColumn(col: CageId | number): Result<Cage> {\n const id = typeof col === 'number' ? Ids.columnCageId(col) : col;\n const cage = this._columns.get(id);\n return cage ? succeed(cage) : fail(`Column ${id} not found`);\n }\n\n public getSection(spec: CageId | IRowColumn): Result<Cage> {\n const id = typeof spec === 'object' ? Ids.sectionCageId(spec.row, spec.col) : spec;\n const cage = this._sections.get(id);\n return cage ? succeed(cage) : fail(`Section ${id} not found`);\n }\n\n public getCage(id: CageId): Result<Cage> {\n const cage = this._cages.get(id);\n return cage ? succeed(cage) : fail(`Cage ${id} not found`);\n }\n\n public toStrings(state: PuzzleState): string[] {\n return Array.from(this._rows.values()).map((row) => row.toString(state));\n }\n\n public toString(state: PuzzleState): string {\n return this.toStrings(state).join('\\n');\n }\n\n private _moveColumn(\n current: IRowColumn,\n direction: 'left' | 'right',\n wrap: NavigationWrap\n ): Result<IRowColumn> {\n const row = current.row;\n\n let col = current.col;\n if (direction === 'left') {\n if (col > 0) {\n col = col - 1;\n } else if (wrap !== 'none') {\n col = this.numColumns - 1;\n if (wrap === 'wrap-next') {\n return this._moveRow({ row, col }, 'up', 'wrap-around');\n }\n } else {\n return fail(`cannot move left from column ${current.col}`);\n }\n } else if (direction === 'right') {\n if (col < this.numColumns - 1) {\n col = col + 1;\n } else if (wrap !== 'none') {\n col = 0;\n if (wrap === 'wrap-next') {\n return this._moveRow({ row, col }, 'down', 'wrap-around');\n }\n } else {\n return fail(`cannot move right from column ${current.col}`);\n }\n }\n return succeed({ row, col });\n }\n\n private _moveRow(current: IRowColumn, direction: 'up' | 'down', wrap: NavigationWrap): Result<IRowColumn> {\n let row = current.row;\n const col = current.col;\n\n if (direction === 'up') {\n if (row > 0) {\n row = row - 1;\n } else if (wrap !== 'none') {\n row = this.numRows - 1;\n if (wrap === 'wrap-next') {\n return this._moveColumn({ row, col }, 'left', 'wrap-around');\n }\n } else {\n return fail(`cannot move up from row ${current.row}`);\n }\n } else if (direction === 'down') {\n if (row < this.numRows - 1) {\n row = row + 1;\n } else if (wrap !== 'none') {\n row = 0;\n if (wrap === 'wrap-next') {\n return this._moveColumn({ row, col }, 'right', 'wrap-around');\n }\n } else {\n return fail(`cannot move down from row ${current.row}`);\n }\n }\n return succeed({ row, col });\n }\n}\n"]}
@@ -0,0 +1,214 @@
1
+ import { Result } from '@fgv/ts-utils';
2
+ import { ICellContents, ICellState, IRowColumn, NavigationDirection, NavigationWrap } from './common';
3
+ import { ICage, ICell } from './public';
4
+ import { ICellUpdate, Puzzle } from './puzzle';
5
+ import { PuzzleState } from './puzzleState';
6
+ interface IPuzzleStep {
7
+ updates: ICellUpdate[];
8
+ }
9
+ /**
10
+ * Represents a single puzzle session, including puzzle, current state and redo/undo.
11
+ * @public
12
+ */
13
+ export declare class PuzzleSession {
14
+ /**
15
+ * The current {@link PuzzleState | state} of this puzzle session.
16
+ */
17
+ state: PuzzleState;
18
+ protected readonly _puzzle: Puzzle;
19
+ protected _nextStep: number;
20
+ protected _numSteps: number;
21
+ protected _steps: IPuzzleStep[];
22
+ /**
23
+ * @internal
24
+ */
25
+ protected constructor(puzzle: Puzzle);
26
+ /**
27
+ * ID of the puzzle being solved.
28
+ */
29
+ get id(): string | undefined;
30
+ /**
31
+ * Description of the puzzle being solved.
32
+ */
33
+ get description(): string;
34
+ /**
35
+ * Number of rows in the puzzle being solved.
36
+ */
37
+ get numRows(): number;
38
+ /**
39
+ * Number of columns in the puzzle being solved.
40
+ */
41
+ get numColumns(): number;
42
+ /**
43
+ * The row {@link ICage | cages} in the puzzle being solved.
44
+ */
45
+ get rows(): ICage[];
46
+ /**
47
+ * The column {@link ICage | cages} in the puzzle being solved.
48
+ */
49
+ get cols(): ICage[];
50
+ /**
51
+ * The section {@link ICage | cages} in the puzzle being solved.
52
+ */
53
+ get sections(): ICage[];
54
+ /**
55
+ * All {@link ICage | cages} in the puzzle being solved.
56
+ */
57
+ get cages(): ICage[];
58
+ /**
59
+ * The cells {@link ICell | cells} in the puzzle being solved.
60
+ */
61
+ get cells(): ICell[];
62
+ /**
63
+ * Index of the next step in this puzzle session.
64
+ */
65
+ get nextStep(): number;
66
+ /**
67
+ * Number of steps currently elapsed in this puzzle session. Note
68
+ * that after undo, `nextStep` will be less than `numSteps`.
69
+ */
70
+ get numSteps(): number;
71
+ /***
72
+ * Indicates whether undo is currently possible.
73
+ */
74
+ get canUndo(): boolean;
75
+ /**
76
+ * Indicates whether redo is currently possible.
77
+ */
78
+ get canRedo(): boolean;
79
+ /**
80
+ * Creates a new {@link PuzzleSession | puzzle session} from a supplied
81
+ * {@link Puzzle | puzzle}.
82
+ * @param puzzle - The {@link Puzzle | puzzle} from which the session is to be
83
+ * initialized.
84
+ * @returns `Success` with the requested {@link PuzzleSession | puzzle session},
85
+ * or `Failure` with details if an error occurs.
86
+ */
87
+ static create(puzzle: Puzzle): Result<PuzzleSession>;
88
+ /**
89
+ * Determines if the puzzle is correctly solved.
90
+ * @returns `true` if the puzzle is solved, `false` if the puzzle has
91
+ * empty or invalid cells.
92
+ */
93
+ checkIsSolved(): boolean;
94
+ /**
95
+ * Determines if the puzzle is valid in its current state.
96
+ * @returns `true` if all non-empty cells in the puzzle are valid,
97
+ * or `false` if any cells are invalid.
98
+ */
99
+ checkIsValid(): boolean;
100
+ /**
101
+ * Gets all of the currently empty {@link ICell | cells} in the puzzle.
102
+ * @returns An array of {@link ICell | ICell} with all empty cells.
103
+ */
104
+ getEmptyCells(): ICell[];
105
+ /**
106
+ * Gets all of the currently invalid {@link ICell | cells} in the puzzle.
107
+ * @returns An array of {@link ICell | ICell} with all invalid cells.
108
+ */
109
+ getInvalidCells(): ICell[];
110
+ /**
111
+ * Determines if a cell is valid.
112
+ * @param spec - A `string` ({@link CellId | CellId}), {@link IRowColumn | RowColumn} or {@link ICell | ICell}
113
+ * describing the cell to be tested.
114
+ * @returns `true` if the cell value is valid, `false` if the cell value or the cell itself is invalid.
115
+ */
116
+ cellIsValid(spec: string | IRowColumn | ICell): boolean;
117
+ /**
118
+ * Determines if a cell has a value.
119
+ * @param spec - A `string` ({@link CellId | CellId}), {@link IRowColumn | RowColumn} or {@link ICell | ICell}
120
+ * describing the cell to be tested.
121
+ * @returns `true` if the cell has a value, `false` if the cell is empty or the cell itself is invalid.
122
+ */
123
+ cellHasValue(spec: string | IRowColumn | ICell): boolean;
124
+ /**
125
+ * Determines if supplied value is valid for a specific cell.
126
+ * @param spec - A `string` ({@link CellId | CellId}), {@link IRowColumn | RowColumn} or {@link ICell | ICell}
127
+ * describing the cell to be tested.
128
+ * @param value - The value to be tested.
129
+ * @returns `true` if `value` is valid for the requested cell, `false` if the value or the cell itself is invalid.
130
+ */
131
+ isValidForCell(spec: string | IRowColumn | ICell, value: number): boolean;
132
+ /**
133
+ * Gets the neighbor for a cell in a given direction using specified wrapping rules.
134
+ * @param spec - A `string` ({@link CellId | CellId}), {@link IRowColumn | RowColumn} or {@link ICell | ICell}
135
+ * describing the cell to be tested.
136
+ * @param direction - The direction of the desired neighbor.
137
+ * @param wrap - Wrapping rules to be applied.
138
+ * @returns `Success` with the requested {@link ICell | cell}, or `Failure` with details if an error occurs.
139
+ */
140
+ getCellNeighbor(spec: string | IRowColumn | ICell, direction: NavigationDirection, wrap: NavigationWrap): Result<ICell>;
141
+ /**
142
+ * Gets the {@link ICellContents | contents} for a specified cell.
143
+ * @param spec - A `string` ({@link CellId | CellId}), {@link IRowColumn | RowColumn} or {@link ICell | ICell}
144
+ * describing the cell to be queried.
145
+ * @returns `Success` with the {@link ICell | cell description} and {@link ICellContents | cell contents}, or
146
+ * `Failure` with details if an error occurs.
147
+ */
148
+ getCellContents(spec: string | IRowColumn): Result<{
149
+ cell: ICell;
150
+ contents: ICellContents;
151
+ }>;
152
+ /**
153
+ * Updates the value of a cell.
154
+ * @param spec - A `string`, {@link IRowColumn | row and column}, or {@link ICell | cell} identifying
155
+ * the cell to be updated.
156
+ * @param value - A new value for the cell.
157
+ * @returns `Success` with `this` if the update is applied, `Failure` with details if an error occurs.
158
+ */
159
+ updateCellValue(spec: string | IRowColumn | ICell, value: number | undefined): Result<this>;
160
+ /**
161
+ * Updates the notes on a cell.
162
+ * @param spec - A `string`, {@link IRowColumn | row and column}, or {@link ICell | cell} identifying
163
+ * the cell to be updated.
164
+ * @param notes - New notes for the cell.
165
+ * @returns `Success` with `this` if the update is applied, `Failure` with details if an error occurs.
166
+ */
167
+ updateCellNotes(spec: string | IRowColumn | ICell, notes: number[]): Result<this>;
168
+ /**
169
+ * Updates value & notes for multiple cells.
170
+ * @param updates - An array of {@link ICellState | cell state} objects, each describing
171
+ * one cell to be updated.
172
+ * @returns `Success` with `this` if the updates are applied, `Failure` with details if
173
+ * an error occurs.
174
+ */
175
+ updateCells(updates: ICellState[]): Result<this>;
176
+ /**
177
+ * Determines if some {@link ICage | cage} contains a specific value.
178
+ * @param spec - A `string` ({@link CageId | CageId}) or {@link ICage | ICage}
179
+ * indicating the cage to be tested.
180
+ * @param value - The value to be tested.
181
+ * @returns `true` if the cage exists and contains the specified value,
182
+ * `false` otherwise.
183
+ */
184
+ cageContainsValue(spec: string | ICage, value: number): boolean;
185
+ /**
186
+ * Determines the numbers currently present in some cage.
187
+ * @param spec - A `string` ({@link CageId | CageId}) or {@link ICage | ICage}
188
+ * indicating the cage to be tested.
189
+ * @returns A `Set<number>` containing all numbers present in the cage.
190
+ */
191
+ cageContainedValues(spec: string | ICage): Set<number>;
192
+ /**
193
+ * Undo a single move in this puzzle session.
194
+ * @returns `Success` with `this` if the undo is applied, or `Failure`
195
+ * with details if an error occurs.
196
+ */
197
+ undo(): Result<this>;
198
+ /**
199
+ * Redo a single move in this puzzle session.
200
+ * @returns `Success` with `this` if the redo is applied, or `Failure`
201
+ * with details if an error occurs.
202
+ */
203
+ redo(): Result<this>;
204
+ /**
205
+ * Gets a string representation of this puzzle, one string
206
+ * per row.
207
+ */
208
+ toStrings(): string[];
209
+ private _addMove;
210
+ private _cage;
211
+ private _cell;
212
+ }
213
+ export {};
214
+ //# sourceMappingURL=puzzleSession.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"puzzleSession.d.ts","sourceRoot":"","sources":["../../../src/packlets/common/puzzleSession.ts"],"names":[],"mappings":"AAwBA,OAAO,EAAE,MAAM,EAAgC,MAAM,eAAe,CAAC;AAGrE,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,UAAU,EAAE,mBAAmB,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAEtG,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,UAAU,CAAC;AACxC,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAC/C,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAE5C,UAAU,WAAW;IACnB,OAAO,EAAE,WAAW,EAAE,CAAC;CACxB;AAED;;;GAGG;AACH,qBAAa,aAAa;IACxB;;OAEG;IACI,KAAK,EAAE,WAAW,CAAC;IAE1B,SAAS,CAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACnC,SAAS,CAAC,SAAS,EAAE,MAAM,CAAC;IAC5B,SAAS,CAAC,SAAS,EAAE,MAAM,CAAC;IAC5B,SAAS,CAAC,MAAM,EAAE,WAAW,EAAE,CAAC;IAEhC;;OAEG;IACH,SAAS,aAAa,MAAM,EAAE,MAAM;IAQpC;;OAEG;IACH,IAAW,EAAE,IAAI,MAAM,GAAG,SAAS,CAElC;IAED;;OAEG;IACH,IAAW,WAAW,IAAI,MAAM,CAE/B;IAED;;OAEG;IACH,IAAW,OAAO,IAAI,MAAM,CAE3B;IAED;;OAEG;IACH,IAAW,UAAU,IAAI,MAAM,CAE9B;IAED;;OAEG;IACH,IAAW,IAAI,IAAI,KAAK,EAAE,CAEzB;IAED;;OAEG;IACH,IAAW,IAAI,IAAI,KAAK,EAAE,CAEzB;IAED;;OAEG;IACH,IAAW,QAAQ,IAAI,KAAK,EAAE,CAE7B;IAED;;OAEG;IACH,IAAW,KAAK,IAAI,KAAK,EAAE,CAE1B;IAED;;OAEG;IACH,IAAW,KAAK,IAAI,KAAK,EAAE,CAE1B;IAED;;OAEG;IACH,IAAW,QAAQ,IAAI,MAAM,CAE5B;IAED;;;OAGG;IACH,IAAW,QAAQ,IAAI,MAAM,CAE5B;IAED;;OAEG;IACH,IAAW,OAAO,IAAI,OAAO,CAE5B;IAED;;OAEG;IACH,IAAW,OAAO,IAAI,OAAO,CAE5B;IAED;;;;;;;OAOG;WACW,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,aAAa,CAAC;IAI3D;;;;OAIG;IACI,aAAa,IAAI,OAAO;IAI/B;;;;OAIG;IACI,YAAY,IAAI,OAAO;IAI9B;;;OAGG;IACI,aAAa,IAAI,KAAK,EAAE;IAI/B;;;OAGG;IACI,eAAe,IAAI,KAAK,EAAE;IAIjC;;;;;OAKG;IACI,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU,GAAG,KAAK,GAAG,OAAO;IAI9D;;;;;OAKG;IACI,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU,GAAG,KAAK,GAAG,OAAO;IAI/D;;;;;;OAMG;IACI,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU,GAAG,KAAK,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO;IAIhF;;;;;;;OAOG;IACI,eAAe,CACpB,IAAI,EAAE,MAAM,GAAG,UAAU,GAAG,KAAK,EACjC,SAAS,EAAE,mBAAmB,EAC9B,IAAI,EAAE,cAAc,GACnB,MAAM,CAAC,KAAK,CAAC;IAIhB;;;;;;OAMG;IACI,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU,GAAG,MAAM,CAAC;QAAE,IAAI,EAAE,KAAK,CAAC;QAAC,QAAQ,EAAE,aAAa,CAAA;KAAE,CAAC;IAInG;;;;;;OAMG;IACI,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU,GAAG,KAAK,EAAE,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAAC,IAAI,CAAC;IAalG;;;;;;OAMG;IACI,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU,GAAG,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,MAAM,CAAC,IAAI,CAAC;IAaxF;;;;;;OAMG;IACI,WAAW,CAAC,OAAO,EAAE,UAAU,EAAE,GAAG,MAAM,CAAC,IAAI,CAAC;IAQvD;;;;;;;OAOG;IACI,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,KAAK,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO;IAItE;;;;;OAKG;IACI,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,KAAK,GAAG,GAAG,CAAC,MAAM,CAAC;IAI7D;;;;OAIG;IACI,IAAI,IAAI,MAAM,CAAC,IAAI,CAAC;IAiB3B;;;;OAIG;IACI,IAAI,IAAI,MAAM,CAAC,IAAI,CAAC;IAgB3B;;;OAGG;IACI,SAAS,IAAI,MAAM,EAAE;IAI5B,OAAO,CAAC,QAAQ;IAUhB,OAAO,CAAC,KAAK;IAWb,OAAO,CAAC,KAAK;CAMd"}
@@ -0,0 +1,361 @@
1
+ "use strict";
2
+ /*
3
+ * MIT License
4
+ *
5
+ * Copyright (c) 2023 Erik Fortune
6
+ *
7
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
8
+ * of this software and associated documentation files (the "Software"), to deal
9
+ * in the Software without restriction, including without limitation the rights
10
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11
+ * copies of the Software, and to permit persons to whom the Software is
12
+ * furnished to do so, subject to the following conditions:
13
+ *
14
+ * The above copyright notice and this permission notice shall be included in all
15
+ * copies or substantial portions of the Software.
16
+ *
17
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23
+ * SOFTWARE.
24
+ */
25
+ Object.defineProperty(exports, "__esModule", { value: true });
26
+ exports.PuzzleSession = void 0;
27
+ const ts_utils_1 = require("@fgv/ts-utils");
28
+ const cage_1 = require("./cage");
29
+ const cell_1 = require("./cell");
30
+ const ids_1 = require("./ids");
31
+ /**
32
+ * Represents a single puzzle session, including puzzle, current state and redo/undo.
33
+ * @public
34
+ */
35
+ class PuzzleSession {
36
+ /**
37
+ * @internal
38
+ */
39
+ constructor(puzzle) {
40
+ this._puzzle = puzzle;
41
+ this.state = puzzle.initialState;
42
+ this._nextStep = 0;
43
+ this._numSteps = 0;
44
+ this._steps = [];
45
+ }
46
+ /**
47
+ * ID of the puzzle being solved.
48
+ */
49
+ get id() {
50
+ return this._puzzle.id;
51
+ }
52
+ /**
53
+ * Description of the puzzle being solved.
54
+ */
55
+ get description() {
56
+ return this._puzzle.description;
57
+ }
58
+ /**
59
+ * Number of rows in the puzzle being solved.
60
+ */
61
+ get numRows() {
62
+ return this._puzzle.numRows;
63
+ }
64
+ /**
65
+ * Number of columns in the puzzle being solved.
66
+ */
67
+ get numColumns() {
68
+ return this._puzzle.numColumns;
69
+ }
70
+ /**
71
+ * The row {@link ICage | cages} in the puzzle being solved.
72
+ */
73
+ get rows() {
74
+ return this._puzzle.rows;
75
+ }
76
+ /**
77
+ * The column {@link ICage | cages} in the puzzle being solved.
78
+ */
79
+ get cols() {
80
+ return this._puzzle.cols;
81
+ }
82
+ /**
83
+ * The section {@link ICage | cages} in the puzzle being solved.
84
+ */
85
+ get sections() {
86
+ return this._puzzle.sections;
87
+ }
88
+ /**
89
+ * All {@link ICage | cages} in the puzzle being solved.
90
+ */
91
+ get cages() {
92
+ return this._puzzle.cages;
93
+ }
94
+ /**
95
+ * The cells {@link ICell | cells} in the puzzle being solved.
96
+ */
97
+ get cells() {
98
+ return this._puzzle.cells;
99
+ }
100
+ /**
101
+ * Index of the next step in this puzzle session.
102
+ */
103
+ get nextStep() {
104
+ return this._nextStep;
105
+ }
106
+ /**
107
+ * Number of steps currently elapsed in this puzzle session. Note
108
+ * that after undo, `nextStep` will be less than `numSteps`.
109
+ */
110
+ get numSteps() {
111
+ return this._numSteps;
112
+ }
113
+ /***
114
+ * Indicates whether undo is currently possible.
115
+ */
116
+ get canUndo() {
117
+ return this._nextStep > 0;
118
+ }
119
+ /**
120
+ * Indicates whether redo is currently possible.
121
+ */
122
+ get canRedo() {
123
+ return this._nextStep < this._numSteps;
124
+ }
125
+ /**
126
+ * Creates a new {@link PuzzleSession | puzzle session} from a supplied
127
+ * {@link Puzzle | puzzle}.
128
+ * @param puzzle - The {@link Puzzle | puzzle} from which the session is to be
129
+ * initialized.
130
+ * @returns `Success` with the requested {@link PuzzleSession | puzzle session},
131
+ * or `Failure` with details if an error occurs.
132
+ */
133
+ static create(puzzle) {
134
+ return (0, ts_utils_1.captureResult)(() => new PuzzleSession(puzzle));
135
+ }
136
+ /**
137
+ * Determines if the puzzle is correctly solved.
138
+ * @returns `true` if the puzzle is solved, `false` if the puzzle has
139
+ * empty or invalid cells.
140
+ */
141
+ checkIsSolved() {
142
+ return this._puzzle.checkIsSolved(this.state);
143
+ }
144
+ /**
145
+ * Determines if the puzzle is valid in its current state.
146
+ * @returns `true` if all non-empty cells in the puzzle are valid,
147
+ * or `false` if any cells are invalid.
148
+ */
149
+ checkIsValid() {
150
+ return this._puzzle.checkIsValid(this.state);
151
+ }
152
+ /**
153
+ * Gets all of the currently empty {@link ICell | cells} in the puzzle.
154
+ * @returns An array of {@link ICell | ICell} with all empty cells.
155
+ */
156
+ getEmptyCells() {
157
+ return this._puzzle.getEmptyCells(this.state);
158
+ }
159
+ /**
160
+ * Gets all of the currently invalid {@link ICell | cells} in the puzzle.
161
+ * @returns An array of {@link ICell | ICell} with all invalid cells.
162
+ */
163
+ getInvalidCells() {
164
+ return this._puzzle.getInvalidCells(this.state);
165
+ }
166
+ /**
167
+ * Determines if a cell is valid.
168
+ * @param spec - A `string` ({@link CellId | CellId}), {@link IRowColumn | RowColumn} or {@link ICell | ICell}
169
+ * describing the cell to be tested.
170
+ * @returns `true` if the cell value is valid, `false` if the cell value or the cell itself is invalid.
171
+ */
172
+ cellIsValid(spec) {
173
+ var _a;
174
+ return ((_a = this._cell(spec)) === null || _a === void 0 ? void 0 : _a.isValid(this.state)) === true;
175
+ }
176
+ /**
177
+ * Determines if a cell has a value.
178
+ * @param spec - A `string` ({@link CellId | CellId}), {@link IRowColumn | RowColumn} or {@link ICell | ICell}
179
+ * describing the cell to be tested.
180
+ * @returns `true` if the cell has a value, `false` if the cell is empty or the cell itself is invalid.
181
+ */
182
+ cellHasValue(spec) {
183
+ var _a;
184
+ return ((_a = this._cell(spec)) === null || _a === void 0 ? void 0 : _a.hasValue(this.state)) === true;
185
+ }
186
+ /**
187
+ * Determines if supplied value is valid for a specific cell.
188
+ * @param spec - A `string` ({@link CellId | CellId}), {@link IRowColumn | RowColumn} or {@link ICell | ICell}
189
+ * describing the cell to be tested.
190
+ * @param value - The value to be tested.
191
+ * @returns `true` if `value` is valid for the requested cell, `false` if the value or the cell itself is invalid.
192
+ */
193
+ isValidForCell(spec, value) {
194
+ var _a;
195
+ return ((_a = this._cell(spec)) === null || _a === void 0 ? void 0 : _a.isValidValue(value, this.state)) === true;
196
+ }
197
+ /**
198
+ * Gets the neighbor for a cell in a given direction using specified wrapping rules.
199
+ * @param spec - A `string` ({@link CellId | CellId}), {@link IRowColumn | RowColumn} or {@link ICell | ICell}
200
+ * describing the cell to be tested.
201
+ * @param direction - The direction of the desired neighbor.
202
+ * @param wrap - Wrapping rules to be applied.
203
+ * @returns `Success` with the requested {@link ICell | cell}, or `Failure` with details if an error occurs.
204
+ */
205
+ getCellNeighbor(spec, direction, wrap) {
206
+ return this._puzzle.getCellNeighbor(spec, direction, wrap);
207
+ }
208
+ /**
209
+ * Gets the {@link ICellContents | contents} for a specified cell.
210
+ * @param spec - A `string` ({@link CellId | CellId}), {@link IRowColumn | RowColumn} or {@link ICell | ICell}
211
+ * describing the cell to be queried.
212
+ * @returns `Success` with the {@link ICell | cell description} and {@link ICellContents | cell contents}, or
213
+ * `Failure` with details if an error occurs.
214
+ */
215
+ getCellContents(spec) {
216
+ return this._puzzle.getCellContents(spec, this.state);
217
+ }
218
+ /**
219
+ * Updates the value of a cell.
220
+ * @param spec - A `string`, {@link IRowColumn | row and column}, or {@link ICell | cell} identifying
221
+ * the cell to be updated.
222
+ * @param value - A new value for the cell.
223
+ * @returns `Success` with `this` if the update is applied, `Failure` with details if an error occurs.
224
+ */
225
+ updateCellValue(spec, value) {
226
+ const idResult = ids_1.Ids.cellId(spec);
227
+ return idResult.onSuccess((id) => {
228
+ const notes = [];
229
+ const update = { id, value, notes };
230
+ return this._puzzle.updateValues(update, this.state).onSuccess((update) => {
231
+ this._addMove(update.cells);
232
+ this.state = update.to;
233
+ return (0, ts_utils_1.succeed)(this);
234
+ });
235
+ });
236
+ }
237
+ /**
238
+ * Updates the notes on a cell.
239
+ * @param spec - A `string`, {@link IRowColumn | row and column}, or {@link ICell | cell} identifying
240
+ * the cell to be updated.
241
+ * @param notes - New notes for the cell.
242
+ * @returns `Success` with `this` if the update is applied, `Failure` with details if an error occurs.
243
+ */
244
+ updateCellNotes(spec, notes) {
245
+ const idResult = ids_1.Ids.cellId(spec);
246
+ return idResult.onSuccess((id) => {
247
+ const value = undefined;
248
+ const update = { id, value, notes };
249
+ return this._puzzle.updateNotes(update, this.state).onSuccess((update) => {
250
+ this._addMove(update.cells);
251
+ this.state = update.to;
252
+ return (0, ts_utils_1.succeed)(this);
253
+ });
254
+ });
255
+ }
256
+ /**
257
+ * Updates value & notes for multiple cells.
258
+ * @param updates - An array of {@link ICellState | cell state} objects, each describing
259
+ * one cell to be updated.
260
+ * @returns `Success` with `this` if the updates are applied, `Failure` with details if
261
+ * an error occurs.
262
+ */
263
+ updateCells(updates) {
264
+ return this._puzzle.updateContents(updates, this.state).onSuccess((update) => {
265
+ this._addMove(update.cells);
266
+ this.state = update.to;
267
+ return (0, ts_utils_1.succeed)(this);
268
+ });
269
+ }
270
+ /**
271
+ * Determines if some {@link ICage | cage} contains a specific value.
272
+ * @param spec - A `string` ({@link CageId | CageId}) or {@link ICage | ICage}
273
+ * indicating the cage to be tested.
274
+ * @param value - The value to be tested.
275
+ * @returns `true` if the cage exists and contains the specified value,
276
+ * `false` otherwise.
277
+ */
278
+ cageContainsValue(spec, value) {
279
+ var _a;
280
+ return ((_a = this._cage(spec)) === null || _a === void 0 ? void 0 : _a.containsValue(value, this.state)) === true;
281
+ }
282
+ /**
283
+ * Determines the numbers currently present in some cage.
284
+ * @param spec - A `string` ({@link CageId | CageId}) or {@link ICage | ICage}
285
+ * indicating the cage to be tested.
286
+ * @returns A `Set<number>` containing all numbers present in the cage.
287
+ */
288
+ cageContainedValues(spec) {
289
+ var _a, _b;
290
+ return (_b = (_a = this._cage(spec)) === null || _a === void 0 ? void 0 : _a.containedValues(this.state)) !== null && _b !== void 0 ? _b : new Set();
291
+ }
292
+ /**
293
+ * Undo a single move in this puzzle session.
294
+ * @returns `Success` with `this` if the undo is applied, or `Failure`
295
+ * with details if an error occurs.
296
+ */
297
+ undo() {
298
+ if (!this.canUndo) {
299
+ return (0, ts_utils_1.fail)(`nothing to undo`);
300
+ }
301
+ return this._puzzle
302
+ .updateContents(this._steps[this._nextStep - 1].updates.map((u) => u.from), this.state)
303
+ .onSuccess((update) => {
304
+ this._nextStep--;
305
+ this.state = update.to;
306
+ return (0, ts_utils_1.succeed)(this);
307
+ });
308
+ }
309
+ /**
310
+ * Redo a single move in this puzzle session.
311
+ * @returns `Success` with `this` if the redo is applied, or `Failure`
312
+ * with details if an error occurs.
313
+ */
314
+ redo() {
315
+ if (!this.canRedo) {
316
+ return (0, ts_utils_1.fail)('nothing to redo');
317
+ }
318
+ return this._puzzle
319
+ .updateContents(this._steps[this._nextStep].updates.map((u) => u.to), this.state)
320
+ .onSuccess((update) => {
321
+ this._nextStep++;
322
+ this.state = update.to;
323
+ return (0, ts_utils_1.succeed)(this);
324
+ });
325
+ }
326
+ /**
327
+ * Gets a string representation of this puzzle, one string
328
+ * per row.
329
+ */
330
+ toStrings() {
331
+ return this._puzzle.toStrings(this.state);
332
+ }
333
+ _addMove(updates) {
334
+ if (this._nextStep < this._steps.length) {
335
+ this._steps[this._nextStep++] = { updates };
336
+ }
337
+ else {
338
+ this._steps.push({ updates });
339
+ this._nextStep = this._steps.length;
340
+ }
341
+ this._numSteps = this._nextStep;
342
+ }
343
+ _cage(spec) {
344
+ if (spec instanceof cage_1.Cage) {
345
+ return spec;
346
+ }
347
+ return ids_1.Ids.cageId(spec)
348
+ .onSuccess((id) => {
349
+ return this._puzzle.getCage(id);
350
+ })
351
+ .orDefault();
352
+ }
353
+ _cell(spec) {
354
+ if (spec instanceof cell_1.Cell) {
355
+ return spec;
356
+ }
357
+ return this._puzzle.getCell(spec).orDefault();
358
+ }
359
+ }
360
+ exports.PuzzleSession = PuzzleSession;
361
+ //# sourceMappingURL=puzzleSession.js.map