C 语言实现简化版大富翁游戏
一、项目背景与概述
“大富翁”(Monopoly)是一款经典的棋盘类桌游,玩家通过掷骰子在棋盘上移动,可以购买土地、收取租金,并通过策略积累财富,最终目标是让其他玩家破产并成为最富有的人。
本项目旨在使用 C 语言 实现一个简化版的大富翁游戏,采用 文本模式 在终端运行。该项目将包含:
- 棋盘系统:使用一维数组模拟棋盘,每个格子可能是“空地”、“已购买的土地”、“运气事件”等。
- 玩家系统:两个玩家交替投掷骰子,在棋盘上移动。
- 财务管理:玩家可以购买土地、支付租金、触发随机事件(如赚取奖金或罚款)。
- 胜负判定:当某名玩家资金低于 0(破产)时,游戏结束。
本项目主要使用 结构体、数组、随机数、循环控制 等 C 语言基础知识,适合作为入门级别的游戏编程案例。
二、项目实现思路
-
棋盘设计
- 使用
struct Property
结构体数组来存储棋盘上的格子信息,包括土地的价格、归属权等。 - 每个格子可能是:
- 可购买的土地
- 已购买的土地(玩家经过时需交租金)
- 特殊事件(如“运气卡”)
- 使用
-
玩家系统
- 使用
struct Player
结构体存储玩家信息(如姓名、位置、资金)。 - 通过
rand()
生成骰子点数,决定玩家前进的步数。
- 使用
-
游戏循环
- 采用
while
循环控制游戏,玩家交替投掷骰子并执行行动:- 走到“未购土地”可选择购买。
- 走到“已购土地”需要支付租金。
- 走到“运气卡”可能会获得奖励或受到惩罚。
- 如果玩家资金降到 0 以下,则破产,游戏结束。
- 采用
三、完整代码(附详细注释)
/********************************************************************
* C 语言实现简化版大富翁游戏
*
* 主要功能:
* 1. 使用一维数组模拟棋盘(包含土地、特殊事件)。
* 2. 玩家通过随机投掷骰子在棋盘上移动。
* 3. 玩家可购买土地,或者支付租金。
* 4. 触发运气事件,可能奖励或扣除资金。
* 5. 玩家破产则游戏结束。
*
* 编译方法: gcc -o monopoly monopoly.c
* 运行方法: ./monopoly
********************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define BOARD_SIZE 20 // 棋盘格子数
#define START_MONEY 1000 // 玩家初始资金
#define PROPERTY_COST 200 // 每块土地价格
#define RENT_COST 100 // 租金费用
#define LUCKY_PRIZE 150 // 运气卡奖金
#define LUCKY_FINE 100 // 运气卡罚款
// 定义棋盘格子类型
typedef enum {
EMPTY, // 空地
PROPERTY, // 可购买土地
LUCKY // 运气卡事件
} SpaceType;
// 定义土地信息
typedef struct {
SpaceType type; // 格子类型
int owner; // 拥有者(-1 表示无人购买)
} Property;
// 定义玩家信息
typedef struct {
char name[20]; // 玩家名称
int position; // 当前位置
int money; // 当前资金
} Player;
// 函数声明
void initialize_board(Property board[]);
void print_board(Property board[], Player *p1, Player *p2);
void move_player(Player *player, Property board[]);
void process_space(Player *player, Player *opponent, Property board[]);
// 主函数
int main() {
srand(time(NULL)); // 初始化随机数种子
// 创建棋盘和玩家
Property board[BOARD_SIZE];
Player player1 = {"玩家1", 0, START_MONEY};
Player player2 = {"玩家2", 0, START_MONEY};
// 初始化棋盘
initialize_board(board);
printf("=== 欢迎来到简化版大富翁 ===\n");
// 交替进行回合
while (player1.money > 0 && player2.money > 0) {
print_board(board, &player1, &player2);
// 玩家1回合
printf("\n%s 的回合,按 Enter 投掷骰子...\n", player1.name);
getchar();
move_player(&player1, board);
process_space(&player1, &player2, board);
if (player1.money <= 0) break; // 破产检测
print_board(board, &player1, &player2);
// 玩家2回合
printf("\n%s 的回合,按 Enter 投掷骰子...\n", player2.name);
getchar();
move_player(&player2, board);
process_space(&player2, &player1, board);
}
// 结束游戏
printf("\n游戏结束!\n");
if (player1.money > 0)
printf("恭喜 %s 获胜!\n", player1.name);
else
printf("恭喜 %s 获胜!\n", player2.name);
return 0;
}
// 初始化棋盘
void initialize_board(Property board[]) {
for (int i = 0; i < BOARD_SIZE; i++) {
if (i % 5 == 0) {
board[i].type = LUCKY; // 设定运气卡
} else {
board[i].type = PROPERTY; // 设定土地
board[i].owner = -1; // -1 表示无人拥有
}
}
}
// 显示棋盘状态
void print_board(Property board[], Player *p1, Player *p2) {
printf("\n棋盘状态:\n");
for (int i = 0; i < BOARD_SIZE; i++) {
if (p1->position == i)
printf("P1 ");
else if (p2->position == i)
printf("P2 ");
else if (board[i].type == PROPERTY && board[i].owner != -1)
printf("🏠 ");
else if (board[i].type == LUCKY)
printf("🎲 ");
else
printf("__ ");
}
printf("\n%s 资金: %d | %s 资金: %d\n", p1->name, p1->money, p2->name, p2->money);
}
// 处理玩家移动
void move_player(Player *player, Property board[]) {
int roll = (rand() % 6) + 1; // 投掷 1-6 点骰子
player->position = (player->position + roll) % BOARD_SIZE;
printf("%s 掷出了 %d,移动到格子 %d\n", player->name, roll, player->position);
}
// 处理玩家到达的格子
void process_space(Player *player, Player *opponent, Property board[]) {
Property *space = &board[player->position];
if (space->type == PROPERTY) {
if (space->owner == -1) {
// 购买土地
if (player->money >= PROPERTY_COST) {
player->money -= PROPERTY_COST;
space->owner = (player == opponent) ? 1 : 0; // 记录玩家占有
printf("%s 购买了该土地!\n", player->name);
}
} else if (space->owner != (player == opponent ? 1 : 0)) {
// 支付租金
player->money -= RENT_COST;
opponent->money += RENT_COST;
printf("%s 支付租金 %d!\n", player->name, RENT_COST);
}
} else if (space->type == LUCKY) {
int lucky = (rand() % 2) ? LUCKY_PRIZE : -LUCKY_FINE;
player->money += lucky;
printf("%s 触发运气卡,%s%d!\n", player->name, lucky > 0 ? "获得" : "损失", abs(lucky));
}
}
四、代码解读(方法作用解析)
1. initialize_board()
— 初始化棋盘
该函数用于初始化棋盘,包括设定哪些格子是 土地(可购买),哪些是 运气卡。棋盘是一个长度为 BOARD_SIZE
的 Property
数组,默认所有土地无人购买,运气卡分布在棋盘上。
2. print_board()
— 显示当前棋盘状态
该函数用于在终端打印当前棋盘、玩家位置、以及玩家的资金情况。
🏠
表示已被购买的土地🎲
代表运气卡P1
和P2
分别代表两个玩家的位置
3. move_player()
— 处理玩家移动
该函数通过 rand()
生成 1-6 之间的随机数,模拟玩家投掷骰子的结果,并 更新玩家的位置。若超出棋盘边界,则使用取模运算 player->position = (player->position + roll) % BOARD_SIZE
使其从棋盘起点循环回到起始位置。
4. process_space()
— 处理玩家到达的格子
该函数负责解析玩家移动后所处格子的类型,并执行相应操作:
- 土地(PROPERTY)
- 若该土地无人购买,玩家可购买(需支付
PROPERTY_COST
)。 - 若土地已被对手拥有,则玩家需支付
RENT_COST
作为租金。
- 若该土地无人购买,玩家可购买(需支付
- 运气卡(LUCKY)
- 玩家可能获得
LUCKY_PRIZE
奖励(+150 金币)。 - 也可能支付
LUCKY_FINE
罚款(-100 金币)。
- 玩家可能获得
5. main()
— 游戏主循环
该函数是游戏的主入口:
- 初始化棋盘
- 游戏回合
- 轮流投掷骰子(调用
move_player()
)。 - 处理格子事件(调用
process_space()
)。 - 检查破产情况,若有玩家资金低于
0
,游戏结束。
- 轮流投掷骰子(调用
- 胜负判定,输出最终赢家。
五、项目总结
1. 项目特色
本项目是一个 简化版的大富翁游戏,具备:
- 完整的游戏逻辑(购买土地、支付租金、运气事件)。
- 基础 AI 对战模式(两个玩家轮流行动)。
- 随机事件(掷骰子 + 运气卡,使游戏更具可玩性)。
- 清晰的 C 语言实现(运用 结构体、数组、随机数、循环控制 等核心知识)。
2. 项目优化方向
该项目可以进一步优化,使其更接近真实的大富翁游戏:
- 增加更多玩家(支持 3 人或 4 人对战)。
- 实现交易系统(玩家可以卖出土地或抵押贷款)。
- 增强运气卡功能(例如“免费移动”、“跳过一轮”)。
- 增加 UI 界面(使用
ncurses
库优化终端显示)。 - 优化 AI 逻辑(智能判断购买土地或跳过)。
3. 个人收获
- 通过此项目,你可以熟练掌握 结构体操作、数组、随机数的使用。
- 通过 游戏逻辑设计,可以锻炼编程思维,提高 算法设计能力。
- 适合作为 C 语言入门游戏开发 的练习,为后续学习 GUI 开发、复杂 AI 设计打下基础。