* Fix getopts version
The pinned version does not compile anymore because of mutable aliasing:
* https://github.com/rust-lang/getopts/pull/61
* https://github.com/rust-lang/getopts/issues/110
This was achieved by temporarily setting the getopts version to "0.2.21"
in Cargo.toml, and running `cargo check`.
Note that this also converts the Cargo.lock to a new format.
* Fix warning: Instead of deprecated macro try!, use question mark operator
* Fix warning: Avoid anonymous parameters
* Fix warning: Use dyn on trait objects
* Fix warning: Avoid unneeded mutability
* Fix warning: Avoid redundant format in panic or assert
* Fix lint: Avoid redundant field names in initializers
* Fix lint: Avoid redundant clone
* Fix lint: Avoid literal cast
* Fix lint: Collapse if/else where applicable
I left some if/else branches in place, if there was a certain symmetry between the branches.
* Fix lint: Avoid needless borrow
I left some if/else branches in place, if there was a certain symmetry between the branches.
* Fix lint: Use cloned instead of custom closure
* Fix lint: Avoid unneeded trait bound
* Fix lint: Avoid unneeded trait bound (2) avoid redundant clone
* Fix lint: Use &[T] instead of &Vec<T>
* Fix lint: Avoid & on each pattern
* Fix lint: Avoid manual assign
* Fix lint: Use implicit return
* Fix lint: Merge if/else branches with same value
I left one complicated branch in place.
* Fix lint: Use is_empty instead of comparing len against 0
* Fix lint: Use sum instead of fold
* Fix lint: Avoid clone on Copy types
I also replaced the callback architecture behind
`PublicInformation.ask_questions()` with a simpler method
`PublicInformation.ask_question()` that gets called repeatedly.
To make all float-based sorts easier, I used the `float-ord` package.
I also used it to clean up some of the sorting in `decide_wrapped()`.
One important change is that now, when deciding which questions to ask, they can see the answer to the last question before asking the next one.
Some design choices:
- Questions now take a BoardState instead of an OwnedGameView.
- When deciding which questions to ask (in ask_questions), we get an immutable public information object
(representing the public information before any questions were asked), and a mutable HandInfo<CardPossibilityTable>
that gets updated as we ask questions. That HandInfo<CardPossibilityTable> was copied instead of taken.
- In ask_questions, we also get some &mut u32 representing "info_remaining" that gets updated for us.
This will later allow for cases where "info_remaining" depends on the answers to previous questions.
- Both get_hint_sum and update_from_hint_sum change the public information object. If you want to compute the
hint sum but aren't sure if you actually want to give the hint, you'll have to clone the public information
object!
- Over time, in the code to decide on a move, we'll be able to build an increasingly complicated tree of
"public information object operations" that will have to be matched exactly in the code to update on a move.
In order to make this less scary, I moved most of the code into
"decide_wrapped" and "update_wrapped". If the call to update_wrapped
(for the player who just made the move) changes the public information
object in different ways than the previous call to decide_wrapped, we
detect this and panic.
This commit should be purely refactoring; all changes to win-rates are
due to bugs.