@slugbugblue/trax 0.5.0 → 0.7.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/point.js ADDED
@@ -0,0 +1,116 @@
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.
14
+ */
15
+
16
+ const is = (v, s) => (typeof v).slice(0, 3) === s // Sigh
17
+
18
+ // Are you tired of doing x,y movements in multiple statements? I am.
19
+
20
+ // Point: an immutable two-dimensional location (x,y)
21
+ // with functions for moving around quickly to neighboring points
22
+ export const Point = class {
23
+ #x = 0
24
+ #y = 0
25
+
26
+ constructor(x, y) {
27
+ if (is(x, 'obj') && is(x.x, 'num') && is(x.y, 'num')) {
28
+ // You can call this with new Point(point) or new Point({x,y})
29
+ this.#x = x.x
30
+ this.#y = x.y
31
+ } else {
32
+ // Or with new Point(x, y)
33
+ if (!is(x, 'num')) throw new SyntaxError('x must be a number')
34
+ if (!is(y, 'num')) throw new SyntaxError('y must be a number')
35
+ this.#x = x
36
+ this.#y = y
37
+ }
38
+ }
39
+
40
+ get x() {
41
+ return this.#x
42
+ }
43
+
44
+ set x(_) {
45
+ throw new ReferenceError('Point is immutable')
46
+ }
47
+
48
+ get y() {
49
+ return this.#y
50
+ }
51
+
52
+ set y(_) {
53
+ throw new ReferenceError('Point is immutable')
54
+ }
55
+
56
+ get up() {
57
+ return new Point(this.#x, this.#y - 1)
58
+ }
59
+
60
+ get down() {
61
+ return new Point(this.#x, this.#y + 1)
62
+ }
63
+
64
+ get left() {
65
+ return new Point(this.#x - 1, this.#y)
66
+ }
67
+
68
+ get right() {
69
+ return new Point(this.#x + 1, this.#y)
70
+ }
71
+
72
+ get around() {
73
+ return [this.up, this.down, this.left, this.right]
74
+ }
75
+
76
+ dir(direction) {
77
+ const error = 'direction must be one of: up, down, left, right, u, d, l, r'
78
+ if (!is(direction, 'str')) throw new SyntaxError(error)
79
+ if (direction[0] === 'u') return this.up
80
+ if (direction[0] === 'd') return this.down
81
+ if (direction[0] === 'l') return this.left
82
+ if (direction[0] === 'r') return this.right
83
+ throw new SyntaxError(error)
84
+ }
85
+
86
+ distX(from) {
87
+ return Math.abs(this.#x - from.x)
88
+ }
89
+
90
+ distY(from) {
91
+ return Math.abs(this.#y - from.y)
92
+ }
93
+
94
+ distance(from) {
95
+ return Math.hypot(this.distX(from), this.distY(from))
96
+ }
97
+
98
+ eq(that) {
99
+ return this.#x === that.x && this.#y === that.y
100
+ }
101
+
102
+ // Play nicely with the rest of the world
103
+
104
+ toString() {
105
+ return 'Point(' + this.#x + ',' + this.#y + ')'
106
+ }
107
+
108
+ toJSON() {
109
+ return { x: this.#x, y: this.#y }
110
+ }
111
+
112
+ [Symbol.for('nodejs.util.inspect.custom')](_, options) {
113
+ const [y, s, n] = [options.stylize, 'special', 'number']
114
+ return `${y('Point', s)}(${y(this.#x, n)},${y(this.#y, n)})`
115
+ }
116
+ }
package/tty.js CHANGED
@@ -17,7 +17,7 @@
17
17
 
18
18
  import process from 'node:process'
19
19
 
20
- import Trax from './engine.js'
20
+ import { Trax } from './engine.js'
21
21
 
22
22
  const esc = '\u001B[' // Start of console color escape code
23
23
  const off = esc + 'm' // Color reset code
@@ -53,19 +53,13 @@ const bg = (n) => '48;5;' + String(set[n]) // Background color_num
53
53
  const sp = () => esc + bg('e') + 'm ' // Lower space
54
54
  // tiles are displayed on two lines; the top half of the first line is empty
55
55
  // and the second half is composed of three characters, up color surrounded by tile color
56
- const uptty = (clr) =>
57
- esc +
58
- fg('t') +
59
- ';' +
60
- bg('e') +
61
- ln +
62
- esc +
63
- fg(clr) +
64
- ln +
65
- esc +
66
- fg('t') +
67
- ln +
68
- ' '
56
+ const uptty = (clr) => {
57
+ const left = esc + fg('t') + ';' + bg('e') + ln
58
+ const center = esc + fg(clr) + ln
59
+ const right = esc + fg('t') + ln + ' '
60
+ return left + center + right
61
+ }
62
+
69
63
  // The top half of the second line has both horizontal lines with a center transition
70
64
  // while the bottom half is the tile background color surrounding the down color
71
65
  const horiztty = (clr) => esc + fg('t') + ';' + bg(clr) + ln
@@ -174,12 +168,14 @@ const printIcon = (icon, setName) => {
174
168
  if (width * 4 < columns - 4 && info.length < rows - 2) {
175
169
  let colOut = ' '
176
170
  for (let col = 1; col <= width; col++) {
177
- colOut += ' ' + Trax.column(col).padEnd(3)
171
+ colOut += ' ' + Trax.encodeCol(col).padEnd(3)
178
172
  }
179
173
 
180
174
  console.info(on + colOut.padEnd((width + 1) * 4) + off)
181
- for (const line of info)
175
+ for (const line of info) {
182
176
  console.info(on + line.o + ''.padEnd((width - line.w) * 4) + ' ' + off)
177
+ }
178
+
183
179
  console.info(on + ''.padEnd((width + 1) * 4) + off)
184
180
  } else {
185
181
  console.warn('Console is too small to display this game')
@@ -211,7 +207,7 @@ export const displayGame = (game = 'trax', moves = '', tentative = false) => {
211
207
  if (tentative) {
212
208
  const drops = trax.dropTile(tentative)
213
209
  if (drops.valid) {
214
- icon = trax.tentativeIcon(drops)
210
+ icon = trax.dropsIcon(drops)
215
211
  } else {
216
212
  tentative = false
217
213
  }
@@ -1,68 +0,0 @@
1
- root: true
2
-
3
- extends:
4
- - eslint:recommended
5
-
6
- parserOptions:
7
- sourceType: module
8
-
9
- env:
10
- node: true
11
- es2021: true
12
-
13
- globals:
14
- crypto: readonly
15
-
16
- rules:
17
- curly:
18
- - error
19
- - multi-line
20
- - consistent
21
- dot-location:
22
- - error
23
- - property
24
- dot-notation: warn
25
- eqeqeq:
26
- - warn
27
- - smart
28
- guard-for-in: warn
29
- indent:
30
- - warn
31
- - 2
32
- - MemberExpression: 0
33
- SwitchCase: 1
34
- linebreak-style:
35
- - error
36
- - unix
37
- max-len:
38
- - warn
39
- - code: 99
40
- tabWidth: 2
41
- no-alert: error
42
- no-caller: error
43
- no-div-regex: warn
44
- no-else-return:
45
- - error
46
- - allowElseIf: false
47
- no-eval: error
48
- no-extra-parens: warn
49
- no-invalid-this: error
50
- no-new: error
51
- no-unused-vars:
52
- - warn
53
- - vars: all
54
- args: all
55
- caughtErrors: all
56
- no-with: error
57
- quotes:
58
- - warn
59
- - single
60
- - avoidEscape: true
61
- allowTemplateLiterals: true
62
- semi:
63
- - error
64
- - never
65
- - beforeStatementContinuationChars: always
66
- wrap-iife:
67
- - error
68
- - inside
package/jsconfig.json DELETED
@@ -1,8 +0,0 @@
1
- {
2
- "compilerOptions": {
3
- "module": "es2020",
4
- "target": "es2020"
5
- },
6
- "checkJs": true,
7
- "exclude": ["node_modules"]
8
- }