use super::{call, insert_uncontested};
use crate::bidding::constraint::{hcp, len, support, top_honors};
use crate::bidding::{Rules, Trie};
use contract_bridge::auction::Call;
use contract_bridge::{Bid, Strain, Suit};
#[must_use]
fn responses(our: Suit) -> Rules {
let trump = Strain::from(our);
let mut rules = Rules::new()
.rule(Bid::new(2, Strain::Notrump), 2.0, hcp(14..) & support(2..))
.rule(Bid::new(4, trump), 1.3, support(4..))
.rule(Bid::new(3, trump), 1.2, support(3..))
.rule(Call::Pass, 0.0, hcp(0..));
for x in [Suit::Clubs, Suit::Diamonds, Suit::Hearts, Suit::Spades] {
if x == our {
continue;
}
let level: u8 = if Strain::from(x) > trump { 2 } else { 3 };
rules = rules.rule(
Bid::new(level, Strain::from(x)),
1.5,
len(x, 5..) & top_honors(x, 2..) & hcp(14..),
);
}
rules
}
#[must_use]
fn ogust_answers(our: Suit) -> Rules {
Rules::new()
.rule(Bid::new(3, Strain::Notrump), 1.5, top_honors(our, 3..))
.rule(
Bid::new(3, Strain::Clubs),
1.0,
hcp(5..=7) & !top_honors(our, 2..),
)
.rule(
Bid::new(3, Strain::Diamonds),
1.0,
hcp(5..=7) & top_honors(our, 2..),
)
.rule(
Bid::new(3, Strain::Hearts),
1.0,
hcp(8..=10) & !top_honors(our, 2..),
)
.rule(
Bid::new(3, Strain::Spades),
1.0,
hcp(8..=10) & top_honors(our, 2..),
)
.rule(Bid::new(3, Strain::Clubs), 0.2, hcp(0..))
}
#[must_use]
fn asker_after_min_major(our: Suit) -> Rules {
let trump = Strain::from(our);
Rules::new()
.rule(Bid::new(4, trump), 1.0, hcp(17..))
.rule(Bid::new(3, trump), 0.5, hcp(0..))
}
#[must_use]
fn asker_after_max_major(our: Suit) -> Rules {
let trump = Strain::from(our);
Rules::new().rule(Bid::new(4, trump), 0.5, hcp(0..))
}
#[must_use]
fn asker_after_diamonds_min_bad() -> Rules {
Rules::new()
.rule(Bid::new(3, Strain::Notrump), 1.0, hcp(17..))
.rule(Bid::new(3, Strain::Diamonds), 0.5, hcp(0..))
}
#[must_use]
fn asker_after_diamonds_min_good() -> Rules {
Rules::new()
.rule(Bid::new(3, Strain::Notrump), 1.0, hcp(17..))
.rule(Call::Pass, 0.0, hcp(0..))
}
#[must_use]
fn asker_after_diamonds_max() -> Rules {
Rules::new()
.rule(Bid::new(5, Strain::Diamonds), 1.0, hcp(17..))
.rule(Bid::new(3, Strain::Notrump), 0.5, hcp(0..))
}
#[must_use]
fn reply_to_new_suit(our: Suit, x: Suit, response_level: u8) -> Rules {
let raise_level = response_level + 1;
let rebid_level: u8 =
if Bid::new(3, Strain::from(our)) > Bid::new(response_level, Strain::from(x)) {
3
} else {
4
};
Rules::new()
.rule(Bid::new(raise_level, Strain::from(x)), 1.0, support(3..))
.rule(Bid::new(rebid_level, Strain::from(our)), 0.5, hcp(0..))
}
pub(super) fn register(book: &mut Trie) {
for our in [Suit::Diamonds, Suit::Hearts, Suit::Spades] {
let trump = Strain::from(our);
let open = call(2, trump);
insert_uncontested(book, &[open], responses(our));
let ogust = call(2, Strain::Notrump);
insert_uncontested(book, &[open, ogust], ogust_answers(our));
register_ogust_continuations(book, our, open, ogust);
register_new_suit_replies(book, our, open);
}
}
fn register_ogust_continuations(book: &mut Trie, our: Suit, open: Call, ogust: Call) {
let min_bad = call(3, Strain::Clubs); let min_good = call(3, Strain::Diamonds); let max_bad = call(3, Strain::Hearts); let max_good = call(3, Strain::Spades);
if our == Suit::Diamonds {
insert_uncontested(
book,
&[open, ogust, min_bad],
asker_after_diamonds_min_bad(),
);
insert_uncontested(
book,
&[open, ogust, min_good],
asker_after_diamonds_min_good(),
);
for max_ans in [max_bad, max_good] {
insert_uncontested(book, &[open, ogust, max_ans], asker_after_diamonds_max());
}
} else {
for min_ans in [min_bad, min_good] {
insert_uncontested(book, &[open, ogust, min_ans], asker_after_min_major(our));
}
for max_ans in [max_bad, max_good] {
insert_uncontested(book, &[open, ogust, max_ans], asker_after_max_major(our));
}
}
}
fn register_new_suit_replies(book: &mut Trie, our: Suit, open: Call) {
let trump = Strain::from(our);
for x in [Suit::Clubs, Suit::Diamonds, Suit::Hearts, Suit::Spades] {
if x == our {
continue;
}
let level: u8 = if Strain::from(x) > trump { 2 } else { 3 };
let new_suit_call = call(level, Strain::from(x));
insert_uncontested(
book,
&[open, new_suit_call],
reply_to_new_suit(our, x, level),
);
}
}