1A2B猜數字,原名為公牛和母牛(Bulls and Cows),算是一種益智類小遊戲,一般是兩個人玩。遊戲規則雖然很簡單,卻十分考驗人的智力和毅力。



經典的遊戲規則是玩家兩人中某方(以下以出題方代稱)先在心裡想出一組由四個皆不同的數所組成的四位數字(例如:1234、5678、0653),且每位數的數字範圍都在0到9。而另一方(以下以猜題方代稱)則要猜出出題方心裡所想的數字。出題方需以XAYB(例如1A2B)的形式提示猜題方猜的答案。XA中的X表示數值正確且位置也正確的數字數量;YB中的Y表示數值正確但位置不正確的數字數量。例如:假設出題方心中的數字為1357,而猜題方所猜的數為1234,則出題方要回答提示1A1B給猜題方,因為出題方的1與猜題方的1位置正確,但出題方的3與猜題方的3位置不正確。下面舉個完整的例子:

現在猜題方要猜出題方的數字,以下是他們的對話內容:
猜題方:1234
出題方:0A0B (此時我們可以確定這個4位數字絕對不會是1、2、3、4所組成。)
猜題方:5678 (因此繼續猜5678)
出題方:0A3B
猜題方:7865
出題方:3A0B
猜題方:7860
出題方:4A0B
直到出題方說出4A0B才算猜題方真的猜中出題方的數字!

熟悉猜數字的玩法之後就可以考慮進行不一樣的玩法,像是增加數字的數量到五位以上,或是把數字改成文字等,甚至還可以邀請更多人一起玩猜數字。

由於這遊戲的變化玩法很多,規則也十分簡單,因此是個非常適合拿來練習寫程式的題目。筆者過去曾經使用Java程式語言來完成基本功能完整的猜數字遊戲文字版,這次就不再做遊戲成品,而是用Rust程式語言來做一個開發猜數字遊戲的框架,讓這個遊戲在未來可以很方便地被移植到不同的遊戲舞台上。

Bulls and Cows

「Bulls and Cows」是筆者開發的套件,提供了開發公牛和母牛猜數字遊戲的程式框架,支援任意資料型別,可以被用在任意的遊戲舞台上。

Crates.io

Cargo.toml

bulls-and-cows = "*"

使用方法

建議先從範例目錄examples中的4_digits.rs開始看起。這支4_digits程式是最典型的猜數字遊戲程式範例,由電腦隨機產生出一串由4個0到9不重複組合而成的數字作為正確答案,使用者直接在終端機上輸入要猜的數字,程式會根據使用者輸入的數字和它原先產生出來的正確答案來計算出XAYB,並提示給使用者,直到出現4A0B後,該回合遊戲才會結束。

bulls-and-cows

4_digits.rs主要使用了bulls-and-cows這個crate提供的Host結構體,來實現出題和回答。Host結構體的用法如下:

let host = bulls_and_cows::Host::build_with_known_answer(bulls_and_cows::Letters::generate_numeric_letters(), vec![1, 2, 3, 4]).unwrap();

assert_eq!((4, 0), host.answer(&[1, 2, 3, 4]).unwrap());
assert_eq!((2, 2), host.answer(&[1, 2, 4, 3]).unwrap());
assert_eq!((0, 4), host.answer(&[4, 3, 2, 1]).unwrap());
assert_eq!((0, 0), host.answer(&[5, 6, 7, 8]).unwrap());

如果要實現更複雜的遊戲舞台,可以使用bulls-and-cows這個crate提供的play模組。例如這支custom_2_players範例程式,就是使用了play模組所提供的players的相關結構體和特性,來實作出在同一個舞台下,可以讓使用者在遊戲開始前自由選擇其想要在遊戲中扮演的角色,看是要當出題者,還是要當猜題者,還是要當個旁觀者看著電腦玩也可以。

bulls-and-cows

bulls-and-cows