Skip to the content.

← 返回上一级目录

相信无数的编程小白,都幻想过能用C++编程制作出一款"好玩到爆炸"的游戏,推广到同学那里,
不得成为整个编程班的"高手"啊……那么这期,就由哎呦手把手教会大家,如何用C++编程制作出
无数游戏主播都玩过的一款热门游戏——骗子酒馆!
注意:本教程仅供娱乐学习,版权和解释权归原作者所有,请勿用此代码进行商业宣传等活动!

1.1 回顾游戏内容

首先,让我们回顾一下"骗子酒馆"这款游戏的内容吧。
游戏开局有四个人,每人发到五张牌(牌型有A,Q,K,Joker),并且游戏开局还会指定一种牌型为系统牌(Joker除外)。
每名玩家都有手枪,手枪里有6发子弹,其中有5发空弹,1发实弹,由系统随机分配。
开始游戏后,将会由随机一名玩家进行出牌。该名玩家可以选择出1~3张牌,可以出与系统牌相符的真牌,也可以出与系统牌不相符的假牌。
下家可以选择质疑:如果上家出的是真牌,则质疑失败,质疑的人开一枪;反之质疑成功,上家开一枪(每次开枪,都会重置手牌和系统牌)。
若下家选择不质疑,则下家出牌,一直延续。如果有玩家出完了牌,则该玩家可以不参与后面的出牌。
当场上一名玩家开枪并开到实弹后,该玩家出局,游戏继续;直到场上只剩一名玩家后,该玩家胜利。
(注意:如果场上只剩下两名玩家,当其中一方出完牌后,另一方必须开牌)。
我们需要用编程,一步步模拟还原这些过程。

1.2 所需代码展示

如果想让我们的游戏更加美观智能,需要用到不少的新代码块,首先就来介绍一下SetConsoleTextAttribute语句:

SetConsoleTextAttribute(handle, COLOR);

这个语句可以改变字体的颜色,让我们的游戏变得引人注目,丰富多彩。至于具体的用法,下面会统一介绍。

另外,我们的游戏不可能只有一个界面,所以我们还需要一个可以清屏的语句:

system("cls");

上面的代码就是用来清屏的语句,同理,在system的括号里填上pause,就可以在屏幕上显示"按下任意键继续"。

此外,为了让我们的游戏更加"高级",可以加入一个判断按键按下的指令:

#define KEY_DOWN(vk) ((GetAsyncKeyState(vk) & 0x8000) ? 1 : 0)
注意:以上介绍的代码块都需要windows.h头文件才可以正常使用!

1.3 搭建主界面

介绍完基础代码,我们就可以考虑搭建游戏的主界面了。
这一部分我们可以做成一个选关界面,玩家可以选择想玩的关卡游玩。这时候,我们的KEY_DOWN指令就能派上用场了。

查看主界面代码

此外,从代码就可以看出来,我们后面搭建的工程量可能会很大,我们尽量做到"模块化",也就是把一个功能放在一个函数里,用到时直接调用。

好了,接下来就让我们正式开始搭建游戏吧!

1.4 核心实现:初始化与全局变量

在开始之前,我们先定义几个关键的全局变量,用来追踪游戏状态:

char a[10]; // 存储玩家的手牌 char b[10]; // 存储对手的手牌 char my[10]; // 当前玩家手牌 char ch[10]; // 存储每个玩家的底牌 int sum_p = 9; // 玩家数量(初始为9) int ap, bp; // 玩家和对手的实弹位置

init函数 负责初始化玩家的"血量"——也就是手枪里实弹的位置:

