C语言小游戏快速入门--三子棋-创新互联
- 一、前言
- 二、游戏界面
- 三、游戏逻辑
- 1.game.h
- 2.game.c
- 3.test.c
- 四、总结
二、游戏界面这是一个非常简单的三子棋小游戏,学过C语言数组语法的就可以写出来。在这里博主实现的是人机对战,当然你们也可以扩展一下人人对战。代码的逻辑是尽量弄得初学者都容易理解,并且减少了很多复杂的代码。比如,AI电脑选手需要分析棋局然后选择合适的下棋位置,但是给简略了。有失必有得,这里也新学到了生成随机数(
rand()
和rand((unsigned)time(NULL))
)这个新的语法点。注意:这里要调用这两个函数必须包含#include
和#include
这两个头文件。这在之后要做的猜数字游戏和其他游戏中会有很大的用处。话不多说,下来一睹风采吧!
在这里的游戏界面框架沿用的上一章中弹跳小球的游戏界面框架,并在此基础上改变了一点文字和颜色总体上是没有多大改变的。在这里就能知道,做一些简单的小游戏,知道一个小游戏如何从无到有是很重要的。框架也不需要刻意去背,只有理解了自己才能写出属于自己的框架。
void menu()//菜单
{system("color 71");//改变全局颜色
printf("|----------------------|\n");
printf("| 1.开始游戏 |\n");
printf("|----------------------|\n");
printf("| 2.游戏帮助 |\n");
printf("|----------------------|\n");
printf("| 3.更新日志 |\n");
printf("|----------------------|\n");
printf("| 0.退出游戏 |\n");
printf("|----------------------|\n");
printf("\n");
printf("(温馨提醒:请按照菜单相应的选项选择)");
printf("\n");
printf("请输入你的选择:>");
}
运行结果:
这里要详解一下
system("color 71")
这个函数。要调用这个函数的话就要包含#include
这个头文件。color
就是颜色的意思,但是后面的7
和1
又是什么呢?7是代表背景颜色,1是代表前景颜色。这个你也不需要特别去记忆。只需要win+R
打开windows系统的运行窗口,然后输入cmd
然后回车,就可实现用户和操作系统的直接交流。这里你也不需要懂操作系统是什么,直接输入color 空格+?
然后就可以自己选择你写的程序运行窗口的前景和背景色了。
第一步:
三、游戏逻辑 1.game.h第二步:
game.h头文件这里新增加的只有生成随机数需要的两个头文件,其他的东西跟弹跳小球的逻辑差不多。这里存放了一些函数的声明。
#include//C语言输入输出流
#include//windows API
#include//生成随机数头文件
#include//随机数种子头文件
#include//_getch()头文件
#define row 3//行
#define col 3//列
char is_win(char arr[row][col], int x, int y);//判断输赢
void conputer_move(char arr[row][col], int x, int y);//电脑走
void player_move(char arr[row][col], int x, int y);//玩家走
void init_chess(char arr[row][col], int x, int y);//初始化数组
void print_chess(char arr[row][col], int x, int y);//打印数组
void update();//更新日志
void game_help();//游戏帮助
void play_game();//开始玩游戏
void menu();//游戏界面
2.game.cgeme.c这个源文件之前在弹跳小球说过,这里主要是放一些函数的实现,也就是函数的定义。博主比较喜欢把函数的声明和定义分开写,这样比较简洁,也容易让别人易懂。这里是打算先解释重要的部分,然后在附上源码。
玩家下棋逻辑:
void player_move(char arr[row][col], int x, int y)
{int x1 = 0;
int y1 = 0;
printf("(玩家:@)\n");
printf("(电脑:#)\n");
printf("玩家走:>\n");
while (1)
{printf("请输入坐标:>");
scanf_s("%d%d",&x1,&y1);
if ((x1>=1&&x1<=row)&&(y1>=1 && y1<=col))
{ if (arr[x1-1][y1-1]==' ')
{ arr[x1-1][y1-1] = '@';
break;
}
else
{ printf("坐标已被占用,请重新输入\n");
}
}
else
{ printf("坐标非法,请重新输入\n");
}
}
}
电脑下棋逻辑:
void conputer_move(char arr[row][col], int x, int y)
{ while (1)
{int x2 = rand()%x;//0~2
int y2 = rand()%y;//0~2
if (arr[x2][y2] == ' ')
{ arr[x2][y2] = '#';
break;
}
}
}
注意:假如这里没有输赢的实现逻辑,电脑这里下棋实会发生死循环的。
打印棋盘:
void print_chess(char arr[row][col],int x,int y)//打印棋盘
{for (int i=0;iprintf("----|");
}
printf("\n");
for (int i=0;ifor (int j=0;j printf(" %c |",arr[i][j]);
}
printf("\n");
for (int j=0;j printf("----|");
}
printf("\n");
}
}
源码:
#include"game.h"
//'Q'代表游戏地图满了,也就是平局
//‘C’代表游戏地图没满
//‘@’代表玩家落子
//‘#’代表电脑落子
//2表示棋盘没满--游戏继续
//3表示棋盘满了--平局
static int find(char arr[row][col], int x, int y)
{for (int i=0;ifor (int j=0;j if (arr[i][j]==' ')
{ return 2;
}
}
}
return 3;
}
char is_win(char arr[row][col], int x, int y)
{for (int i=0;ifor (int j=0;j if ((arr[i][0]==arr[i][1])&&(arr[i][1]==arr[i][2])&&arr[i][0]!=' ')
{ return arr[i][0];
}
if ((arr[0][j] == arr[1][j]) && (arr[1][j] == arr[2][j]) && arr[0][j] != ' ')
{ return arr[0][j];
}
}
}
if ((arr[0][0] == arr[1][1]) && (arr[1][1] == arr[2][2]) && arr[0][0] != ' ')
{return arr[1][1];
}
if ((arr[2][0] == arr[1][1]) && (arr[1][1] == arr[0][2]) && arr[2][0] != ' ')
{return arr[2][0];
}
int n = find(arr, x, y);
if (3==n)
{return 'Q';
}
else
{return 'C';
}
}
void conputer_move(char arr[row][col], int x, int y)
{ while (1)
{int x2 = rand()%x;
int y2 = rand()%y;
if (arr[x2][y2] == ' ')
{ arr[x2][y2] = '#';
break;
}
}
}
void player_move(char arr[row][col], int x, int y)
{int x1 = 0;
int y1 = 0;
printf("(玩家:@)\n");
printf("(电脑:#)\n");
printf("玩家走:>\n");
while (1)
{printf("请输入坐标:>");
scanf_s("%d%d",&x1,&y1);
if ((x1>=1&&x1<=row)&&(y1>=1 && y1<=col))
{ if (arr[x1-1][y1-1]==' ')
{ arr[x1-1][y1-1] = '@';
break;
}
else
{ printf("坐标已被占用,请重新输入\n");
}
}
else
{ printf("坐标非法,请重新输入\n");
}
}
}
void init_chess(char arr[row][col], int x, int y)//初始化棋盘为空格
{for (int i=0;ifor (int j=0;j arr[i][j] = ' ';
}
}
}
void print_chess(char arr[row][col],int x,int y)//打印棋盘
{for (int i=0;iprintf("----|");
}
printf("\n");
for (int i=0;ifor (int j=0;j printf(" %c |",arr[i][j]);
}
printf("\n");
for (int j=0;j printf("----|");
}
printf("\n");
}
}
static void update_menu()//更新日志菜单
{printf("(暂无)\n");
printf("\n");
printf("\n");
printf("\n");
printf("(按1返回,按任意键退出)\n");
printf("请选择:>");
}
void update()//更新日志
{update_menu();
switch (_getch())
{case '1':
break;
default:
exit(0);
break;
}
}
static void game_help_menu()//游戏帮助菜单
{printf("\n");
printf("游戏操作:\n");
printf("\n");
printf("①:输入相应的坐标点进行下棋\n");
printf("\n");
printf(" 例如:2 3\n (中间空格or回车都行)\n");
printf("\n");
printf("!!!输入坐标后请按回车\n");
printf("\n");
printf(" (温馨提醒:请按标准格式输入)\n");
printf("\n");
printf("\n");
printf("\n");
printf("(按1返回,按任意键退出)\n");
printf("请选择:>");
}
void game_help()//游戏帮助
{game_help_menu();
switch (_getch())
{case '1':
break;
default:
exit(0);
break;
}
}
void play_game()//开始游戏
{char chessboard[row][col] = {0};
init_chess(chessboard, row, col);
print_chess(chessboard,row,col);
char n = '0';
while (1)
{player_move(chessboard, row, col);
system("cls");
print_chess(chessboard, row, col);
n=is_win(chessboard,row,col);
if (n!='C')
{ break;
}
conputer_move(chessboard,row,col);
system("cls");
print_chess(chessboard, row, col);
n = is_win(chessboard, row, col);
if (n!='C')
{ break;
}
}
if (n == '@')
{printf("游戏结束!!!");
MessageBox(NULL, "玩家赢", "提示", MB_OK);
}
else if (n=='#')
{printf("游戏结束!!!");
MessageBox(NULL, "电脑赢", "提示", MB_OK);
}
else if(n=='Q')
{printf("游戏结束!!!");
MessageBox(NULL, "平局", "提示", MB_OK);
}
}
void menu()//菜单
{system("color 71");
printf("|----------------------|\n");
printf("| 1.开始游戏 |\n");
printf("|----------------------|\n");
printf("| 2.游戏帮助 |\n");
printf("|----------------------|\n");
printf("| 3.更新日志 |\n");
printf("|----------------------|\n");
printf("| 0.退出游戏 |\n");
printf("|----------------------|\n");
printf("\n");
printf("(温馨提醒:请按照菜单相应的选项选择)");
printf("\n");
printf("请输入你的选择:>");
}
3.test.c这里放的是一些函数的调用,需要讲的就说随机数的种子放在了这里,因为我们就需要调用一次种子就可以了。主函数里一个
do-while
循环就可以实现函数借口调用。
#include"game.h"//在这里相当于包含了game.h里面的全部头文件
int main()
{srand((unsigned)time(NULL));//生成随机数的种子
system("mode con cols=32 lines=16");//控制窗口大小
SetConsoleTitle("简单三子棋游戏");
do
{system("cls");
menu();
switch (_getch())
{case '1':
system("cls");
play_game();//开始游戏
break;
case '2':
system("cls");
game_help();//游戏帮助
break;
case '3':
system("cls");
update();//更新日志
break;
case '0':
exit(0);//退出
break;
default:
//一个消息机制,用来实现用户输入其他然后提示
MessageBox(NULL, "输入有误,请重新输入", "提示", MB_OK);
break;
}
} while ('0');
return 0;
}
四、总结学会怎样在c或者其他任何程序语言中使用这些既有的功能也是学习编程的一门重头戏。
你是否还在寻找稳定的海外服务器提供商?创新互联www.cdcxhl.cn海外机房具备T级流量清洗系统配攻击溯源,准确流量调度确保服务器高可用性,企业级服务器适合批量采购,新人活动首月15元起,快前往官网查看详情吧
分享名称:C语言小游戏快速入门--三子棋-创新互联
浏览路径:http://myzitong.com/article/ceideo.html