Skip to content

Commit 9931c46

Browse files
committed
Create pawn moves
1 parent 32f1730 commit 9931c46

File tree

2 files changed

+155
-39
lines changed

2 files changed

+155
-39
lines changed

src/board.rs

Lines changed: 137 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ impl Board {
144144
_ => panic!("Invalid FEN"),
145145
};
146146

147-
self.add_piece(color, piece, rank, file);
147+
self.add_piece(color, piece, rank * 8 + file);
148148
file += 1;
149149
}
150150
}
@@ -172,8 +172,7 @@ impl Board {
172172
self.fullmove_number = parts[5].parse().unwrap();
173173
}
174174

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) {
177176
let bb = Bitboard::from_index(index);
178177

179178
match color {
@@ -251,6 +250,10 @@ impl Board {
251250
!self.white_occupancy.is_set(index) && !self.black_occupancy.is_set(index)
252251
}
253252

253+
pub fn is_index_in_bounds(index: i64) -> bool {
254+
index >= 0 && index < 64
255+
}
256+
254257
pub fn print(&self) {
255258
for rank in (0..8).rev() {
256259
for file in 0..8 {
@@ -296,55 +299,63 @@ impl Board {
296299
Color::Black => -8,
297300
};
298301
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);
300303
self.remove_piece(
301304
match mv.color {
302305
Color::White => Color::Black,
303306
Color::Black => Color::White,
304307
},
305308
Piece::Pawn,
306-
(mv.to as i32 + direction) as usize,
309+
(mv.to as i32 - direction) as usize,
307310
);
308311
} else if mv.castling {
309312
match mv.to {
310313
2 => {
311314
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);
313316
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);
315318
}
316319
6 => {
317320
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);
319322
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);
321324
}
322325
58 => {
323326
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);
325328
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);
327330
}
328331
62 => {
329332
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);
331334
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);
333336
}
334337
_ => panic!("Invalid castling move"),
335338
}
336339
} else if let Some(promotion) = mv.promotion {
337340
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);
339342
} else {
340343
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);
342345
}
343346

344-
if let Some(ep) = self.en_passant_square {
347+
if self.en_passant_square.is_some() {
345348
self.en_passant_square = None;
346349
}
347350

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+
348359
self.turn = match self.turn {
349360
Color::White => Color::Black,
350361
Color::Black => Color::White,
@@ -363,14 +374,22 @@ impl Board {
363374
}
364375

365376
pub fn generate_possible_moves(self) -> Vec<Move> {
366-
let moves = Vec::new();
377+
let mut moves = Vec::new();
367378

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));
369388

370389
moves
371390
}
372391

373-
pub fn generate_pawn_moves(self) -> Vec<Move> {
392+
pub fn generate_pawn_moves(mut self) -> Vec<Move> {
374393
let mut moves = Vec::new();
375394
let pawns = match self.turn {
376395
Color::White => self.white_pieces.pawns,
@@ -383,19 +402,59 @@ impl Board {
383402
if !pawns.is_set(i) {
384403
continue;
385404
}
405+
386406
let direction = match self.turn {
387407
Color::White => 8,
388408
Color::Black => -8,
389409
};
390410

411+
let pos = i;
391412
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+
}
393438

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 {
396455
moves.push(Move {
397456
from,
398-
to: to as usize,
457+
to,
399458
piece: Piece::Pawn,
400459
color: self.turn,
401460
en_passant: false,
@@ -404,6 +463,61 @@ impl Board {
404463
});
405464
}
406465
}
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+
}
407521
}
408522

409523
moves

src/constans.rs

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,22 @@
1-
pub const RANK_1: u64 = 0x00000000000000FF;
2-
pub const RANK_2: u64 = 0x000000000000FF00;
3-
pub const RANK_3: u64 = 0x0000000000FF0000;
4-
pub const RANK_4: u64 = 0x00000000FF000000;
5-
pub const RANK_5: u64 = 0x000000FF00000000;
6-
pub const RANK_6: u64 = 0x0000FF0000000000;
7-
pub const RANK_7: u64 = 0x00FF000000000000;
8-
pub const RANK_8: u64 = 0xFF00000000000000;
1+
use crate::bitboard::Bitboard;
92

10-
pub const FILE_A: u64 = 0x0101010101010101;
11-
pub const FILE_B: u64 = 0x0202020202020202;
12-
pub const FILE_C: u64 = 0x0404040404040404;
13-
pub const FILE_D: u64 = 0x0808080808080808;
14-
pub const FILE_E: u64 = 0x1010101010101010;
15-
pub const FILE_F: u64 = 0x2020202020202020;
16-
pub const FILE_G: u64 = 0x4040404040404040;
17-
pub const FILE_H: u64 = 0x8080808080808080;
3+
pub const RANK_1: Bitboard = Bitboard(0x00000000000000FF);
4+
pub const RANK_2: Bitboard = Bitboard(0x000000000000FF00);
5+
pub const RANK_3: Bitboard = Bitboard(0x0000000000FF0000);
6+
pub const RANK_4: Bitboard = Bitboard(0x00000000FF000000);
7+
pub const RANK_5: Bitboard = Bitboard(0x000000FF00000000);
8+
pub const RANK_6: Bitboard = Bitboard(0x0000FF0000000000);
9+
pub const RANK_7: Bitboard = Bitboard(0x00FF000000000000);
10+
pub const RANK_8: Bitboard = Bitboard(0xFF00000000000000);
11+
12+
pub const FILE_A: Bitboard = Bitboard(0x0101010101010101);
13+
pub const FILE_B: Bitboard = Bitboard(0x0202020202020202);
14+
pub const FILE_C: Bitboard = Bitboard(0x0404040404040404);
15+
pub const FILE_D: Bitboard = Bitboard(0x0808080808080808);
16+
pub const FILE_E: Bitboard = Bitboard(0x1010101010101010);
17+
pub const FILE_F: Bitboard = Bitboard(0x2020202020202020);
18+
pub const FILE_G: Bitboard = Bitboard(0x4040404040404040);
19+
pub const FILE_H: Bitboard = Bitboard(0x8080808080808080);
1820

1921
pub const STARTING_POSITION: &str = "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1";
2022

0 commit comments

Comments
 (0)