lettersoup 1.0.2 → 1.1.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/README.md +67 -10
- package/dist/Entities/Cordenates.d.ts +20 -0
- package/dist/Entities/Cordenates.js +90 -0
- package/dist/Entities/CrossRow.d.ts +14 -0
- package/dist/Entities/CrossRow.js +44 -0
- package/dist/Entities/DimensionBoard.d.ts +11 -0
- package/dist/Entities/DimensionBoard.js +20 -0
- package/dist/Entities/PlayBoard.d.ts +12 -0
- package/dist/Entities/PlayBoard.js +39 -0
- package/dist/Entities/Word.d.ts +15 -0
- package/dist/Entities/Word.js +40 -0
- package/dist/Types.d.ts +33 -0
- package/dist/Types.js +17 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +6 -0
- package/dist/letterSoup.d.ts +16 -0
- package/dist/letterSoup.js +127 -0
- package/dist/utils/regex.d.ts +8 -0
- package/dist/utils/regex.js +50 -0
- package/dist/utils/string.d.ts +4 -0
- package/dist/utils/string.js +5 -0
- package/package.json +15 -2
- package/.github/workflows/npm-publish.yml +0 -33
- package/.nvmrc +0 -1
- package/__tests__/index.test.ts +0 -36
- package/__tests__/utils/regex.test.ts +0 -80
- package/jest.config.js +0 -7
- package/src/Entities/Cords.ts +0 -127
- package/src/Entities/Dimension.ts +0 -24
- package/src/Entities/Lines.ts +0 -59
- package/src/Entities/Matrix.ts +0 -43
- package/src/Entities/Word.ts +0 -115
- package/src/Types.ts +0 -40
- package/src/index.ts +0 -2
- package/src/letterSoup.ts +0 -130
- package/src/utils/regex.ts +0 -68
- package/src/utils/string.ts +0 -10
- package/tsconfig.json +0 -111
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.generateRegexByLine = exports.generateRegexByGroupOfSpacesAndLetters = exports.chunkListCharactersByCriterial = exports.joinRegexStringWithPipe = exports.splitsGroupOfSpacesAndLetter = exports.isWhiteSpace = exports.hasAnotherLetters = void 0;
|
|
4
|
+
const hasAnotherLetters = (space) => /[A-Z]|Á|É|Í|Ó|Ú|Ñ/i.test(space);
|
|
5
|
+
exports.hasAnotherLetters = hasAnotherLetters;
|
|
6
|
+
const isWhiteSpace = (groupToText) => /\s+/.test(groupToText);
|
|
7
|
+
exports.isWhiteSpace = isWhiteSpace;
|
|
8
|
+
const splitsGroupOfSpacesAndLetter = (line) => {
|
|
9
|
+
return line.match(/\s+|\S+/g);
|
|
10
|
+
};
|
|
11
|
+
exports.splitsGroupOfSpacesAndLetter = splitsGroupOfSpacesAndLetter;
|
|
12
|
+
const isFirstGroup = (index) => index === 0;
|
|
13
|
+
const isLastGroup = (index, lengthGroup) => index === (lengthGroup - 1);
|
|
14
|
+
const isBetweenGroup = (index, lengthGroup) => 0 < index && index < (lengthGroup - 1);
|
|
15
|
+
const regexByListGroup = (groups) => groups.reduce((regex, group, index, groups) => {
|
|
16
|
+
if (isFirstGroup(index))
|
|
17
|
+
regex += '(^';
|
|
18
|
+
if (isWhiteSpace(group) && isBetweenGroup(index, groups.length))
|
|
19
|
+
regex += `.{${group.length}}`;
|
|
20
|
+
else if (isWhiteSpace(group))
|
|
21
|
+
regex += `.{1,${group.length}}`;
|
|
22
|
+
if (!isWhiteSpace(group))
|
|
23
|
+
regex += `${group}`;
|
|
24
|
+
if (isLastGroup(index, groups.length))
|
|
25
|
+
regex += '$)';
|
|
26
|
+
return regex;
|
|
27
|
+
}, '');
|
|
28
|
+
const chunkListCharactersByCriterial = (groups) => {
|
|
29
|
+
let chunked = [];
|
|
30
|
+
while (groups.length > 0) {
|
|
31
|
+
const criterial = isWhiteSpace(groups[0]) ? 3 : 2;
|
|
32
|
+
chunked.push(groups.slice(0, criterial));
|
|
33
|
+
groups.splice(0, groups.length <= criterial ? criterial : criterial - 1);
|
|
34
|
+
}
|
|
35
|
+
return chunked;
|
|
36
|
+
};
|
|
37
|
+
exports.chunkListCharactersByCriterial = chunkListCharactersByCriterial;
|
|
38
|
+
const joinRegexStringWithPipe = (...stringRegex) => stringRegex.join('|');
|
|
39
|
+
exports.joinRegexStringWithPipe = joinRegexStringWithPipe;
|
|
40
|
+
const generateRegexByGroupOfSpacesAndLetters = (groups) => {
|
|
41
|
+
return new RegExp(joinRegexStringWithPipe(regexByListGroup(groups), ...chunkListCharactersByCriterial(groups).map(chunk => regexByListGroup(chunk))), 'gm');
|
|
42
|
+
};
|
|
43
|
+
exports.generateRegexByGroupOfSpacesAndLetters = generateRegexByGroupOfSpacesAndLetters;
|
|
44
|
+
const generateRegexByLine = (line) => {
|
|
45
|
+
const splitedLine = splitsGroupOfSpacesAndLetter(line);
|
|
46
|
+
if (!splitedLine)
|
|
47
|
+
throw 'Error for split line';
|
|
48
|
+
return generateRegexByGroupOfSpacesAndLetters(splitedLine);
|
|
49
|
+
};
|
|
50
|
+
exports.generateRegexByLine = generateRegexByLine;
|
package/package.json
CHANGED
|
@@ -1,12 +1,18 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "lettersoup",
|
|
3
|
-
"version": "1.0
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"description": "generate letterSoup",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
7
|
+
"files": [
|
|
8
|
+
"dist"
|
|
9
|
+
],
|
|
7
10
|
"scripts": {
|
|
8
11
|
"build": "tsc --project tsconfig.json",
|
|
9
|
-
"
|
|
12
|
+
"prebuild": "rm -rf dist",
|
|
13
|
+
"prepublishOnly": "npm run build",
|
|
14
|
+
"test": "jest",
|
|
15
|
+
"lint": "eslint 'src/**/*.ts' '__tests__/**/*.ts'"
|
|
10
16
|
},
|
|
11
17
|
"keywords": [
|
|
12
18
|
"letterSoup",
|
|
@@ -17,8 +23,15 @@
|
|
|
17
23
|
],
|
|
18
24
|
"author": "Fabian Escarate",
|
|
19
25
|
"license": "ISC",
|
|
26
|
+
"repository": {
|
|
27
|
+
"type": "git",
|
|
28
|
+
"url": "https://github.com/FabianEscarate/letterSoup"
|
|
29
|
+
},
|
|
20
30
|
"devDependencies": {
|
|
21
31
|
"@types/jest": "^29.5.12",
|
|
32
|
+
"@typescript-eslint/eslint-plugin": "^8.53.0",
|
|
33
|
+
"@typescript-eslint/parser": "^8.53.0",
|
|
34
|
+
"eslint": "^9.39.2",
|
|
22
35
|
"jest": "^29.7.0",
|
|
23
36
|
"ts-jest": "^29.2.2",
|
|
24
37
|
"ts-node": "^10.9.2",
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
# This workflow will run tests using node and then publish a package to GitHub Packages when a release is created
|
|
2
|
-
# For more information see: https://docs.github.com/en/actions/publishing-packages/publishing-nodejs-packages
|
|
3
|
-
|
|
4
|
-
name: Node.js Package
|
|
5
|
-
|
|
6
|
-
on:
|
|
7
|
-
release:
|
|
8
|
-
types: [created]
|
|
9
|
-
|
|
10
|
-
jobs:
|
|
11
|
-
build:
|
|
12
|
-
runs-on: ubuntu-latest
|
|
13
|
-
steps:
|
|
14
|
-
- uses: actions/checkout@v4
|
|
15
|
-
- uses: actions/setup-node@v4
|
|
16
|
-
with:
|
|
17
|
-
node-version: 20
|
|
18
|
-
- run: npm ci
|
|
19
|
-
- run: npm test
|
|
20
|
-
|
|
21
|
-
publish-npm:
|
|
22
|
-
needs: build
|
|
23
|
-
runs-on: ubuntu-latest
|
|
24
|
-
steps:
|
|
25
|
-
- uses: actions/checkout@v4
|
|
26
|
-
- uses: actions/setup-node@v4
|
|
27
|
-
with:
|
|
28
|
-
node-version: 20
|
|
29
|
-
registry-url: https://registry.npmjs.org/
|
|
30
|
-
- run: npm ci
|
|
31
|
-
- run: npm publish
|
|
32
|
-
env:
|
|
33
|
-
NODE_AUTH_TOKEN: ${{secrets.npm_token}}
|
package/.nvmrc
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
v22.4.1
|
package/__tests__/index.test.ts
DELETED
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
import { WordSearch } from "../src"
|
|
2
|
-
|
|
3
|
-
describe('letterSoup generator', () => {
|
|
4
|
-
|
|
5
|
-
const wordsArray = [
|
|
6
|
-
"tarjetas",
|
|
7
|
-
"Weaselling",
|
|
8
|
-
"Pinwales",
|
|
9
|
-
"populoso",
|
|
10
|
-
"participio",
|
|
11
|
-
"Cuddliest",
|
|
12
|
-
"Especias",
|
|
13
|
-
"teléfonos",
|
|
14
|
-
"epigráfico",
|
|
15
|
-
"hidrométrico",
|
|
16
|
-
"licitador",
|
|
17
|
-
"partición",
|
|
18
|
-
"miembros",
|
|
19
|
-
"nuestra",
|
|
20
|
-
"restituciones"
|
|
21
|
-
]
|
|
22
|
-
|
|
23
|
-
test('should return a object when call generate function', () => {
|
|
24
|
-
const {
|
|
25
|
-
getPuzzle,
|
|
26
|
-
getWords
|
|
27
|
-
} = new WordSearch(wordsArray)
|
|
28
|
-
|
|
29
|
-
const listOfWord = getWords()
|
|
30
|
-
const puzzle = getPuzzle()
|
|
31
|
-
|
|
32
|
-
expect(puzzle).toBeDefined()
|
|
33
|
-
expect(listOfWord).toBeDefined()
|
|
34
|
-
|
|
35
|
-
})
|
|
36
|
-
})
|
|
@@ -1,80 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
hasAnotherLetters,
|
|
3
|
-
generateRegexByGroupOfSpacesAndLetters,
|
|
4
|
-
isWhiteSpace,
|
|
5
|
-
splitsGroupOfSpacesAndLetter,
|
|
6
|
-
chunkListCharactersByCriterial,
|
|
7
|
-
joinRegexStringWithPipe
|
|
8
|
-
} from "../../src/utils/regex";
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
describe('Regex Suite', () => {
|
|
12
|
-
|
|
13
|
-
test('should validate if line has letters', () => {
|
|
14
|
-
const lineWithLetters = ' sa '
|
|
15
|
-
const lineWithOutLetters = ' '
|
|
16
|
-
|
|
17
|
-
expect(hasAnotherLetters(lineWithLetters)).toBeTruthy()
|
|
18
|
-
expect(hasAnotherLetters(lineWithOutLetters)).toBeFalsy()
|
|
19
|
-
})
|
|
20
|
-
|
|
21
|
-
test('should valid a empty string', () => {
|
|
22
|
-
const lineEmpty = ' '
|
|
23
|
-
|
|
24
|
-
expect(isWhiteSpace(lineEmpty)).toBeTruthy()
|
|
25
|
-
})
|
|
26
|
-
|
|
27
|
-
test('should valid a string with letters', () => {
|
|
28
|
-
const lineEmpty = 'asdf'
|
|
29
|
-
|
|
30
|
-
expect(!isWhiteSpace(lineEmpty)).toBeTruthy()
|
|
31
|
-
})
|
|
32
|
-
|
|
33
|
-
test('should return groups of space and letters', () => {
|
|
34
|
-
const lineGenerate = ' i a '.toUpperCase()
|
|
35
|
-
|
|
36
|
-
const splittedLine = splitsGroupOfSpacesAndLetter(lineGenerate)
|
|
37
|
-
|
|
38
|
-
if (!splittedLine) return
|
|
39
|
-
|
|
40
|
-
expect(splittedLine.length).toBe(5)
|
|
41
|
-
expect(splittedLine[1]).toBe('I')
|
|
42
|
-
expect(splittedLine[3]).toBe('A')
|
|
43
|
-
})
|
|
44
|
-
|
|
45
|
-
test('should join regex string with pipes', () => {
|
|
46
|
-
const firstRegex = '(^.{1,7}i.{4}a.{1,4}$)'
|
|
47
|
-
const secondRegex = '(^.{1,7}i.{1,4}$)'
|
|
48
|
-
const thirdRegex = '(^.{1,4}a.{1,4}$)'
|
|
49
|
-
const expectedStringRegex = '(^.{1,7}i.{4}a.{1,4}$)|(^.{1,7}i.{1,4}$)|(^.{1,4}a.{1,4}$)'
|
|
50
|
-
|
|
51
|
-
expect(
|
|
52
|
-
joinRegexStringWithPipe(
|
|
53
|
-
firstRegex,
|
|
54
|
-
secondRegex,
|
|
55
|
-
thirdRegex
|
|
56
|
-
)
|
|
57
|
-
).toBe(expectedStringRegex)
|
|
58
|
-
})
|
|
59
|
-
|
|
60
|
-
test('should return chunked array', () => {
|
|
61
|
-
const groupToGenerate = [' ', 'i', ' ', 'a', ' '] as RegExpMatchArray
|
|
62
|
-
const secondGroupToGenerate = ['s',' ', 'i', ' ', 'a', ' ', 'e'] as RegExpMatchArray
|
|
63
|
-
|
|
64
|
-
const chunkedArray = chunkListCharactersByCriterial(groupToGenerate)
|
|
65
|
-
const secondChunkedArray = chunkListCharactersByCriterial(secondGroupToGenerate)
|
|
66
|
-
|
|
67
|
-
expect(chunkedArray.length).toBe(2)
|
|
68
|
-
expect(secondChunkedArray.length).toBe(4)
|
|
69
|
-
|
|
70
|
-
})
|
|
71
|
-
|
|
72
|
-
test('should return regex expresion from expecific group of spaces and letters', () => {
|
|
73
|
-
const groupGenerate = [' ', 'i', ' ', 'a', ' '] as RegExpMatchArray
|
|
74
|
-
const regexExpected = '/(^.{1,7}i.{4}a.{1,4}$)|(^.{1,7}i.{1,4}$)|(^.{1,4}a.{1,4}$)/gm'
|
|
75
|
-
const regexExpresionResult = generateRegexByGroupOfSpacesAndLetters(groupGenerate)
|
|
76
|
-
|
|
77
|
-
expect(regexExpresionResult.toString()).toBe(regexExpected)
|
|
78
|
-
})
|
|
79
|
-
|
|
80
|
-
})
|
package/jest.config.js
DELETED
package/src/Entities/Cords.ts
DELETED
|
@@ -1,127 +0,0 @@
|
|
|
1
|
-
import { orientationEnum, orientationType } from "../Types"
|
|
2
|
-
import { DimensionType } from "./Dimension"
|
|
3
|
-
import Lines from "./Lines"
|
|
4
|
-
import Matrix from "./Matrix"
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
export class Cord {
|
|
9
|
-
cordX: number
|
|
10
|
-
cordY: number
|
|
11
|
-
|
|
12
|
-
constructor(cordX: number, cordY: number) {
|
|
13
|
-
this.cordX = cordX
|
|
14
|
-
this.cordY = cordY
|
|
15
|
-
}
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
export default class Cords {
|
|
19
|
-
private matrix: Matrix
|
|
20
|
-
private currentPosition?: Cord = undefined
|
|
21
|
-
private allCordsOfMatrix: Cord[]
|
|
22
|
-
constructor(matrix: Matrix) {
|
|
23
|
-
this.matrix = matrix
|
|
24
|
-
this.allCordsOfMatrix = this.getAllCordsOfMatrix(matrix.dimension.getDimension())
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
private getAllCordsOfMatrix = (dimensionMatrix: DimensionType) => {
|
|
28
|
-
const {
|
|
29
|
-
width,
|
|
30
|
-
height
|
|
31
|
-
} = dimensionMatrix
|
|
32
|
-
|
|
33
|
-
const result = []
|
|
34
|
-
|
|
35
|
-
for (let x = 0; x < height; x++)
|
|
36
|
-
for (let y = 0; y < width; y++)
|
|
37
|
-
result.push(new Cord(x, y))
|
|
38
|
-
|
|
39
|
-
return result
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
scrambleCordsOfMatrix = () => {
|
|
43
|
-
let scrambleCords = []
|
|
44
|
-
const cordsOfMatrix = this.allCordsOfMatrix
|
|
45
|
-
while (cordsOfMatrix.length > 0) {
|
|
46
|
-
scrambleCords.push(cordsOfMatrix.splice(Math.floor(Math.random() * cordsOfMatrix.length), 1)[0])
|
|
47
|
-
}
|
|
48
|
-
return scrambleCords
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
setCordPosition = (cord: Cord) => {
|
|
52
|
-
this.currentPosition = cord
|
|
53
|
-
this.matrix.setLines(new Lines(this.matrix))
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
getCordPosition = () => {
|
|
57
|
-
if (!this.currentPosition)
|
|
58
|
-
throw new Error("Undefined current cord position ");
|
|
59
|
-
|
|
60
|
-
return this.currentPosition
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
private horizontalCords = (): Cord[] => {
|
|
64
|
-
const result = []
|
|
65
|
-
const { width } = this.matrix.dimension.getDimension()
|
|
66
|
-
const { cordX } = this.matrix.cords.getCordPosition()
|
|
67
|
-
|
|
68
|
-
for (let i = 0; i < width; i++) {
|
|
69
|
-
result.push(new Cord(cordX,i))
|
|
70
|
-
}
|
|
71
|
-
return result
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
private verticalCords = (): Cord[] => {
|
|
75
|
-
const result = []
|
|
76
|
-
const { height } = this.matrix.dimension.getDimension()
|
|
77
|
-
const { cordY } = this.matrix.cords.getCordPosition()
|
|
78
|
-
|
|
79
|
-
for (let i = 0; i < height; i++) {
|
|
80
|
-
result.push(new Cord(i, cordY))
|
|
81
|
-
}
|
|
82
|
-
return result
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
private diagonalCords = (): Cord[] => {
|
|
86
|
-
const result = []
|
|
87
|
-
const { width, height } = this.matrix.dimension.getDimension()
|
|
88
|
-
const { cordX, cordY } = this.matrix.cords.getCordPosition()
|
|
89
|
-
|
|
90
|
-
for (let x = Math.max(0, cordX - cordY); x < Math.min(height, height + cordX - cordY); x++) {
|
|
91
|
-
const y = x - (cordX - cordY);
|
|
92
|
-
if (0 <= y && y < width) {
|
|
93
|
-
result.push(new Cord(x, y));
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
return result
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
private antiDiagonalCords = (): Cord[] => {
|
|
100
|
-
const result = []
|
|
101
|
-
const { width, height } = this.matrix.dimension.getDimension()
|
|
102
|
-
const { cordX, cordY } = this.matrix.cords.getCordPosition()
|
|
103
|
-
|
|
104
|
-
for (let x = Math.max(0, cordX + cordY - width + 1); x < Math.min(height, cordX + cordY + 1); x++) {
|
|
105
|
-
const y = cordX + cordY - x;
|
|
106
|
-
if (0 <= y && y < width) {
|
|
107
|
-
result.push(new Cord(x, y))
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
return result.reverse()
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
getCordsFromCurrentPositionByOrientation = (orientation: orientationType): Cord[] => {
|
|
115
|
-
switch (orientation) {
|
|
116
|
-
case "horizontally":
|
|
117
|
-
return this.horizontalCords()
|
|
118
|
-
case "vertically":
|
|
119
|
-
return this.verticalCords()
|
|
120
|
-
case "diagonally":
|
|
121
|
-
return this.diagonalCords()
|
|
122
|
-
case "antidiagonally":
|
|
123
|
-
return this.antiDiagonalCords()
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
}
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
const MARGIN_PUZZLE = 1
|
|
3
|
-
|
|
4
|
-
export type DimensionType = {
|
|
5
|
-
width: number,
|
|
6
|
-
height: number
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
export default class DimensionPuzzle {
|
|
10
|
-
private width: number
|
|
11
|
-
private height: number
|
|
12
|
-
|
|
13
|
-
constructor(length: number) {
|
|
14
|
-
this.width = MARGIN_PUZZLE + length + MARGIN_PUZZLE
|
|
15
|
-
this.height = MARGIN_PUZZLE + length + MARGIN_PUZZLE
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
getDimension(): DimensionType {
|
|
19
|
-
return {
|
|
20
|
-
width: this.width,
|
|
21
|
-
height: this.height
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
}
|
package/src/Entities/Lines.ts
DELETED
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
import { orientationEnum, orientationType, regexValueByLineType } from "../Types";
|
|
2
|
-
import { generateRegexByLine } from "../utils/regex";
|
|
3
|
-
import Matrix from "./Matrix";
|
|
4
|
-
|
|
5
|
-
export default class Lines {
|
|
6
|
-
horizontallyLine: string = ''
|
|
7
|
-
verticallyLine: string = ''
|
|
8
|
-
diagonallyDownLine: string = ''
|
|
9
|
-
diagonallyUpLine: string = ''
|
|
10
|
-
|
|
11
|
-
constructor(matrix?: Matrix) {
|
|
12
|
-
if (!matrix)
|
|
13
|
-
return
|
|
14
|
-
|
|
15
|
-
const {
|
|
16
|
-
cords: { getCordsFromCurrentPositionByOrientation },
|
|
17
|
-
getSlot
|
|
18
|
-
} = matrix
|
|
19
|
-
|
|
20
|
-
this.horizontallyLine = getCordsFromCurrentPositionByOrientation(orientationEnum.horizontally).map(cord => getSlot(cord.cordX, cord.cordY)).join('')
|
|
21
|
-
this.verticallyLine = getCordsFromCurrentPositionByOrientation(orientationEnum.vertically).map(cord => getSlot(cord.cordX, cord.cordY)).join('')
|
|
22
|
-
this.diagonallyDownLine = getCordsFromCurrentPositionByOrientation(orientationEnum.diagonally).map(cord => getSlot(cord.cordX, cord.cordY)).join('')
|
|
23
|
-
this.diagonallyUpLine = getCordsFromCurrentPositionByOrientation(orientationEnum.antidiagonally).map(cord => getSlot(cord.cordX, cord.cordY)).join('')
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
getLinesWithRegex = (): regexValueByLineType => {
|
|
27
|
-
const lines = {
|
|
28
|
-
horizontallyLine: this.horizontallyLine,
|
|
29
|
-
verticallyLine: this.verticallyLine,
|
|
30
|
-
diagonallyDownLine: this.diagonallyDownLine,
|
|
31
|
-
diagonallyUpLine: this.diagonallyUpLine
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
const regexForLines = Object.keys(lines).reduce((result, key) => {
|
|
35
|
-
const newObj = {} as any
|
|
36
|
-
newObj[`regex${key.capitalize()}`] = generateRegexByLine(lines[key as keyof typeof lines])
|
|
37
|
-
return {
|
|
38
|
-
...result,
|
|
39
|
-
...newObj
|
|
40
|
-
}
|
|
41
|
-
}, {} as regexValueByLineType)
|
|
42
|
-
|
|
43
|
-
return regexForLines
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
getLineByOrientation = (orientation: orientationType) => {
|
|
47
|
-
switch (orientation) {
|
|
48
|
-
case "horizontally":
|
|
49
|
-
return this.horizontallyLine
|
|
50
|
-
case "vertically":
|
|
51
|
-
return this.verticallyLine
|
|
52
|
-
case "diagonally":
|
|
53
|
-
return this.diagonallyDownLine
|
|
54
|
-
case "antidiagonally":
|
|
55
|
-
return this.diagonallyUpLine
|
|
56
|
-
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
}
|
package/src/Entities/Matrix.ts
DELETED
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
import { puzzleType } from "../Types";
|
|
2
|
-
import Cords, { Cord } from "./Cords";
|
|
3
|
-
import DimensionPuzzle from "./Dimension";
|
|
4
|
-
import Lines from "./Lines";
|
|
5
|
-
|
|
6
|
-
const BLANK_SPACE = ' '
|
|
7
|
-
|
|
8
|
-
export default class Matrix {
|
|
9
|
-
dimension: DimensionPuzzle
|
|
10
|
-
cords: Cords
|
|
11
|
-
lines: Lines
|
|
12
|
-
private matrix: string[][]
|
|
13
|
-
|
|
14
|
-
constructor(length: number) {
|
|
15
|
-
this.dimension = new DimensionPuzzle(length)
|
|
16
|
-
this.matrix = this.generate()
|
|
17
|
-
this.cords = new Cords(this)
|
|
18
|
-
this.lines = new Lines()
|
|
19
|
-
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
private generate = () => {
|
|
23
|
-
const {
|
|
24
|
-
width,
|
|
25
|
-
height
|
|
26
|
-
} = this.dimension.getDimension()
|
|
27
|
-
|
|
28
|
-
const matrix: puzzleType = Array(...Array(width * height)).reduce((resultValue, currentValue, index, array) => {
|
|
29
|
-
resultValue = [...resultValue, array.splice(0, width).map(index => BLANK_SPACE)]
|
|
30
|
-
return resultValue
|
|
31
|
-
}, [])
|
|
32
|
-
|
|
33
|
-
return matrix
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
setSlot = (cordX: number, cordY: number, letter: string) => { this.matrix[cordX][cordY] = letter }
|
|
37
|
-
|
|
38
|
-
getSlot = (cordX: number, cordY: number) => this.matrix[cordX][cordY]
|
|
39
|
-
|
|
40
|
-
setLines = (lines: Lines) => { this.lines = lines }
|
|
41
|
-
|
|
42
|
-
getMatrix = () => this.matrix
|
|
43
|
-
}
|
package/src/Entities/Word.ts
DELETED
|
@@ -1,115 +0,0 @@
|
|
|
1
|
-
import { orientationType, wordListByLineType } from "../Types"
|
|
2
|
-
import { Cord } from "./Cords"
|
|
3
|
-
import Matrix from "./Matrix"
|
|
4
|
-
|
|
5
|
-
const LETTERS = 'ABCDEFGHIJKLMNÑOPQRSTUVWXYZ'
|
|
6
|
-
|
|
7
|
-
export default class Words {
|
|
8
|
-
private matrix: Matrix
|
|
9
|
-
private listOfWords: string[]
|
|
10
|
-
|
|
11
|
-
constructor(matrix: Matrix, listOfWords: string[]) {
|
|
12
|
-
this.matrix = matrix
|
|
13
|
-
this.listOfWords = listOfWords.slice()
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
removeWord = (word: string) => {
|
|
17
|
-
this.listOfWords.splice(this.listOfWords.indexOf(word), 1)
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
private putWordHorizontally = (word: string, padStart: number = 0) => {
|
|
21
|
-
const { width } = this.matrix.dimension.getDimension()
|
|
22
|
-
|
|
23
|
-
const { cordX } = this.matrix.cords.getCordPosition()
|
|
24
|
-
let wordIndex = 0
|
|
25
|
-
for (let horizontalIndex = 0; horizontalIndex < width; horizontalIndex++) {
|
|
26
|
-
if (horizontalIndex >= padStart && wordIndex < word.length) {
|
|
27
|
-
this.matrix.setSlot(cordX, horizontalIndex, word.charAt(wordIndex))
|
|
28
|
-
wordIndex++
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
private putWordVertically = (word: string, padStart: number = 0) => {
|
|
34
|
-
const { height } = this.matrix.dimension.getDimension()
|
|
35
|
-
|
|
36
|
-
const { cordY } = this.matrix.cords.getCordPosition()
|
|
37
|
-
let wordIndex = 0
|
|
38
|
-
for (let verticalIndex = 0; verticalIndex < height; verticalIndex++) {
|
|
39
|
-
if (verticalIndex >= padStart && wordIndex < word.length) {
|
|
40
|
-
this.matrix.setSlot(verticalIndex, cordY, word.charAt(wordIndex))
|
|
41
|
-
wordIndex++
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
private putWordDiagonally = (word: string, padStart: number = 0) => {
|
|
47
|
-
const { height, width } = this.matrix.dimension.getDimension()
|
|
48
|
-
const { cordX, cordY } = this.matrix.cords.getCordPosition()
|
|
49
|
-
|
|
50
|
-
let wordIndex = 0
|
|
51
|
-
let spaceToStart = padStart
|
|
52
|
-
for (let i = Math.max(0, cordX - cordY); i < Math.min(height, height + cordX - cordY); i++) {
|
|
53
|
-
const j = i - (cordX - cordY);
|
|
54
|
-
if (0 <= j && j < width) {
|
|
55
|
-
if (spaceToStart > 0) {
|
|
56
|
-
spaceToStart--
|
|
57
|
-
continue
|
|
58
|
-
}
|
|
59
|
-
this.matrix.setSlot(i, j, wordIndex < word.length ? word.charAt(wordIndex) : this.matrix.getSlot(i, j))
|
|
60
|
-
wordIndex++
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
private putWordAntiDiagonally = (word: string, padStart: number = 0) => {
|
|
66
|
-
const { height, width } = this.matrix.dimension.getDimension()
|
|
67
|
-
const { cordX, cordY } = this.matrix.cords.getCordPosition()
|
|
68
|
-
|
|
69
|
-
let wordIndex = 0
|
|
70
|
-
let spaceToStart = padStart
|
|
71
|
-
for (let x = Math.max(0, cordX + cordY - width + 1); x < Math.min(height, cordX + cordY + 1); x++) {
|
|
72
|
-
const y = cordX + cordY - x;
|
|
73
|
-
if (0 <= y && y < width) {
|
|
74
|
-
if (spaceToStart > 0) {
|
|
75
|
-
spaceToStart--
|
|
76
|
-
continue
|
|
77
|
-
}
|
|
78
|
-
this.matrix.setSlot(x, y, wordIndex < word.length ? word.charAt(wordIndex) : this.matrix.getSlot(x, y))
|
|
79
|
-
wordIndex++
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
putWord = (word: string, orientation: orientationType, padStart: number = 0) => {
|
|
85
|
-
switch (orientation) {
|
|
86
|
-
case "diagonally":
|
|
87
|
-
this.putWordDiagonally(word, padStart)
|
|
88
|
-
break;
|
|
89
|
-
case "vertically":
|
|
90
|
-
this.putWordVertically(word, padStart)
|
|
91
|
-
break;
|
|
92
|
-
case "horizontally":
|
|
93
|
-
this.putWordHorizontally(word, padStart)
|
|
94
|
-
break;
|
|
95
|
-
case "antidiagonally":
|
|
96
|
-
this.putWordAntiDiagonally(word, padStart)
|
|
97
|
-
break;
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
getWordsEveryOrientation = (): wordListByLineType => {
|
|
102
|
-
const linesWithSearhRegex = this.matrix.lines.getLinesWithRegex()
|
|
103
|
-
|
|
104
|
-
const wordsByLine = Object.keys(linesWithSearhRegex).reduce((result, key) => {
|
|
105
|
-
const newObj = {} as any
|
|
106
|
-
newObj[`match${key.capitalize()}`] = this.listOfWords.filter(word => word.match(linesWithSearhRegex[key as keyof typeof linesWithSearhRegex]) as string[])
|
|
107
|
-
return {
|
|
108
|
-
...result,
|
|
109
|
-
...newObj
|
|
110
|
-
}
|
|
111
|
-
}, {} as wordListByLineType)
|
|
112
|
-
|
|
113
|
-
return wordsByLine
|
|
114
|
-
}
|
|
115
|
-
}
|
package/src/Types.ts
DELETED
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
export type puzzleType = string[][]
|
|
3
|
-
export type orientationType = "horizontally" | "vertically" | "diagonally" | "antidiagonally"
|
|
4
|
-
export type linesByCordsType = {
|
|
5
|
-
horizontallyLine: string;
|
|
6
|
-
verticallyLine: string;
|
|
7
|
-
diagonallyDownLine: string;
|
|
8
|
-
diagonallyUpLine: string;
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
export enum matchRegexLines {
|
|
12
|
-
matchRegexDiagonallyDownLine = "diagonally",
|
|
13
|
-
matchRegexDiagonallyUpLine = "antidiagonally",
|
|
14
|
-
matchRegexHorizontallyLine = "horizontally",
|
|
15
|
-
matchRegexVerticallyLine = "vertically"
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
export type regexValueByLine<Type> = {
|
|
19
|
-
[key in keyof Type as `regex${Capitalize<string & key>}`]: RegExp
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
export type regexValueByLineType = regexValueByLine<linesByCordsType>
|
|
23
|
-
export enum orientationEnum {
|
|
24
|
-
horizontally = "horizontally",
|
|
25
|
-
vertically = "vertically",
|
|
26
|
-
diagonally = "diagonally",
|
|
27
|
-
antidiagonally = "antidiagonally"
|
|
28
|
-
}
|
|
29
|
-
export type wordListByLine<Type> = {
|
|
30
|
-
[key in keyof Type as `match${Capitalize<string & key>}`]: string[]
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
export type wordListByLineType = wordListByLine<regexValueByLineType>
|
|
34
|
-
|
|
35
|
-
export type interectionType = {
|
|
36
|
-
wordIndex: number,
|
|
37
|
-
lineIndex: number
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
export type interectionsType = interectionType[]
|
package/src/index.ts
DELETED