C語言探索之旅 | 第二部分第九課: 實(shí)戰(zhàn)"懸掛小人"游戲

作者 謝恩銘,公眾號「程序員聯(lián)盟」(微信號:coderhub)昆婿。
轉(zhuǎn)載請注明出處。
原文:http://www.reibang.com/p/6cbf452666bd

《C語言探索之旅》全系列

內(nèi)容簡介


  1. 前言
  2. 題目規(guī)定
  3. 優(yōu)化建議
  4. 第二部分第十課預(yù)告

1. 前言


第二部分的理論知識基本講完了痕支。上一課我們經(jīng)歷了很有意思的 C語言探索之旅 | 第二部分第八課:動態(tài)分配 品擎。

這一課我們來實(shí)戰(zhàn)一下,要實(shí)現(xiàn)的游戲叫“懸掛小人”揍异。

這個(gè)“小人”全陨,不是“君子和小人”的小人。是 little man(小小的人)的意思衷掷。

讀者:“你有必要這么強(qiáng)調(diào)嗎辱姨?簡直無聊嘛...”

好的,話休絮煩...

俗語說得好:“實(shí)踐是必要的戚嗅!”

對于大家來說這又尤為重要雨涛,因?yàn)槲覀儎倓偨Y(jié)束了一輪 C語言的高級技術(shù)的“猛烈進(jìn)攻”,需要好好復(fù)習(xí)一下懦胞,消化消化替久。

不論你多厲害,在編程領(lǐng)域躏尉,不實(shí)踐是永遠(yuǎn)不行的蚯根。盡管你可能讀懂了之前的所有課程,但是如果不配合一定的實(shí)踐胀糜,是不能深刻理解的颅拦。

以前我大學(xué)里入門編程以前看 C語言的書,覺得看懂了教藻,但是一上手要寫程序距帅,就像擠牙膏一樣費(fèi)勁。

這次的實(shí)戰(zhàn)練習(xí)怖竭,我們一起來實(shí)現(xiàn)一個(gè)小游戲:“懸掛小人”锥债,或叫 “上吊游戲”陡蝇。英語叫 HangMan痊臭,是挺著名的一個(gè)休閑益智游戲哮肚。

雖說是游戲,但是比較可惜的是還不能有圖形界面 (不過課程后面會說怎么實(shí)現(xiàn)在控制臺繪制小人广匙,其實(shí)也可以實(shí)現(xiàn)簡陋的“圖形化”): 因?yàn)?C語言本身不具備繪制 GUI(Graphical User Interface 的縮寫允趟,表示“圖形用戶接口”)的能力,需要引入第三方的庫鸦致。

懸掛小人游戲是一個(gè)經(jīng)典的字母游戲潮剪,在規(guī)定步數(shù)內(nèi)一個(gè)字母一個(gè)字母地猜單詞,直到猜出整個(gè)單詞分唾。

所以我們的游戲暫時(shí)還是以控制臺的形式(黑框框)與大家見面抗碰,當(dāng)然如果你會圖形編程,也可以把這個(gè)游戲擴(kuò)展成圖形界面的绽乔。

相信不少讀者應(yīng)該見過這個(gè)游戲的圖形界面版本弧蝇,就是每猜錯(cuò)一個(gè)字母畫一筆,直到用完規(guī)定次數(shù)折砸,小人被“吊死”看疗。

這個(gè)實(shí)戰(zhàn)的目的是讓我們可以復(fù)習(xí)之前學(xué)過的所有 C語言知識:指針,字符串睦授,文件讀寫两芳,結(jié)構(gòu)體,數(shù)組去枷,等等怖辆,都是好家伙!

2. 題目規(guī)定


既然是出題目的實(shí)戰(zhàn)删顶,那么就需要委屈大家按照我的題目要求來編寫這個(gè)游戲啦疗隶。

