|  | @@ -27,8 +27,24 @@ enum MoveUndo {
 | 
	
		
			
				|  |  |  //06         v := −negamax(child, depth − 1, −color)
 | 
	
		
			
				|  |  |  //07         bestValue := max( bestValue, v )
 | 
	
		
			
				|  |  |  //08     return bestValue
 | 
	
		
			
				|  |  | -pub fn search() {
 | 
	
		
			
				|  |  | +pub fn search(game: &Game, depth: i32) -> Move {
 | 
	
		
			
				|  |  | +    let mut best = i32::min_value();
 | 
	
		
			
				|  |  | +    let mut best_move = Move::default();
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +    if depth == 0 {
 | 
	
		
			
				|  |  | +        return best_move;
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    let moves = generate_moves(game, game.turn);
 | 
	
		
			
				|  |  | +    for mov in moves {
 | 
	
		
			
				|  |  | +        let new_game = apply_move(game, mov);
 | 
	
		
			
				|  |  | +        let val = -negamax(&new_game, depth - 1);
 | 
	
		
			
				|  |  | +        if val > best {
 | 
	
		
			
				|  |  | +            best = val;
 | 
	
		
			
				|  |  | +            best_move = mov;
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +    return best_move;
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  fn negamax(game: &Game, depth: i32) -> i32 {
 | 
	
	
		
			
				|  | @@ -36,14 +52,57 @@ fn negamax(game: &Game, depth: i32) -> i32 {
 | 
	
		
			
				|  |  |          return evaluate(game);
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -    let best = i32::min_value();
 | 
	
		
			
				|  |  | +    let mut best = i32::min_value();
 | 
	
		
			
				|  |  | +    let mut best_move = Move::default();
 | 
	
		
			
				|  |  |      let moves = generate_moves(game, game.turn);
 | 
	
		
			
				|  |  |      for mov in moves {
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | +        let new_game = apply_move(game, mov);
 | 
	
		
			
				|  |  | +        let val = -negamax(&new_game, depth - 1);
 | 
	
		
			
				|  |  | +        if val > best {
 | 
	
		
			
				|  |  | +            best = val;
 | 
	
		
			
				|  |  | +            best_move = mov;
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  | +    println!("bestmove {:?}", best_move);
 | 
	
		
			
				|  |  |      return 0;
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -fn apply_move(game: &Game, mov: Move) -> Game {
 | 
	
		
			
				|  |  | +pub fn apply_move(game: &Game, mov: Move) -> Game {
 | 
	
		
			
				|  |  | +    let mut new_game = game.clone();
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    let side = game.turn;
 | 
	
		
			
				|  |  | +    let friends = game.get_all_side(side);
 | 
	
		
			
				|  |  | +    let others = game.get_all_side(!side);
 | 
	
		
			
				|  |  | +    match mov {
 | 
	
		
			
				|  |  | +        Move::Default { mov: mov, piece_type: pt } => {
 | 
	
		
			
				|  |  | +            if from_square(mov.to) | others != 0 {
 | 
	
		
			
				|  |  | +                new_game.apply_mask(!from_square(mov.to));
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +            let moved_piece = mov.apply_to(new_game.get_piece(pt, side));
 | 
	
		
			
				|  |  | +            new_game.set_piece(pt, side, moved_piece);
 | 
	
		
			
				|  |  | +        },
 | 
	
		
			
				|  |  | +        Move::Castling { side, left } => {
 | 
	
		
			
				|  |  | +            let king = game.get_piece(KING, side);
 | 
	
		
			
				|  |  | +            let rook = if left {
 | 
	
		
			
				|  |  | +                game.get_piece(ROOK, side) & (king << 4)
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +            else {
 | 
	
		
			
				|  |  | +                game.get_piece(ROOK, side) & (king >> 3)
 | 
	
		
			
				|  |  | +            };
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            let new_king = if left { king << 2 } else { king >> 2 };
 | 
	
		
			
				|  |  | +            let new_rook = if left { rook >> 3 } else { rook << 2 };
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            new_game.set_piece(KING, side, new_king);
 | 
	
		
			
				|  |  | +            new_game.set_piece(ROOK, side, new_rook);
 | 
	
		
			
				|  |  | +        },
 | 
	
		
			
				|  |  | +        Move::EnPassant { side: side, column: col } => { panic!("oh no"); },
 | 
	
		
			
				|  |  | +        Move::Promotion { mov: mov, promote_to: pt } => { panic!("oh no"); },
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    new_game.turn = !new_game.turn;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +    return new_game;
 | 
	
		
			
				|  |  |  }
 |