@slugbugblue/trax 0.12.0 → 0.13.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.
package/src/threats.js CHANGED
@@ -1,20 +1,9 @@
1
- /* Copyright 2022 Chad Transtrum
2
- *
3
- * Licensed under the Apache License, Version 2.0 (the "License");
4
- * you may not use this file except in compliance with the License.
5
- * You may obtain a copy of the License at
6
- *
7
- * http://www.apache.org/licenses/LICENSE-2.0
8
- *
9
- * Unless required by applicable law or agreed to in writing, software
10
- * distributed under the License is distributed on an "AS IS" BASIS,
11
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
- * See the License for the specific language governing permissions and
13
- * limitations under the License.
1
+ /** Threats database: hand-coded threats
2
+ * @copyright 2022
3
+ * @author Chad Transtrum <chad@transtrum.net>
4
+ * @license Apache-2.0
14
5
  */
15
6
 
16
- // Threats database: hand-coded threats
17
-
18
7
  const REGEX = {
19
8
  a: '[am]', // White that pairs with the next white
20
9
  c: '[cp]', // White that forms a connectable pair with next white
@@ -30,10 +19,12 @@ class CustomInspectableThreat {
30
19
  #depth = 0
31
20
  #pattern = ''
32
21
  #rx = null
22
+ #reforms = false
33
23
 
34
- constructor(depth, pattern) {
24
+ constructor(depth, pattern, reforms = false) {
35
25
  this.#depth = depth
36
26
  this.#pattern = pattern
27
+ this.#reforms = reforms
37
28
 
38
29
  let rx = ''
39
30
  for (const char of pattern) {
@@ -55,16 +46,22 @@ class CustomInspectableThreat {
55
46
  return this.#rx
56
47
  }
57
48
 
49
+ get value() {
50
+ return this.#reforms ? 2 : 1
51
+ }
52
+
58
53
  // To make life at the REPL a little easier
59
54
  [Symbol.for('nodejs.util.inspect.custom')](_, out) {
60
55
  const style = out.stylize
61
- return [
56
+ const display = [
62
57
  '[' + style('Threat', 'special') + ']',
63
58
  '{',
64
59
  style(this.#pattern, 'string') + ':',
65
60
  style(this.#depth, 'number'),
61
+ this.#reforms ? '!' : '',
66
62
  '}',
67
- ].join(' ')
63
+ ]
64
+ return display.filter((d) => d !== '').join(' ')
68
65
  }
69
66
  }
70
67
 
@@ -78,9 +75,9 @@ class CustomInspectableThreatsDB {
78
75
  }
79
76
  }
80
77
 
81
- add(depth, pattern) {
78
+ add(depth, pattern, reforms = false) {
82
79
  this.#depth = Math.max(depth, this.#depth)
83
- this.#db[pattern] = new CustomInspectableThreat(depth, pattern)
80
+ this.#db[pattern] = new CustomInspectableThreat(depth, pattern, reforms)
84
81
  return this.#db[pattern]
85
82
  }
86
83
 
@@ -127,22 +124,26 @@ const corners = {
127
124
 
128
125
  export const threats = new CustomInspectableThreatsDB(Object.keys(corners))
129
126
 
130
- // Attacks
131
- const attacks = [
132
- 'a?w', // Simple attack and wide attack
133
- ]
134
- attacks.map((a) => threats.add(1, a))
135
-
136
127
  // Re-forming attacks
137
- const reform = [
128
+ const reformAttacks = [
138
129
  'rm?lr', // Cave/wide cave attack
139
- 'rp?lr',
140
130
  'rbm?lbr', // Deep cave/deep wide cave attack (impossibly rare?)
141
- 'rbp?lbr',
142
131
  'ralmrw', // Attack at top of cave
143
132
  'arlmwr', // Reversed
144
133
  ]
145
- reform.map((r) => threats.add(2, r))
134
+ reformAttacks.map((ra) => threats.add(1, ra, true))
135
+
136
+ const reformThreats = [
137
+ 'rp?lr', // Cave/wide cave threat
138
+ 'rbp?lbr', // Deep cave/deept wide cave attach (impossibly rare?)
139
+ ]
140
+ reformThreats.map((rt) => threats.add(2, rt))
141
+
142
+ // Attacks
143
+ const attacks = [
144
+ 'a?w', // Simple attack and wide attack
145
+ ]
146
+ attacks.map((a) => threats.add(1, a))
146
147
 
147
148
  // Create multi-stage threats
148
149
  for (const one of Object.keys(corners)) {
@@ -160,5 +161,3 @@ for (const one of Object.keys(corners)) {
160
161
  threats.add(3, one + '!b*b¡' + two)
161
162
  }
162
163
  }
163
-
164
- // Create edge threats
package/src/tty.js CHANGED
@@ -17,12 +17,21 @@
17
17
 
18
18
  import process from 'node:process'
19
19
 
20
- import { Trax } from './engine.js'
20
+ import { Trax } from '@slugbugblue/trax'
21
21
 
22
22
  const esc = '\u001B[' // Start of console color escape code
23
23
  const off = esc + 'm' // Color reset code
24
-
25
- // Colorize a string
24
+ const ENV = process.env
25
+ const NERD = ENV.NERDFONT
26
+ const POWER = ENV.POWERLINE || ENV.P9K_TTY || ENV.P9K_SSH
27
+ const leftBubble = NERD ? '' : POWER ? '' : '▐'
28
+ const rightBubble = NERD ? '' : POWER ? '' : '▌'
29
+
30
+ /** Colorize a string.
31
+ * @arg {string} contents
32
+ * @arg {string|number} [fgcolor]
33
+ * @arg {string|number} [bgcolor]
34
+ */
26
35
  export const color = (contents = '', fgcolor = '', bgcolor = '') => {
27
36
  const c = []
28
37
  if (fgcolor) c.push('38;5;' + fgcolor)
@@ -35,9 +44,7 @@ export const outty = (message, fgcolor, bgcolor) => {
35
44
  console.log(color(message, fgcolor, bgcolor) + off)
36
45
  }
37
46
 
38
- let set = 'trax' // Which color set should we draw with?
39
-
40
- // a little magic to display the game in progress
47
+ // A little magic to display the game in progress
41
48
  const colorSets = {
42
49
  // Colors for terminal sequence: <Esc>[38;5;<color_num>m
43
50
  // b, B, w, W: color of line for each player, capital for a winning line
@@ -48,6 +55,8 @@ const colorSets = {
48
55
  tentative: { b: 235, B: 18, e: 19, t: 244, w: 252, W: 217 },
49
56
  }
50
57
 
58
+ let set = colorSets.trax // Which color set should we draw with?
59
+
51
60
  export const name = (rules) => {
52
61
  if (Trax.variants.has(rules)) {
53
62
  return color(Trax.names[rules], colorSets[rules].t)
@@ -67,7 +76,12 @@ export const bubble = (clr, text) => {
67
76
  }
68
77
 
69
78
  const c = colors[clr]
70
- return color('', c.bg) + color(text, c.fg, c.bg) + off + color('', c.bg)
79
+ return (
80
+ color(leftBubble, c.bg) +
81
+ color(text, c.fg, c.bg) +
82
+ off +
83
+ color(rightBubble, c.bg)
84
+ )
71
85
  }
72
86
 
73
87
  const ln = 'm\u2584' // Lower half block -- with the leading m to terminate ansi color escape
@@ -124,7 +138,7 @@ const tileTty = (tile, top) => {
124
138
  }
125
139
  }
126
140
 
127
- let value = false
141
+ let value = ''
128
142
  if (tile in tiles) {
129
143
  tile = tiles[tile]
130
144
  if (top) {
@@ -154,7 +168,7 @@ const mergeTentative = () => {
154
168
 
155
169
  const printIcon = (icon, setName) => {
156
170
  set = colorSets[setName] || colorSets.trax
157
- mergeTentative(set)
171
+ mergeTentative()
158
172
  const on = esc + '38;5;' + String(set.t) + ';48;5;' + String(set.e) + 'm'
159
173
  let o1 = ' '
160
174
  let o2 = '1 '
@@ -208,10 +222,11 @@ const printIcon = (icon, setName) => {
208
222
  }
209
223
  }
210
224
 
211
- // Flexible way to get a Trax game object
212
- // game = existing Trax instance, or a string indicating the variant name
213
- // moves = optional list or string of moves to be made on the game
214
- // returns a Trax instance
225
+ /** Flexible way to get a Trax game object.
226
+ * @arg {Trax|TraxVariant} [game] - existing Trax instance or a string indicating the variant name
227
+ * @arg {string|string[]} [moves] - optional list or string of moves to be made on the game
228
+ * @returns {Trax} a Trax instance
229
+ */
215
230
  export const traxGame = (game = 'trax', moves = '') => {
216
231
  let trax
217
232
  if (game instanceof Trax) {
@@ -253,7 +268,7 @@ const printNotation = (trax, tentative, show = Number.POSITIVE_INFINITY) => {
253
268
  export const display = (
254
269
  game,
255
270
  players,
256
- tentative = false,
271
+ tentative = '',
257
272
  showMove = Number.POSITIVE_INFINITY,
258
273
  ) => {
259
274
  const trax = traxGame(game)
@@ -266,7 +281,7 @@ export const display = (
266
281
  if (drops.valid || drops.dropped.length > 0) {
267
282
  icon = trax.dropsIcon(drops)
268
283
  } else {
269
- tentative = false
284
+ tentative = ''
270
285
  }
271
286
  } else if (showMove <= trax.moves.length) {
272
287
  icon = trax.dropsIcon({
package/src/types.d.ts ADDED
@@ -0,0 +1,105 @@
1
+ /** Type information.
2
+ * @author Chad Transtrum <chad@transtrum.net>
3
+ * @license Apache-2.0
4
+ */
5
+
6
+ /** Color is a single character to represent white or black. */
7
+ type Color = 'w' | 'b'
8
+
9
+ /** Colorize is a fancy function for colorizing text. */
10
+ type Colorize = (text: string, def?: string | number) => string
11
+
12
+ /** Colorer is a little too fancy. Hence the gnarly typescript. */
13
+ type Colorer = {
14
+ (text: string, def?: string | number): string
15
+ black: Colorize
16
+ command: Colorize
17
+ default: Colorize
18
+ error: Colorize
19
+ fatal: Colorize
20
+ help: Colorize
21
+ id: Colorize
22
+ variable: Colorize
23
+ optional: Colorize
24
+ short: Colorize
25
+ white: Colorize
26
+ }
27
+
28
+ /** A point-like object has numerical x and y properties. */
29
+ type PointLike = {
30
+ x: number
31
+ y: number
32
+ }
33
+
34
+ /** A puzzle. */
35
+ type Puzzle = {
36
+ id: string
37
+ src: string
38
+ game: TraxVariant
39
+ notation: string
40
+ icon: string
41
+ level: number
42
+ max: number
43
+ player: number
44
+ title?: string
45
+ desc?: string
46
+ hint?: string
47
+ hints?: string[]
48
+ }
49
+
50
+ type PuzzleSource = {
51
+ name: string
52
+ copyright?: string
53
+ url?: string
54
+ }
55
+
56
+ /** Treat the save state as an opaque object,
57
+ * produced by save() and fed into restore().
58
+ */
59
+ type SaveState = {
60
+ id: string
61
+ move: number
62
+ turn: number
63
+ over: boolean
64
+ left: number
65
+ right: number
66
+ top: number
67
+ bottom: number
68
+ notation: string
69
+ tiles: string
70
+ path: string
71
+ invalid: boolean
72
+ }
73
+
74
+ /** Representations of the different ways a tile can curve.
75
+ * Matches the symbols used in Trax notation.
76
+ */
77
+ type Slash = '/' | '\\' | '+'
78
+
79
+ /** A single tile on the board. */
80
+ type Tile = {
81
+ id: TileId
82
+ loc: Point
83
+ type: TileType
84
+ move: number
85
+ seq: number
86
+ }
87
+
88
+ /** When a tile is dropped, this object represents the results. */
89
+ type TileDrop = {
90
+ dropped: Tile[]
91
+ notation: string
92
+ valid: boolean
93
+ }
94
+
95
+ /** A TileId is just a string. */
96
+ type TileId = string
97
+
98
+ /** Invalid tiles are represented by 'x'. */
99
+ type TileType = ValidTiles | 'x'
100
+
101
+ /** All of the variants supported by the engine. */
102
+ type TraxVariant = 'trax' | 'traxloop' | 'trax8'
103
+
104
+ /** Tile types are represented by one of the following single characters. */
105
+ type ValidTiles = 'a' | 'b' | 'c' | 'd' | 'e' | 'f'
package/src/version.js CHANGED
@@ -1,2 +1,2 @@
1
1
  // Generated by genversion.
2
- export const version = '0.12.0'
2
+ export const version = '0.13.0'