目录
前言:
是之前写了一次没有写出来,然后最近又想看看能不能写出来。
一,初始化数据
数据是采用字符数组来存储,这个不初始化的话,在打印棋盘的时候,对不齐,所以我还是在里面初始化为空格。
//下棋数据
char data[3][3];
//初始化数据
void initData(){
for(int i=0;i<3;i++){
for(int j=0;j<3;j++){
data[i][j]=' ';
}
}
}
二,打印棋盘
就是按格式进行打印,用循环来实现即可。打印落子的棋盘。
//打印棋盘
void initPrint(){
//打印棋盘
int i,j;
for(i=0;i<3;i++){
for(j=0;j<3;j++){
printf(" %c ",data[i][j]);
if(j<2){
printf("|");
}
}
printf("\n");//换行
if(i<2){
printf("___|___|___");
}
printf("\n");
}
}
三,玩家落子
玩家下棋我是用’*‘字符来表示,坐标是1~3,越界会报错,并要求重新输入,落子坐标已经有棋子也会报错,这就要用到循环来实现,知道满足要求了再把’*‘赋值给落子的位置的数组中。
//玩家下棋
void manpower(){
int x,y;
while(true){
printf("请输入落子坐标 x,y :");
scanf("%d,%d",&x,&y);
//玩家落子需要判断输入是否越界以及位置上是否以及有棋子
if(x>=1&&x<=3 && y>=1&&y<=3){
if(data[x-1][y-1]==' '){
break;
}else{
printf("该位置已经有棋子覆盖了,请重新输入\n");
}
}else{
printf("落子坐标越界,请重新输入\n");
}
}
data[x-1][y-1]='*';
}
四,机器落子
目前还不会智能的那种算法,机器落子是采用随机的方式进行,确定范围之后就不用考虑越界,然后就是找有效的位置,位置上有棋子也不需要输出提示,因为是机器在下,然后找到有效位置之后用’@‘字符来标记。
#include<time.h>
#include<stdlib.h>
//机器下棋
void machine(){
int x=0;
int y=0;
srand((unsigned)time(NULL));
do{
x=rand()%3;
y=rand()%3;
}while(data[x][y]!=' ');
data[x][y]='@';
}
五,结果判断
我是用一个全局变量来标记是谁赢了,先判断游戏是不是在棋盘还有位置的时候提前结束,就是三行三列和两对角线上是不是有连续的三个相同的字符,有就表示游戏结束了,说明玩家和机器有一方胜利了,再者就是判断棋盘上都没有位置的话就是平局,游戏也就结束了。
//游戏结果(win,lose,dogfall)
char flag='w';
bool judge(){
int i,j;
//行列的判断
for(i=0;i<3;i++){
//玩家胜利
if(data[i][0]==data[i][1] && data[i][1]==data[i][2] && data[i][0]=='*'){
flag='w';
return true;
}
if(data[0][i]==data[1][i] && data[1][i]==data[2][i] && data[0][i]=='*'){
flag='w';
return true;
}
//机器胜利
if(data[i][0]==data[i][1] && data[i][1]==data[i][2] && data[i][0]=='@'){
flag='l';
return true;
}
if(data[0][i]==data[1][i] && data[1][i]==data[2][i] && data[0][i]=='@'){
flag='l';
return true;
}
}
//这个放到循环里面应该是弄不了的
//对角线的判断
//玩家胜利
if(data[0][0]==data[1][1] && data[1][1]==data[2][2] && data[0][0]=='*'){
flag='w';
return true;
}
if(data[0][2]==data[1][1] && data[1][1]==data[2][0] && data[0][2]=='*'){
flag='w';
return true;
}
//机器胜利
if(data[0][0]==data[1][1] && data[1][1]==data[2][2] && data[0][0]=='@'){
flag='l';
return true;
}
if(data[0][2]==data[1][1] && data[1][1]==data[2][0] && data[0][2]=='@'){
flag='w';
return true;
}
//所以胜利的都判断之后再来判断是不是平局,可能就是提前结束
for(i=0;i<3;i++){
for(j=0;j<3;j++){
if(data[i][j]==' '){//还有位置没满
return false;
}
}
}
flag='d';
return true;
}
六,游戏开始
前面都属于前期的准备,然后就是游戏的开始,玩家和机器依次落子,下完棋之后还需要打印一下棋盘,给玩家知道哪些地方可以落子,直到游戏判定结束,输出对应的提示语,需要注意在玩家下完棋之后还需要进行一次游戏是否结束的判断。
//开始游戏
void startGame(){
while(!judge()){
manpower();
initPrint();
//这个机器下还有判断一下,可能就一直卡bug
//当棋盘慢的时候是到机器下,但是没有位置可以落子,就会一直卡着
if(!judge()){
machine();
initPrint();
}
}
switch(flag){
case 'w':
printf("恭喜玩家获胜\n");
break;
case 'l':
printf("机器获胜\n");
break;
case 'd':
printf("平局哦\n");
}
}
七,主函数
int main(){
initData();//初始化数据
initPrint();//打印棋盘
startGame();//游戏开始
return 0;
}
八,全部代码
//头文件
#include<stdio.h>
//#include<windows.h> 这个就不刷新了吧
#include<time.h>
#include<stdlib.h>
//函数声明
void initPrint();//打印棋盘
void initData();//初始化数据(还是要初始化的,不然打印的棋盘对不齐)
void startGame();//开始游戏
void machine();//机器下棋(随机落子)
void manpower();//玩家下棋(用户输入坐标)
bool judge();//判断游戏是否结束
//下棋数据
char data[3][3];
//游戏结果(win,lose,dogfall)
char flag='w';
int main(){
initData();//初始化数据
initPrint();//打印棋盘
startGame();//游戏开始
return 0;
}
//初始化数据
void initData(){
for(int i=0;i<3;i++){
for(int j=0;j<3;j++){
data[i][j]=' ';
}
}
}
//打印棋盘
void initPrint(){
//刷新棋盘
//system("cls");
//打印棋盘
int i,j;
for(i=0;i<3;i++){
for(j=0;j<3;j++){
printf(" %c ",data[i][j]);
if(j<2){
printf("|");
}
}
printf("\n");//换行
if(i<2){
printf("___|___|___");
}
printf("\n");
}
}
//开始游戏
void startGame(){
while(!judge()){
manpower();
initPrint();
//这个机器下还有判断一下,可能就一直卡bug
//当棋盘慢的时候是到机器下,但是没有位置可以落子,就会一直卡着
if(!judge()){
machine();
initPrint();
}
}
switch(flag){
case 'w':
printf("恭喜玩家获胜\n");
break;
case 'l':
printf("机器获胜\n");
break;
case 'd':
printf("平局哦\n");
}
}
//机器下棋
void machine(){
int x=0;
int y=0;
srand((unsigned)time(NULL));
do{
x=rand()%3;
y=rand()%3;
}while(data[x][y]!=' ');
data[x][y]='@';
}
//玩家下棋
void manpower(){
int x,y;
while(true){
printf("请输入落子坐标 x,y :");
scanf("%d,%d",&x,&y);
//玩家落子需要判断输入是否越界以及位置上是否以及有棋子
if(x>=1&&x<=3 && y>=1&&y<=3){
if(data[x-1][y-1]==' '){
break;
}else{
printf("该位置已经有棋子覆盖了,请重新输入\n");
}
}else{
printf("落子坐标越界,请重新输入\n");
}
}
data[x-1][y-1]='*';
}
bool judge(){
int i,j;
//行列的判断
for(i=0;i<3;i++){
//玩家胜利
if(data[i][0]==data[i][1] && data[i][1]==data[i][2] && data[i][0]=='*'){
flag='w';
return true;
}
if(data[0][i]==data[1][i] && data[1][i]==data[2][i] && data[0][i]=='*'){
flag='w';
return true;
}
//机器胜利
if(data[i][0]==data[i][1] && data[i][1]==data[i][2] && data[i][0]=='@'){
flag='l';
return true;
}
if(data[0][i]==data[1][i] && data[1][i]==data[2][i] && data[0][i]=='@'){
flag='l';
return true;
}
}
//这个放到循环里面应该是弄不了的
//对角线的判断
//玩家胜利
if(data[0][0]==data[1][1] && data[1][1]==data[2][2] && data[0][0]=='*'){
flag='w';
return true;
}
if(data[0][2]==data[1][1] && data[1][1]==data[2][0] && data[0][2]=='*'){
flag='w';
return true;
}
//机器胜利
if(data[0][0]==data[1][1] && data[1][1]==data[2][2] && data[0][0]=='@'){
flag='l';
return true;
}
if(data[0][2]==data[1][1] && data[1][1]==data[2][0] && data[0][2]=='@'){
flag='w';
return true;
}
//所以胜利的都判断之后再来判断是不是平局,可能就是提前结束
for(i=0;i<3;i++){
for(j=0;j<3;j++){
if(data[i][j]==' '){//还有位置没满
return false;
}
}
}
flag='d';
return true;
}
总结
写出大概的还是挺开心的,如果有问题的话,希望各位大佬可以指正。