好,就來公布我們的題目要求:

  • 游戲每一輪有 7 次(次數(shù)可以設(shè)置翼闹,不一定是 7 次)猜測的機(jī)會斑鼻,用完則此輪失敗。

  • 每輪會從字典中隨機(jī)抽取一個(gè)單詞供玩家猜猎荠,初始時(shí)單詞是以若干個(gè)星號(*)的方式來表示坚弱。說明所有字母都還隱藏著。

  • 字典的所有單詞儲存在一個(gè)文本文件中(在 Windows 下通常是 txt 文件关摇,在 Unix/Linux/macOS 下一般可以是任意后綴名的文件)荒叶。

  • 每猜錯(cuò)一個(gè)字母就扣掉一次機(jī)會,猜對一個(gè)字母不扣除機(jī)會數(shù)输虱。猜對的字母會顯示在屏幕上的單詞中些楣,替換掉星號。

一個(gè)回合的運(yùn)作機(jī)制


假設(shè)要猜的單詞是 OSCAR。

假設(shè)我們給程序輸入一個(gè)字母 B(猜的第一個(gè)字母)愁茁,程序會驗(yàn)證字母是否在這個(gè)單詞里蚕钦。

有兩種情況:

  • 所猜的字母在單詞中,此時(shí)程序會顯示這個(gè)單詞鹅很,不是全部顯示嘶居,而是顯示猜到的那些字母,其他的還未猜到的字母用 * 表示促煮。

  • 所猜的字母不在單詞中(目前的情況邮屁,因?yàn)樽帜?B 不在單詞 OSCAR 中),此時(shí)程序會告訴玩家“你猜錯(cuò)了”菠齿,剩余的機(jī)會數(shù)會被扣除一個(gè)佑吝。如果剩余機(jī)會數(shù)變?yōu)?0,游戲結(jié)束绳匀。

在圖形化的“懸掛小人”(Hangman)游戲中迹蛤,每猜一次會有一個(gè)小人被畫出來。我們的游戲襟士,雖然還不能真正實(shí)現(xiàn)圖形化盗飒,但是如果優(yōu)化一下,也可以在控制臺實(shí)現(xiàn)類似這樣的效果:

假設(shè)玩家輸入一個(gè) C陋桂,因?yàn)?C 在單詞 OSCAR 中逆趣,那么程序不會扣除玩家的剩余機(jī)會數(shù),而且會顯示已猜到的字母嗜历,如下:

單詞:**C**

如果玩家繼續(xù)輸入宣渗,這回輸入的是 O,那么程序會顯示如下:

單詞:O*C**

多個(gè)相同字母的情況


有一些單詞中梨州,同一個(gè)字母會出現(xiàn)多次痕囱。比如在 APPLE(表示“蘋果”)中,P 這個(gè)字母就出現(xiàn)了 2 次暴匠;在 ELEGANCE(表示“優(yōu)雅”)中鞍恢,E 這個(gè)字母出現(xiàn)了 3 次。

Hangman 游戲?qū)Υ说囊?guī)則很簡單:只要猜出一個(gè)字母每窖,其他重復(fù)的字母會同時(shí)顯示帮掉。

假如要猜的單詞是 ELEGANCE,用戶輸入了一個(gè) E窒典,那么會如下顯示:

單詞:E*E****E

一個(gè)回合的例子


歡迎來到懸掛小人游戲蟆炊!

您還剩 7 次機(jī)會
神秘單詞是什么呢?*****
輸入一個(gè)字母:E

您還剩 6 次機(jī)會
神秘單詞是什么呢瀑志?*****
輸入一個(gè)字母:S

您還剩 6 次機(jī)會
神秘單詞是什么呢涩搓?*S***
輸入一個(gè)字母:R

您還剩 6 次機(jī)會
神秘單詞是什么呢污秆?*S**R
輸入一個(gè)字母:

游戲就會這樣進(jìn)行下去,直到玩家在 7 個(gè)機(jī)會用完前猜到單詞昧甘,或者用完 7 個(gè)機(jī)會還沒猜到單詞良拼,游戲結(jié)束。

