C语言小游戏实例 C语言
以下设计了三个难度递进的C语言命令行小游戏,分别涵盖基本语法、数组与逻辑、数据结构与状态管理,适合大学教学使用。
游戏一:猜数字(难度:★☆☆☆☆)
教学要点:随机数生成、循环、条件判断、基本输入输出
玩法:系统随机生成1-100数字,玩家输入猜测,提示“太大/太小”,直到猜中并显示猜测次数。
// guess_number.c
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main() {
int target, guess, attempts = 0;
srand(time(NULL));
target = rand() % 100 + 1; // 1~100随机数
printf("=== 猜数字游戏 ===\n");
printf("我已想好一个1~100之间的整数,请猜:\n");
do {
printf("输入你的猜测: ");
scanf("%d", &guess);
attempts++;
if (guess > target)
printf("太大了!\n");
else if (guess < target)
printf("太小了!\n");
else
printf("恭喜!猜中了,共用了 %d 次猜测。\n", attempts);
} while (guess != target);
return 0;
}
游戏二:井字棋(人机随机)(难度:★★☆☆☆)
教学要点:二维数组、函数封装、随机AI、胜负判定
玩法:玩家执X,电脑执O,轮流下子,先连成一行/列/对角线者胜。
// tic_tac_toe.c
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <ctype.h>
char board[3][3];
// 初始化棋盘
void initBoard() {
for (int i = 0; i < 3; i++)
for (int j = 0; j < 3; j++)
board[i][j] = ' ';
}
// 显示棋盘
void printBoard() {
printf("\n 1 2 3\n");
for (int i = 0; i < 3; i++) {
printf("%d", i+1);
for (int j = 0; j < 3; j++) {
printf(" %c ", board[i][j]);
if (j < 2) printf("|");
}
printf("\n");
if (i < 2) printf(" -----------\n");
}
printf("\n");
}
// 检查是否胜利
int checkWin(char player) {
// 行、列、对角线检查
for (int i = 0; i < 3; i++) {
if (board[i][0] == player && board[i][1] == player && board[i][2] == player) return 1;
if (board[0][i] == player && board[1][i] == player && board[2][i] == player) return 1;
}
if (board[0][0] == player && board[1][1] == player && board[2][2] == player) return 1;
if (board[0][2] == player && board[1][1] == player && board[2][0] == player) return 1;
return 0;
}
// 检查平局
int isDraw() {
for (int i = 0; i < 3; i++)
for (int j = 0; j < 3; j++)
if (board[i][j] == ' ') return 0;
return 1;
}
// 玩家移动
void playerMove() {
int row, col;
while (1) {
printf("你的回合 (行 列,如 1 2): ");
scanf("%d %d", &row, &col);
row--; col--;
if (row >= 0 && row < 3 && col >= 0 && col < 3 && board[row][col] == ' ') {
board[row][col] = 'X';
break;
}
printf("无效位置,重新输入!\n");
}
}
// 电脑随机移动
void computerMove() {
int row, col;
printf("电脑思考中...\n");
while (1) {
row = rand() % 3;
col = rand() % 3;
if (board[row][col] == ' ') {
board[row][col] = 'O';
break;
}
}
}
int main() {
srand(time(NULL));
initBoard();
printBoard();
while (1) {
playerMove();
printBoard();
if (checkWin('X')) { printf("你赢了!\n"); break; }
if (isDraw()) { printf("平局!\n"); break; }
computerMove();
printBoard();
if (checkWin('O')) { printf("电脑赢了!\n"); break; }
if (isDraw()) { printf("平局!\n"); break; }
}
return 0;
}
游戏三:推箱子(单关卡)(难度:★★★☆☆)
教学要点:复杂状态管理、结构体、模块化设计、键盘输入处理
玩法:WASD移动,将两个箱子推到目标点(显示为★)。胜利后自动退出。
// sokoban.c
#include <stdio.h>
#include <stdlib.h>
#include <conio.h> // Windows下用_getch(),Linux可替换为curses或termios
#include <stdbool.h>
#define WIDTH 8
#define HEIGHT 7
// 静态层:0空地 1墙 2目标点
int staticMap[HEIGHT][WIDTH] = {
{1,1,1,1,1,1,1,1},
{1,2,0,0,0,0,0,1},
{1,0,1,0,1,0,0,1},
{1,0,0,3,0,0,0,1}, // 注意3和4是动态数据,这里初始用箱子/玩家标记,实际动态独立存储
{1,0,0,0,4,0,0,1},
{1,0,0,0,0,0,0,1},
{1,1,1,1,1,1,1,1}
};
// 动态数据
int playerX, playerY;
bool boxMap[HEIGHT][WIDTH]; // 箱子位置
int targetCount = 0; // 目标点总数
// 保存初始状态
int initPlayerX, initPlayerY;
bool initBoxMap[HEIGHT][WIDTH];
// 初始化:从静态地图中提取玩家、箱子、目标点
void initGame() {
targetCount = 0;
for (int i = 0; i < HEIGHT; i++) {
for (int j = 0; j < WIDTH; j++) {
if (staticMap[i][j] == 2) targetCount++;
if (staticMap[i][j] == 3) { // 临时表示箱子
boxMap[i][j] = true;
staticMap[i][j] = 0; // 还原为空地
} else if (staticMap[i][j] == 4) { // 临时表示玩家
playerX = i; playerY = j;
staticMap[i][j] = 0;
} else {
boxMap[i][j] = false;
}
}
}
// 保存初始状态
initPlayerX = playerX;
initPlayerY = playerY;
for (int i = 0; i < HEIGHT; i++)
for (int j = 0; j < WIDTH; j++)
initBoxMap[i][j] = boxMap[i][j];
}
// 重置游戏
void resetGame() {
playerX = initPlayerX;
playerY = initPlayerY;
for (int i = 0; i < HEIGHT; i++)
for (int j = 0; j < WIDTH; j++)
boxMap[i][j] = initBoxMap[i][j];
}
// 显示地图
void drawMap() {
system("cls"); // 清屏,Windows使用,Linux可改为system("clear")
for (int i = 0; i < HEIGHT; i++) {
for (int j = 0; j < WIDTH; j++) {
if (i == playerX && j == playerY) {
// 玩家站在目标点上显示特殊符号
if (staticMap[i][j] == 2) printf("♀ ");
else printf("♂ ");
}
else if (boxMap[i][j]) {
// 箱子在目标点上显示为★
if (staticMap[i][j] == 2) printf("★ ");
else printf("■ ");
}
else {
if (staticMap[i][j] == 1) printf("█ ");
else if (staticMap[i][j] == 2) printf("☆ ");
else printf(" ");
}
}
printf("\n");
}
printf("\nWASD移动,R重置,Q退出\n");
}
// 检查胜利(所有箱子是否都在目标点上)
bool checkWin() {
for (int i = 0; i < HEIGHT; i++) {
for (int j = 0; j < WIDTH; j++) {
if (boxMap[i][j] && staticMap[i][j] != 2) return false;
}
}
return true;
}
// 尝试移动
bool move(int dx, int dy) {
int newX = playerX + dx;
int newY = playerY + dy;
// 边界或墙壁
if (newX < 0 || newX >= HEIGHT || newY < 0 || newY >= WIDTH) return false;
if (staticMap[newX][newY] == 1) return false;
// 前方有箱子
if (boxMap[newX][newY]) {
int pushX = newX + dx;
int pushY = newY + dy;
if (pushX < 0 || pushX >= HEIGHT || pushY < 0 || pushY >= WIDTH) return false;
if (staticMap[pushX][pushY] == 1) return false;
if (boxMap[pushX][pushY]) return false; // 箱子前还有箱子
// 推动箱子
boxMap[pushX][pushY] = true;
boxMap[newX][newY] = false;
playerX = newX;
playerY = newY;
return true;
}
// 空地或目标点
else {
playerX = newX;
playerY = newY;
return true;
}
}
int main() {
initGame();
char ch;
while (1) {
drawMap();
if (checkWin()) {
printf("恭喜过关!按任意键退出...\n");
getch();
break;
}
ch = getch();
switch (ch) {
case 'w': case 'W': move(-1, 0); break;
case 's': case 'S': move(1, 0); break;
case 'a': case 'A': move(0, -1); break;
case 'd': case 'D': move(0, 1); break;
case 'r': case 'R': resetGame(); break;
case 'q': case 'Q': return 0;
}
}
return 0;
}
编译与运行说明
猜数字 / 井字棋:直接使用任意C编译器(gcc、clang、MSVC)编译运行,无需额外依赖。
推箱子:
Windows:使用gcc sokoban.c -o sokoban.exe,依赖<conio.h>。
Linux/macOS:需替换_getch()为getchar()或使用curses库。教学环境中可统一使用Windows或安装conio.h模拟库。
教学建议
猜数字:让学生理解循环和随机数,可扩展为计分、难度选择。
井字棋:讲解二维数组遍历、函数模块化,可让学生尝试实现“智能AI”(如优先防守)。
推箱子:演示复杂状态管理、重置功能、胜利检测,适合作为课程大作业基础。
这三个游戏逐步增加数据结构复杂度,便于学生循序渐进掌握C语言核心编程能力
评论 (0)
登录后可以发表评论
立即登录还没有评论,快来发表第一条评论吧!