Skip to content

Commit e72ae16

Browse files
Add files via upload
1 parent 2277597 commit e72ae16

1 file changed

Lines changed: 37 additions & 21 deletions

File tree

‎microchess/microchess.js‎

Lines changed: 37 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
/**
2-
* microchess.js (Production Infinite Daemon Loop - Anti-Lockup Version)
2+
* microchess.js (Production 1-Hour Interval Daemon Engine)
33
*
4-
* Generates continuous neural-network chess matches back-to-back.
5-
* Uses high-efficiency array-slice trimming to eliminate disk I/O bottlenecks.
4+
* Runs a deep evaluation chess simulation once every 1 hour.
5+
* Employs instant array-slicing to eliminate disk I/O deadlocks completely.
66
*/
77
const path = require('path');
88
require('dotenv').config();
@@ -18,18 +18,20 @@ const { Chess } = require('../dist/cjs/chess.js');
1818

1919
const convnetjs = require('./core/convnet.js');
2020

21-
//
22-
// Configuration Matrix Mappings
23-
//
21+
// ═══════════════════════════════════════════════════════════════════════════
22+
// ─── CONFIGURATION & MATRIX PATH MAPPINGS
23+
// ═══════════════════════════════════════════════════════════════════════════
2424
const OUTPUT_FILE = process.env.MICROCHESS_OUTPUT_FILE
2525
? path.resolve(process.env.MICROCHESS_OUTPUT_FILE)
2626
: path.join(__dirname, 'randomchess.json');
2727

2828
const LOG_FILE = path.join(__dirname, 'microchess.log');
2929

30-
const MAX_HISTORY_GAMES = 30; // KEEP EXACTLY 30 GAMES. Removes heavy byte size loops!
31-
const MAX_MOVES = 60; // Keeps matches fast, tactical, and dynamic
30+
const MAX_HISTORY_GAMES = 30; // Hard boundary: keeps exactly the last 30 games
31+
const MAX_MOVES = 60; // Quick, tactical games to prevent 100-move draw stalls
32+
const GENERATOR_INTERVAL = parseInt(process.env.MICROCHESS_GENERATOR_INTERVAL, 10) || 3600000; // 1 Hour
3233