例如:


您還剩 2 次機(jī)會
神秘單詞是什么呢疾层?OS*AR
輸入一個(gè)字母:C

勝利了将饺!神秘單詞是:OSCAR

在控制臺輸入一個(gè)字母


在控制臺中讓程序讀入一個(gè)字母贡避,看起來簡單痛黎,但其實(shí)暗藏玄機(jī)。不信我們來試一下刮吧。

要輸入一個(gè)字母湖饱,一般大家會認(rèn)為是這樣做:

scanf("%c", &myLetter);

確實(shí)是不錯(cuò)的,因?yàn)?%c 標(biāo)明了等待用戶輸入一個(gè)字符杀捻。輸入的字符會儲存在 myLetter 這個(gè)變量(類型是 char)中井厌。

如果我們只寫一個(gè) scanf,那是沒問題的致讥。但是假如有好幾個(gè) scanf仅仆,會怎么樣呢?我們來測試一下:

int main(int argc, char* argv[])
{
    char myLetter = 0;

    scanf("%c", &myLetter);
    printf("%c", myLetter);

    scanf("%c", &myLetter);
    printf("%c", myLetter);

    return 0;
}

照我們的設(shè)想垢袱,上述程序應(yīng)該會請求用戶輸入一個(gè)字符墓拜,再打印出來: 進(jìn)行兩次。

測試一下请契,實(shí)際情況是怎么樣的呢咳榜?你輸入了一個(gè)字符,沒錯(cuò)爽锥,然后呢...

程序?yàn)槟愦蛴〕鰜砹四爿斎氲哪莻€(gè)字符涌韩,假如你輸入的是 a,那么程序輸出

a

然后程序就退出了氯夷,沒有下文了臣樱。為什么不提示我輸入第二個(gè)字符了呢?就好像它忽略了第二個(gè) scanf 一樣腮考。到底發(fā)生了什么呢擎淤?

事實(shí)上,當(dāng)你在控制臺(console)里面輸入時(shí)秸仙,你輸入的內(nèi)容都被記錄到內(nèi)存的某處嘴拢,當(dāng)然也包括按下 Enter 鍵(回車鍵)時(shí)產(chǎn)生的輸入:

\n

因此,你先輸入了一個(gè)字符(例如 a)寂纪,然后你按了一下回車鍵:

字符 a 就被第一個(gè) scanf 取走了席吴,第二個(gè) scanf 則把你的回車鍵(\n)取走了赌结。

為了避免這個(gè)問題,我們寫一個(gè)函數(shù) readCharacter() 來處理:

char readCharacter()
{
    char character = 0;
    character = getchar();  // 讀取輸入的第一個(gè)字母

    character = toupper(character); // 把這個(gè)字母轉(zhuǎn)成大寫

    // 讀取其他的字符孝冒,直到 \n (為了忽略它們)
    while (getchar() != '\n')
        ;

    return character;  // 返回讀到的第一個(gè)字母
}

可以看到柬姚,以上程序中,我們使用了 getchar 函數(shù)庄涡,這個(gè)函數(shù)是在標(biāo)準(zhǔn)庫的 stdio.h 中量承,用于讀取一個(gè)用戶輸入的字符,效果相當(dāng)于

scanf("%c", &letter);

然后穴店,我們又用到了一個(gè)在本課程中還沒學(xué)習(xí)過的函數(shù):toupper撕捍。

根據(jù)字面意思 to + upper 是英語“轉(zhuǎn)換為大寫”的意思,所以這個(gè)函數(shù)就是用于把一個(gè)字母轉(zhuǎn)成大寫字母泣洞。

看到了吧忧风,如果函數(shù)名起得好,幾乎就不需要注釋球凰,看名字就知道大致是干什么的(論編程命名的重要性)狮腿。

借著 toupper 這個(gè)函數(shù),玩家就可以輸入小寫字母或者大寫字母了呕诉,因?yàn)樵凇皯覓煨∪恕庇螒蛑性迪幔覀冿@示的單詞中的字母都是大寫的。

