schachnovelle 1.0.0-beta-6 → 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/CHANGELOG.md +23 -0
- package/README.md +8 -4
- package/index.js +1 -39
- package/package.json +19 -3
- package/server/api.js +132 -0
- package/server/index.js +436 -11
- package/ui/Board.js +52 -16
- package/ui/Fen.js +5 -0
- package/ui/Game.js +648 -176
- package/ui/LichessGame.js +11 -0
- package/ui/Printer.js +27 -2
- package/ui/Side.js +91 -0
- package/ui/Utils.js +12 -2
- package/ui/index.js +91 -35
- package/ui/moves.js +0 -0
- package/views/error.pug +6 -0
- package/views/index.pug +6 -0
- package/views/layout.pug +6 -0
- package/views/welcome.pug +6 -0
- package/.env +0 -4
- package/lichess/index.js +0 -6
- package/tests/consoletest.js +0 -53
- package/tests/controller/index.js +0 -16
- package/tests/processes.js +0 -57
- package/yarn-error.log +0 -367
package/ui/Printer.js
CHANGED
|
@@ -1,11 +1,35 @@
|
|
|
1
|
+
const readline = require('readline')
|
|
2
|
+
|
|
1
3
|
class Printer {
|
|
2
4
|
constructor (spacing) {
|
|
3
5
|
this.spacing = spacing
|
|
4
6
|
this.tab = ' '
|
|
7
|
+
this.lineCount = 0
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
clearView () {
|
|
11
|
+
const blank = '\n'.repeat(process.stdout.rows)
|
|
12
|
+
console.log(blank)
|
|
13
|
+
readline.cursorTo(process.stdout, 0, 0)
|
|
14
|
+
readline.clearScreenDown(process.stdout)
|
|
15
|
+
// while (this.lineCount > 0) {
|
|
16
|
+
// process.stdout.clearLine(0)
|
|
17
|
+
// this.lineCount--
|
|
18
|
+
// process.stdout.cursorTo(0, this.lineCount)
|
|
19
|
+
// }
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
clearForward () {
|
|
23
|
+
// process.stdout.clearScreenDown()
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
printLine (value) {
|
|
27
|
+
process.stdout.write(value + '\n')
|
|
28
|
+
this.lineCount++
|
|
5
29
|
}
|
|
6
30
|
|
|
7
31
|
print (value) {
|
|
8
|
-
|
|
32
|
+
process.stdout.write(value)
|
|
9
33
|
}
|
|
10
34
|
|
|
11
35
|
addSpace (direction, string) {
|
|
@@ -15,7 +39,8 @@ class Printer {
|
|
|
15
39
|
}
|
|
16
40
|
} else {
|
|
17
41
|
for (let i = 0; i < this.spacing; i++) {
|
|
18
|
-
|
|
42
|
+
process.stdout.write('\n')
|
|
43
|
+
this.lineCount++
|
|
19
44
|
}
|
|
20
45
|
}
|
|
21
46
|
return string
|
package/ui/Side.js
CHANGED
|
@@ -2,7 +2,17 @@ class Side {
|
|
|
2
2
|
constructor (color) {
|
|
3
3
|
this.pieces = []
|
|
4
4
|
if (color === 'white') {
|
|
5
|
+
//
|
|
6
|
+
//
|
|
7
|
+
//
|
|
8
|
+
this.inCheck = false,
|
|
9
|
+
//
|
|
10
|
+
//
|
|
11
|
+
//
|
|
5
12
|
this.captured = []
|
|
13
|
+
//
|
|
14
|
+
//
|
|
15
|
+
//
|
|
6
16
|
this.pieces = [
|
|
7
17
|
{
|
|
8
18
|
pos: ['a', 2],
|
|
@@ -116,12 +126,56 @@ class Side {
|
|
|
116
126
|
piece: '♔',
|
|
117
127
|
value: Infinity
|
|
118
128
|
}
|
|
129
|
+
],
|
|
130
|
+
//
|
|
131
|
+
//
|
|
132
|
+
//
|
|
133
|
+
this.promotionChoices = [
|
|
134
|
+
{
|
|
135
|
+
pos: null,
|
|
136
|
+
prefix: 'Q',
|
|
137
|
+
type: 'Queen',
|
|
138
|
+
piece: '♕',
|
|
139
|
+
value: 7
|
|
140
|
+
},
|
|
141
|
+
{
|
|
142
|
+
pos: null,
|
|
143
|
+
prefix: 'R',
|
|
144
|
+
type: 'Rook',
|
|
145
|
+
piece: '♖',
|
|
146
|
+
value: 5
|
|
147
|
+
},
|
|
148
|
+
{
|
|
149
|
+
pos: null,
|
|
150
|
+
prefix: 'B',
|
|
151
|
+
type: 'Bishop',
|
|
152
|
+
piece: '♗',
|
|
153
|
+
value: 3
|
|
154
|
+
},
|
|
155
|
+
{
|
|
156
|
+
pos: null,
|
|
157
|
+
prefix: 'N',
|
|
158
|
+
type: 'Knight',
|
|
159
|
+
piece: '♘',
|
|
160
|
+
value: 3
|
|
161
|
+
}
|
|
119
162
|
]
|
|
120
163
|
} else if (color === 'black') {
|
|
164
|
+
//
|
|
165
|
+
//
|
|
166
|
+
//
|
|
167
|
+
this.inCheck = false,
|
|
168
|
+
//
|
|
169
|
+
//
|
|
170
|
+
//
|
|
121
171
|
this.captured = []
|
|
172
|
+
//
|
|
173
|
+
//
|
|
174
|
+
//
|
|
122
175
|
this.pieces = [
|
|
123
176
|
{
|
|
124
177
|
pos: ['a', 7],
|
|
178
|
+
// pos: ['f', 3],
|
|
125
179
|
prefix: 'p',
|
|
126
180
|
type: 'Pawn',
|
|
127
181
|
piece: '♟',
|
|
@@ -232,9 +286,46 @@ class Side {
|
|
|
232
286
|
piece: '♚',
|
|
233
287
|
value: Infinity
|
|
234
288
|
}
|
|
289
|
+
],
|
|
290
|
+
//
|
|
291
|
+
//
|
|
292
|
+
//
|
|
293
|
+
this.promotionChoices = [
|
|
294
|
+
{
|
|
295
|
+
pos: null,
|
|
296
|
+
prefix: 'Q',
|
|
297
|
+
type: 'Queen',
|
|
298
|
+
piece: '♛',
|
|
299
|
+
value: 7
|
|
300
|
+
},
|
|
301
|
+
{
|
|
302
|
+
pos: null,
|
|
303
|
+
prefix: 'R',
|
|
304
|
+
type: 'Rook',
|
|
305
|
+
piece: '♜',
|
|
306
|
+
value: 5
|
|
307
|
+
},
|
|
308
|
+
{
|
|
309
|
+
pos: null,
|
|
310
|
+
prefix: 'B',
|
|
311
|
+
type: 'Bishop',
|
|
312
|
+
piece: '♝',
|
|
313
|
+
value: 3
|
|
314
|
+
},
|
|
315
|
+
{
|
|
316
|
+
pos: null,
|
|
317
|
+
prefix: 'N',
|
|
318
|
+
type: 'Knight',
|
|
319
|
+
piece: '♞',
|
|
320
|
+
value: 3
|
|
321
|
+
}
|
|
235
322
|
]
|
|
236
323
|
}
|
|
237
324
|
}
|
|
325
|
+
|
|
326
|
+
getPieces () {
|
|
327
|
+
return this.pieces
|
|
328
|
+
}
|
|
238
329
|
}
|
|
239
330
|
|
|
240
331
|
module.exports = Side
|
package/ui/Utils.js
CHANGED
|
@@ -2,8 +2,18 @@ class Utils {
|
|
|
2
2
|
/**
|
|
3
3
|
* Returns opposing party's color
|
|
4
4
|
*/
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
opposingColor (color) {
|
|
6
|
+
const opposing = color === 'white' ? 'black' : 'white'
|
|
7
|
+
return opposing
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Gets piece at current position
|
|
12
|
+
*/
|
|
13
|
+
getPieceAt (set, pos) {
|
|
14
|
+
return set.find((piece) => {
|
|
15
|
+
return piece.pos[0] === pos[0] && piece.pos[1] === pos[1]
|
|
16
|
+
})
|
|
7
17
|
}
|
|
8
18
|
}
|
|
9
19
|
|
package/ui/index.js
CHANGED
|
@@ -1,59 +1,115 @@
|
|
|
1
|
-
const
|
|
1
|
+
const spacing = 1
|
|
2
|
+
const { Select } = require('enquirer')
|
|
3
|
+
|
|
4
|
+
const { spawn } = require('child_process')
|
|
5
|
+
|
|
2
6
|
const Game = require('./Game')
|
|
3
|
-
const spacing = 2
|
|
4
|
-
const mode = 'bare' // bare / color
|
|
5
7
|
const Printer = require('./Printer')
|
|
8
|
+
|
|
6
9
|
const printer = new Printer(spacing)
|
|
7
10
|
|
|
8
|
-
|
|
11
|
+
/**
|
|
12
|
+
* Welcome to Schachnovelle
|
|
13
|
+
*/
|
|
14
|
+
exports.welcomeMessage = () => {
|
|
9
15
|
printer.addSpace('y')
|
|
10
|
-
printer.
|
|
11
|
-
printer.
|
|
12
|
-
printer.
|
|
16
|
+
printer.printLine(printer.addSpaceBefore('S . C . V . E'))
|
|
17
|
+
printer.printLine(printer.addSpaceBefore(' C A H O E L '))
|
|
18
|
+
printer.printLine(printer.addSpaceBefore('. H . N . L .'))
|
|
13
19
|
printer.addSpace('y')
|
|
14
|
-
printer.
|
|
20
|
+
printer.printLine(printer.addSpaceBefore(' >>Um Gottes Willen! Nicht!<<'))
|
|
15
21
|
printer.addSpace('y')
|
|
16
22
|
}
|
|
17
23
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
exports.
|
|
22
|
-
|
|
24
|
+
//
|
|
25
|
+
//
|
|
26
|
+
// Spawn a server
|
|
27
|
+
exports.spawnServer = () => {
|
|
28
|
+
const server = spawn("node", ["./server/index.js"]);
|
|
29
|
+
|
|
30
|
+
server.stdout.on('data', (data) => {
|
|
31
|
+
const responseCode = data.toString()
|
|
32
|
+
|
|
33
|
+
if (responseCode === 'streamReady') {
|
|
34
|
+
printer.clearView()
|
|
35
|
+
|
|
36
|
+
this.welcomeMessage()
|
|
37
|
+
printer.addSpace('y')
|
|
38
|
+
printer.printLine(printer.addSpaceBefore(' Welcome'))
|
|
39
|
+
printer.addSpace('y')
|
|
40
|
+
|
|
41
|
+
setTimeout(() => {
|
|
42
|
+
this.localGame()
|
|
43
|
+
})
|
|
44
|
+
}
|
|
45
|
+
});
|
|
23
46
|
|
|
47
|
+
server.stderr.on('data', (data) => {
|
|
48
|
+
console.error(data.toString())
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
server.on('close', (code) => {
|
|
52
|
+
// printer.clearView()
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
//
|
|
57
|
+
//
|
|
58
|
+
// Just play a local game
|
|
59
|
+
exports.localGame = () => {
|
|
24
60
|
let choices = {}
|
|
25
61
|
|
|
26
|
-
const
|
|
62
|
+
const color = new Select({
|
|
27
63
|
name: 'color',
|
|
28
64
|
message: 'Play as',
|
|
29
65
|
choices: ['white', 'black']
|
|
30
66
|
})
|
|
31
|
-
|
|
32
|
-
const prompt2 = new Select({
|
|
33
|
-
name: 'mode',
|
|
34
|
-
message: 'Choose mode',
|
|
35
|
-
choices: ['bare', 'color']
|
|
36
|
-
})
|
|
37
67
|
|
|
38
|
-
|
|
68
|
+
color.run()
|
|
39
69
|
.then(answer => {
|
|
40
70
|
choices.color = answer
|
|
41
|
-
printer.addSpace('y')
|
|
42
71
|
|
|
43
|
-
|
|
44
|
-
.
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
const game = new Game({
|
|
49
|
-
playingAs: choices.color,
|
|
50
|
-
spacing,
|
|
51
|
-
mode: answer
|
|
52
|
-
})
|
|
72
|
+
const game = new Game({
|
|
73
|
+
playingAs: choices.color,
|
|
74
|
+
spacing,
|
|
75
|
+
mode: 'bare'
|
|
76
|
+
})
|
|
53
77
|
|
|
54
|
-
|
|
55
|
-
|
|
78
|
+
printer.clearView()
|
|
79
|
+
|
|
80
|
+
game.init()
|
|
56
81
|
})
|
|
57
|
-
.catch(console.error)
|
|
82
|
+
.catch(console.error)
|
|
58
83
|
}
|
|
59
84
|
|
|
85
|
+
//
|
|
86
|
+
//
|
|
87
|
+
// INIT
|
|
88
|
+
exports.init = () => {
|
|
89
|
+
//
|
|
90
|
+
//
|
|
91
|
+
// Don't be shy, say hello to that person!
|
|
92
|
+
this.welcomeMessage()
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
const what = new Select({
|
|
96
|
+
name: 'todo',
|
|
97
|
+
message: 'How do you want to play?',
|
|
98
|
+
choices: ['local', 'on lichess (beta)']
|
|
99
|
+
})
|
|
100
|
+
|
|
101
|
+
what.run()
|
|
102
|
+
.then((answer) => {
|
|
103
|
+
printer.addSpace('y')
|
|
104
|
+
|
|
105
|
+
if (answer === 'local') {
|
|
106
|
+
this.localGame()
|
|
107
|
+
} else {
|
|
108
|
+
this.spawnServer()
|
|
109
|
+
|
|
110
|
+
printer.addSpace('y')
|
|
111
|
+
printer.printLine(printer.addSpaceBefore(' Log in with Lichess to begin'))
|
|
112
|
+
printer.addSpace('y')
|
|
113
|
+
}
|
|
114
|
+
})
|
|
115
|
+
}
|
package/ui/moves.js
ADDED
|
File without changes
|
package/views/error.pug
ADDED
package/views/index.pug
ADDED
package/views/layout.pug
ADDED
package/.env
DELETED
package/lichess/index.js
DELETED
package/tests/consoletest.js
DELETED
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
const { prompt } = require('enquirer')
|
|
2
|
-
|
|
3
|
-
const promptMove = async () => {
|
|
4
|
-
const response = await prompt([
|
|
5
|
-
{
|
|
6
|
-
type: 'select',
|
|
7
|
-
name: 'piece',
|
|
8
|
-
message: 'Piece',
|
|
9
|
-
choices: ['Rook', 'Knight', 'Queen']
|
|
10
|
-
},
|
|
11
|
-
{
|
|
12
|
-
type: 'select',
|
|
13
|
-
name: 'file',
|
|
14
|
-
message: 'File:',
|
|
15
|
-
choices: [
|
|
16
|
-
'a',
|
|
17
|
-
'b',
|
|
18
|
-
'c'
|
|
19
|
-
]
|
|
20
|
-
},
|
|
21
|
-
{
|
|
22
|
-
type: 'select',
|
|
23
|
-
name: 'rank',
|
|
24
|
-
message: 'Rank:',
|
|
25
|
-
choices: ['1', '2', '3'],
|
|
26
|
-
result: (result) => {
|
|
27
|
-
return Number(result)
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
]);
|
|
31
|
-
|
|
32
|
-
validateMove(response)
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
const validateMove = (response) => {
|
|
36
|
-
const legal = true
|
|
37
|
-
// somehow find out if it's a legal move. Then;
|
|
38
|
-
if (legal) {
|
|
39
|
-
// Commit the move to update the board
|
|
40
|
-
console.log(`Moved ${response.piece} to ${response.file}${response.rank}`)
|
|
41
|
-
// Opponent to move
|
|
42
|
-
} else {
|
|
43
|
-
// retry
|
|
44
|
-
console.error('Not a legal move. Try again')
|
|
45
|
-
runPrompt()
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
const commitMove = () => {
|
|
50
|
-
//
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
runPrompt()
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
const fetch = require('node-fetch')
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Test the API
|
|
5
|
-
*/
|
|
6
|
-
exports.testMove = () => {
|
|
7
|
-
const move = { move: 'e5' }
|
|
8
|
-
|
|
9
|
-
fetch('http://localhost:1337/move', {
|
|
10
|
-
method: 'post',
|
|
11
|
-
body: JSON.stringify(move),
|
|
12
|
-
headers: { 'Content-Type': 'application/json' }
|
|
13
|
-
})
|
|
14
|
-
.then(res => res.json())
|
|
15
|
-
.then(body => console.log(body));
|
|
16
|
-
}
|
package/tests/processes.js
DELETED
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
// https://www.youtube.com/watch?v=9o8B3L0-d9c
|
|
2
|
-
const { spawn } = require('child_process')
|
|
3
|
-
|
|
4
|
-
if (process.argv[2] === 'child') {
|
|
5
|
-
console.log(' ... to man')
|
|
6
|
-
} else {
|
|
7
|
-
// const child = spawn(process.execPath, [__filename, 'child'])
|
|
8
|
-
|
|
9
|
-
// child.stdout.on('data', (data) => {
|
|
10
|
-
// console.log('from child', data.toString())
|
|
11
|
-
// })
|
|
12
|
-
// or
|
|
13
|
-
// child.stdout.pipe(process.stdout)
|
|
14
|
-
// or
|
|
15
|
-
const child = spawn(process.execPath, [__filename, 'child'], {
|
|
16
|
-
stdio: 'inherit'
|
|
17
|
-
})
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
// exec('cat ./tests/processes.js', (err, stdout, stderr) => {
|
|
22
|
-
// console.log('we got our catted file', stdout)
|
|
23
|
-
// })
|
|
24
|
-
|
|
25
|
-
// const fs = require('fs')
|
|
26
|
-
|
|
27
|
-
// fs.createReadStream(__filename)
|
|
28
|
-
// .pipe(process.stdout)
|
|
29
|
-
|
|
30
|
-
// console.log('hello')
|
|
31
|
-
// process.stdout.write('hello \n')
|
|
32
|
-
|
|
33
|
-
const writeLine = (line, speed) => {
|
|
34
|
-
let count = 0
|
|
35
|
-
|
|
36
|
-
const writing = setInterval(() => {
|
|
37
|
-
if (count < line.length) {
|
|
38
|
-
process.stdout.write(line[count])
|
|
39
|
-
count++
|
|
40
|
-
} else {
|
|
41
|
-
process.stdout.write('\n')
|
|
42
|
-
clearInterval(writing)
|
|
43
|
-
}
|
|
44
|
-
}, speed || 10)
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
// let count = 0
|
|
48
|
-
// setInterval(() => {
|
|
49
|
-
// if (count < 10) {
|
|
50
|
-
// process.stdout.write('a')
|
|
51
|
-
// count++
|
|
52
|
-
// } else {
|
|
53
|
-
// process.exit()
|
|
54
|
-
// }
|
|
55
|
-
// }, 1000)
|
|
56
|
-
|
|
57
|
-
// writeLine('>> Um Gottes Wille! Nicht! <<', 10)
|