jordanbray / chess

A rust library to manage chess move generation
https://jordanbray.github.io/chess/
MIT License
243 stars 55 forks source link

Add method to get side to move as number #33

Closed UlisseMini closed 4 years ago

UlisseMini commented 4 years ago

A common idiom in engines is something like this

fn eval(board: chess::Board) {
  // ... do stuff ...

  let color = if board.side_to_move() == Color::White { 1 } else { -1 };
  return evaluation * color;
}

It would be convenient if there was a method to get the number version of the side to move, perhaps a method on Color, such as

fn to_num(self) -> i32 {
  match self {
    Color::White => 1,
    Color::Black => -1,
  }
}

(name is debatable, but this is the idea)

jordanbray commented 4 years ago

there is already to_indexwhich converts it into a 0 or 1, but not a -1, 1 as you are requesting.

However, the most common case for this is to move a square forward. As a result, there are functions Square::forward(&self, color: Color) and Square::uforward(&self, color: Color) which moves the square in the correct direction.

UlisseMini commented 4 years ago

I know its niche, but IMO having to write

  let color = if board.side_to_move() == Color::White {
    1
  } else {
    -1
  };

(rustfmt forces it to be this way) Distracts from the business logic. I understand a reluctance to add such a small niche feature though, I can always extract the else-if to a helper function.

jordanbray commented 4 years ago

Can you give me an example of where this may be used?

A more ergonomic (and branchless) way to write this would be board.side_to_move().to_index() * 2 - 1, which converts Color::White to -1 and Color::Black to 1. You could put a ! on the color to inverse that as shown in your example.

UlisseMini commented 4 years ago

Oh yeah I'm an idiot, I'll use to_index() * 2 - 1, Thanks!