Strawberry adjunct
1m-(2M)-
3♠ = FG, 6+oM
3♥ = FG, 5=oM
3♥-3♠ = ask for stopper
I came up with this convention when I was writing system notes for my Polish Club.
Computer science and contract bridge
1m-(2M)-
3♠ = FG, 6+oM
3♥ = FG, 5=oM
3♥-3♠ = ask for stopper
I came up with this convention when I was writing system notes for my Polish Club.
I encountered asset loading problem when playing Poker Chase in IPv6 networks. Asset loading fails from time to time. Sometimes I have to switch to mobile app to continue playing.
I found a solution on Firefox. Go to about:config
and set
network.http.fast-fallback-to-IPv4
to false
. I am still not sure what causes
the problem. I suspect it is related to the CDN used by the game.
I want Natsuki to notify me when she goes down. This task is harder than I have thought. How can I count on a failing bot to send a message? I cannot trust the hosting provider, either. They may be the reason why the bot goes down. I have to rely on a third party.
This sounds like a blasphemy against the single-responsibility principle. There are practical reasons to do this.
Below is how I pair Natsuki with an Axum server. The Axum server only serves 204 No Content at root.
#[shuttle_runtime::async_trait]
impl Service for Natsuki {
async fn bind(mut self, addr: std::net::SocketAddr) -> Result<(), Error> {
use axum::{response::NoContent, routing::get, Router};
let router = Router::new().route("/", get(|| async { NoContent }));
let (axum, serenity) = futures::join!(
shuttle_axum::AxumService(router).bind(addr),
self.0.start_autosharded(),
);
serenity.map_err(CustomError::new)?;
axum
}
}
The other part of the plan is a watchdog that periodically pings the web server. The watchdog informs me through a Discord channel whenever a ping fails. Since the web server is available worldwide, the watchdog can live anywhere such as GitHub Actions. Given the importance of GitHub, it is much more reliable than self-hosting.
My watchdog is open-source like Natsuki. It takes a Discord webhook to send messages. I make it an environment variable because the webhook contains sensitive data. If the webhook is leaked, other people can send arbitrary messages to the channel.
use dotenv::var;
use serde_json::json;
#[tokio::main]
async fn main() -> anyhow::Result<()> {
let client = reqwest::Client::new();
let ping = || async {
const ENDPOINT: &str = "https://natsuki-oehk.shuttle.app/";
anyhow::ensure!(client.head(ENDPOINT).send().await?.status().is_success());
Ok(())
};
if let Err(error) = ping().await {
client
.post(var("WEBHOOK")?)
.json(&json!({ "content": error.to_string() }))
.send()
.await?;
}
Ok(())
}
An o’ish relay is a forcing bid that is natural or has extra strength. Famous examples are Birthright (Kokish Relay, 2♣-2♦-2♥) and Polish Club (1♣), after which I name this treatment. I advocate playing a transfer o’ish relay instead, the relay that either transfers to the next suit or has extra strength. This method renders the negative response nonforcing and allows more descriptive rebids.
A classical problem with the strong 2♣ opening is whether the auction is game-forcing. One solution is the Kokish Relay, where opener bids 2♥ to show hearts or a unilaterally game-forcing hand. This treatment potentially wastes space because opener hardly passes 2♥-2♠.
The rebids after 2♣-2♦ I propose are:
After 2♥, the default 2♠ fits any hand that responder would pass natural 2♠. Other responses are game-forcing.
After 2♠, responder passes with weak long spades. The 3♥ response is to play. Whether 2NT is game-forcing is up to partnership agreement.
It took me almost one year to accept this idea until I realized that 1♣-1X-2♣ should retransfer to diamonds. The strength difference between natural diamonds (11+ HCP) and clubs (18+ HCP) is so large that opener should transfer twice. The odwrotka sequence of 1♣-1X-2♦ remains a power reverse.
Responding to TOR + 1 is more complicated than TOR. You can no longer park at the negative relay (TOR + 1). Accepting the transfer (TOR + 5) becomes default and often meets a pass. Take 1♦ (showing clubs) for example:
I’ve been with my girlfriend for 2+ months and finally found the red and blue mascots for my bridge bidding systems.
Oshawott is my girlfriend’s favorite pokémon. She thinks that Litten is my pokémon since my fursona is an orange cat. These two pokémons fit the color stickers from WBF systems policy and also the Red Oni, Blue Oni trope.
By the way, recently I reached 1800+ Elo on Cuebids. I took a screenshot because I not only was proud of it but also thought it cannot last long.
I’m rewriting Natsuki (3.0) in Rust for several reasons. You can track my progress at this branch.
I made a new icon for the Taipei Forcing Club and this site. This icon honors both my hobbies: contract bridge and Japanese mahjong.
I used Inkscape to create the icon. I’m not a graphic designer, but I’m happy with the result. This icon combines lietxia’s 🀙 (1p) mahjong tile and ♣ in Noto Sans TC.
I tested my bidding systems on Cuebids, a web app for pairs to practice bidding. All three accounts using my bidding systems made it to the top 10 this week. The following is the screenshot of the top 10 list when Mijumaru Blue Club (known as Bluepill (Canapé) Club then) just entered the list. My own account and Irene playing only Litten Polish Club were the top two.
We are still on top 5 as of this writing. We will try to stay on top 10 but not to be top 3 at the same time to keep the environment competitive.
My collection of bidding systems is available on GitHub. It contains aforementioned systems and a defensive system. Litten Polish Club is almost complete. Mijumaru Blue Club is still evolving. The defensive system is still in its infancy.
This collection is free software. You can use it for any purpose, including commercial purposes, at your own risk. I would appreciate it if you could share your experience with me.
Inspired by Thomas Andrews’ article on single hand evaluators, I want to check out how good such an evaluator NLTC is. Since LTCs need an established trump fit, we only consider suit offense tricks, i.e. the most tricks a partnership can take in any suit contract.
Thomas built his data with Matt Ginsberg’s (GIB) double dummy library containing 700K+ deals. However, available sources of that library are long gone. To achieve similar statistical power, I would have to solve about 1M deals. Thanks to DDS, the well known double dummy solver in C++, along with modern computer architecture, we can solve 1M deals within one day.
I generated all data in this article with my bridge utility. It took 8 hours to solve 1M deals for only suit contracts. The following is the correlation coefficient matrix of various evaluations.
Tricks | HCP+ | BUM-RAP+ | LTC | NLTC | ALTC |
---|---|---|---|---|---|
1 | 0.508270 | 0.512822 | -0.482577 | -0.521692 | -0.516951 |
1 | 0.987782 | -0.861016 | -0.927226 | -0.903264 | |
1 | -0.831184 | -0.943001 | -0.915663 | ||
1 | 0.919761 | 0.935646 | |||
1 | 0.979818 | ||||
1 |
The plus sign stands for short-suit points in GIB bid descriptions. As BUM-RAP gives fractional points, I made such an adjustment more rigorous.
As for how this adjustment is slightly better than max(X, S) and X + S, there will be a separate article.
ALTC is what Jeff Rubens suggested. Adjust −0.5 losers for each held ace and +0.5 for each guarded queen. NLTC bears this in mind but adjusts for missing aces and queens instead.
Things are different when we add up evaluations in each partnership. LTCs are less additive than HCP+. I think this phenomenon arises from counting values twice. A classic example is that a long suit in one hand and the corresponding doubleton in another are both counted as values a priori.
Tricks | HCP+ | BUM-RAP+ | LTC | NLTC | ALTC |
---|---|---|---|---|---|
1 | 0.861012 | 0.870637 | -0.749171 | -0.839970 | -0.813800 |
1 | 0.987937 | -0.832577 | -0.910715 | -0.880367 | |
1 | -0.804589 | -0.924311 | -0.890025 | ||
1 | 0.922495 | 0.940156 | |||
1 | 0.974347 | ||||
1 |
NLTC is more a single hand evaluator than an additive one. It is good to use NLTC for suit-oriented initial actions like preemptive openings and overcalls. Consider using additive point counts to assess supports.
The exact ranges of NLTC for preemptive openings are up to partnership agreement. I’d still like to point out some problems if you try to migrate from LTC to NLTC.
With the plain LTC, we estimate the minimum playing tricks to be 13 − LTC. However, NLTC counts more losers than LTC, especially in single suiters. NLTC counts x and xx as 1.5 and 2.5 losers respectively, i.e. each 0.5 more than LTC. Single suiters are rich in singletons and doubletons. Besides, it is discouraged to preempt with a void. In general, NLTC intrinsically counts 1–1.5 more losers than LTC for single suiters. I am still not sure how to map NLTC to preemptive bids. There is going to be an update if I finally figure it out.