34+
// Setup Logger Pipeline
3335
const logger = winston.createLogger({
3436
level: 'info',
3537
format: winston.format.combine(
@@ -42,7 +44,9 @@ const logger = winston.createLogger({
4244
],
4345
});
4446

45-
// ConvNetJS Network Layer Setup
47+
// ═══════════════════════════════════════════════════════════════════════════
48+
// ─── NEURAL NETWORK MATRIX SETUP (CONVNETJS)
49+
// ═══════════════════════════════════════════════════════════════════════════
4650
const netLayerDefs = [];
4751
netLayerDefs.push({ type: 'input', out_sx: 1, out_sy: 1, out_depth: 64 });
4852
netLayerDefs.push({ type: 'fc', num_neurons: 32, activation: 'relu' });
@@ -57,6 +61,9 @@ const networkTrainer = new convnetjs.Trainer(neuralEvaluator, {
5761
batch_size: 1
5862
});
5963

64+
/**
65+
* Transforms an 8x8 matrix grid layout into standard convolutional float vectors
66+
*/
6067
function boardToVolumeInput(board) {
6168
const inputSequence = new Array(64).fill(0);
6269
const numericWeights = { p: 1, n: 3, b: 3, r: 5, q: 9, k: 10 };
@@ -76,6 +83,9 @@ function boardToVolumeInput(board) {
7683
return vol;
7784
}
7885

86+
// ═══════════════════════════════════════════════════════════════════════════
87+
// ─── ATOMIC DISK STORAGE OPERATIONS
88+
// ═══════════════════════════════════════════════════════════════════════════
7989
async function atomicWriteJson(filePath, data) {
8090
const tmpPath = `${filePath}.${Date.now()}.${process.pid}.tmp`;
8191
await writeFile(tmpPath, JSON.stringify(data, null, 2) + os.EOL, 'utf8');
@@ -95,6 +105,9 @@ async function loadLogs() {
95105
return [];
96106
}
97107

108+
// ═══════════════════════════════════════════════════════════════════════════
109+
// ─── CORE ENGINE COMPUTATION THREAD PASS
110+
// ═══════════════════════════════════════════════════════════════════════════
98111
async function runOnce() {
99112
const seed = crypto.randomBytes(8).toString('hex');
100113
const chess = new Chess();
@@ -147,10 +160,11 @@ async function runOnce() {
147160
else if (chess.isStalemate()) { reason = 'Stalemate'; }
148161
else if (chess.isDraw()) { reason = 'Draw'; }
149162

150-
const pgnHeaders = `[Event "ConvNetJS Continuous Daemon Iteration"]\n[Result "${result}"]\n[Reason "${reason}"]\n[PlyCount "${moves.length}"]`;
163+
const pgnHeaders = `[Event "ConvNetJS Periodic Engine Pass"]\n[Result "${result}"]\n[Reason "${reason}"]\n[PlyCount "${moves.length}"]`;
151164
const pgn = `${pgnHeaders}\n\n${pgnMoves} ${result}`;
152165
const meanLossMetric = (calculationSteps > 0 && !isNaN(totalGameLoss)) ? (totalGameLoss / calculationSteps) : 0.015;
153166

167+
// Structural type-safeties for Webpack frontend chart rendering guarantees
154168
const targetGameRecord = {
155169
process: 'microchess-nn',
156170
timestamp: new Date().toISOString(),
@@ -165,32 +179,34 @@ async function runOnce() {
165179
loss_metric: isNaN(meanLossMetric) ? 0.015000 : parseFloat(meanLossMetric.toFixed(6))
166180
};
167181

168-
// ⚡ HIGH-EFFICIENCY LOG OVERWRITE PIPELINE
182+
// Low-overhead storage append & slide window slice trim
169183
let currentLogsArray = await loadLogs();
170184
currentLogsArray.push(targetGameRecord);
171185

172-
// Instant sliding window trim down to maximum history size
173186
if (currentLogsArray.length > MAX_HISTORY_GAMES) {
174187
currentLogsArray = currentLogsArray.slice(-MAX_HISTORY_GAMES);
175188
}
176189

177190
await atomicWriteJson(OUTPUT_FILE, currentLogsArray);
178-
logger.info(`Neural chess game completed and updated database. (seed=${seed}, result=${result}, moves=${moves.length})`);
191+
logger.info(`Periodic chess game completed and synced. (seed=${seed}, result=${result}, moves=${moves.length})`);
179192
}
180193

181-
//
182-
// SYSTEM INCEPTION (INFINITE PERSISTENT DAEMON WORKER LOOP)
183-
//
194+
// ═══════════════════════════════════════════════════════════════════════════
195+
// ─── RUNTIME BACKGROUND DEAMON CONTROL INTERVAL
196+
// ═══════════════════════════════════════════════════════════════════════════
184197
(async function startup() {
185-
logger.info('Continuous infinite processing loop initialized.');
198+
logger.info(`Microchess daemon fully active. Scheduled execution frequency interval: ${GENERATOR_INTERVAL / 60000} minutes.`);
199+
186200
while (true) {
187201
try {
188202
await runOnce();
189-
// 3-second cooling gap to guarantee the file handles completely release
190-
await new Promise((resolve) => setTimeout(resolve, 3000));
203+
204+
logger.info(`Sleeping for ${GENERATOR_INTERVAL / 3600000} hour before triggering next iteration calculation pass...`);
205+
// Controlled sleep window to drop thread CPU utilization straight to 0%
206+
await new Promise((resolve) => setTimeout(resolve, GENERATOR_INTERVAL));
191207
} catch (err) {
192-
logger.error(`Loop pass encountered error: ${err.message}`);
193-
await new Promise((resolve) => setTimeout(resolve, 5000));
208+
logger.error(`Error encountered in calculation loop frame: ${err.message}`);
209+
await new Promise((resolve) => setTimeout(resolve, 10000)); // Hold 10 seconds on fail
194210
}
195211
}
196212
})();

0 commit comments

Comments
 (0)