IPv6 problem on Poker Chase
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.
Notifications when a Discord bot goes down
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.
Pair the bot with a web server
This sounds like a blasphemy against the single-responsibility principle. There are practical reasons to do this.
- Hosting providers may put idle bots to sleep. Some providers are so web-centric that they require serving a web page to keep the bot alive.
- HTTP(S) serves as a simple and reliable endpoint. Everyone online can ping it.
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
}
}
Monitor the web server
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(())
}
Transfer O’ish Relay
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.
Basic structure
- TOR = transfer or extra
- (R) = NF negative, accepts the transfer
- TOR + 1 = transfer back to the suit of TOR
Examples
Birthright (Kokish Relay)
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:
- 2♥
- 5+ spades or FG
- 2♠
- NF, 5+ hearts
- 2NT to 3♦
- NAT NF
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.
Polish Club with swapped minor suits
- 1♣
- Polish Club with diamonds instead of clubs:
- Balanced 12–14 HCP
- 11–17 HCP, 5+ diamonds or 4441
- 18+ HCP, any
- 1♦
- 11–17 HCP, 5+ clubs or (441)4
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.
Drawbacks
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:
- Pass: weak long diamonds
- 1NT: constructive natural, effectively 4+ diamonds
- 2♣: almost a signoff with 3–4 clubs
- 2♥♠: game try with 3+ clubs
- 2NT: preemptive raise with 4+ clubs
- 3♣: mixed raise with 4+ clubs
Renaming bidding systems
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.
Rewriting Natsuki in Rust
I’m rewriting Natsuki (3.0) in Rust for several reasons. You can track my progress at this branch.
- Hosting: Free hosting tend to assume that node.js projects are websites. They put the app to sleep when idle, which effectively takes down a Discord bot. I’m now self-hosting Natsuki, but I’m not a fan of that. Rewriting in another language solves this issue.
- Economy commands: Shuttle provides free hosting even with 500 MB of database. This means we can make stateful features in the future, such as economy and games.
- Also please note that I’m considering remove NSFW functions. Discord has been more and more hostile to NSFW features. Making Natsuki SFW can spread her further.
Rebranding with a new icon
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.
My bidding systems tested with Cuebids
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.
NLTC, a good single hand evaluator
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.
- S = (void = 3, singleton = 2, doubleton = 1)
- X+ = max(X, S, X + S − 1) for each suit
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 |
Using NLTC in bidding
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.
Don’t directly apply the rule of 2, 3, 4
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.
My defense to strong 1♣
My favorite defense to strong 1♣ is Psycho Suction. I filled in 2NT and the 1-level as per the useful space principle. This defense is so flexible that it also applies to small 1♣, strong 1♦, and over the forced responder, e.g. (1♣)-(1♦).
X | Takeout double or stolen bid |
1x | Natural or lead-directing |
1NT | Non-touching pairs (♠ ♦ or ♥ ♣) |
2♣ | Clubs or red suits |
2♦ | Diamonds or majors |
2♥ | Hearts or black suits |
2♠ | Spades or minors (supplement to 2NT) |
2NT | Minors |
Psycho Suction is an extension to the natural defense. It is a superset of the weak twos. The two suiters increase the probabilities of the 2-bids and unanchor them. Psycho Suction establishes a pass-or-correct system where the 2x overcalls are also pass-or-correct. The word “psycho” reflects the risk of playing an undoubled misfit like psychic bids.
Paradox advances
The paradox principle in a pass-or-correct system is to bypass underbids. For example, hearing (1♣)-2♦, we hold
♠ J98
♥ KJ1032
♦ Q98
♣ Q2
Option | Advance |
---|---|
Diamonds | 3♦ |
Majors | 4♥ |
Bid 3♦. Besides diamond support, this bid also shows that we can also raise either major. Underbidding 2♥ conveys too little information and takes away too little space.
The paradox lies in that we do not bid our favorite strain. We have to make the cheapest call of the conjectured advances. Resultantly, we usually bid for the worst case.
Comparison with defenses to 1NT
Similarities
The most common subtype of strong 1♣ is a strong notrump. The opener is so strong that we are unlikely to have a game, so our main goal is to compete with partscores. Our cuebid strain is notrump because opponents have shown strength but no suit.
A common way to devise a defense to 1♣ is using our defense to 1NT. Suction is originally a defense to 1NT. Such a defense to 1NT with no anchor suit is banned in the ACBL Basic+ chart.1 However, artificial defenses to an artifical opening are generally allowed.2 Therefore, we can derive a defense to 1♣ from such an exotic defense to 1NT.
Differences
An obvious difference is that we can access 1-level overcalls. Beware of the lowest 2 overcalls as they give out bidding space.
X | Gives 2 steps (P, XX) |
1♦ | Gives 1 step (P) |
1♥ | Neither gives nor takes |
1♠ | Takes 1 step |
1NT | Takes 2 steps |
X and 1♦ are better constructive to make bidding space useful to everyone. Natural 1♥ and 1♠ are fine. Try to increase the probability of 2-level overcalls, which take considerable space.
Another difference is that 1NT is limited and descriptive. The opener does not have much to say even if given a second chance to bid. The probability that the opener has a major is also lower. These reasons make major-oriented overcalls effective, e.g. Multi-Landy.
On the other hand, a strong artificial opening is usually unlimited. Forcing overcalls are less effective since they let the opener pass at ease. Thus, a natural defense to 1♣ is stronger than to 1NT. Besides, Inverted Psycho Suction may work for 1NT, but Psycho Suction works better for 1♣.
Discussions
5=4 two suiters
I include some 5=4 two suiters to increase the probabilities of Psycho Suction bids. The rest can be easily expressed with a simple major overcall, where the 4-card suit is lower than the 5-card major.
1♥ | 5+ hearts |
1♠ | 5+ spades |
1NT | 4+ spades 5+ diamonds or 4+ hearts 5+ clubs |
2♣ | 6+ clubs or 4+ hearts 5+ diamonds |
2♦ | 6+ diamonds or 4+ spades 5+ hearts |
2♥ | 6+ hearts or 4+ spades 5+ clubs |
2♠ | 6+ spades or 4+ diamonds 5+ clubs |
2NT | 5+ diamonds 4+ clubs |
I believe 5=4 is the sweet spot of two suiters. The original 5-5 is too infrequent to make these overcalls different from weak twos. The 5-4 pattern is as frequent as the single-suited, putting the pass at higher risk. Moreover, 5-4 bids are better guided with an extra step showing equal preference. For example, Landy shows 5-4 in majors, and the 2♦ advance indicates equal preference. Nevertheless, this additional step bears a suit we deny, so it lets opponents come in cheaply.
Strength of X and 1♦
The strength to double is opening values. The double is a two-way call that is either a takeout double or a stolen opening bid with 5+ cards.
The 1♦ overcall is slightly stronger than 1♥ and 1♠ because it gives space yet exhibits no major. I suggest near average strength, i.e. 10+ total points in which there are 8+ HCP. I even recommend this approach to natural 1♣ since 1♦ leaks information without taking space.
Overcalls with 16+ HCP
Congratulations on holding yet another strong club! A comeback after passing the first round definitely reveals 16+ HCP. There are also situations where an initial double is better. To decide the best overcall, we have to investigate their pros and cons.
The pass is better when coming back is easy. The following qualities suggest a pass.
- Single suiter
- 5-card major
- Balanced
The takeout double is made for three suiters. It lets our partner decide the strain. If our partner bids our shortness, we can bid 1NT to provide choices again.
Two suiters fall between these scenarios. First, try to bid 1NT and 2NT since they are forcing. Next, hide a 4-card minor with a pass because introducing the longest suit is often enough. Then, we are left with the following two suiters to double.
- Majors
- 4=5 or more in same-colored suits
When a fit is not found yet, we can easily run to the cheaper suit. This strategy happens to spare 2♣, our rebid to show a regular opener with clubs.
Advance | Majors | Black | Red |
---|---|---|---|
1♦ | 1♥ | 1♠ | |
1♥ | 1♠ | ||
1♠ | 2♦ |
-
Overcalls higher than 2♣ must be anchored except that 2♦ can be Multi. ↩
-
Except fert bids, described as purely destructive in the ACBL convention charts. ↩