int init(int player) { int bomm = rand() % 6 + 1; // 实弹在第几发(1~6) return bomm; }

每次对局开始时,我们需要重置所有状态:

memset(a, 0, sizeof(a)); memset(b, 0, sizeof(b)); sum_p = 9; int ap = init(1); // 玩家实弹位置 a[ap] = 1; // 标记玩家已开枪1次 int bp = init(2); // 对手实弹位置 b[bp] = 1;
💡 理解实弹机制:手枪有6发子弹,其中1发是实弹。init函数随机返回1~6的数字,代表实弹的位置。当玩家开枪次数达到这个数字时,就"中弹"出局。

1.5 底牌生成与手牌分配

每一轮游戏开始,系统会随机指定一张底牌(Ace/Queen/King):

int p = init(2); // 随机生成底牌索引 char ch_p; if(ch[p] == 'A') { cout << "本轮底牌:Ace" << endl; ch_p = 'A'; } else if(ch[p] == 'Q') { cout << "本轮底牌:Queen" << endl; ch_p = 'Q'; } else { cout << "本轮底牌:King" << endl; ch_p = 'K'; }

玩家的手牌由两部分组成:随机生成的牌(80%概率为底牌,20%概率为Joker)和补全的牌:

int num1 = rand() % 5 + 1; // 随机生成1~5张"真牌" for(int i = 1; i <= num1; i++) { int joker = rand() % 100 + 1; if(joker <= 80) { my[i] = ch_p; // 80%概率是底牌 } else { my[i] = 'J'; // 20%概率是Joker } } // 补全剩余手牌(非底牌,且不能是Joker) for(int i = num1 + 1; i <= 5; i++) { int pp = init(4); if(pp == 1) { if(ch_p == 'A') my[i] = 'Q'; if(ch_p == 'Q') my[i] = 'A'; if(ch_p == 'K') my[i] = 'A'; } else { if(ch_p == 'A') my[i] = 'K'; if(ch_p == 'Q') my[i] = 'A'; if(ch_p == 'K') my[i] = 'Q'; } }
⚠️ 注意:Joker是万能牌,可以当作任何牌使用。在质疑判定时,Joker视为真牌。

1.6 出牌逻辑与质疑机制

出牌环节是整个游戏的核心。玩家可以选择出1~3张牌:

// 玩家选择出牌张数 int n; cin >> n; if(n > 3) n = 3; int right = 1; // 标记出的是否为真牌 for(int i = 1; i <= n; i++) { int x; cin >> x; // 输入手牌位置(1~5) if(my[x] != ch_p && my[x] != 'J') { right = 0; // 不是真牌也不是Joker → 假牌 } my[x] = '0'; // 标记该位置已出牌 }

质疑机制:对手可以选择是否质疑。在基础版本中,我们用随机数模拟对手的决策:

int k = rand() % 100 + 1; if(k <= 40 || len1 == 0) { // 40%概率质疑,或没牌时强制质疑 if(right == 1) { cnt = 1; // 出真牌 → 质疑失败,对手开枪 } else { cnt = 2; // 出假牌 → 质疑成功,你开枪 } } else { shunxu = 2; // 不质疑,轮到对手出牌 }
🎯 质疑规则总结:
• 出真牌 + 质疑 → 质疑者开枪(质疑失败)
• 出假牌 + 质疑 → 出牌者开枪(质疑成功)
• 不质疑 → 继续游戏

1.7 开枪与死亡判定

当质疑发生后,失败的一方需要开一枪:

if(cnt == 1) { // 对手开枪 your_bomm++; if(your_bomm == bp) { cout << "You are the last winner!" << endl; return; } } else { // 你开枪 my_bomm++; if(my_bomm == ap) { cout << "You are die!" << endl; return; } }

1.8 完整游戏循环框架

整合以上所有部分,我们得到完整的游戏循环:

查看完整框架代码

1.9 对手AI的简单实现

双人模式中,对手的AI至少需要包含出牌策略和质疑策略:

// 对手出牌策略 int pai = rand() % 2 + 1; // 1=出真牌,2=出假牌 if(pai == 1 || num2 == 0) { // 出真牌(1~3张) int num = min(3, 5 - num2); len2 -= num; num2 += num; } else { // 出假牌(随机1~3张) int your = rand() % 3 + 1; len2 -= your; } // 玩家选择是否质疑 int kai; cin >> kai; if(kai == 1) { if(pai == 1) cnt = 2; // 真牌→质疑失败→你开枪 else cnt = 1; // 假牌→质疑成功→对手开枪 }

1.10 特殊情况处理

📌 必须注意的特殊情况:
• 手牌出完:len1 == 0 或 len2 == 0 时,该玩家不出牌
• 强制开牌:只剩两名玩家时,一方出完牌,另一方必须质疑
• 实弹随机:每次开局实弹位置随机(1~6),增加不确定性

1.11 基础版本总结

至此,我们已完成骗子酒馆基础版本的所有核心功能:

🎮 基础版游戏流程:
1. 初始化:分配实弹位置,重置所有状态
2. 每轮开始:生成底牌和手牌
3. 随机决定先手
4. 出牌方选择出牌(真牌或假牌)
5. 对方选择是否质疑
6. 质疑发生后,失败方开一枪
7. 检查是否有人达到死亡阈值
8. 如果无人死亡,清屏进入下一轮
9. 直到一方死亡,游戏结束

下期预告

在下一期教程中,我们将为游戏加入更多有趣的机制:

敬请期待《游戏教程02:教你手搓骗子酒馆(下)》!

帖子信息

最新更新时间:2026年8月12日