@slugbugblue/trax 0.19.0 → 0.21.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.
@@ -1,4 +1,4 @@
1
- /* Copyright 2022 Chad Transtrum
1
+ /* Copyright 2022-2023 Chad Transtrum
2
2
  *
3
3
  * Licensed under the Apache License, Version 2.0 (the "License");
4
4
  * you may not use this file except in compliance with the License.
@@ -16,6 +16,7 @@
16
16
  // CLI suggest command
17
17
 
18
18
  import { suggest } from '@slugbugblue/trax/analyst'
19
+ import { timeString } from '@slugbugblue/trax/utils'
19
20
 
20
21
  export const suggestCmd = {
21
22
  name: 'suggest',
@@ -47,6 +48,8 @@ suggestCmd.fn = (CLI, debug) => {
47
48
  m.push(move.move + ' ' + move.score)
48
49
  }
49
50
 
50
- CLI.out('[' + m.join(', ') + '] ' + suggestion.ms + 'ms')
51
+ CLI.out(
52
+ '[' + m.join(', ') + '] ' + CLI.color.black(timeString(suggestion.ms)),
53
+ )
51
54
  }
52
55
  }
package/src/cmds/view.js CHANGED
@@ -27,11 +27,15 @@ export const viewCmd = {
27
27
  ],
28
28
  }
29
29
 
30
- viewCmd.fn = (CLI, move) => {
30
+ viewCmd.fn = (CLI, move, ...extra) => {
31
31
  if (!CLI.GAME?.id) {
32
32
  return CLI.error('No active game. Type "new" to start a game.')
33
33
  }
34
34
 
35
+ if (move?.length > 1 && 'puzzles'.startsWith(move)) {
36
+ return CLI.do('puzzles', 'list', ...extra)
37
+ }
38
+
35
39
  const trax = CLI.TRAX
36
40
 
37
41
  let show = Number.POSITIVE_INFINITY
package/src/puzzles.js CHANGED
@@ -26,6 +26,15 @@ export const sources = {
26
26
  book1: {
27
27
  name: 'Martin M. S. Pedersen',
28
28
  url: 'https://gnutrax.com/book',
29
+ copyright: '2011',
30
+ license: 'CC BY 4.0',
31
+ licenseUrl: 'https://creativecommons.org/licenses/by/4.0/',
32
+ },
33
+ book2: {
34
+ name: 'Martin M. S. Pedersen',
35
+ copyright: '2023',
36
+ license: 'CC BY 4.0',
37
+ licenseUrl: 'https://creativecommons.org/licenses/by/4.0/',
29
38
  },
30
39
  }
31
40
 
@@ -764,7 +773,7 @@ export const puzzles = [
764
773
  level: 3,
765
774
  player: 2,
766
775
  max: 16,
767
- hints: ['A0+', 'C2\\'],
776
+ hint: 'A0+',
768
777
  },
769
778
  {
770
779
  id: 'hb4.trx',
@@ -811,7 +820,7 @@ export const puzzles = [
811
820
  hint: 'B1+',
812
821
  },
813
822
  {
814
- id: 'book_01.trx',
823
+ id: 'book.01',
815
824
  src: 'book1',
816
825
  game: 'traxloop',
817
826
  notation: '@0/ @1+ B0/ C1+ D2/ C3/',
@@ -822,18 +831,18 @@ export const puzzles = [
822
831
  hint: '@2/',
823
832
  },
824
833
  {
825
- id: 'book_02.trx',
834
+ id: 'book.02',
826
835
  src: 'book1',
827
836
  game: 'traxloop',
828
837
  notation: '@0+ B1+ C1/ B0/ B0/ B0/ B0/ D5/ E5/ E6+ C4/ C3+ B6+',
829
- icon: '0df:0ca:0df:cd:eecdc:0efae',
838
+ icon: '0df:0ca:0de:0cd:eecdc:0efae',
830
839
  level: 2,
831
840
  player: 2,
832
841
  max: 18,
833
842
  hints: ['D2\\', 'D3/'],
834
843
  },
835
844
  {
836
- id: 'book_03.trx',
845
+ id: 'book.03',
837
846
  src: 'book1',
838
847
  game: 'traxloop',
839
848
  notation: '@0/ @1/ @1+ @1/ @1+ C0/ D1/ E1+ D0+ E1+ F1\\ E0+',
@@ -844,18 +853,18 @@ export const puzzles = [
844
853
  hint: 'C1\\',
845
854
  },
846
855
  {
847
- id: 'book_04.trx',
856
+ id: 'book.04',
848
857
  src: 'book1',
849
858
  game: 'traxloop',
850
- notation: '@0+ B1/ @1/ A0/ C3/ A4+ @4+ @3/ a5\\',
859
+ notation: '@0+ B1/ @1/ A0/ C3/ A4+ @4+ @3/ A5\\',
851
860
  icon: '1caf:1dec:dcafd:aeec:fd',
852
861
  level: 3,
853
862
  player: 2,
854
863
  max: 16,
855
- hint: 'C0/',
864
+ hints: ['C0/', 'D0\\'],
856
865
  },
857
866
  {
858
- id: 'book_05.trx',
867
+ id: 'book.05',
859
868
  src: 'book1',
860
869
  game: 'traxloop',
861
870
  notation: '@0/ @1/ B0+ @2+ A0/ @2+',
@@ -866,7 +875,7 @@ export const puzzles = [
866
875
  hints: ['B4\\', 'C4/'],
867
876
  },
868
877
  {
869
- id: 'book_07.trx',
878
+ id: 'book.07',
870
879
  src: 'book1',
871
880
  game: 'traxloop',
872
881
  notation: '@0/ A2+ A0+ @2\\ B0+ C1+ B0/ B0/ A2+',
@@ -877,7 +886,7 @@ export const puzzles = [
877
886
  hint: 'C6+',
878
887
  },
879
888
  {
880
- id: 'book_08.trx',
889
+ id: 'book.08',
881
890
  src: 'book1',
882
891
  game: 'traxloop',
883
892
  notation: '@0/ @1/ A2/ A0/ B1/ @1+ @1/ A0/ @1/',
@@ -888,7 +897,7 @@ export const puzzles = [
888
897
  hint: 'A0\\',
889
898
  },
890
899
  {
891
- id: 'book_09.trx',
900
+ id: 'book.09',
892
901
  src: 'book1',
893
902
  game: 'traxloop',
894
903
  notation: '@0/ @1/ B0/ B0/ A0/ A5/ @3\\ @4/',
@@ -899,7 +908,7 @@ export const puzzles = [
899
908
  hint: 'A2\\',
900
909
  },
901
910
  {
902
- id: 'book_10.trx',
911
+ id: 'book.10',
903
912
  src: 'book1',
904
913
  game: 'traxloop',
905
914
  notation: '@0/ A0+ A0/ A4+ A0/ A0/ B4+ C4/ @4+ @4/ @4/',
@@ -907,10 +916,10 @@ export const puzzles = [
907
916
  level: 2,
908
917
  player: 2,
909
918
  max: 18,
910
- hint: 'E6+',
919
+ hints: ['D7\\', 'E6+'],
911
920
  },
912
921
  {
913
- id: 'book_11.trx',
922
+ id: 'book.11',
914
923
  src: 'book1',
915
924
  game: 'traxloop',
916
925
  notation: '@0+ B1+ C1/ C0/ B0/ @3+',
@@ -921,7 +930,7 @@ export const puzzles = [
921
930
  hint: 'B1\\',
922
931
  },
923
932
  {
924
- id: 'book_12.trx',
933
+ id: 'book.12',
925
934
  src: 'book1',
926
935
  game: 'traxloop',
927
936
  notation: '@0+ B1+ C1/ C0/ B0/ D2+',
@@ -929,8 +938,297 @@ export const puzzles = [
929
938
  level: 3,
930
939
  player: 1,
931
940
  max: 15,
941
+ hints: ['B4\\', 'C4/'],
942
+ },
943
+ {
944
+ id: 'book.13',
945
+ src: 'book1',
946
+ game: 'traxloop',
947
+ notation: '@0/ @1/ B2+ A0\\ @1+ @1\\ C4/ B4/',
948
+ icon: 'aefa:1cd:1fb:0dc',
949
+ level: 3,
950
+ player: 1,
951
+ max: 15,
952
+ hint: 'C5\\',
953
+ },
954
+ {
955
+ id: 'book.15',
956
+ src: 'book1',
957
+ game: 'traxloop',
958
+ notation: '@0/ A0/ @1+ A0\\ C1+ D1+ B0+ A0/ @5+ A2/ A0+ @1\\ A4+ @4+',
959
+ icon: 'caef:dfdca:cacdef:eefafbb:0faec:0aefd',
960
+ level: 3,
961
+ player: 1,
962
+ max: 21,
963
+ hints: ['B7\\', 'C7/'],
964
+ },
965
+ {
966
+ id: 'book.17',
967
+ src: 'book1',
968
+ game: 'traxloop',
969
+ notation: '@0/ @1/ B0+ C1/ @1\\ B0/ C0/ D0+ A2+ @2+',
970
+ icon: '2de:eecaf:0fdec:0acd',
971
+ level: 3,
972
+ player: 1,
973
+ max: 19,
974
+ hints: ['A1/', 'B1\\'],
975
+ },
976
+ {
977
+ id: 'book.18',
978
+ src: 'book1',
979
+ game: 'traxloop',
980
+ notation: '@0+ B1+ C1/ B2\\ B3\\ B4\\ B5\\',
981
+ icon: 'eec:0fd:0ac:0fd:0ac',
982
+ level: 2,
983
+ player: 2,
984
+ max: 14,
985
+ hint: 'D3+',
986
+ },
987
+ {
988
+ id: 'book.19',
989
+ src: 'book1',
990
+ game: 'traxloop',
991
+ notation: '@0+ B1+ @1/ @1/ B2\\',
992
+ icon: 'cdee:fa',
993
+ level: 2,
994
+ player: 2,
995
+ max: 12,
996
+ hint: 'E1\\',
997
+ },
998
+ {
999
+ id: 'book.20',
1000
+ src: 'book1',
1001
+ game: 'traxloop',
1002
+ notation: '@0/ @1/ B0+ B0/ C3+ D3+ E3\\',
1003
+ icon: '0c:de:cdeef',
1004
+ level: 2,
1005
+ player: 2,
1006
+ max: 14,
1007
+ hints: ['C4+', 'B4\\'],
1008
+ },
1009
+ {
1010
+ id: 'book.23',
1011
+ src: 'book1',
1012
+ game: 'traxloop',
1013
+ notation: '@0+ @1\\ @1\\ @1\\ @1+ A0+ @1/ B3\\ E3/',
1014
+ icon: 'cb:fbafae:0a1d',
1015
+ level: 2,
1016
+ player: 2,
1017
+ max: 12,
1018
+ hint: 'F1+',
1019
+ },
1020
+ {
1021
+ id: 'book.25',
1022
+ src: 'book1',
1023
+ game: 'traxloop',
1024
+ notation: '@0/ @1/ B0/ B0+ C1/ C0+ B0/ A2+ @1/ @3\\',
1025
+ icon: '0cdca:0fbde:facbd:afdc:facd',
1026
+ level: 3,
1027
+ player: 1,
1028
+ max: 17,
1029
+ hint: 'B0+',
1030
+ },
1031
+ {
1032
+ id: 'book.26',
1033
+ src: 'book1',
1034
+ game: 'traxloop',
1035
+ notation: '@0/ @1/ @1/ @1+ A0\\ B0+ @3/ @3/',
1036
+ icon: '1cbaf:cdfafa:dcbdcd',
1037
+ level: 4,
1038
+ player: 1,
1039
+ max: 21,
932
1040
  hint: 'B4\\',
933
1041
  },
1042
+ {
1043
+ id: 'book.28',
1044
+ src: 'book1',
1045
+ game: 'traxloop',
1046
+ notation: '@0/ @1/ B0/ C1/ C0/ @2+ A0+ D0+ @2\\ @3+ A4/ @4\\ A2/',
1047
+ icon: '3cde:dcaefaf:aefdcdc:fdcbdcd:0afacdc',
1048
+ level: 2,
1049
+ player: 2,
1050
+ max: 20,
1051
+ hint: 'G6+',
1052
+ },
1053
+ {
1054
+ id: 'book.29',
1055
+ src: 'book1',
1056
+ game: 'traxloop',
1057
+ notation: '@0/ B1+ B2\\ B3/',
1058
+ icon: 'de:af:0c',
1059
+ level: 3,
1060
+ player: 1,
1061
+ max: 13,
1062
+ hint: '@2/',
1063
+ },
1064
+ {
1065
+ id: 'book.30',
1066
+ src: 'book1',
1067
+ game: 'traxloop',
1068
+ notation:
1069
+ '@0/ @1/ @1/ D1+ A2+ E1+ E2+ E0+ F1\\ G1+ G2\\ F3+ E4\\ G3+ H2\\ C5\\ D5+ D6\\ D7\\',
1070
+ icon: '3efba:dcdeecaf:bdcdeeec:0afafd:0faec:2fd:2ac',
1071
+ level: 4,
1072
+ player: 2,
1073
+ max: 30,
1074
+ hints: ['H4/', 'G4\\'],
1075
+ },
1076
+ {
1077
+ id: 'book.31',
1078
+ src: 'book1',
1079
+ game: 'traxloop',
1080
+ notation: '@0/ @1/ C1/ A2+ B3+ A3/ D3\\ B4\\ D4+ C5+ E2\\ E3+',
1081
+ icon: 'cdcaf:ecdfa:decae:afde:1bd',
1082
+ level: 3,
1083
+ player: 1,
1084
+ max: 23,
1085
+ hints: ['E0/', '@4/'],
1086
+ },
1087
+ {
1088
+ id: 'book.32',
1089
+ src: 'book1',
1090
+ game: 'traxloop',
1091
+ notation: '@0/ @1+ C1/ B2+ A2/ B3+ D2/ E2\\ D3+ F2+ G2\\ G3\\ C4\\ C5+ A4+',
1092
+ icon: 'bdc:cbdcaef:fbaeefa:bafd:afb',
1093
+ level: 3,
1094
+ player: 2,
1095
+ max: 24,
1096
+ hint: 'G4+',
1097
+ },
1098
+ {
1099
+ id: 'book.35',
1100
+ src: 'book1',
1101
+ game: 'traxloop',
1102
+ notation: '@0+ B1+ A0+ @2+ @2+ @2+ A1+ @1/ E3/',
1103
+ icon: 'de1e:aeeeee:2fd',
1104
+ level: 4,
1105
+ player: 2,
1106
+ max: 20,
1107
+ hint: 'E4\\',
1108
+ },
1109
+ {
1110
+ id: 'book.38',
1111
+ src: 'book1',
1112
+ game: 'traxloop',
1113
+ notation: '@0/ B1/ C1/ D1/ A2+ E1+ D3\\ E3+ F3+ F4\\ G4\\ F5\\ G5\\',
1114
+ icon: 'dcdcb:bdcdca:0afaeef:4fa:4af',
1115
+ level: 3,
1116
+ player: 2,
1117
+ max: 22,
1118
+ hint: 'B4+',
1119
+ },
1120
+ {
1121
+ id: 'book.40',
1122
+ src: 'book1',
1123
+ game: 'traxloop',
1124
+ notation: '@0/ @1/ A2+ @2/ @2/ B1+ B3\\',
1125
+ icon: 'decd:cdec:fa',
1126
+ level: 3,
1127
+ player: 2,
1128
+ max: 14,
1129
+ hint: 'E2+',
1130
+ },
1131
+ {
1132
+ id: 'book.42',
1133
+ src: 'book1',
1134
+ game: 'traxloop',
1135
+ notation: '@0/ B1+ @1+ A2/ A3+ B0+ D2+ E2\\ D1/',
1136
+ icon: 'deeca:bdeef:c:d',
1137
+ level: 2,
1138
+ player: 2,
1139
+ max: 16,
1140
+ hint: 'F1/',
1141
+ },
1142
+ {
1143
+ id: 'book.43',
1144
+ src: 'book1',
1145
+ game: 'traxloop',
1146
+ notation:
1147
+ '@0/ A0/ A0/ A0+ @1\\ C1+ D1/ E1+ F1/ D0+ B1+ A0/ @1+ @1/ D0+ D0\\',
1148
+ icon: '2f:2ba:decaf:afdecb:1aeecbd:1fd:1ac:1fd',
1149
+ level: 3,
1150
+ player: 1,
1151
+ max: 27,
1152
+ hints: ['E6\\', 'F6/'],
1153
+ },
1154
+ {
1155
+ id: 'book.44',
1156
+ src: 'book1',
1157
+ game: 'traxloop',
1158
+ notation: '@0/ @1/ C1/ D1+ B2/ D3\\ E1\\ D0/ F2+ E4+ F3\\ F4\\',
1159
+ icon: '2dfa:cdcbae:0cdcdf:0fafba',
1160
+ level: 3,
1161
+ player: 1,
1162
+ max: 19,
1163
+ hint: 'D5+',
1164
+ },
1165
+ {
1166
+ id: 'book.45',
1167
+ src: 'book1',
1168
+ game: 'traxloop',
1169
+ notation: 'A0+ B1+ C1/ C0/ B0/ D2\\ A4\\ A5\\ C4+ @3+',
1170
+ icon: '1d:1cdf:eeec:0fde:0acd',
1171
+ level: 3,
1172
+ player: 1,
1173
+ max: 17,
1174
+ hint: 'E1/',
1175
+ },
1176
+ {
1177
+ id: 'book.47',
1178
+ src: 'book1',
1179
+ game: 'traxloop',
1180
+ notation: '@0/ A0/ @2+ B0+ B0+ @3\\ @3\\ @3\\ A2/',
1181
+ icon: '3b:c1cb:fafdc:2bd',
1182
+ level: 2,
1183
+ player: 2,
1184
+ max: 14,
1185
+ hint: 'A1\\',
1186
+ },
1187
+ {
1188
+ id: 'book.49',
1189
+ src: 'book1',
1190
+ game: 'traxloop',
1191
+ notation: '@0/ @1/ @1/ @1/ D0+ @2+ @2/ @2/ @2/ F3\\ G3\\',
1192
+ icon: '2cdcde:dcdecdcd:3faf',
1193
+ level: 3,
1194
+ player: 2,
1195
+ max: 16,
1196
+ hints: ['A1+', 'A3+'],
1197
+ },
1198
+ {
1199
+ id: 'book.50',
1200
+ src: 'book1',
1201
+ game: 'traxloop',
1202
+ notation: '@0/ @1/ @1/ @1+ @1/ @1/ A0/ A3/ D3+',
1203
+ icon: 'c:dcbdcd:cdcbdc',
1204
+ level: 3,
1205
+ player: 2,
1206
+ max: 16,
1207
+ hint: 'D1+',
1208
+ },
1209
+ {
1210
+ id: 'book2.132',
1211
+ src: 'book2',
1212
+ game: 'traxloop',
1213
+ notation: '@0+ B1+ C1/ @1\\ D2\\ E2+ D3\\ D4\\',
1214
+ icon: 'aeec:2fb:2ac:2fd',
1215
+ level: 4,
1216
+ player: 1,
1217
+ max: 15,
1218
+ hint: 'C3\\',
1219
+ },
1220
+ {
1221
+ id: 'book2.148',
1222
+ src: 'book2',
1223
+ game: 'traxloop',
1224
+ notation:
1225
+ '@0/ B1\\ A2/ A0/ C1\\ @2/ @2+ A0\\ @2/ @2/ @2/ B4+ A5+ A1+ E0+ E0/ E0/',
1226
+ icon: '3ca:3df:0cdcba:efafaf:dcdcdcaf:afaecdf:fbd1c:b',
1227
+ level: 4,
1228
+ player: 2,
1229
+ max: 24,
1230
+ hint: 'B2\\',
1231
+ },
934
1232
  ]
935
1233
 
936
1234
  puzzles.sort(
package/src/threats.js CHANGED
@@ -83,7 +83,7 @@ export class ThreatsDB {
83
83
  }
84
84
 
85
85
  compose(depth, pattern) {
86
- pattern = pattern.replaceAll(/(?<=.)A/g, 'a').replaceAll(/W(?=.)/g, 'w')
86
+ pattern = pattern.replace(/(?<=.)A/g, 'a').replace(/W(?=.)/g, 'w')
87
87
  return this.add(depth, pattern)
88
88
  }
89
89
 
package/src/types.d.ts CHANGED
@@ -71,11 +71,17 @@ type FaultyThreats = {
71
71
 
72
72
  /** An object with keys representing each level, with arrays for each threat of
73
73
  * that level. */
