use super::{call, insert_uncontested};
use crate::bidding::constraint::{balanced, hcp, len, support};
use crate::bidding::{Rules, Trie};
use contract_bridge::auction::Call;
use contract_bridge::{Bid, Strain, Suit};
fn rebid_one_heart_one_spade() -> Rules {
Rules::new()
.rule(Bid::new(4, Strain::Spades), 2.6, support(4..) & hcp(19..))
.rule(
Bid::new(3, Strain::Spades),
2.2,
support(4..) & hcp(16..=18),
)
.rule(
Bid::new(2, Strain::Spades),
1.8,
support(4..) & hcp(12..=15),
)
.rule(Bid::new(2, Strain::Hearts), 1.4, len(Suit::Hearts, 6..))
.rule(Bid::new(2, Strain::Notrump), 1.2, hcp(18..=19) & balanced())
.rule(Bid::new(2, Strain::Clubs), 0.9, len(Suit::Clubs, 4..))
.rule(Bid::new(2, Strain::Diamonds), 0.9, len(Suit::Diamonds, 4..))
.rule(Bid::new(1, Strain::Notrump), 0.5, hcp(12..=14))
.rule(Bid::new(1, Strain::Notrump), 0.2, hcp(12..))
}
fn rebid_after_forcing_notrump(major: Suit) -> Rules {
let trump = Strain::from(major);
let mut rules = Rules::new()
.rule(Bid::new(2, Strain::Notrump), 1.2, hcp(18..=19) & balanced())
.rule(Bid::new(2, trump), 1.0, len(major, 6..));
for suit in [Suit::Clubs, Suit::Diamonds, Suit::Hearts] {
if Strain::from(suit) < trump {
rules = rules.rule(Bid::new(2, Strain::from(suit)), 0.9, len(suit, 4..));
}
}
rules.rule(Bid::new(2, trump), 0.3, len(major, 5..))
}
fn rebid_raise_major(responder_major: Suit, opener_minor: Suit) -> Rules {
let m = Strain::from(responder_major);
Rules::new()
.rule(Bid::new(4, m), 2.6, support(4..) & hcp(19..))
.rule(Bid::new(3, m), 2.2, support(4..) & hcp(16..=18))
.rule(Bid::new(2, m), 1.8, support(4..) & hcp(12..=15))
.rule(Bid::new(2, Strain::Notrump), 1.2, hcp(18..=19) & balanced())
.rule(
Bid::new(2, Strain::from(opener_minor)),
0.9,
len(opener_minor, 5..),
)
.rule(Bid::new(1, Strain::Notrump), 0.5, hcp(12..=14) & balanced())
.rule(Bid::new(1, Strain::Notrump), 0.2, hcp(12..))
}
fn rebid_one_club_one_diamond() -> Rules {
Rules::new()
.rule(Bid::new(1, Strain::Hearts), 1.3, len(Suit::Hearts, 4..))
.rule(
Bid::new(1, Strain::Spades),
1.3,
len(Suit::Spades, 4..) & len(Suit::Hearts, ..4),
)
.rule(
Bid::new(3, Strain::Diamonds),
1.5,
support(4..) & hcp(16..=18),
)
.rule(
Bid::new(2, Strain::Diamonds),
1.2,
support(4..) & hcp(12..=15),
)
.rule(Bid::new(2, Strain::Notrump), 1.1, hcp(18..=19) & balanced())
.rule(Bid::new(1, Strain::Notrump), 0.5, hcp(12..=14) & balanced())
.rule(Bid::new(1, Strain::Notrump), 0.2, hcp(12..))
}
fn responder_after_forcing_notrump(major: Suit) -> Rules {
let trump = Strain::from(major);
let mut rules = Rules::new()
.rule(Bid::new(3, trump), 1.5, len(major, 3..) & hcp(10..=12))
.rule(Bid::new(2, Strain::Notrump), 1.2, hcp(11..=12))
.rule(Bid::new(2, trump), 1.0, len(major, 2..) & hcp(7..))
.rule(Call::Pass, 0.0, hcp(0..));
for suit in [Suit::Clubs, Suit::Diamonds, Suit::Hearts, Suit::Spades] {
if suit != major {
rules = rules.rule(
Bid::new(2, Strain::from(suit)),
1.1,
len(suit, 6..) & hcp(..=9),
);
}
}
rules
}
fn opener_accept_notrump_invite() -> Rules {
Rules::new()
.rule(Bid::new(3, Strain::Notrump), 1.0, hcp(14..))
.rule(Call::Pass, 0.0, hcp(0..))
}
fn opener_accept_limit_raise(major: Suit) -> Rules {
Rules::new()
.rule(Bid::new(4, Strain::from(major)), 1.0, hcp(14..))
.rule(Call::Pass, 0.0, hcp(0..))
}
fn register_forcing_notrump_continuations(book: &mut Trie) {
for major in [Suit::Hearts, Suit::Spades] {
let one_major = call(1, Strain::from(major));
let one_nt = call(1, Strain::Notrump);
let mut seen: Vec<Call> = Vec::new();
for rule in rebid_after_forcing_notrump(major).rules() {
let rebid = rule.call();
if rebid != call(2, Strain::Notrump) && !seen.contains(&rebid) {
seen.push(rebid);
}
}
for rebid in seen {
insert_uncontested(
book,
&[one_major, one_nt, rebid],
responder_after_forcing_notrump(major),
);
insert_uncontested(
book,
&[one_major, one_nt, rebid, call(2, Strain::Notrump)],
opener_accept_notrump_invite(),
);
insert_uncontested(
book,
&[one_major, one_nt, rebid, call(3, Strain::from(major))],
opener_accept_limit_raise(major),
);
}
}
}
pub(super) fn register(book: &mut Trie) {
register_forcing_notrump_continuations(book);
insert_uncontested(
book,
&[call(1, Strain::Hearts), call(1, Strain::Spades)],
rebid_one_heart_one_spade(),
);
for major in [Suit::Hearts, Suit::Spades] {
insert_uncontested(
book,
&[call(1, Strain::from(major)), call(1, Strain::Notrump)],
rebid_after_forcing_notrump(major),
);
}
insert_uncontested(
book,
&[call(1, Strain::Clubs), call(1, Strain::Diamonds)],
rebid_one_club_one_diamond(),
);
for minor in [Suit::Clubs, Suit::Diamonds] {
for responder_major in [Suit::Hearts, Suit::Spades] {
insert_uncontested(
book,
&[
call(1, Strain::from(minor)),
call(1, Strain::from(responder_major)),
],
rebid_raise_major(responder_major, minor),
);
}
}
}