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 */
77const path = require ( 'path' ) ;
88require ( 'dotenv' ) . config ( ) ;
@@ -18,18 +18,20 @@ const { Chess } = require('../dist/cjs/chess.js');
1818
1919const convnetjs = require ( './core/convnet.js' ) ;
2020
21- //
22- // Configuration Matrix Mappings
23- //
21+ // ═══════════════════════════════════════════════════════════════════════════
22+ // ─── CONFIGURATION & MATRIX PATH MAPPINGS
23+ // ═══════════════════════════════════════════════════════════════════════════
2424const OUTPUT_FILE = process . env . MICROCHESS_OUTPUT_FILE
2525 ? path . resolve ( process . env . MICROCHESS_OUTPUT_FILE )
2626 : path . join ( __dirname , 'randomchess.json' ) ;
2727
2828const 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
3335const 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+ // ═══════════════════════════════════════════════════════════════════════════
4650const netLayerDefs = [ ] ;
4751netLayerDefs . push ( { type : 'input' , out_sx : 1 , out_sy : 1 , out_depth : 64 } ) ;
4852netLayerDefs . 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+ */
6067function 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+ // ═══════════════════════════════════════════════════════════════════════════
7989async 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+ // ═══════════════════════════════════════════════════════════════════════════
98111async 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