@@ -47,7 +47,7 @@ export default class DraughtsRLEnvironment extends RLEnvironmentBase {
4747 ]
4848 const checkBound = ( x , y ) => 0 <= x && x < this . _size [ 0 ] && 0 <= y && y < this . _size [ 1 ]
4949 for ( let i = 0 ; i < this . _size [ 0 ] ; i ++ ) {
50- for ( let j = i % 2 === 0 ? 0 : 1 ; j < this . _size [ 1 ] ; j += 2 ) {
50+ for ( let j = i % 2 === 1 ? 0 : 1 ; j < this . _size [ 1 ] ; j += 2 ) {
5151 let midpath = [ ]
5252 for ( const [ di , dj ] of d ) {
5353 const i1 = i + di
@@ -93,18 +93,14 @@ export default class DraughtsRLEnvironment extends RLEnvironmentBase {
9393 get states ( ) {
9494 const s = [ [ RED , WHITE ] ]
9595 for ( let i = 0 ; i < this . _size [ 0 ] ; i ++ ) {
96- for ( let j = 0 ; j < this . _size [ 1 ] ; j ++ ) {
97- if ( j % 2 === i % 2 ) {
98- s . push ( [
99- EMPTY ,
100- DraughtsRLEnvironment . OWN ,
101- DraughtsRLEnvironment . OWN | KING ,
102- DraughtsRLEnvironment . OTHER ,
103- DraughtsRLEnvironment . OTHER | KING ,
104- ] )
105- } else {
106- s . push ( [ EMPTY ] )
107- }
96+ for ( let j = i % 2 === 0 ? 1 : 0 ; j < this . _size [ 1 ] ; j += 2 ) {
97+ s . push ( [
98+ EMPTY ,
99+ DraughtsRLEnvironment . OWN ,
100+ DraughtsRLEnvironment . OWN | KING ,
101+ DraughtsRLEnvironment . OTHER ,
102+ DraughtsRLEnvironment . OTHER | KING ,
103+ ] )
108104 }
109105 }
110106 return s
@@ -123,7 +119,7 @@ export default class DraughtsRLEnvironment extends RLEnvironmentBase {
123119 _makeState ( board , agentturn , gameturn ) {
124120 const s = [ gameturn ]
125121 for ( let i = 0 ; i < this . _size [ 0 ] ; i ++ ) {
126- for ( let j = 0 ; j < this . _size [ 1 ] ; j ++ ) {
122+ for ( let j = i % 2 === 0 ? 1 : 0 ; j < this . _size [ 1 ] ; j += 2 ) {
127123 const p = board . at ( [ i , j ] )
128124 if ( p === EMPTY ) {
129125 s . push ( EMPTY )
@@ -144,7 +140,7 @@ export default class DraughtsRLEnvironment extends RLEnvironmentBase {
144140 const board = new DraughtsBoard ( this . _size , this . _evaluation )
145141 const opturn = turn === RED ? WHITE : RED
146142 for ( let i = 0 , p = 1 ; i < this . _size [ 0 ] ; i ++ ) {
147- for ( let j = 0 ; j < this . _size [ 1 ] ; j ++ , p ++ ) {
143+ for ( let j = i % 2 === 0 ? 1 : 0 ; j < this . _size [ 1 ] ; j += 2 , p ++ ) {
148144 if ( state [ p ] === EMPTY ) {
149145 board . _board [ i ] [ j ] = EMPTY
150146 } else {
@@ -241,6 +237,7 @@ class DraughtsBoard {
241237 constructor ( size , evaluator ) {
242238 this . _evaluator = evaluator
243239 this . _size = size
240+ this . _lines = 3
244241
245242 this . reset ( )
246243 }
@@ -280,6 +277,26 @@ class DraughtsBoard {
280277 return null
281278 }
282279
280+ toString ( ) {
281+ let buf = ''
282+ for ( let i = 0 ; i < this . _size [ 0 ] ; i ++ ) {
283+ for ( let j = 0 ; j < this . _size [ 1 ] ; j ++ ) {
284+ if ( j > 0 ) {
285+ buf += ' '
286+ }
287+ if ( this . _board [ i ] [ j ] === RED ) {
288+ buf += 'x'
289+ } else if ( this . _board [ i ] [ j ] === WHITE ) {
290+ buf += 'o'
291+ } else {
292+ buf += '-'
293+ }
294+ }
295+ buf += '\n'
296+ }
297+ return buf
298+ }
299+
283300 nextTurn ( turn ) {
284301 if ( turn === WHITE ) {
285302 return RED
@@ -310,20 +327,44 @@ class DraughtsBoard {
310327 }
311328 }
312329
330+ _num_to_pos ( n ) {
331+ if ( typeof n !== 'number' ) {
332+ return n
333+ }
334+ const r = Math . floor ( ( n - 1 ) / this . _size [ 1 ] )
335+ const c = ( n - 1 ) % this . _size [ 1 ]
336+ if ( c < ( this . _size [ 1 ] - 1 ) / 2 ) {
337+ return [ r * 2 , c * 2 + 1 ]
338+ } else {
339+ return [ r * 2 + 1 , ( c - Math . floor ( this . _size [ 1 ] / 2 ) ) * 2 ]
340+ }
341+ }
342+
313343 at ( p ) {
344+ if ( typeof p === 'number' ) {
345+ p = this . _num_to_pos ( p )
346+ }
314347 return this . _board [ p [ 0 ] ] [ p [ 1 ] ]
315348 }
316349
317350 set ( p , turn ) {
318- let piece = this . _board [ p . from [ 0 ] ] [ p . from [ 1 ] ]
351+ p = {
352+ from : this . _num_to_pos ( p . from ) ,
353+ path : p . path . map ( v => this . _num_to_pos ( v ) ) ,
354+ jump : p . jump . map ( v => this . _num_to_pos ( v ) ) ,
355+ }
356+ let piece = this . at ( p . from )
319357 if ( ! ( turn & piece ) ) {
320358 return false
321359 }
360+ if ( ( p . jump . length !== 0 || p . path . length !== 1 ) && p . jump . length !== p . path . length ) {
361+ return false
362+ }
322363 const nturn = this . nextTurn ( turn )
323- if ( p . jump . some ( ( [ i , j ] ) => ! ( this . _board [ i ] [ j ] & nturn ) ) ) {
364+ if ( p . jump . some ( j => ! ( this . at ( j ) & nturn ) ) ) {
324365 return false
325366 }
326- if ( p . path . some ( ( [ i , j ] ) => this . _board [ i ] [ j ] !== EMPTY ) ) {
367+ if ( p . path . some ( j => this . at ( j ) !== EMPTY ) ) {
327368 return false
328369 }
329370
@@ -334,6 +375,27 @@ class DraughtsBoard {
334375 }
335376 }
336377
378+ if ( p . jump . length === 0 ) {
379+ for ( let i = 0 ; i < 2 ; i ++ ) {
380+ if ( Math . abs ( p . from [ i ] - p . path [ 0 ] [ i ] ) !== 1 ) {
381+ return false
382+ }
383+ }
384+ } else {
385+ let pos = p . from
386+ for ( let k = 0 ; k < p . path . length ; k ++ ) {
387+ for ( let i = 0 ; i < 2 ; i ++ ) {
388+ if ( Math . abs ( pos [ i ] - p . jump [ k ] [ i ] ) !== 1 ) {
389+ return false
390+ }
391+ if ( Math . abs ( p . jump [ k ] [ i ] - p . path [ k ] [ i ] ) !== 1 ) {
392+ return false
393+ }
394+ }
395+ pos = p . path [ k ]
396+ }
397+ }
398+
337399 this . _board [ p . from [ 0 ] ] [ p . from [ 1 ] ] = EMPTY
338400 for ( const [ i , j ] of p . jump ) {
339401 this . _board [ i ] [ j ] = EMPTY
@@ -354,10 +416,10 @@ class DraughtsBoard {
354416 this . _board [ i ] = Array ( this . _size [ 1 ] ) . fill ( EMPTY )
355417 }
356418 for ( let i = 0 ; i < this . _size [ 0 ] ; i ++ ) {
357- for ( let j = 0 ; j < this . _size [ 1 ] ; j ++ ) {
358- if ( i < 3 && ( i + j ) % 2 === 0 ) {
419+ for ( let j = i % 2 === 0 ? 1 : 0 ; j < this . _size [ 1 ] ; j += 2 ) {
420+ if ( i < this . _lines ) {
359421 this . _board [ i ] [ j ] = RED
360- } else if ( this . _size [ 0 ] - 3 <= i && ( i + j ) % 2 === 0 ) {
422+ } else if ( this . _size [ 0 ] - this . _lines <= i ) {
361423 this . _board [ i ] [ j ] = WHITE
362424 }
363425 }
@@ -418,9 +480,9 @@ class DraughtsBoard {
418480 cp . _board [ x + dx * 2 ] [ y + dy * 2 ] = this . _board [ x ] [ y ]
419481 cp . _board [ x ] [ y ] = EMPTY
420482 cp . _board [ x + dx ] [ y + dy ] = EMPTY
421- if ( turn === RED && x * dx * 2 === this . _size [ 0 ] - 1 ) {
483+ if ( turn === RED && x + dx * 2 === this . _size [ 0 ] - 1 ) {
422484 cp . _board [ x + dx * 2 ] [ y + dy * 2 ] |= KING
423- } else if ( turn === WHITE && x * dx * 2 === 0 ) {
485+ } else if ( turn === WHITE && x + dx * 2 === 0 ) {
424486 cp . _board [ x + dx * 2 ] [ y + dy * 2 ] |= KING
425487 }
426488 const npath = cp . allPath ( x + dx * 2 , y + dy * 2 , turn , false )
0 commit comments