当前位置: 首页 > backend >正文

C语言实现三子棋

目录

1.通过模块化来实现三子棋

2.三子棋代码基本逻辑

3.代码的书写

第一步:

第二步:

第三步:

第四步:

gane.h

gane.c

main.c

第五步:

game.h

game.c

main.c

第六步:

game.h

game.c

main.c

第七步:

game.h

game.c

main.c

第八步:

game.h

game.c

main.c

第九步:

game.c

4.最终代码的形式

game.h

game.c

main.c


1.通过模块化来实现三子棋

main.c --> 测试游戏的逻辑

game.c --> 游戏代码的实现

game.h --> 游戏代码的声明(函数声明,符号定义)

注意:我们先一个比较长的代码时,要写一点代码测试一点,这样才能避免bug的出现,不然到后面,就会懒得去改代码了。

2.三子棋代码基本逻辑

首先我们要有个游戏界面;然后要选择开始游戏和结束游戏;开始游戏前我们要打印一个棋盘,这个棋盘要怎么储存里面的数据呢?那就要用到我们的二维数组,想一想二维数组分布是不是很像一个棋盘;游戏开始后我们就要开始下棋了,玩家下棋,电脑下棋,有三种结局:玩家赢、电脑赢、平局(棋盘下满了)。都不是则游戏进行(未分出胜负,棋盘也未下满)。最后的结果,我们要打印,并且把最后的棋盘的落子情况也打印了。

3.代码的书写

第一步:

打印游戏界面,选择1游戏开始,选择0游戏结束

