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;
}