toupper 這個(gè)函數(shù)定義在 ctype.h 這個(gè)標(biāo)準(zhǔn)庫的頭文件中甩挫,所以需要

#include <ctype.h>

繼續(xù)看我們的函數(shù)贴硫,可以看到其中最關(guān)鍵的地方是:

while (getchar() != '\n')
    ;

這一小段代碼使得我們可以清除第一個(gè)輸入的字母外的其他字符,直到遇見 \n(回車符)捶闸。

函數(shù)返回的就是第一個(gè)輸入的字母夜畴,這樣可以保證不再受回車符的影響了。

我們用了一個(gè) while 循環(huán)删壮,而循環(huán)體部分只有一個(gè)分號(;)贪绘,很簡潔吧。

也許你會問央碟,之前的課程中 while 循環(huán)的循環(huán)體不是由大括號圍起來的么税灌,怎么這里只有一個(gè)分號呢?

事實(shí)上亿虽,這個(gè)分號就相當(dāng)于

{
}

就是空循環(huán)體菱涤,什么都不做,所以其實(shí)以上的代碼相當(dāng)于:

while (getchar() != '\n')
{
}

但是分號比大括號寫起來更簡單么洛勉,不要忘了程序員是懂得如何偷懶的一群人!

此 while 循環(huán)一直執(zhí)行粘秆,直到用戶輸入回車符,其他的字符都被從內(nèi)存中清除了收毫,我們稱其為 “清空緩沖區(qū)”攻走。

因此:

為了在我們的程序中每次讀取用戶輸入的一個(gè)字母殷勘,我們不要使用

scanf("%c", &myLetter);

而須要借助我們寫的函數(shù):

myLetter = readCharacter();

于是,我們的測試程序變成這樣:

#include <stdio.h>
#include <ctype.h>

char readCharacter()
{
    char character = 0;

    character = getchar();  // 讀取一個(gè)字母

    character = toupper(character);  // 把這個(gè)字母轉(zhuǎn)成大寫

    // 讀取其他的字符昔搂,直到 \n (為了忽略它)
    while (getchar() != '\n')
        ;

    return character;  // 返回讀到的第一個(gè)字母
}

int main(int argc, char* argv[])
{
    char myLetter = 0;

    myLetter = readCharacter();

    printf("%c\n", myLetter);

    myLetter = readCharacter();

    printf("%c\n", myLetter);

    return 0;
}

運(yùn)行玲销,輸出類似如下(假如用戶輸入 o,回車摘符;輸入 k贤斜,回車):

o
O
k
K

字典 / 詞庫


因?yàn)槲覀兊挠螒蚴且徊讲綄懗傻模砸婚_始逛裤,肯定先寫簡單的瘩绒,再逐步完善游戲。

因此别凹,猜測的單詞一開始我們只用一個(gè)草讶。所以洽糟,我們一開始會這么寫:

char secretWord[] = "BOTTLE";

你會說:“這樣不是很無聊嘛炉菲,猜測的單詞總是這一個(gè)”。

是的坤溃,但之后我們肯定會擴(kuò)展拍霜。一開始這樣做是為了不把問題復(fù)雜化,一次做一件事情薪介,慢慢來么祠饺。

之后如果猜測一個(gè)單詞的代碼可以運(yùn)行了,我們再用一個(gè)文件來儲存所有可能的單詞汁政,這個(gè)文件可以起名為 dictionary(表示“字典”)道偷。

那什么是字典或詞庫呢?

在我們的游戲里记劈,就是一個(gè)文件勺鸦,文件中的每一行存放了一個(gè)單詞,之后我們的程序會隨機(jī)從此文件中抽取一個(gè)單詞來作為每一輪的猜測單詞目木。

詞庫是類似這樣的:

YOU
MOTHER
LOVE
PANDA
BOTTLE
FUNNY
HONEY
LIKE
JAZZ
MUSIC
BREAD
APPLE
WATER
PEOPLE