74
- type FoundThreats = Record<string, FoundThreat[]>
74
+ type ColorThreats = Record<string, FoundThreat[]>
75
75
 
76
76
  /** All the threats found for both the white and black player. */
77
77
  type FoundThreatsCollection = { b: ColorThreats; w: ColorThreats }
78
78
 
79
+ /** Scores for each player. */
80
+ type Scores = {
81
+ b: number
82
+ w: number
83
+ }
84
+
79
85
  /** A note with a move number */
80
86
  type GameNote = {
81
87
  move: number
@@ -116,8 +122,10 @@ type Puzzle = {
116
122
 
117
123
  type PuzzleSource = {
118
124
  name: string
119
- copyright?: string
120
125
  url?: string
126
+ copyright?: string
127
+ license?: string
128
+ licenseUrl?: string
121
129
  }
122
130
 
123
131
  /** Array of objects representing the spaces surrounding the perimeter of a
package/src/utils.js ADDED
@@ -0,0 +1,22 @@
1
+ /** Shared utilities
2
+ * @copyright 2023
3
+ * @author Chad Transtrum <chad@transtrum.net>
4
+ * @license Apache-2.0
5
+ */
6
+
7
+ /** Convert milliseconds to a human readable string in ms, sec, or min units.
8
+ * @arg {number} ms - the number of milliseconds
9
+ * @returns {string} a short human-readable representation of the time
10
+ */
11
+ export const timeString = (ms) => {
12
+ if (ms < 1000) {
13
+ return (ms === Math.floor(ms) ? String(ms) : ms.toFixed(2)) + ' ms'
14
+ }
15
+
16
+ ms /= 1000
17
+ if (ms < 60) return ms.toFixed(3) + ' sec'
18
+
19
+ const min = Math.floor(ms / 60)
20
+ ms -= min * 60
21
+ return String(min) + ' min ' + ms.toFixed(3) + ' sec'
22
+ }
package/src/version.js CHANGED
@@ -1,2 +1,2 @@
1
1
  // Generated by genversion.
2
- export const version = '0.19.0'
2
+ export const version = '0.21.0'
package/.husky/pre-commit DELETED
@@ -1,4 +0,0 @@
1
- #!/usr/bin/env sh
2
- . "$(dirname -- "$0")/_/husky.sh"
3
-
4
- npm test
@@ -1,60 +0,0 @@
1
- {
2
- "0.17.0": {
3
- "puzzles.firstmove.tutorial": {
4
- "count": 16,
5
- "ms": 2007
6
- },
7
- "puzzles.firstmove.beginner": {
8
- "count": 16,
9
- "ms": 2664
10
- },
11
- "puzzles.firstmove.tough": {
12
- "count": 1,
13
- "ms": 76
14
- },
15
- "puzzles.firstmove.total": {
16
- "count": 33,
17
- "ms": 4838
18
- }
19
- },
20
- "0.18.0": {
21
- "puzzles.firstmove.tutorial": {
22
- "count": 16,
23
- "ms": 10164
24
- },
25
- "puzzles.firstmove.beginner": {
26
- "count": 15,
27
- "ms": 17864
28
- },
29
- "puzzles.firstmove.tough": {
30
- "count": 26,
31
- "ms": 30349
32
- },
33
- "puzzles.firstmove.advanced": {
34
- "count": 1,
35
- "ms": 427
36
- },
37
- "puzzles.firstmove.total": {
38
- "count": 58,
39
- "ms": 59031
40
- }
41
- },
42
- "0.19.0": {
43
- "puzzles.firstmove.tutorial": {
44
- "count": 16,
45
- "ms": 9753
46
- },
47
- "puzzles.firstmove.beginner": {
48
- "count": 15,
49
- "ms": 17376
50
- },
51
- "puzzles.firstmove.tough": {
52
- "count": 25,
53
- "ms": 26380
54
- },
55
- "puzzles.firstmove.total": {
56
- "count": 56,
57
- "ms": 55167
58
- }
59
- }
60
- }