menu()
{printf("**************************\n");printf("**********1.play**********\n");printf("**********0.exit**********\n");printf("**************************\n");}int main()
{int input = 0;do{menu;//打印菜单printf("请选择:>");scanf("%d",&input);}while();return 0;
}

第二步:

第一步只是一次游戏,但我们要实现能多次进行游戏,所以要switch循环实现游戏界面的选择和多次游戏

int main()
{int input = 0;do{menu();//打印菜单printf("请选择:>");scanf("%d", &input);switch (input){case 1:game();break;case 0:printf("退出游戏\n");break;default:printf("选择错误!\n");break;}} while (input);return 0;
}

第三步:

开始写游戏函数(game),玩家下完棋后,电脑要下棋,就要存起来,才能下,下去,如果不知道上次下在哪,怎么下。想象一下,三子棋的棋盘是一个九宫格,棋子要落在上面,那么我们就要用3*3的一个二维数组存放

void game()
{char board[3][3] = { 0 };
}

第四步:

为了便于以后更改为五子棋,十子棋,我们要在头文件里面定义一个标识符常量。

gane.h

#pragma once#define ROW 3
#define COL 3

游戏开始之前棋盘要初始化,数组每个打印空格,制造一种没下棋的假象。

gane.c

#include "game.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] = ' ';}}
}

main.c

#include "game.h"
#include <stdio.h>void game()
{char ret = 0;char board[ROW][COL] = { 0 };//初始化棋盘的函数InitBoard(board, ROW, COL);
}

第五步:

打印棋盘,本质还是打印二维数组。我们把一个分割列和两列竖线看作一组数据,最后一组只要两行竖线,没有分割行。

这里来个小技巧,在game头文件放入printf的头文件,这样就引入game头文件就可以,把printf头文件一起引入了方便

game.h

#pragma once#include <stdio.h>#define ROW 3
#define COL 3//初始化棋盘
void InitBoard(char board[ROW][COL], int row, int col);//打印棋盘
void DispalyBoard(char board[ROW][COL], int row, int col);

game.c

//打印棋盘第一个版本
/*
void DispalyBoard(char board[ROW][COL], int row, int col)
{int i = 0;for (i = 0;i < row;i++){//打印数据printf(" %c | %c | %c \n", board[i][0], board[i][1], board[i][2]);//打印分割信息if (i < row - 1){printf("---|---|---\n");}}
}
*///打印棋盘的第二个版本
void DispalyBoard(char board[ROW][COL], int row, int col)
{int i = 0;for (i = 0;i < row;i++){//打印数据//printf(" %c | %c | %c \n", board[i][0], board[i][1], board[i][2]);int j = 0;for (j = 0;j < col;j++){printf(" %c ", board[i][j]);if (j < col - 1)printf("|");}printf("\n");//打印分割行信息//printf("---|---|---\n");if (i < row - 1){int j = 0;for (j = 0;j < col;j++){printf("---");if (j < col - 1)printf("|");}printf("\n");}}
}

main.c

void game()
{char ret = 0;char board[ROW][COL] = { 0 };//初始化棋盘的函数InitBoard(board, ROW, COL);//打印棋盘DispalyBoard(board, ROW, COL);
}

第六步:

开始下棋,玩家下棋

game.h

#pragma once#include <stdio.h>#define ROW 3
#define COL 3//初始化棋盘
void InitBoard(char board[ROW][COL], int row, int col);//打印棋盘
void DispalyBoard(char board[ROW][COL], int row, int col);//玩家下棋
void PlayerMove(char board[ROW][COL], int row, int col);

game.c

#include "game.h"//玩家下棋
void PlayerMove(char board[ROW][COL], int row, int col)
{int x = 0;int y = 0;printf("玩家下棋:>\n");while (1){printf("请输入坐标:>");scanf("%d %d", &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("坐标非法,请重新输入\n");}}
}

main.c

void game()
{char ret = 0;char board[ROW][COL] = { 0 };//初始化棋盘的函数InitBoard(board, ROW, COL);//打印棋盘DispalyBoard(board, ROW, COL);//开始下棋while (1){PlayerMove(board, ROW, COL);DispalyBoard(board, ROW, COL);}
}

第七步:

电脑下棋,找没有下棋的空白区域,也就是数组为空格的元素,随机下棋,要用到rand()函数,srand()函数,time()函数。

game.h

#pragma once#include <stdio.h>
#include <stdlib.h>
#include <time.h>#define ROW 3
#define COL 3//初始化棋盘
void InitBoard(char board[ROW][COL], int row, int col);//打印棋盘
void DispalyBoard(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);

game.c

//电脑下棋
void ComputerMove(char board[ROW][COL], int row, int col)
{printf("电脑下棋:>\n");int x = 0;int y = 0;while (1){x = rand() % row;//0~2y = rand() % col;//0~2if (board[x][y] == ' '){board[x][y] = '#';break;}}}

main.c

void game()
{char ret = 0;char board[ROW][COL] = { 0 };//初始化棋盘的函数InitBoard(board, ROW, COL);//打印棋盘DispalyBoard(board, ROW, COL);//开始下棋while (1){//玩家下棋PlayerMove(board, ROW, COL);DispalyBoard(board, ROW, COL);//电脑下棋ComputerMove(board, ROW, COL);DispalyBoard(board, ROW, COL);}
}int main()
{srand((unsigned int)time(NULL));//设置随机数的生成起点的int input = 0;do{menu();//打印菜单printf("请选择:>");scanf("%d", &input);switch (input){case 1:game();break;case 0:printf("退出游戏\n");break;default:printf("选择错误!\n");break;}} while (input);return 0;
}

第八步:

判断输赢,玩家赢 - '*'、电脑赢 - '#'、平局 - 'Q',这三种种情况游戏退出,游戏继续 - 'C'。判断二维数组,行、列、对角线是否三个元素相等,换句话说就是判断他们是不是行、列、对角线,两两元素是否相等,并且不能等于空格,然后,返回值为三个元素中的一个(这样可以省去很多代码,想想是不是这个道理)。

game.h

//判断输赢
//玩家赢 - '*'
//电脑赢 - '#'
//平局 - 'Q'
//游戏继续 - 'C'
char IsWin(char board[ROW][COL], int row, int col);

game.c

//判断输赢,判断二维数组,行、列、对角线是否三个元素相等
char IsWin(char board[ROW][COL], int row, int col)
{//行int i = 0;for (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];}}//列int j = 0;for (j = 0;j < col;j++){if (board[0][j] == board[1][j] && board[1][j] == board[2][j] && board[1][j] != ' '){return board[1][j];}}//对角线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];}
}

main.c

void game()
{char ret = 0;char board[ROW][COL] = { 0 };//初始化棋盘的函数InitBoard(board, ROW, COL);//打印棋盘DispalyBoard(board, ROW, COL);//开始下棋while (1){PlayerMove(board, ROW, COL);//判断输赢ret = IsWin(board, ROW, COL);if (ret != 'C'){break;}DispalyBoard(board, ROW, COL);ComputerMove(board, ROW, COL);//判断输赢ret = IsWin(board, ROW, COL);if (ret != 'C'){break;}DispalyBoard(board, ROW, COL);}if (ret == '*'){printf("玩家赢\n");}else if (ret == '#'){printf("电脑赢\n");}else{printf("平局\n");}DispalyBoard(board, ROW, COL);
}

第九步:

平局,IsWin函数里面写一个平局函数,判断棋盘是不是满的,平局函数,如果满了返回1,不满返回0。如果,电脑没赢,玩家没赢,也没平局就继续游戏。

game.c

//平局函数,如果满了返回1,不满返回0
int IsFull(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++){if (board[i][j] == ' '){return 0;}}}return 1;
}
//判断输赢,判断二维数组,行、列、对角线是否三个元素相等
char IsWin(char board[ROW][COL], int row, int col)
{//行int i = 0;for (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];}}//列int j = 0;for (j = 0;j < col;j++){if (board[0][j] == board[1][j] && board[1][j] == board[2][j] && board[1][j] != ' '){return board[1][j];}}//对角线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 (IsFull(board, row, col)){return 'Q';}//游戏继续return 'C';
}

4.最终代码的形式

game.h

#pragma once#include <stdio.h>
#include <stdlib.h>
#include <time.h>#define ROW 3
#define COL 3//初始化棋盘
void InitBoard(char board[ROW][COL], int row, int col);//打印棋盘
void DispalyBoard(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);

game.c

#include "game.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 DispalyBoard(char board[ROW][COL], int row, int col)
{int i = 0;for (i = 0;i < row;i++){//打印数据printf(" %c | %c | %c \n", board[i][0], board[i][1], board[i][2]);//打印分割信息if (i < row - 1){printf("---|---|---\n");}}
}
*///打印棋盘的第二个版本
void DispalyBoard(char board[ROW][COL], int row, int col)
{int i = 0;for (i = 0;i < row;i++){//打印数据//printf(" %c | %c | %c \n", board[i][0], board[i][1], board[i][2]);int j = 0;for (j = 0;j < col;j++){printf(" %c ", board[i][j]);if (j < col - 1)printf("|");}printf("\n");//打印分割行信息//printf("---|---|---\n");if (i < row - 1){int j = 0;for (j = 0;j < col;j++){printf("---");if (j < col - 1)printf("|");}printf("\n");}}
}//玩家下棋
void PlayerMove(char board[ROW][COL], int row, int col)
{int x = 0;int y = 0;printf("玩家下棋:>\n");while (1){printf("请输入坐标:>");scanf("%d %d", &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("坐标非法,请重新输入\n");}}
}//电脑下棋
void ComputerMove(char board[ROW][COL], int row, int col)
{printf("电脑下棋:>\n");int x = 0;int y = 0;while (1){x = rand() % row;//0~2y = rand() % col;//0~2if (board[x][y] == ' '){board[x][y] = '#';break;}}}//平局函数,如果满了返回1,不满返回0
int IsFull(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++){if (board[i][j] == ' '){return 0;}}}return 1;
}
//判断输赢,判断二维数组,行、列、对角线是否三个元素相等
char IsWin(char board[ROW][COL], int row, int col)
{//行int i = 0;for (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];}}//列int j = 0;for (j = 0;j < col;j++){if (board[0][j] == board[1][j] && board[1][j] == board[2][j] && board[1][j] != ' '){return board[1][j];}}//对角线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 (IsFull(board, row, col)){return 'Q';}//游戏继续return 'C';
}

main.c

#include "game.h"menu()
{printf("**************************\n");printf("**********1.play**********\n");printf("**********0.exit**********\n");printf("**************************\n");}void game()
{char ret = 0;char board[ROW][COL] = { 0 };//初始化棋盘的函数InitBoard(board, ROW, COL);//打印棋盘DispalyBoard(board, ROW, COL);//开始下棋while (1){PlayerMove(board, ROW, COL);//判断输赢ret = IsWin(board, ROW, COL);if (ret != 'C'){break;}DispalyBoard(board, ROW, COL);ComputerMove(board, ROW, COL);//判断输赢ret = IsWin(board, ROW, COL);if (ret != 'C'){break;}DispalyBoard(board, ROW, COL);}if (ret == '*'){printf("玩家赢\n");}else if (ret == '#'){printf("电脑赢\n");}else{printf("平局\n");}DispalyBoard(board, ROW, COL);
}int main()
{srand((unsigned int)time(NULL));//设置随机数的生成起点的int input = 0;do{menu();//打印菜单printf("请选择:>");scanf("%d", &input);switch (input){case 1:game();break;case 0:printf("退出游戏\n");break;default:printf("选择错误!\n");break;}} while (input);return 0;
}
http://www.xdnf.cn/news/5107.html

相关文章:

  • java volatile关键字
  • LINUX CFS算法解析
  • YOLO目标检测算法
  • 麦角硫因:全能型护肤成分的技术突破与应用前景
  • 数据链路层服务
  • 基础RNN网络详解
  • 餐饮行业新风口:上门厨师服务系统的技术实现路径
  • 机器视觉的平板电脑屏幕组件覆膜应用
  • canoe的安装总结
  • requests库
  • 【笔记】BCEWithLogitsLoss
  • [Windows] 摄像头分身工具【CamSplitter】
  • upload文件上传
  • ES6新增Set、Map两种数据结构、WeakMap、WeakSet举例说明详细。(含DeepSeek讲解)
  • 【PINN】DeepXDE学习训练营(18)——operator-diff_rec_unaligned_pideeponet.py
  • 安全核查基线-1.LPD服务
  • 【软件设计师:体系结构】15.计算机体系结构概论
  • 将/root下的employee.json挪到/home/Downloads/
  • 让模型具备“道生一,一生二,二生三,三生万物”的现实实用主义能力
  • Stagehand:AI驱动的下一代浏览器自动化框架
  • 历史温度曲线能优化样本存储的条件还是确保样本处于稳定状态呢?
  • Linux系统入门第十一章 --Shell编程之函数与数组
  • CreArt 2.5.6 |无限AI图片生成工具,将文字描述转化为独特艺术作品,解锁高级版
  • FastChat部署大模型
  • 从量子计算到人工智能代理
  • PPT插入图像自带透明
  • 分布式处理架构
  • android动态调试
  • Android对工程中的String中文字符的整理
  • 多序列比对软件 Clustal Omega 介绍