马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
x
本帖最后由 超过光速c 于 2021-8-25 18:47 编辑
三子棋游戏!!
三个文件,先直接贴上来。
test_.c 文件的内容/**
* @file test_.c
* @date 2021-08-24
*
* 三子棋
*
*/
#include "game_3.h"
#include "game_3.c"
void menu(){
printf("****************************************************************\n");
printf("**************** 1.Play 0.exit ******************\n");
printf("****************************************************************\n");
}
// 游戏的整个算法实现
void game_3(){
char ret;
// 数组-存放走出的棋盘信息
char board[ROW][COL] = {0}; // 全部空格,初始化一下棋盘,即初始化数组
// 初始化棋盘
InitBoard(board, ROW, COL);
// 打印棋盘
DisplayBoard(board, ROW, COL);
//下棋
while(1){
// 玩家下棋
PlayerMove(board, ROW, COL);
DisplayBoard(board, ROW, COL);
// 判断玩家是否赢
ret = IsWin(board, ROW, COL);
if(ret != 'C') {
break;
}
// 电脑下棋
ComputerMove(board, ROW, COL);
DisplayBoard(board, ROW, COL);
// 判断电脑是否赢
ret = IsWin(board, ROW, COL);
if(ret != 'C') {
break;
}
}
if (ret == '*')
{
printf("玩家赢了\n");
}
else if (ret == '#')
{
printf("电脑赢了\n");
}
else
{
printf("平局!\n");
}
}
void test_(){
int input=0;
// 随机存储生成器
srand((unsigned int)time(NULL));
do{
menu();
printf("请选择 : >> ");
scanf("%d",&input);
switch(input){
case 1:
game_3();
// printf("开始游戏!\n");
break;
case 0:
printf("退出游戏!\n");
break;
default:
printf("输入错误,请重新输入:");
break;
}
}while(input);
}
int main(){
test_();
printf("\n");
return 0;
}
game_3.c 文件内容#include "game_3.h"
// 实现初始化
void InitBoard(char board[ROW][COL], int row, int col){
int i=0;
int j=0;
for(i=0;i<row;i++){
for(j=0;j<col;j++){
board[i][j] = ' ';
}
}
}
// 实现打印棋盘
void DisplayBoard(char board[ROW][COL], int row, int col){
int i = 0;
int j = 0;
for(i=0;i<row;i++){
// 1.打印第一行数据
for(j=0;j<col;j++){
printf(" %c ",board[i][j]);
if(j < col-1) printf("|");
}
printf("\n");
// printf(" %c | %c | %c \n",board[i][0], board[i][1], board[i][2]);
// 2.打印分割行
if(i < row-1){
for(j=0;j<col;j++){
printf("---");
if(j < col-1) printf("|");
}
printf("\n");
}
// printf("---|---|---\n");
}
}
// 实现玩家下棋
void PlayerMove(char board[ROW][COL], int row, int col){
int x=0, y=0;
printf("玩家走:> \n");
while(1){
printf("请输入要下的坐标:>");
scanf("%d%d",&x,&y);
getchar();
// 判断x和y输入的合法性
if(x>=1 && x<=ROW && y>=1 && y<=COL){
if(board[x-1][y-1] == ' '){
board[x-1][y-1] = '*';
break;
}
else{
printf("坐标被占用\n");
}
}
else
{
printf("坐标非法,请重新输入!");
}
}
}
// 实现电脑下棋
void ComputerMove(char board[ROW][COL], int row, int col){
int x=0;
int y=0;
printf("电脑走!\n");
while(1){
x = rand() % row;
y = rand() % col;
if(board[x][y] == ' '){
board[x][y] = '#';
break;
}
}
}
// 满了返回1,没满返回0
int IsFull(char board[ROW][COL], int row, int col)
{
for(int j=0;j<row;j++)
{
for(int i=0;i<col;i++)
{
if(board[i][j] == ' ')
{
return 0; // 没满
}
}
}
return 1; // 满了
}
// 实现判断输赢
char IsWin(char board[ROW][COL], int row, int col){
// 判断行
for(int i = 0; i < row; i++){
if(board[i][0] == board[i][1] && board[i][1] == board[i][2] && board[i][1] != ' ')
{
return board[i][1];
}
}
// 判断列
for(int i = 0; i < col; i++){
if(board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[1][i] != ' ')
{
return board[1][i];
}
}
// 判断交叉
if(board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[1][1] != ' ')
{
return board[1][1];
}
if(board[0][2] == board[1][1] && board[1][1] == board[2][0] && board[1][1] != ' ')
{
return board[1][1];
}
// 判断平局
if(1 == IsFull(board, ROW, COL))
{
return 'Q';
}
return 'C';
}
game_3.h 文件内容#define ROW 3
#define COL 3
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
// #include "game_3.c"
// 声明
void InitBoard(char board[ROW][COL], int row, int col);
void DisplayBoard(char board[ROW][COL], int row, int col);
void PlayerMove(char board[ROW][COL], int row, int col);
void ComputerMove(char board[ROW][COL], int row, int col);
// 告诉我门四种游戏状态,玩家赢 * 、电脑赢 #、平局 Q、继续 C
char IsWin(char board[ROW][COL], int row, int col);
/**
* 整体逻辑回顾
*
* 1、游戏便于循环玩,所以将所有操作包含在一个 do while 循环内
* -- 先打印选择目录,用户选择输入 1开始游戏,0退出游戏(退出循环)
* -- 对输入有一个检验,若输入错误则提示用户重新输入
* 2、游戏的操作
* -- 用一个二维数组来存储棋盘
* -- 初始化棋盘,再将棋盘打印出来。利用for循环将棋盘拆分成每一个单独的元素进行遍历打印,更加的灵活
* -- 用户下棋:提示用户输入坐标,检验输入的坐标有效性,1、是否输入错误数值;2、输入坐标是否被占用。将坐标数组添加*号
* -- 电脑下棋:使用随机数值,检验坐标是否被占用。将坐标数组添加#号 随机存储生成器不理解?
* -- 每次走一步后将棋盘打印输出,观察走棋后的结果
* 3、判断输赢
* -- 横、纵、交叉的坐标数组内相等,且任意一个坐标不等于‘ ’值(棋盘初始化为' '空值),就返回此前坐标数组内的符号,返回*则玩家赢,返回#则电脑赢
* -- 检验棋盘空格数。循环遍历检验每一个坐标数组,若满则返回为平局,若未满则继续游戏
*
*
* 学得:
* C语言,随机存储生成器,随机数的使用
* rand() 函数包含于 <stdlib.h> 头文件中【random() 函数不是一个标准函数,无法再VC/VS等编译器通过。】
* rand() 会随机产生一个位于 0~RAND_MAX(至少是32767)之间的整数
* 伪随机数,根据电脑启动时而定,则不再变化。随机存储生成器:srand((unsigned)time(NULL)),根据时间进行随机产生新的数值
* 随机数的范围设定:
* rand() % 10 即 0~9
* rand() % 51 + 13 即 13~63。rand()%51 即0~50,+13则是 0+13~50+13 即 13~63
*
* 连续随机数的产生
* 用for循环产生的都是一样的随机数
* for(int i=0; i<10; i++)
* {
* srand((unsigned)time(NULL));
* a[i] = rand() % 100;
* printf("%d", a[i]);
* }
*
*
* 关于头文件 #include "" 和 <> 的区别用法,调取其他文件的函数
* <> : 到库里面寻找头文件
* "" : 优先到当前目录下寻找,找不到再到库里面取找。尽量优先使用,减少寻找所占用的资源。
*/
效果是这样的:
|