至于這個(gè)文件里有多少單詞换途,因?yàn)槲覀兊脑~庫是可擴(kuò)展的(之后肯定可以添加新的單詞),所以其實(shí)只要統(tǒng)計(jì)回車符(\n)的數(shù)目就可以刽射,因?yàn)槭敲啃幸粋€(gè)單詞军拟。

好了,游戲的基本點(diǎn)我們介紹到這里誓禁,其實(shí)有了前面所有課程的基礎(chǔ)懈息,你已經(jīng)有能力來完成這個(gè)看似有點(diǎn)復(fù)雜的游戲了,不過要組織得好還是不那么容易的摹恰,你可以用多個(gè)函數(shù)來實(shí)現(xiàn)不同的功能辫继。

加油阁最,堅(jiān)持不懈就是勝利,期待你的成果骇两!

3. 優(yōu)化建議


如果你是在 Windows 下用 CodeBlocks 等 IDE 來編譯的速种,那么請將字典文件 dictionary 改成 dictionary.txt。
因?yàn)?Windows 的文件儲存形式和 Linux/Unix/macOS 有些不一樣低千。

改進(jìn)游戲


  1. 目前來說配阵,我們只讓玩家玩一輪,如果能加一個(gè)循環(huán)示血,使得游戲每次詢問玩家是否要再玩一次棋傍,那“真真是極好的”。

  2. 目前還是單機(jī)模式难审,可以創(chuàng)建一個(gè)二人模式瘫拣,就是一個(gè)玩家輸入一個(gè)單詞,第二個(gè)玩家來猜告喊。

  3. 為什么不用 printf 函數(shù)來打郁镏簟(繪制)一個(gè)懸掛小人呢?在每次我們猜錯(cuò)的時(shí)候黔姜,就把它畫出來拢切,每錯(cuò)一個(gè),多畫一筆秆吵,這樣可以增加樂趣淮椰,可以用如下的代碼:

if (猜錯(cuò)1個(gè)字母)
{
    printf(" _____\n");
    printf(" |  |\n");
    printf(" |  O\n");
    printf(" |\n");
    printf(" |\n");
    printf(" |\n");
    printf(" |\n");
    printf("_|__\n");
}
else if (猜錯(cuò)2個(gè)字母)
{
    printf(" _____\n");
    printf(" |  |\n");
    printf(" |  O\n");
    printf(" |  |\n");
    printf(" |\n");
    printf(" |\n");
    printf(" |\n");
    printf("_|__\n");
}
else if (猜錯(cuò)3個(gè)字母)
{
    printf(" _____\n");
    printf(" |  |\n");
    printf(" |  O\n");
    printf(" | \\|\n");
    printf(" |\n");
    printf(" |\n");
    printf(" |\n");
    printf("_|__\n");
}
else if (猜錯(cuò)4個(gè)字母)
{
    printf(" _____\n");
    printf(" |  |\n");
    printf(" |  O\n");
    printf(" | \\|/\n");
    printf(" |\n");
    printf(" |\n");
    printf(" |\n");
    printf("_|__\n");
}
else if (猜錯(cuò)5個(gè)字母)
{
    printf(" _____\n");
    printf(" |  |\n");
    printf(" |  O\n");
    printf(" | \\|/\n");
    printf(" |  |\n");
    printf(" |\n");
    printf(" |\n");
    printf("_|__\n");
}
else if (猜錯(cuò)6個(gè)字母)
{
    printf(" _____\n");
    printf(" |  |\n");
    printf(" |  O\n");
    printf(" | \\|/\n");
    printf(" |  |\n");
    printf(" | /\n");
    printf(" |\n");
    printf("_|__\n");
}
else if (猜錯(cuò)7個(gè)字母)
{
    printf(" _____\n");
    printf(" |  |\n");
    printf(" |  O\n");
    printf(" | \\|/\n");
    printf(" |  |\n");
    printf(" | / \\\n");
    printf(" |\n");
    printf("_|__\n");
}

