@@ -45,6 +45,7 @@ var simulate = false
45
45
var hit_char = HIT
46
46
var miss_char = AIR
47
47
var head_char = HEAD
48
+ var seed = 0
48
49
49
50
func usage {
50
51
print <<"EOT"
58
59
--miss=s : character used when a plane is missed (default: "#{ miss_char } ")
59
60
--colors! : use ANSI colors (requires Term::ANSIColor) (default: #{ use_colors } )
60
61
--simulate! : run a random simulation (default: #{ simulate } )
62
+ --seed=i : run with a given pseudorandom seed value > 0 (default: #{ seed } )
61
63
62
64
help:
63
65
--help : print this message and exit
@@ -85,6 +87,7 @@ if (ARGV) {
85
87
getopt . GetOptions (
86
88
'board-size|size=i' => func ( _ , v ) { BOARD_SIZE = Num ( v ) } ,
87
89
'planes-num=i' => func ( _ , v ) { PLANES_NUM = Num ( v ) } ,
90
+ 'seed=i' => func ( _ , v ) { seed = Num ( v ) } ,
88
91
'hit-char=s' => func ( _ , v ) { hit_char = Str ( v ) } ,
89
92
'miss-char=s' => func ( _ , v ) { miss_char = Str ( v ) } ,
90
93
'wrap!' => func ( _ , v ) { wrap_plane = Bool ( v ) } ,
@@ -95,6 +98,11 @@ if (ARGV) {
95
98
)
96
99
}
97
100
101
+ if ( seed ) {
102
+ iseed ( seed )
103
+ Perl . eval ( "srand(#{ seed } )" )
104
+ }
105
+
98
106
#---------------------------------------------------------------
99
107
100
108
func pointers ( board , x , y , indices ) {
@@ -241,24 +249,24 @@ func create_planes(play_board) {
241
249
func guess ( info_board , play_board , plane_count ) {
242
250
243
251
var count = 0
244
- var sampled = Set ( )
245
252
var max_tries = BOARD_SIZE *BOARD_SIZE
253
+ var indices = PAIR_INDICES . shuffle
246
254
247
255
while ( count != ( PLANES_NUM - plane_count ) ) {
248
256
249
257
#var x = irand(1, BOARD_SIZE)-1
250
258
#var y = irand(1, BOARD_SIZE)-1
251
259
252
- var ( x , y ) = ( PAIR_INDICES . shuffle . first_by { |idx |
253
- ( play_board [ idx [ 0 ] ] [ idx [ 1 ] ] == BLANK ) && ( info_board [ idx [ 0 ] ] [ idx [ 1 ] ] == BLANK ) && !sampled . has ( idx )
254
- } \\ return nil) ...
260
+ var ( x , y ) = ( indices . pop_rand \\ return nil ) ...
261
+ loop {
262
+ ( play_board [ x ] [ y ] == BLANK ) && ( info_board [ x ] [ y ] == BLANK ) && break
263
+ ( x , y ) = ( indices . pop_rand \\ return nil ) ...
264
+ }
255
265
256
266
if ( --max_tries <= 0 ) {
257
267
return nil
258
268
}
259
269
260
- sampled << [ x , y ]
261
-
262
270
var good_directions = DIRECTIONS . grep { |dir |
263
271
var plane = pointers ( info_board , x , y , dir )
264
272
plane && plane . none { *_ = = AIR }
@@ -362,10 +370,24 @@ func solve(callback) {
362
370
var all_dead = true
363
371
var new_info = false
364
372
365
- get_head_positions ( play_board ) . shuffle . each_2d { |i , j |
373
+ var head_pos = get_head_positions ( play_board ) . shuffle
374
+
375
+ head_pos = head_pos . grep_2d { |x , y | info_board [ x ] [ y ] == BLANK } . map_2d { |x , y |
376
+ [ x , y , DIRECTIONS . first_by { |d |
377
+ ( pointers ( play_board , x , y , d ) . count_by { *_ = = HIT } == 7 ) &&
378
+ ( pointers ( info_board , x , y , d ) . none { *_ = = AIR } )
379
+ } ]
380
+ }
381
+
382
+ # Prefer the planes with the most hits
383
+ head_pos = head_pos . sort_by { |p |
384
+ pointers ( info_board , p [ 0 ] , p [ 1 ] , p [ 2 ] ) . count_by { *_ = = HIT }
385
+ } . flip
386
+
387
+ head_pos . each_2d { |i , j |
366
388
367
- if ( info_board [ i ] [ j ] == HEAD ) {
368
- next # already destroyed
389
+ if ( info_board [ i ] [ j ] != BLANK ) {
390
+ next
369
391
}
370
392
371
393
all_dead = false
@@ -381,10 +403,11 @@ func solve(callback) {
381
403
if ( score == HEAD ) {
382
404
new_info = true
383
405
boards = make_play_boards ( info_board )
406
+ next
384
407
}
385
408
elsif ( score == AIR ) {
386
409
new_info = true
387
- boards = boards . grep { valid_assignment ( . head , info_board ) }
410
+ boards = boards . grep { valid_assignment ( . head , info_board ) } . flip
388
411
}
389
412
390
413
break
0 commit comments