From 2b8524edbccb3f959297df32efa9ecac64119770 Mon Sep 17 00:00:00 2001 From: Alan Davidson Date: Sun, 29 Sep 2024 00:09:09 -0400 Subject: [PATCH 1/3] add bids for Stayman lebensohl sequences --- src/Bids/Lebensohl.hs | 44 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 43 insertions(+), 1 deletion(-) diff --git a/src/Bids/Lebensohl.hs b/src/Bids/Lebensohl.hs index 605dcc8..aa714db 100644 --- a/src/Bids/Lebensohl.hs +++ b/src/Bids/Lebensohl.hs @@ -17,10 +17,12 @@ module Bids.Lebensohl( , b1No2D2S , b1No2D2N , b1No2D2N3CP + , b1No2D2N3C3D , b1No2D2N3C3H , b1No2D2N3C3S , b1No2D2N3C3N , b1No2D3C + , b1No2D3D , b1No2D3H , b1No2D3S , b1No2D3N @@ -28,20 +30,24 @@ module Bids.Lebensohl( , b1No2H2N , b1No2H2N3CP , b1No2H2N3C3D + , b1No2H2N3C3H , b1No2H2N3C3S , b1No2H2N3C3N , b1No2H3C , b1No2H3D + , b1No2H3H , b1No2H3S , b1No2H3N , b1No2S2N , b1No2S2N3CP , b1No2S2N3C3D , b1No2S2N3C3H + , b1No2S2N3C3S , b1No2S2N3C3N , b1No2S3C , b1No2S3D , b1No2S3H + , b1No2S3S , b1No2S3N -- For when the opponents show both majors , b1NoBM2N @@ -56,7 +62,7 @@ import Action(Action, withholdBid) import qualified Bids.OneNotrump as NT import EDSL(minSuitLength, makeCall, makeAlertableCall, pointRange, forEach, forbid, balancedHand, hasStopper, alternatives, soundHolding, - longerThan, atLeastAsLong) + longerThan, atLeastAsLong, suitLength) import Output((.+)) import qualified Terminology as T @@ -278,6 +284,38 @@ b1NoBM2N3C3N :: Action b1NoBM2N3C3N = bid3N_ [T.Hearts, T.Spades] True +-- Stayman-like cue bids +cueBid_ :: T.Suit -> Bool -> Action +cueBid_ oppsSuit shouldHaveStopper = do + NT.gameForcing + -- TODO: if the opponents overcall a natural 2D, do you need exactly 4-4 in + -- the majors? What if you're 4-3? What if you're 5-4? + forEach (filter (/= oppsSuit) T.majorSuits) (`suitLength` 4) + when shouldHaveStopper (hasStopper oppsSuit) + makeAlertableCall (T.Bid 3 oppsSuit) + ("Stayman with" ++ + (if shouldHaveStopper then "" else "out") ++ + " a stopper") + +b1No2D3D :: Action +b1No2D3D = cueBid_ T.Diamonds False + +b1No2D2N3C3D :: Action +b1No2D2N3C3D = cueBid_ T.Diamonds True + +b1No2H3H :: Action +b1No2H3H = cueBid_ T.Hearts False + +b1No2H2N3C3H :: Action +b1No2H2N3C3H = cueBid_ T.Hearts True + +b1No2S3S :: Action +b1No2S3S = cueBid_ T.Spades False + +b1No2S2N3C3S :: Action +b1No2S2N3C3S = cueBid_ T.Spades True + + -- Time for the actual lebensohl relays! b1N2N3C :: Action b1N2N3C = makeAlertableCall (T.Bid 3 T.Clubs) "relay completed" @@ -286,6 +324,7 @@ b1N2N3C = makeAlertableCall (T.Bid 3 T.Clubs) "relay completed" b1No2D2N :: Action b1No2D2N = do alternatives [ b1No2D2N3CP + , b1No2D2N3C3D , b1No2D2N3C3H , b1No2D2N3C3S , b1No2D2N3C3N @@ -297,6 +336,7 @@ b1No2H2N :: Action b1No2H2N = do alternatives [ b1No2H2N3CP , b1No2H2N3C3D + , b1No2H2N3C3H , b1No2D2N3C3S , b1No2D2N3C3N ] @@ -308,6 +348,7 @@ b1No2S2N = do alternatives [ b1No2S2N3CP , b1No2S2N3C3D , b1No2S2N3C3H + , b1No2S2N3C3S , b1No2S2N3C3N ] makeAlertableCall (T.Bid 2 T.Notrump) ("relay to " .+ T.Bid 3 T.Clubs) @@ -319,5 +360,6 @@ b1NoBM2N = do alternatives [ b1No2S2N3CP , b1No2S2N3C3D , b1NoBM2N3C3N + -- Don't bother with a Stayman-like bid: RHO has both majors ] makeAlertableCall (T.Bid 2 T.Notrump) ("relay to " .+ T.Bid 3 T.Clubs) From a2254970f4572fc8c4cca7a623416aee943f0b8c Mon Sep 17 00:00:00 2001 From: Alan Davidson Date: Sun, 29 Sep 2024 00:27:29 -0400 Subject: [PATCH 2/3] and situations for the new bids --- src/Topics/Lebensohl.hs | 177 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 174 insertions(+), 3 deletions(-) diff --git a/src/Topics/Lebensohl.hs b/src/Topics/Lebensohl.hs index 9e9fda2..5d8902f 100644 --- a/src/Topics/Lebensohl.hs +++ b/src/Topics/Lebensohl.hs @@ -371,12 +371,83 @@ bid3NWithoutStopper = let <~ T.allVulnerabilities +cueBidWithStopper :: Situations +cueBidWithStopper = let + sit (overcall, relay, bid) = let + action = do + setOpener T.North + Leb.b1N + _ <- overcall + withholdBid bid + explanation = + "Partner opened a strong " .+ Leb.b1N .+ ", and RHO " .+ + "interfered with the auction. We'd prefer to play in a " .+ + "major-suit fit if we have one, but can tolerate " .+ + T.Bid 3 T.Notrump .+ " without one because we have a stopper " .+ + "in the opponent's suit. Relay through " .+ + relay .+ ", then bid " .+ bid .+ " as Stayman. Partner can " .+ + "bid the correct game, based on whether we've got a major-suit fit." + in situation "rel3N" action relay explanation + in + wrap $ return sit <~ [ (Nat.b1No2D, Leb.b1No2D2N, Leb.b1No2D2N3C3D) + , (Nat.b1No2H, Leb.b1No2H2N, Leb.b1No2H2N3C3H) + , (Nat.b1No2S, Leb.b1No2S2N, Leb.b1No2S2N3C3S) + , (DONT.b1No2D, Leb.b1No2D2N, Leb.b1No2D2N3C3D) + -- DONT.b1No2H: skip Stayman when RHO has both majors + , (DONT.b1No2S, Leb.b1No2S2N, Leb.b1No2S2N3C3S) + , (MW.b1No2D, Leb.b1No2D2N, Leb.b1No2D2N3C3D) + , (MW.b1No2H, Leb.b1No2H2N, Leb.b1No2H2N3C3H) + , (MW.b1No2S, Leb.b1No2S2N, Leb.b1No2S2N3C3S) + -- Capp.b1No2D: skip Stayman when RHO has both majors + , (Capp.b1No2H, Leb.b1No2H2N, Leb.b1No2H2N3C3H) + , (Capp.b1No2S, Leb.b1No2S2N, Leb.b1No2S2N3C3S) + ] + -- East should be an unpassed hand to interfere. + <~ [T.North, T.South, T.West] + <~ T.allVulnerabilities + + +cueBidWithoutStopper :: Situations +cueBidWithoutStopper = let + sit (overcall, bid) = let + action = do + setOpener T.North + Leb.b1N + overcall + explanation = + "Partner opened a strong " .+ Leb.b1N .+ ", and RHO " .+ + "interfered with the auction. We'd prefer to play in a " .+ + "major-suit fit if we have one, but if we don't, playing in " .+ + T.Bid 3 T.Notrump .+ " might be risky, because we don't have a " .+ + "stopper in the opponents' suit in our hand. Make a cue bid as " .+ + "Stayman: partner can bid a major-suit game if we've got a fit, " .+ + "can bid " .+ T.Bid 3 T.Notrump .+ " if we don't have a fit " .+ + "but they have a stopper, and if we don't have a fit and " .+ + "neither of us can stop the opponent's suit, we'll scramble " .+ + "into a minor-suit contract or perhaps a 7-card fit." + in situation "3N" action bid explanation + in + wrap $ return sit <~ [ (Nat.b1No2D, Leb.b1No2D3D) + , (Nat.b1No2H, Leb.b1No2H3H) + , (Nat.b1No2S, Leb.b1No2S3S) + , (DONT.b1No2D, Leb.b1No2D3D) + -- DONT.b1No2H: skip Stayman when RHO has both majors + , (DONT.b1No2S, Leb.b1No2S3S) + , (MW.b1No2D, Leb.b1No2D3D) + , (MW.b1No2H, Leb.b1No2H3H) + , (MW.b1No2S, Leb.b1No2S3S) + -- Capp.b1No2D: skip Stayman when RHO has both majors + , (Capp.b1No2H, Leb.b1No2H3H) + , (Capp.b1No2S, Leb.b1No2S3S) + ] + -- East should be an unpassed hand to interfere. + <~ [T.North, T.South, T.West] + <~ T.allVulnerabilities + + -- TODO: --- cue bid for Stayman --- relay to cue bid (answer should be 2N planning to rebid the cue) -- opener responds to Stayman -- pass or bid game after relay and invite (maybe not: should be obvious) --- opener uses normal systems after X or 2C topic :: Topic @@ -392,4 +463,104 @@ topic = makeTopic , passSignoff , invite , wrap [bid3NWithStopper, bid3NWithoutStopper] + , wrap [cueBidWithStopper, cueBidWithoutStopper] + , wrap [cueBidWithStopper, cueBidWithoutStopper] + , wrap [cueBidWithStopper, cueBidWithoutStopper] + , wrap [cueBidWithStopper, cueBidWithoutStopper] + , wrap [cueBidWithStopper, cueBidWithoutStopper] + , wrap [cueBidWithStopper, cueBidWithoutStopper] + , wrap [cueBidWithStopper, cueBidWithoutStopper] + , wrap [cueBidWithStopper, cueBidWithoutStopper] + , wrap [cueBidWithStopper, cueBidWithoutStopper] + , wrap [cueBidWithStopper, cueBidWithoutStopper] + , wrap [cueBidWithStopper, cueBidWithoutStopper] + , wrap [cueBidWithStopper, cueBidWithoutStopper] + , wrap [cueBidWithStopper, cueBidWithoutStopper] + , wrap [cueBidWithStopper, cueBidWithoutStopper] + , wrap [cueBidWithStopper, cueBidWithoutStopper] + , wrap [cueBidWithStopper, cueBidWithoutStopper] + , wrap [cueBidWithStopper, cueBidWithoutStopper] + , wrap [cueBidWithStopper, cueBidWithoutStopper] + , wrap [cueBidWithStopper, cueBidWithoutStopper] + , wrap [cueBidWithStopper, cueBidWithoutStopper] + , wrap [cueBidWithStopper, cueBidWithoutStopper] + , wrap [cueBidWithStopper, cueBidWithoutStopper] + , wrap [cueBidWithStopper, cueBidWithoutStopper] + , wrap [cueBidWithStopper, cueBidWithoutStopper] + , wrap [cueBidWithStopper, cueBidWithoutStopper] + , wrap [cueBidWithStopper, cueBidWithoutStopper] + , wrap [cueBidWithStopper, cueBidWithoutStopper] + , wrap [cueBidWithStopper, cueBidWithoutStopper] + , wrap [cueBidWithStopper, cueBidWithoutStopper] + , wrap [cueBidWithStopper, cueBidWithoutStopper] + , wrap [cueBidWithStopper, cueBidWithoutStopper] + , wrap [cueBidWithStopper, cueBidWithoutStopper] + , wrap [cueBidWithStopper, cueBidWithoutStopper] + , wrap [cueBidWithStopper, cueBidWithoutStopper] + , wrap [cueBidWithStopper, cueBidWithoutStopper] + , wrap [cueBidWithStopper, cueBidWithoutStopper] + , wrap [cueBidWithStopper, cueBidWithoutStopper] + , wrap [cueBidWithStopper, cueBidWithoutStopper] + , wrap [cueBidWithStopper, cueBidWithoutStopper] + , wrap [cueBidWithStopper, cueBidWithoutStopper] + , wrap [cueBidWithStopper, cueBidWithoutStopper] + , wrap [cueBidWithStopper, cueBidWithoutStopper] + , wrap [cueBidWithStopper, cueBidWithoutStopper] + , wrap [cueBidWithStopper, cueBidWithoutStopper] + , wrap [cueBidWithStopper, cueBidWithoutStopper] + , wrap [cueBidWithStopper, cueBidWithoutStopper] + , wrap [cueBidWithStopper, cueBidWithoutStopper] + , wrap [cueBidWithStopper, cueBidWithoutStopper] + , wrap [cueBidWithStopper, cueBidWithoutStopper] + , wrap [cueBidWithStopper, cueBidWithoutStopper] + , wrap [cueBidWithStopper, cueBidWithoutStopper] + , wrap [cueBidWithStopper, cueBidWithoutStopper] + , wrap [cueBidWithStopper, cueBidWithoutStopper] + , wrap [cueBidWithStopper, cueBidWithoutStopper] + , wrap [cueBidWithStopper, cueBidWithoutStopper] + , wrap [cueBidWithStopper, cueBidWithoutStopper] + , wrap [cueBidWithStopper, cueBidWithoutStopper] + , wrap [cueBidWithStopper, cueBidWithoutStopper] + , wrap [cueBidWithStopper, cueBidWithoutStopper] + , wrap [cueBidWithStopper, cueBidWithoutStopper] + , wrap [cueBidWithStopper, cueBidWithoutStopper] + , wrap [cueBidWithStopper, cueBidWithoutStopper] + , wrap [cueBidWithStopper, cueBidWithoutStopper] + , wrap [cueBidWithStopper, cueBidWithoutStopper] + , wrap [cueBidWithStopper, cueBidWithoutStopper] + , wrap [cueBidWithStopper, cueBidWithoutStopper] + , wrap [cueBidWithStopper, cueBidWithoutStopper] + , wrap [cueBidWithStopper, cueBidWithoutStopper] + , wrap [cueBidWithStopper, cueBidWithoutStopper] + , wrap [cueBidWithStopper, cueBidWithoutStopper] + , wrap [cueBidWithStopper, cueBidWithoutStopper] + , wrap [cueBidWithStopper, cueBidWithoutStopper] + , wrap [cueBidWithStopper, cueBidWithoutStopper] + , wrap [cueBidWithStopper, cueBidWithoutStopper] + , wrap [cueBidWithStopper, cueBidWithoutStopper] + , wrap [cueBidWithStopper, cueBidWithoutStopper] + , wrap [cueBidWithStopper, cueBidWithoutStopper] + , wrap [cueBidWithStopper, cueBidWithoutStopper] + , wrap [cueBidWithStopper, cueBidWithoutStopper] + , wrap [cueBidWithStopper, cueBidWithoutStopper] + , wrap [cueBidWithStopper, cueBidWithoutStopper] + , wrap [cueBidWithStopper, cueBidWithoutStopper] + , wrap [cueBidWithStopper, cueBidWithoutStopper] + , wrap [cueBidWithStopper, cueBidWithoutStopper] + , wrap [cueBidWithStopper, cueBidWithoutStopper] + , wrap [cueBidWithStopper, cueBidWithoutStopper] + , wrap [cueBidWithStopper, cueBidWithoutStopper] + , wrap [cueBidWithStopper, cueBidWithoutStopper] + , wrap [cueBidWithStopper, cueBidWithoutStopper] + , wrap [cueBidWithStopper, cueBidWithoutStopper] + , wrap [cueBidWithStopper, cueBidWithoutStopper] + , wrap [cueBidWithStopper, cueBidWithoutStopper] + , wrap [cueBidWithStopper, cueBidWithoutStopper] + , wrap [cueBidWithStopper, cueBidWithoutStopper] + , wrap [cueBidWithStopper, cueBidWithoutStopper] + , wrap [cueBidWithStopper, cueBidWithoutStopper] + , wrap [cueBidWithStopper, cueBidWithoutStopper] + , wrap [cueBidWithStopper, cueBidWithoutStopper] + , wrap [cueBidWithStopper, cueBidWithoutStopper] + , wrap [cueBidWithStopper, cueBidWithoutStopper] ] From e0e1ccf6c151e1e068d79187065127b7b631a797 Mon Sep 17 00:00:00 2001 From: Alan Davidson Date: Sun, 29 Sep 2024 00:37:24 -0400 Subject: [PATCH 3/3] remove debugging --- src/Topics/Lebensohl.hs | 99 ----------------------------------------- 1 file changed, 99 deletions(-) diff --git a/src/Topics/Lebensohl.hs b/src/Topics/Lebensohl.hs index 5d8902f..e5afd12 100644 --- a/src/Topics/Lebensohl.hs +++ b/src/Topics/Lebensohl.hs @@ -464,103 +464,4 @@ topic = makeTopic , invite , wrap [bid3NWithStopper, bid3NWithoutStopper] , wrap [cueBidWithStopper, cueBidWithoutStopper] - , wrap [cueBidWithStopper, cueBidWithoutStopper] - , wrap [cueBidWithStopper, cueBidWithoutStopper] - , wrap [cueBidWithStopper, cueBidWithoutStopper] - , wrap [cueBidWithStopper, cueBidWithoutStopper] - , wrap [cueBidWithStopper, cueBidWithoutStopper] - , wrap [cueBidWithStopper, cueBidWithoutStopper] - , wrap [cueBidWithStopper, cueBidWithoutStopper] - , wrap [cueBidWithStopper, cueBidWithoutStopper] - , wrap [cueBidWithStopper, cueBidWithoutStopper] - , wrap [cueBidWithStopper, cueBidWithoutStopper] - , wrap [cueBidWithStopper, cueBidWithoutStopper] - , wrap [cueBidWithStopper, cueBidWithoutStopper] - , wrap [cueBidWithStopper, cueBidWithoutStopper] - , wrap [cueBidWithStopper, cueBidWithoutStopper] - , wrap [cueBidWithStopper, cueBidWithoutStopper] - , wrap [cueBidWithStopper, cueBidWithoutStopper] - , wrap [cueBidWithStopper, cueBidWithoutStopper] - , wrap [cueBidWithStopper, cueBidWithoutStopper] - , wrap [cueBidWithStopper, cueBidWithoutStopper] - , wrap [cueBidWithStopper, cueBidWithoutStopper] - , wrap [cueBidWithStopper, cueBidWithoutStopper] - , wrap [cueBidWithStopper, cueBidWithoutStopper] - , wrap [cueBidWithStopper, cueBidWithoutStopper] - , wrap [cueBidWithStopper, cueBidWithoutStopper] - , wrap [cueBidWithStopper, cueBidWithoutStopper] - , wrap [cueBidWithStopper, cueBidWithoutStopper] - , wrap [cueBidWithStopper, cueBidWithoutStopper] - , wrap [cueBidWithStopper, cueBidWithoutStopper] - , wrap [cueBidWithStopper, cueBidWithoutStopper] - , wrap [cueBidWithStopper, cueBidWithoutStopper] - , wrap [cueBidWithStopper, cueBidWithoutStopper] - , wrap [cueBidWithStopper, cueBidWithoutStopper] - , wrap [cueBidWithStopper, cueBidWithoutStopper] - , wrap [cueBidWithStopper, cueBidWithoutStopper] - , wrap [cueBidWithStopper, cueBidWithoutStopper] - , wrap [cueBidWithStopper, cueBidWithoutStopper] - , wrap [cueBidWithStopper, cueBidWithoutStopper] - , wrap [cueBidWithStopper, cueBidWithoutStopper] - , wrap [cueBidWithStopper, cueBidWithoutStopper] - , wrap [cueBidWithStopper, cueBidWithoutStopper] - , wrap [cueBidWithStopper, cueBidWithoutStopper] - , wrap [cueBidWithStopper, cueBidWithoutStopper] - , wrap [cueBidWithStopper, cueBidWithoutStopper] - , wrap [cueBidWithStopper, cueBidWithoutStopper] - , wrap [cueBidWithStopper, cueBidWithoutStopper] - , wrap [cueBidWithStopper, cueBidWithoutStopper] - , wrap [cueBidWithStopper, cueBidWithoutStopper] - , wrap [cueBidWithStopper, cueBidWithoutStopper] - , wrap [cueBidWithStopper, cueBidWithoutStopper] - , wrap [cueBidWithStopper, cueBidWithoutStopper] - , wrap [cueBidWithStopper, cueBidWithoutStopper] - , wrap [cueBidWithStopper, cueBidWithoutStopper] - , wrap [cueBidWithStopper, cueBidWithoutStopper] - , wrap [cueBidWithStopper, cueBidWithoutStopper] - , wrap [cueBidWithStopper, cueBidWithoutStopper] - , wrap [cueBidWithStopper, cueBidWithoutStopper] - , wrap [cueBidWithStopper, cueBidWithoutStopper] - , wrap [cueBidWithStopper, cueBidWithoutStopper] - , wrap [cueBidWithStopper, cueBidWithoutStopper] - , wrap [cueBidWithStopper, cueBidWithoutStopper] - , wrap [cueBidWithStopper, cueBidWithoutStopper] - , wrap [cueBidWithStopper, cueBidWithoutStopper] - , wrap [cueBidWithStopper, cueBidWithoutStopper] - , wrap [cueBidWithStopper, cueBidWithoutStopper] - , wrap [cueBidWithStopper, cueBidWithoutStopper] - , wrap [cueBidWithStopper, cueBidWithoutStopper] - , wrap [cueBidWithStopper, cueBidWithoutStopper] - , wrap [cueBidWithStopper, cueBidWithoutStopper] - , wrap [cueBidWithStopper, cueBidWithoutStopper] - , wrap [cueBidWithStopper, cueBidWithoutStopper] - , wrap [cueBidWithStopper, cueBidWithoutStopper] - , wrap [cueBidWithStopper, cueBidWithoutStopper] - , wrap [cueBidWithStopper, cueBidWithoutStopper] - , wrap [cueBidWithStopper, cueBidWithoutStopper] - , wrap [cueBidWithStopper, cueBidWithoutStopper] - , wrap [cueBidWithStopper, cueBidWithoutStopper] - , wrap [cueBidWithStopper, cueBidWithoutStopper] - , wrap [cueBidWithStopper, cueBidWithoutStopper] - , wrap [cueBidWithStopper, cueBidWithoutStopper] - , wrap [cueBidWithStopper, cueBidWithoutStopper] - , wrap [cueBidWithStopper, cueBidWithoutStopper] - , wrap [cueBidWithStopper, cueBidWithoutStopper] - , wrap [cueBidWithStopper, cueBidWithoutStopper] - , wrap [cueBidWithStopper, cueBidWithoutStopper] - , wrap [cueBidWithStopper, cueBidWithoutStopper] - , wrap [cueBidWithStopper, cueBidWithoutStopper] - , wrap [cueBidWithStopper, cueBidWithoutStopper] - , wrap [cueBidWithStopper, cueBidWithoutStopper] - , wrap [cueBidWithStopper, cueBidWithoutStopper] - , wrap [cueBidWithStopper, cueBidWithoutStopper] - , wrap [cueBidWithStopper, cueBidWithoutStopper] - , wrap [cueBidWithStopper, cueBidWithoutStopper] - , wrap [cueBidWithStopper, cueBidWithoutStopper] - , wrap [cueBidWithStopper, cueBidWithoutStopper] - , wrap [cueBidWithStopper, cueBidWithoutStopper] - , wrap [cueBidWithStopper, cueBidWithoutStopper] - , wrap [cueBidWithStopper, cueBidWithoutStopper] - , wrap [cueBidWithStopper, cueBidWithoutStopper] - , wrap [cueBidWithStopper, cueBidWithoutStopper] ]