上面代碼中的空格也許不同平臺的顯示不一樣,可能需要大家自行調(diào)整纳寂。

如果 7 次機(jī)會全部用完主穗,則小人掛掉,游戲結(jié)束毙芜。

請大家花點(diǎn)時(shí)間忽媒,好好理解這個(gè)游戲,并且盡可能地改進(jìn)它爷肝。如果你可以不看我們的答案猾浦,而自己完成游戲和改進(jìn),那么你會收獲很多的灯抛!

4. 第二部分第十課預(yù)告


今天的課就到這里金赦,一起加油吧!

下一課我們就會公布懸掛小人游戲的解題思路和答案咯对嚼。

下一課:C語言探索之旅 | 第二部分第十課: 實(shí)戰(zhàn)"懸掛小人"游戲 答案


我是 謝恩銘夹抗,公眾號「程序員聯(lián)盟」(微信號:coderhub)運(yùn)營者,慕課網(wǎng)精英講師 Oscar 老師纵竖,終生學(xué)習(xí)者漠烧。
熱愛生活杏愤,喜歡游泳,略懂烹飪已脓。
人生格言:「向著標(biāo)桿直跑」

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末珊楼,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子度液,更是在濱河造成了極大的恐慌厕宗,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,204評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件堕担,死亡現(xiàn)場離奇詭異已慢,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)霹购,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,091評論 3 395
  • 文/潘曉璐 我一進(jìn)店門佑惠,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人齐疙,你說我怎么就攤上這事膜楷。” “怎么了剂碴?”我有些...
    開封第一講書人閱讀 164,548評論 0 354
  • 文/不壞的土叔 我叫張陵把将,是天一觀的道長轻专。 經(jīng)常有香客問我忆矛,道長,這世上最難降的妖魔是什么请垛? 我笑而不...
    開封第一講書人閱讀 58,657評論 1 293
  • 正文 為了忘掉前任催训,我火速辦了婚禮,結(jié)果婚禮上宗收,老公的妹妹穿的比我還像新娘漫拭。我一直安慰自己,他們只是感情好混稽,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,689評論 6 392
  • 文/花漫 我一把揭開白布采驻。 她就那樣靜靜地躺著,像睡著了一般匈勋。 火紅的嫁衣襯著肌膚如雪礼旅。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,554評論 1 305
  • 那天洽洁,我揣著相機(jī)與錄音痘系,去河邊找鬼。 笑死饿自,一個(gè)胖子當(dāng)著我的面吹牛汰翠,可吹牛的內(nèi)容都是我干的龄坪。 我是一名探鬼主播,決...
    沈念sama閱讀 40,302評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼复唤,長吁一口氣:“原來是場噩夢啊……” “哼健田!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起佛纫,我...
    開封第一講書人閱讀 39,216評論 0 276
  • 序言:老撾萬榮一對情侶失蹤抄课,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后雳旅,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體跟磨,經(jīng)...
    沈念sama閱讀 45,661評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,851評論 3 336
  • 正文 我和宋清朗相戀三年攒盈,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了抵拘。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,977評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡型豁,死狀恐怖僵蛛,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情迎变,我是刑警寧澤充尉,帶...
    沈念sama閱讀 35,697評論 5 347
  • 正文 年R本政府宣布,位于F島的核電站衣形,受9級特大地震影響驼侠,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜谆吴,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,306評論 3 330
  • 文/蒙蒙 一倒源、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧句狼,春花似錦笋熬、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,898評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至筹吐,卻和暖如春糖耸,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背骏令。 一陣腳步聲響...
    開封第一講書人閱讀 33,019評論 1 270
  • 我被黑心中介騙來泰國打工蔬捷, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,138評論 3 370
  • 正文 我出身青樓周拐,卻偏偏與公主長得像铡俐,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子妥粟,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,927評論 2 355

推薦閱讀更多精彩內(nèi)容