@@ -144,7 +144,7 @@ impl Board {
144
144
_ => panic ! ( "Invalid FEN" ) ,
145
145
} ;
146
146
147
- self . add_piece ( color, piece, rank, file) ;
147
+ self . add_piece ( color, piece, rank * 8 + file) ;
148
148
file += 1 ;
149
149
}
150
150
}
@@ -172,8 +172,7 @@ impl Board {
172
172
self . fullmove_number = parts[ 5 ] . parse ( ) . unwrap ( ) ;
173
173
}
174
174
175
- fn add_piece ( & mut self , color : Color , piece : Piece , rank : usize , file : usize ) {
176
- let index = rank * 8 + file;
175
+ fn add_piece ( & mut self , color : Color , piece : Piece , index : usize ) {
177
176
let bb = Bitboard :: from_index ( index) ;
178
177
179
178
match color {
@@ -251,6 +250,10 @@ impl Board {
251
250
!self . white_occupancy . is_set ( index) && !self . black_occupancy . is_set ( index)
252
251
}
253
252
253
+ pub fn is_index_in_bounds ( index : i64 ) -> bool {
254
+ index >= 0 && index < 64
255
+ }
256
+
254
257
pub fn print ( & self ) {
255
258
for rank in ( 0 ..8 ) . rev ( ) {
256
259
for file in 0 ..8 {
@@ -296,55 +299,63 @@ impl Board {
296
299
Color :: Black => -8 ,
297
300
} ;
298
301
self . remove_piece ( mv. color , Piece :: Pawn , mv. from ) ;
299
- self . add_piece ( mv. color , Piece :: Pawn , mv. to / 8 , mv . to % 8 ) ;
302
+ self . add_piece ( mv. color , Piece :: Pawn , mv. to ) ;
300
303
self . remove_piece (
301
304
match mv. color {
302
305
Color :: White => Color :: Black ,
303
306
Color :: Black => Color :: White ,
304
307
} ,
305
308
Piece :: Pawn ,
306
- ( mv. to as i32 + direction) as usize ,
309
+ ( mv. to as i32 - direction) as usize ,
307
310
) ;
308
311
} else if mv. castling {
309
312
match mv. to {
310
313
2 => {
311
314
self . remove_piece ( mv. color , Piece :: King , mv. from ) ;
312
- self . add_piece ( mv. color , Piece :: King , mv. to / 8 , mv . to % 8 ) ;
315
+ self . add_piece ( mv. color , Piece :: King , mv. to ) ;
313
316
self . remove_piece ( mv. color , Piece :: Rook , 0 ) ;
314
- self . add_piece ( mv. color , Piece :: Rook , 3 / 8 , 3 % 8 ) ;
317
+ self . add_piece ( mv. color , Piece :: Rook , 3 ) ;
315
318
}
316
319
6 => {
317
320
self . remove_piece ( mv. color , Piece :: King , mv. from ) ;
318
- self . add_piece ( mv. color , Piece :: King , mv. to / 8 , mv . to % 8 ) ;
321
+ self . add_piece ( mv. color , Piece :: King , mv. to ) ;
319
322
self . remove_piece ( mv. color , Piece :: Rook , 7 ) ;
320
- self . add_piece ( mv. color , Piece :: Rook , 5 / 8 , 5 % 8 ) ;
323
+ self . add_piece ( mv. color , Piece :: Rook , 5 ) ;
321
324
}
322
325
58 => {
323
326
self . remove_piece ( mv. color , Piece :: King , mv. from ) ;
324
- self . add_piece ( mv. color , Piece :: King , mv. to / 8 , mv . to % 8 ) ;
327
+ self . add_piece ( mv. color , Piece :: King , mv. to ) ;
325
328
self . remove_piece ( mv. color , Piece :: Rook , 56 ) ;
326
- self . add_piece ( mv. color , Piece :: Rook , 59 / 8 , 59 % 8 ) ;
329
+ self . add_piece ( mv. color , Piece :: Rook , 59 ) ;
327
330
}
328
331
62 => {
329
332
self . remove_piece ( mv. color , Piece :: King , mv. from ) ;
330
- self . add_piece ( mv. color , Piece :: King , mv. to / 8 , mv . to % 8 ) ;
333
+ self . add_piece ( mv. color , Piece :: King , mv. to ) ;
331
334
self . remove_piece ( mv. color , Piece :: Rook , 63 ) ;
332
- self . add_piece ( mv. color , Piece :: Rook , 61 / 8 , 61 % 8 ) ;
335
+ self . add_piece ( mv. color , Piece :: Rook , 61 ) ;
333
336
}
334
337
_ => panic ! ( "Invalid castling move" ) ,
335
338
}
336
339
} else if let Some ( promotion) = mv. promotion {
337
340
self . remove_piece ( mv. color , Piece :: Pawn , mv. from ) ;
338
- self . add_piece ( mv. color , promotion, mv. to / 8 , mv . to % 8 ) ;
341
+ self . add_piece ( mv. color , promotion, mv. to ) ;
339
342
} else {
340
343
self . remove_piece ( mv. color , mv. piece , mv. from ) ;
341
- self . add_piece ( mv. color , mv. piece , mv. to / 8 , mv . to % 8 ) ;
344
+ self . add_piece ( mv. color , mv. piece , mv. to ) ;
342
345
}
343
346
344
- if let Some ( ep ) = self . en_passant_square {
347
+ if self . en_passant_square . is_some ( ) {
345
348
self . en_passant_square = None ;
346
349
}
347
350
351
+ if mv. en_passant {
352
+ let direction = match mv. color {
353
+ Color :: White => 8 ,
354
+ Color :: Black => -8 ,
355
+ } ;
356
+ self . en_passant_square = Some ( ( mv. to as i64 - direction) as usize ) ;
357
+ }
358
+
348
359
self . turn = match self . turn {
349
360
Color :: White => Color :: Black ,
350
361
Color :: Black => Color :: White ,
@@ -363,14 +374,22 @@ impl Board {
363
374
}
364
375
365
376
pub fn generate_possible_moves ( self ) -> Vec < Move > {
366
- let moves = Vec :: new ( ) ;
377
+ let mut moves = Vec :: new ( ) ;
367
378
368
- // TODO: Generate all possible moves
379
+ moves. append ( & mut self . generate_pawn_moves ( ) ) ;
380
+
381
+ // TODO: Generate bishop moves
382
+ // TODO: Generate knight moves
383
+ // TODO: Generate rook moves
384
+ // TODO: Generate queen moves
385
+ // TODO: Generate king moves
386
+
387
+ moves. iter ( ) . for_each ( |m| println ! ( "{:?}" , m) ) ;
369
388
370
389
moves
371
390
}
372
391
373
- pub fn generate_pawn_moves ( self ) -> Vec < Move > {
392
+ pub fn generate_pawn_moves ( mut self ) -> Vec < Move > {
374
393
let mut moves = Vec :: new ( ) ;
375
394
let pawns = match self . turn {
376
395
Color :: White => self . white_pieces . pawns ,
@@ -383,19 +402,59 @@ impl Board {
383
402
if !pawns. is_set ( i) {
384
403
continue ;
385
404
}
405
+
386
406
let direction = match self . turn {
387
407
Color :: White => 8 ,
388
408
Color :: Black => -8 ,
389
409
} ;
390
410
411
+ let pos = i;
391
412
let from = i;
392
- let to = i as i32 + direction;
413
+ let possible_to = i as i64 + direction;
414
+
415
+ if !Board :: is_index_in_bounds ( possible_to) {
416
+ continue ;
417
+ }
418
+
419
+ let to = possible_to as usize ;
420
+
421
+ // DOUBLE PUSH
422
+ if ( RANK_2 . is_set ( pos) && self . turn == Color :: White )
423
+ || ( RANK_7 . is_set ( pos) && self . turn == Color :: Black )
424
+ {
425
+ let double = to as i64 + direction;
426
+ if self . is_square_empty ( to) && self . is_square_empty ( double as usize ) {
427
+ moves. push ( Move {
428
+ from,
429
+ to : double as usize ,
430
+ piece : Piece :: Pawn ,
431
+ color : self . turn ,
432
+ en_passant : true ,
433
+ castling : false ,
434
+ promotion : None ,
435
+ } ) ;
436
+ }
437
+ }
393
438
394
- if to < 64 && to >= 0 {
395
- if self . is_square_empty ( to as usize ) {
439
+ // EN PASSANT
440
+ if let Some ( ep) = self . en_passant_square {
441
+ let left = ep - 1 ;
442
+ let right = ep + 1 ;
443
+ if left == ep {
444
+ moves. push ( Move {
445
+ from,
446
+ to,
447
+ piece : Piece :: Pawn ,
448
+ color : self . turn ,
449
+ en_passant : false ,
450
+ castling : false ,
451
+ promotion : None ,
452
+ } ) ;
453
+ }
454
+ if right == ep {
396
455
moves. push ( Move {
397
456
from,
398
- to : to as usize ,
457
+ to,
399
458
piece : Piece :: Pawn ,
400
459
color : self . turn ,
401
460
en_passant : false ,
@@ -404,6 +463,61 @@ impl Board {
404
463
} ) ;
405
464
}
406
465
}
466
+
467
+ // PROMOTION
468
+ if ( self . turn == Color :: White && RANK_7 . is_set ( pos) && self . is_square_empty ( to) )
469
+ || ( self . turn == Color :: Black && RANK_2 . is_set ( pos) && self . is_square_empty ( to) )
470
+ {
471
+ moves. push ( Move {
472
+ from,
473
+ to : to,
474
+ piece : Piece :: Pawn ,
475
+ color : self . turn ,
476
+ en_passant : false ,
477
+ castling : false ,
478
+ promotion : Some ( Piece :: Queen ) ,
479
+ } ) ;
480
+ moves. push ( Move {
481
+ from,
482
+ to : to,
483
+ piece : Piece :: Pawn ,
484
+ color : self . turn ,
485
+ en_passant : false ,
486
+ castling : false ,
487
+ promotion : Some ( Piece :: Rook ) ,
488
+ } ) ;
489
+ moves. push ( Move {
490
+ from,
491
+ to : to,
492
+ piece : Piece :: Pawn ,
493
+ color : self . turn ,
494
+ en_passant : false ,
495
+ castling : false ,
496
+ promotion : Some ( Piece :: Bishop ) ,
497
+ } ) ;
498
+ moves. push ( Move {
499
+ from,
500
+ to : to,
501
+ piece : Piece :: Pawn ,
502
+ color : self . turn ,
503
+ en_passant : false ,
504
+ castling : false ,
505
+ promotion : Some ( Piece :: Knight ) ,
506
+ } ) ;
507
+ }
508
+
509
+ // NORMAL PUSH
510
+ if self . is_square_empty ( to) {
511
+ moves. push ( Move {
512
+ from,
513
+ to,
514
+ piece : Piece :: Pawn ,
515
+ color : self . turn ,
516
+ en_passant : false ,
517
+ castling : false ,
518
+ promotion : None ,
519
+ } ) ;
520
+ }
407
521
}
408
522
409
523
moves
0 commit comments