game.rs 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923
  1. use bitboard::*;
  2. use movegen::*;
  3. use log::info;
  4. use std::sync::Arc;
  5. use zobrist::{ZobristTable};
  6. use zobrist;
  7. use crate::movegen;
  8. #[derive(Clone)]
  9. pub struct Game
  10. {
  11. pub pieces: [Bitboard; 12],
  12. pub turn: Side,
  13. /// None if no en passant move is possible,
  14. /// otherwise contains the file of the last (double-) pushed pawn
  15. pub en_passant: Option<u8>,
  16. ///
  17. /// castling rights in the following order
  18. /// white kingside, white queenside, black kingside, black queenside
  19. ///
  20. pub castling_rights: [bool; 4],
  21. //
  22. // non-hashed part
  23. // vvv
  24. pub turn_number: i32,
  25. pub halfmoves_since_last_event: i8,
  26. pub zobrist: Option<(Arc<ZobristTable>, zobrist::Hash)>
  27. }
  28. impl Default for Game {
  29. fn default () -> Game {
  30. Game {
  31. pieces: [
  32. ROW_2,
  33. 0x42,
  34. 0x24,
  35. 0x81,
  36. 0x10,
  37. 0x08,
  38. ROW_7,
  39. 0x42 << 56,
  40. 0x24 << 56,
  41. 0x81 << 56,
  42. 0x10 << 56,
  43. 0x08 << 56,
  44. ],
  45. turn: WHITE,
  46. en_passant: None,
  47. castling_rights: [true; 4],
  48. halfmoves_since_last_event: 0,
  49. turn_number: 0,
  50. zobrist: None
  51. }
  52. }
  53. }
  54. impl std::hash::Hash for Game {
  55. fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
  56. if let Some((ref _zt, ref zb)) = &self.zobrist {
  57. zb.hash(state);
  58. }
  59. }
  60. }
  61. impl PartialEq for Game {
  62. fn eq(&self, other: &Self) -> bool {
  63. self.pieces == other.pieces &&
  64. self.turn == other.turn &&
  65. self.en_passant == other.en_passant &&
  66. self.castling_rights == other.castling_rights
  67. }
  68. }
  69. impl Eq for Game {
  70. }
  71. impl Game {
  72. pub fn empty() -> Game {
  73. Game {
  74. pieces: [0; 12],
  75. turn: WHITE,
  76. en_passant: None,
  77. castling_rights: [true; 4],
  78. halfmoves_since_last_event: 0,
  79. turn_number: 0,
  80. zobrist: None
  81. }
  82. }
  83. pub fn from_fen(fen: &[&str]) -> Option<Game> {
  84. let mut game: Game = Game::empty();
  85. //let example = "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1";
  86. let position = fen[0];
  87. let turn = fen[1];
  88. let castling_rights = fen[2];
  89. let en_passant = fen[3];
  90. let halfmoves_since_last_event = fen[4];
  91. let turn_number = fen[5];
  92. {
  93. let rows = position.split('/');
  94. let mut row_index: i32 = 7;
  95. for row in rows {
  96. if row_index < 0 {
  97. return None;
  98. }
  99. let mut col_index = 0;
  100. for c in row.chars() {
  101. if col_index >= 8 {
  102. return None;
  103. }
  104. let bit_to_set = from_indices(col_index, row_index as _);
  105. match c {
  106. 'p' => { *game.pawns_mut(BLACK) |= bit_to_set },
  107. 'n' => { *game.knights_mut(BLACK) |= bit_to_set },
  108. 'b' => { *game.bishops_mut(BLACK) |= bit_to_set },
  109. 'r' => { *game.rooks_mut(BLACK) |= bit_to_set },
  110. 'q' => { *game.queens_mut(BLACK) |= bit_to_set },
  111. 'k' => { *game.kings_mut(BLACK) |= bit_to_set },
  112. 'P' => { *game.pawns_mut(WHITE) |= bit_to_set },
  113. 'N' => { *game.knights_mut(WHITE) |= bit_to_set },
  114. 'B' => { *game.bishops_mut(WHITE) |= bit_to_set },
  115. 'R' => { *game.rooks_mut(WHITE) |= bit_to_set },
  116. 'Q' => { *game.queens_mut(WHITE) |= bit_to_set },
  117. 'K' => { *game.kings_mut(WHITE) |= bit_to_set },
  118. num => {
  119. col_index += match num.to_digit(10) {
  120. Some(x) => x,
  121. None => { return None; }
  122. } as u8 - 1;
  123. }
  124. }
  125. col_index += 1;
  126. }
  127. row_index -= 1;
  128. }
  129. }
  130. if turn == "b" {
  131. game.turn = BLACK
  132. }
  133. // parse castling rights
  134. game.castling_rights[0] = castling_rights.contains('K');
  135. game.castling_rights[1] = castling_rights.contains('Q');
  136. game.castling_rights[2] = castling_rights.contains('k');
  137. game.castling_rights[3] = castling_rights.contains('q');
  138. // parse en passant
  139. game.en_passant = Move::parse_square(en_passant).map(|sq| indices_from_square(sq).0);
  140. //info!("en passant on file {:?}", game.en_passant);
  141. game.halfmoves_since_last_event = halfmoves_since_last_event.parse::<i8>().unwrap_or(0);
  142. game.turn_number = turn_number.parse::<i32>().unwrap_or(0);
  143. Some(game)
  144. }
  145. pub fn from_fen_str(fen: &str) -> Option<Game> {
  146. let fen_parts = fen.split_whitespace();
  147. Self::from_fen(fen_parts.collect::<Vec<&str>>().as_slice())
  148. }
  149. pub fn parse_move(&self, mov: &str) -> Result<Move, ()> {
  150. if mov.len() < 4 {
  151. Err(())
  152. }
  153. else {
  154. let origin = Move::parse_square(&mov[0..2]);
  155. let target = Move::parse_square(&mov[2..4]);
  156. let promote_to = if mov.len() == 5 {
  157. Some(match mov.chars().nth(4) {
  158. Some('Q') | Some('q') => QUEEN,
  159. Some('N') | Some('n') => KNIGHT,
  160. Some('B') | Some('b') => BISHOP,
  161. Some('R') | Some('r') => ROOK,
  162. _ => panic!("invalid move: {}", mov)
  163. })
  164. }
  165. else {
  166. None
  167. };
  168. if let (Some(from), Some(to)) = (origin, target) {
  169. let (piece_type, side) = self.get_square(from);
  170. //println!("from: {}", from);
  171. let (cap, cs) = self.get_square(to);
  172. let captured = if cap != NO_PIECE { Some(cap) } else { None };
  173. if cap != NO_PIECE && cs == side {
  174. // cannot capture own piece
  175. return Err(());
  176. }
  177. if piece_type == NO_PIECE {
  178. return Err(());
  179. }
  180. if side != self.turn { // wrong side to move
  181. return Err(());
  182. }
  183. if let Some(promote_to) = promote_to {
  184. if piece_type != PAWN {
  185. return Err(());
  186. }
  187. Ok(Move::Promotion{ mov: SimpleMove{ from, to }, promote_to, captured })
  188. }
  189. else {
  190. if piece_type == KING && (from as i32 - to as i32).abs() == 2 {
  191. let left = from < to;
  192. //println!("OMG castling!");
  193. return Ok(Move::Castling{ side, left });
  194. }
  195. // pawn capture
  196. let (from_file, from_row) = indices_from_square(from);
  197. let (target_file, _target_row) = indices_from_square(to);
  198. if piece_type == PAWN && from_file != target_file {
  199. let others = self.get_all_side(!side);
  200. if others & from_square(to) == 0 {
  201. let beaten = square_from_indices(target_file, from_row);
  202. return Ok(Move::EnPassant{ mov: SimpleMove{ from, to }, beaten });
  203. }
  204. }
  205. //println!("pt: {}", piece_type);
  206. Ok(Move::Default{ mov: SimpleMove{ from, to }, piece_type, captured })
  207. }
  208. }
  209. else {
  210. Err(())
  211. }
  212. }
  213. }
  214. pub fn bitboard(&self, pt: PieceType, side: Side) -> Bitboard {
  215. if side == BLACK {
  216. self.pieces[(pt + 6) as usize]
  217. } else {
  218. self.pieces[pt as usize]
  219. }
  220. }
  221. /**
  222. * finds the first bitboard that has overlapping bits with the given bitboard
  223. * and returns the piece type of that bitboard
  224. */
  225. pub fn find_piece(&self, bitboard: Bitboard) -> Option<PieceType> {
  226. for i in 0..12 {
  227. if self.pieces[i] & bitboard != 0 {
  228. return Some(if i >= 6 { i - 6 } else { i } as PieceType);
  229. }
  230. }
  231. return None;
  232. }
  233. /**
  234. * \return bitboard containig all occupied squares
  235. */
  236. pub fn occupied(&self) -> Bitboard {
  237. self.pieces.iter().fold(0, |a, b| { a | b } )
  238. }
  239. pub fn pawns(&self, side: Side) -> Bitboard {
  240. match side {
  241. WHITE => self.pieces[0],
  242. BLACK => self.pieces[6],
  243. }
  244. }
  245. pub fn knights(&self, side: Side) -> Bitboard {
  246. match side {
  247. WHITE => self.pieces[1],
  248. BLACK => self.pieces[7],
  249. }
  250. }
  251. pub fn bishops(&self, side: Side) -> Bitboard {
  252. match side {
  253. WHITE => self.pieces[2],
  254. BLACK => self.pieces[8],
  255. }
  256. }
  257. pub fn rooks(&self, side: Side) -> Bitboard {
  258. match side {
  259. WHITE => self.pieces[3],
  260. BLACK => self.pieces[9],
  261. }
  262. }
  263. pub fn queens(&self, side: Side) -> Bitboard {
  264. match side {
  265. WHITE => self.pieces[4],
  266. BLACK => self.pieces[10],
  267. }
  268. }
  269. pub fn kings(&self, side: Side) -> Bitboard {
  270. match side {
  271. WHITE => self.pieces[5],
  272. BLACK => self.pieces[11],
  273. }
  274. }
  275. pub fn pawns_mut(&mut self, side: Side) -> &mut Bitboard {
  276. match side {
  277. WHITE => &mut self.pieces[0],
  278. BLACK => &mut self.pieces[6],
  279. }
  280. }
  281. pub fn knights_mut(&mut self, side: Side) -> &mut Bitboard {
  282. match side {
  283. WHITE => &mut self.pieces[1],
  284. BLACK => &mut self.pieces[7],
  285. }
  286. }
  287. pub fn bishops_mut(&mut self, side: Side) -> &mut Bitboard {
  288. match side {
  289. WHITE => &mut self.pieces[2],
  290. BLACK => &mut self.pieces[8],
  291. }
  292. }
  293. pub fn rooks_mut(&mut self, side: Side) -> &mut Bitboard {
  294. match side {
  295. WHITE => &mut self.pieces[3],
  296. BLACK => &mut self.pieces[9],
  297. }
  298. }
  299. pub fn queens_mut(&mut self, side: Side) -> &mut Bitboard {
  300. match side {
  301. WHITE => &mut self.pieces[4],
  302. BLACK => &mut self.pieces[10],
  303. }
  304. }
  305. pub fn kings_mut(&mut self, side: Side) -> &mut Bitboard {
  306. match side {
  307. WHITE => &mut self.pieces[5],
  308. BLACK => &mut self.pieces[11],
  309. }
  310. }
  311. pub fn get_piece(&self, piece_type: PieceType, side: Side) -> Bitboard {
  312. match side {
  313. WHITE => self.pieces[piece_type as usize],
  314. BLACK => self.pieces[piece_type as usize + 6],
  315. }
  316. }
  317. pub fn set_piece(&mut self, piece_type: PieceType, side: Side, bitboard: Bitboard) {
  318. match side {
  319. WHITE => self.pieces[piece_type as usize] = bitboard,
  320. BLACK => self.pieces[piece_type as usize + 6] = bitboard,
  321. }
  322. }
  323. pub fn get_piece_mut(&mut self, piece_type: PieceType, side: Side) -> &mut Bitboard {
  324. match side {
  325. WHITE => &mut self.pieces[piece_type as usize],
  326. BLACK => &mut self.pieces[piece_type as usize + 6],
  327. }
  328. }
  329. pub fn get_all_side(&self, side: Side) -> Bitboard {
  330. match side {
  331. WHITE => self.pieces[0] | self.pieces[1] | self.pieces[2] | self.pieces[3] |
  332. self.pieces[4] | self.pieces[5],
  333. BLACK => self.pieces[6] | self.pieces[7] | self.pieces[8] | self.pieces[9] |
  334. self.pieces[10] | self.pieces[11]
  335. }
  336. }
  337. pub fn get_square(&self, square: Square) -> (PieceType, Side) {
  338. let square_mask = 1 << square;
  339. for i in 0..6 {
  340. if self.pieces[i] & square_mask != 0 {
  341. return (i as PieceType, WHITE);
  342. }
  343. }
  344. for i in 0..6 {
  345. if self.pieces[i + 6] & square_mask != 0 {
  346. return (i as PieceType, BLACK);
  347. }
  348. }
  349. return (NO_PIECE, WHITE);
  350. }
  351. /**
  352. * @brief masks all bitboards.
  353. */
  354. pub fn apply_mask(&mut self, mask: Bitboard) {
  355. for board in &mut self.pieces {
  356. *board &= mask;
  357. }
  358. }
  359. /**
  360. * @brief creates a unicode string containing the board
  361. *
  362. * Example:
  363. *
  364. * ┌───┬───┬───┬───┬───┬───┬───┬───┐
  365. * 8 │ ♜ │ ♞ │ ♝ │ ♛ │ ♚ │ ♝ │ ♞ │ ♜ │
  366. * ├───┼───┼───┼───┼───┼───┼───┼───┤
  367. * 7 │ ♟ │ ♟ │ ♟ │ ♟ │ ♟ │ ♟ │ ♟ │ ♟ │
  368. * ├───┼───┼───┼───┼───┼───┼───┼───┤
  369. * 6 │ │ │ │ │ │ │ │ │
  370. * ├───┼───┼───┼───┼───┼───┼───┼───┤
  371. * 5 │ │ │ │ │ │ │ │ │
  372. * ├───┼───┼───┼───┼───┼───┼───┼───┤
  373. * 4 │ │ │ │ │ │ │ │ │
  374. * ├───┼───┼───┼───┼───┼───┼───┼───┤
  375. * 3 │ │ │ │ │ │ │ │ │
  376. * ├───┼───┼───┼───┼───┼───┼───┼───┤
  377. * 2 │ ♙ │ ♙ │ ♙ │ ♙ │ ♙ │ ♙ │ ♙ │ ♙ │
  378. * ├───┼───┼───┼───┼───┼───┼───┼───┤
  379. * 1 │ ♖ │ ♘ │ ♗ │ ♕ │ ♔ │ ♗ │ ♘ │ ♖ │
  380. * └───┴───┴───┴───┴───┴───┴───┴───┘
  381. * a b c d e f g h
  382. *
  383. */
  384. pub fn beautiful_print(&self) -> String {
  385. let chars = ['─', '│', '┌', '┐', '└', '┘', '├', '┤', '┬', '┴', '┼'];
  386. let figures = ['♙', '♘', '♗', '♖', '♕', '♔', '♟', '♞', '♝', '♜', '♛', '♚'];
  387. let mut board: String = String::new();
  388. #[derive(Copy, Clone)]
  389. struct GridLine {
  390. left: char,
  391. center: char,
  392. right: char,
  393. }
  394. let top = GridLine { left: chars[2], center: chars[8], right: chars[3] };
  395. let center = GridLine { left: chars[6], center: chars[10], right: chars[7] };
  396. let bot = GridLine { left: chars[4], center: chars[9], right: chars[5] };
  397. let generate_line = |gl: GridLine| {
  398. let mut line = String::new();
  399. for i in 0..33 {
  400. match i {
  401. 0 => { line.push(gl.left) }
  402. 32 => { line.push(gl.right) }
  403. x => { line.push(if x % 4 == 0 { gl.center } else { chars[0] }) }
  404. }
  405. }
  406. return line;
  407. };
  408. let piece_line = |row: u8| {
  409. let mut line = String::new();
  410. line.push(chars[1]);
  411. line.push(' ');
  412. for i in 0..8 {
  413. let (pt, side) = self.get_square(square_from_indices(i, 7 - row));
  414. if pt == NO_PIECE {
  415. line.push(' ');
  416. }
  417. else {
  418. let fig_index = pt as usize + if side == BLACK { 6 } else { 0 };
  419. line.push(figures[fig_index]);
  420. }
  421. line.push(' '); line.push(chars[1]); line.push(' ');
  422. }
  423. return line;
  424. };
  425. board.push_str(" ");
  426. board.push_str(&generate_line(top));
  427. board.push('\n');
  428. for i in 0..8 {
  429. board.push_str(&(8 - i).to_string());
  430. board.push(' ');
  431. board.push_str(&piece_line(i));
  432. board.push('\n');
  433. if i != 7 {
  434. board.push_str(" ");
  435. board.push_str(&generate_line(center));
  436. board.push('\n');
  437. }
  438. }
  439. board.push_str(" ");
  440. board.push_str(&generate_line(bot));
  441. board.push_str("\n a b c d e f g h");
  442. let chars = ['K', 'Q', 'k', 'q'];
  443. let mut cr: [char; 4] = [' '; 4];
  444. for i in 0..4 {
  445. cr[i] = if self.castling_rights[i] {
  446. chars[i]
  447. } else { ' ' };
  448. }
  449. if self.turn == WHITE {
  450. board.push_str("\nWhite to move\n");
  451. }
  452. else {
  453. board.push_str("\nBlack to move\n");
  454. }
  455. board.push_str(&format!("\nCastling : {}{}{}{}", cr[0], cr[1], cr[2], cr[3]));
  456. board.push_str(&format!("\nEn Passant : {}", self.en_passant.map(|f| f.to_string()).unwrap_or("-".to_owned())));
  457. board.push_str(&format!("\nTurn number : {}", self.turn_number));
  458. board.push_str(&format!("\nHalfmoves slt : {}", self.halfmoves_since_last_event));
  459. return board;
  460. }
  461. pub fn update_zobrist(&mut self, h: zobrist::Hash) {
  462. if let Some((ref _zt, ref mut zh)) = self.zobrist {
  463. *zh ^= h;
  464. }
  465. }
  466. pub fn calculate_zobrist(&self, zt: &ZobristTable) -> zobrist::Hash {
  467. let mut hash: zobrist::Hash = 0;
  468. for pt in 0..6 {
  469. let bb_it_w = BitboardIterator(self.get_piece(pt, WHITE));
  470. let bb_it_b = BitboardIterator(self.get_piece(pt, BLACK));
  471. for bb_square in bb_it_w {
  472. hash ^= zt.piece_hash(pt as _, WHITE, square(bb_square));
  473. }
  474. for bb_square in bb_it_b {
  475. hash ^= zt.piece_hash(pt as _, BLACK, square(bb_square));
  476. }
  477. }
  478. for cr_id in 0..4 {
  479. if self.castling_rights[cr_id] {
  480. hash ^= zt.castling_rights_hash(cr_id as _);
  481. }
  482. }
  483. if let Some(file) = self.en_passant {
  484. hash ^= zt.en_passant_hash(file);
  485. }
  486. if self.turn {
  487. hash ^= zt.turn_hash();
  488. }
  489. return hash;
  490. }
  491. pub fn is_zobrist_correct(&self) -> bool {
  492. if let Some((ref zt, zv)) = self.zobrist {
  493. self.calculate_zobrist(zt) == zv
  494. }
  495. else {
  496. false
  497. }
  498. }
  499. ///
  500. /// TODO: improve
  501. ///
  502. pub fn is_legal(&self, mov: Move) -> bool {
  503. movegen::generate_legal_moves(&mut self.clone(), self.turn, false).contains(&mov)
  504. }
  505. pub fn apply(&mut self, mov: Move) -> MoveUndo {
  506. /*if !self.is_zobrist_correct() {
  507. println!("{}", self.beautiful_print());
  508. println!("incorrect zobrist before apply {} {:?}", mov.to_string(), mov);
  509. info!("incorrect zobrist before apply");
  510. panic!("zobrist");
  511. let val = if let Some((ref zt, _zv)) = self.zobrist {
  512. self.calculate_zobrist(zt)
  513. } else { 0 };
  514. if let Some((ref _zt, ref mut zv)) = self.zobrist {
  515. *zv = val;
  516. }
  517. }*/
  518. // save irrecoverable values
  519. let castling_rights_before = self.castling_rights.clone();
  520. let halfmoves_since_last_event_before = self.halfmoves_since_last_event.clone();
  521. let en_passant_before = self.en_passant;
  522. let side = self.turn;
  523. let others = self.get_all_side(!side);
  524. match mov {
  525. Move::Default{ mov, piece_type: pt, captured: _ } => {
  526. if pt == KING {
  527. // invalidate castling rights
  528. self.castling_rights[if side == BLACK { 2 } else { 0 }] = false;
  529. self.castling_rights[if side == BLACK { 3 } else { 1 }] = false;
  530. }
  531. // invalidate castling rights
  532. if mov.from == square_from_indices(7, 0) || mov.to == square_from_indices(7, 0) {
  533. self.castling_rights[0] = false;
  534. }
  535. if mov.from == square_from_indices(0, 0) || mov.to == square_from_indices(0, 0) {
  536. self.castling_rights[1] = false;
  537. }
  538. if mov.from == square_from_indices(7, 7) || mov.to == square_from_indices(7, 7) {
  539. self.castling_rights[2] = false;
  540. }
  541. if mov.from == square_from_indices(0, 7) || mov.to == square_from_indices(0, 7) {
  542. self.castling_rights[3] = false;
  543. }
  544. // if it is a capture
  545. if from_square(mov.to) & others != 0 {
  546. let (other_piece, other_side) = self.get_square(mov.to);
  547. // update zobrist
  548. if let Some((ref zt, ref mut zv)) = self.zobrist {
  549. let hup = zt.piece_hash(other_piece, other_side, mov.to);
  550. *zv ^= hup;
  551. }
  552. *self.get_piece_mut(other_piece, other_side) &= !from_square(mov.to);
  553. }
  554. // reset en passant and then check if possible
  555. self.en_passant = None;
  556. if pt == PAWN {
  557. let row1 = indices_from_square(mov.from).1;
  558. let row2 = indices_from_square(mov.to).1;
  559. // check for double push
  560. if i32::abs(row1 as i32 - row2 as i32) >= 2 {
  561. let opponent_pawns = self.get_piece(PAWN, !side);
  562. let target_bb = from_square(mov.to);
  563. if (west_one(target_bb) | east_one(target_bb)) & opponent_pawns != 0 {
  564. self.en_passant = Some(indices_from_square(mov.to).0);
  565. }
  566. }
  567. }
  568. let moved_piece = mov.apply_to(self.get_piece(pt, side));
  569. self.set_piece(pt, side, moved_piece);
  570. if let Some((ref zt, ref mut zv)) = self.zobrist {
  571. let hup = zt.piece_hash(pt, side, mov.from) ^ zt.piece_hash(pt, side, mov.to);
  572. *zv ^= hup;
  573. }
  574. },
  575. Move::Castling { side, left } => {
  576. // invalidate future castling rights
  577. self.castling_rights[if side == BLACK { 2 } else { 0 }] = false;
  578. self.castling_rights[if side == BLACK { 3 } else { 1 }] = false;
  579. let king = self.get_piece(KING, side);
  580. let rook = if left {
  581. self.get_piece(ROOK, side) & (king << 4)
  582. }
  583. else {
  584. self.get_piece(ROOK, side) & (king >> 3)
  585. };
  586. let new_king = if left { king << 2 } else { king >> 2 };
  587. let new_rook = if left { rook >> 3 } else { rook << 2 };
  588. self.set_piece(KING, side, new_king);
  589. *self.get_piece_mut(ROOK, side) &= !rook;
  590. *self.get_piece_mut(ROOK, side) |= new_rook;
  591. if let Some((ref zt, ref mut zv)) = self.zobrist {
  592. let hupk = zt.piece_hash(KING, side, square(king)) ^ zt.piece_hash(KING, side, square(new_king));
  593. let hup = zt.piece_hash(ROOK, side, square(rook)) ^ zt.piece_hash(ROOK, side, square(new_rook));
  594. *zv ^= hup ^ hupk;
  595. }
  596. self.en_passant = None;
  597. },
  598. Move::EnPassant { mov, beaten } => {
  599. if let Some(_ep) = self.en_passant {
  600. *self.get_piece_mut(PAWN, side) &= !from_square(mov.from);
  601. *self.get_piece_mut(PAWN, side) |= from_square(mov.to);
  602. *self.get_piece_mut(PAWN, !side) &= !from_square(beaten);
  603. if let Some((ref zt, ref mut zv)) = self.zobrist {
  604. let hup = zt.piece_hash(PAWN, side, mov.from) ^ zt.piece_hash(PAWN, side, mov.to);
  605. let hupo = zt.piece_hash(PAWN, !side, beaten);
  606. *zv ^= hup ^ hupo;
  607. }
  608. self.en_passant = None;
  609. }
  610. else {
  611. info!("internal en passant error");
  612. panic!("internal en passant error");
  613. }
  614. },
  615. Move::Promotion { mov, promote_to, captured } => {
  616. //if from_square(mov.to) & others != 0 {
  617. if let Some(pt) = captured {
  618. *self.get_piece_mut(pt, !side) &= !from_square(mov.to);
  619. if let Some((ref zt, ref mut zv)) = self.zobrist {
  620. let hup = zt.piece_hash(pt, !side, mov.to);
  621. *zv ^= hup;
  622. }
  623. }
  624. *self.get_piece_mut(PAWN, side) &= !from_square(mov.from);
  625. if let Some((ref zt, ref mut zv)) = self.zobrist {
  626. let hup = zt.piece_hash(PAWN, side, mov.from);
  627. *zv ^= hup;
  628. }
  629. match promote_to {
  630. QUEEN => { *self.queens_mut(side) |= from_square(mov.to); }
  631. ROOK => { *self.rooks_mut(side) |= from_square(mov.to); }
  632. BISHOP => { *self.bishops_mut(side) |= from_square(mov.to); }
  633. KNIGHT => { *self.knights_mut(side) |= from_square(mov.to); }
  634. _ => {
  635. info!("internal error");
  636. }
  637. }
  638. if let Some((ref zt, ref mut zv)) = self.zobrist {
  639. let hup = zt.piece_hash(promote_to, side, mov.to);
  640. *zv ^= hup;
  641. }
  642. self.en_passant = None;
  643. },
  644. Move::Nullmove => {}
  645. }
  646. if self.turn == BLACK {
  647. self.turn_number += 1;
  648. }
  649. self.turn = !self.turn;
  650. if let Some((ref zt, ref mut zv)) = self.zobrist {
  651. let hup = zt.turn_hash();
  652. let castling_hup = zt.all_castling_rights_hash(castling_rights_before) ^ zt.all_castling_rights_hash(self.castling_rights);
  653. let enpass_hup = en_passant_before.map(|f| zt.en_passant_hash(f)).unwrap_or(0) ^ self.en_passant.map(|f| zt.en_passant_hash(f)).unwrap_or(0);
  654. *zv ^= hup ^ castling_hup ^ enpass_hup;
  655. }
  656. /*if !self.is_zobrist_correct() {
  657. println!("{}", self.beautiful_print());
  658. println!("incorrect zobrist after apply {} {:?}", mov.to_string(), mov);
  659. info!("incorrect zobrist after apply");
  660. panic!("zobrist");
  661. let val = if let Some((ref zt, _zv)) = self.zobrist {
  662. self.calculate_zobrist(zt)
  663. } else { 0 };
  664. if let Some((ref _zt, ref mut zv)) = self.zobrist {
  665. *zv = val;
  666. }
  667. }*/
  668. MoveUndo {
  669. castling_rights_before,
  670. halfmoves_since_last_event_before,
  671. en_passant_before,
  672. mov
  673. }
  674. }
  675. pub fn undo_move(&mut self, umov: MoveUndo) {
  676. /*if !self.is_zobrist_correct() {
  677. println!("{}", self.beautiful_print());
  678. println!("incorrect zobrist before undo {} {:?}", umov.mov.to_string(), umov.mov);
  679. info!("incorrect zobrist before undo {} {:?}", umov.mov.to_string(), umov.mov);
  680. panic!("zobrist");
  681. }*/
  682. if let Some((ref zt, ref mut zv)) = self.zobrist {
  683. let crhup = zt.all_castling_rights_hash(self.castling_rights) ^ zt.all_castling_rights_hash(umov.castling_rights_before);
  684. let enpass_hup = self.en_passant.map(|f| zt.en_passant_hash(f)).unwrap_or(0) ^ umov.en_passant_before.map(|f| zt.en_passant_hash(f)).unwrap_or(0);
  685. *zv ^= crhup ^ enpass_hup;
  686. }
  687. self.castling_rights = umov.castling_rights_before;
  688. self.halfmoves_since_last_event = umov.halfmoves_since_last_event_before;
  689. self.en_passant = umov.en_passant_before;
  690. let mov = umov.mov;
  691. // the side that played the turn that is to be reverted
  692. let side = !self.turn;
  693. match mov {
  694. Move::Default{ mov, piece_type, captured } => {
  695. let moved_piece_bb = self.get_piece_mut(piece_type, side);
  696. *moved_piece_bb &= !from_square(mov.to);
  697. *moved_piece_bb |= from_square(mov.from);
  698. if let Some((ref zt, ref mut zv)) = self.zobrist {
  699. let hup = zt.piece_hash(piece_type, side, mov.from) ^ zt.piece_hash(piece_type, side, mov.to);
  700. *zv ^= hup;
  701. }
  702. if let Some(pt) = captured {
  703. *self.get_piece_mut(pt, !side) |= from_square(mov.to);
  704. if let Some((ref zt, ref mut zv)) = self.zobrist {
  705. let hup = zt.piece_hash(pt, !side, mov.to);
  706. *zv ^= hup;
  707. }
  708. }
  709. },
  710. Move::Castling { side, left } => {
  711. let king = self.get_piece(KING, side);
  712. let rook = if left {
  713. self.get_piece(ROOK, side) & (king >> 1)
  714. }
  715. else {
  716. self.get_piece(ROOK, side) & (king << 1)
  717. };
  718. let old_king = if left { king >> 2 } else { king << 2 };
  719. let old_rook = if left { rook << 3 } else { rook >> 2 };
  720. self.set_piece(KING, side, old_king);
  721. *self.get_piece_mut(ROOK, side) &= !rook;
  722. *self.get_piece_mut(ROOK, side) |= old_rook;
  723. if let Some((ref zt, ref mut zv)) = self.zobrist {
  724. let khup = zt.piece_hash(KING, side, square(old_king)) ^ zt.piece_hash(KING, side, square(king));
  725. let rhup = zt.piece_hash(ROOK, side, square(rook)) ^ zt.piece_hash(ROOK, side, square(old_rook));
  726. *zv ^= khup ^ rhup;
  727. }
  728. },
  729. Move::EnPassant { mov, beaten } => {
  730. *self.get_piece_mut(PAWN, side) |= from_square(mov.from);
  731. *self.get_piece_mut(PAWN, side) &= !from_square(mov.to);
  732. *self.get_piece_mut(PAWN, !side) |= from_square(beaten);
  733. if let Some((ref zt, ref mut zv)) = self.zobrist {
  734. let phup = zt.piece_hash(PAWN, side, mov.from) ^ zt.piece_hash(PAWN, side, mov.to);
  735. let chup = zt.piece_hash(PAWN, !side, beaten);
  736. *zv ^= phup ^ chup;
  737. }
  738. // should already be reverted
  739. //self.en_passant = Some(indices_from_square(beaten).0);
  740. },
  741. Move::Promotion { mov, promote_to, captured } => {
  742. match promote_to {
  743. QUEEN => { *self.queens_mut(side) &= !from_square(mov.to); }
  744. ROOK => { *self.rooks_mut(side) &= !from_square(mov.to); }
  745. BISHOP => { *self.bishops_mut(side) &= !from_square(mov.to); }
  746. KNIGHT => { *self.knights_mut(side) &= !from_square(mov.to); }
  747. _ => {
  748. info!("internal error");
  749. }
  750. }
  751. *self.pawns_mut(side) |= from_square(mov.from);
  752. if let Some((ref zt, ref mut zv)) = self.zobrist {
  753. let hup = zt.piece_hash(PAWN, side, mov.from) ^ zt.piece_hash(promote_to, side, mov.to);
  754. *zv ^= hup;
  755. }
  756. if let Some(pt) = captured {
  757. *self.get_piece_mut(pt, !side) |= from_square(mov.to);
  758. if let Some((ref zt, ref mut zv)) = self.zobrist {
  759. let hup = zt.piece_hash(pt, !side, mov.to);
  760. *zv ^= hup;
  761. }
  762. }
  763. },
  764. Move::Nullmove => {}
  765. }
  766. self.turn = side;
  767. if side == BLACK {
  768. self.turn_number -= 1;
  769. }
  770. if let Some((ref zt, ref mut zv)) = self.zobrist {
  771. *zv ^= zt.turn_hash();
  772. }
  773. /*if !self.is_zobrist_correct() {
  774. println!("{}", self.beautiful_print());
  775. println!("incorrect zobrist after undo {} {:?}", umov.mov.to_string(), umov.mov);
  776. info!("incorrect zobrist after undo {} {:?}", umov.mov.to_string(), umov.mov);
  777. panic!("zobrist");
  778. }*/
  779. /*let val = if let Some((ref zt, _zv)) = self.zobrist {
  780. self.calculate_zobrist(zt)
  781. } else { 0 };
  782. if let Some((ref _zt, ref mut zv)) = self.zobrist {
  783. *zv = val;
  784. }*/
  785. }
  786. pub fn to_vector(&self) -> Vec<f64> {
  787. let mut v = Vec::new();
  788. for side in [WHITE, BLACK] {
  789. for pt in 0..6 {
  790. for sq in 0..64 {
  791. if self.get_square(sq) == (pt, side) {
  792. v.push(1f64);
  793. }
  794. else {
  795. v.push(0f64);
  796. }
  797. }
  798. }
  799. }
  800. v
  801. }
  802. }