前言
本次项目仅个人练习即见解,并没有过多优化,作为一个编程初学者,欢迎各位来一起学习交流,批评指正。
首先写代码之前要有一个很好的思路,画图的方法也是可以弥补思维缺陷的。
先来描述一下具体的思路是如何的,再逐步去完成
目录
第一部分打印主菜单包括选择游戏:
所有头文件都写入到'game.h'里,'test.c'再去包含'game.h'就会方便很多
#define _CRT_SECURE_NO_WARNINGS
#include "game.h"
//菜单内容
void meun()
{
printf("**************************\n");
printf("******* 三子棋游戏 *******\n");
printf("****** 1.play 2.exit *****\n");
printf("**************************\n");
}
//主函数
int main()
{
//打印菜单
meun();
int input = 0;
do
{
printf("请选择1/0是否进入游戏\n");
scanf("%d", &input);
switch (input)
{
case 1:
printf("三子棋游戏开始\n");
game();
break;
case 0:
printf("退出游戏\n");
break;
default:
printf("选择错误,请重新选择\n");
break;
}
} while (input);
return 0;
}
第二部分初始化棋盘和打印棋盘内容
//实现游戏内容
void game()
{
//初始化数组
char board[ROW][COL] = { 0 };
//初始化棋盘
InitBoard(board, ROW, COL);
//打印棋盘内容
DipiayBoard(board, ROW, COL);
}
函数声明在game.h头文件中创建
#include <stdio.h>
#define ROW 3
#define COL 3
#include <time.h>
//初始化棋盘声明
void InitBoard(char board[ROW][COL], int row, int col);
//打印棋盘声明
void DipiayBoard(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;
for (i = 0; i < row; i++)
{
int j = 0;
for (j = 0; j < col; j++)
{
board[i][j] = ' ';
}
}
}
//打印棋盘实现
void DipiayBoard(char board[ROW][COL], int row, int col)
{
int i = 0;
for (i = 0; i < row; i++)
{
int j = 0;
for (j = 0; j < col; j++)
{
printf(" %c ", board[i][j]);
if (j < col - 1)
{
printf("|");
}
}
printf("\n");
if (i < row - 1)
{
for (j = 0; j < row; j++)
{
printf("---");
if (j < col - 1)
{
printf("|");
}
}
printf("\n");
}
}
}
效果如下:
第三部分实现玩家下棋与电脑下棋
玩家先下棋,然后电脑再下棋并打印出各自下棋后的棋盘
while (1)
{
//1.玩家下并打印出棋盘
player_down(board, ROW, COL);
DipiayBoard(board, ROW, COL);
//2.电脑下并打印出棋盘
PlayerMove(board, ROW, COL);
DipiayBoard(board, ROW, COL);
}
头文件中继续声明函数
//玩家下棋声明
void player_down(char board[ROW][COL], int row, int col);
//电脑下棋声明
void PlayerMove(char board[ROW][COL], int row, int col);
在game.c源文件中进行实现
下棋之前首先要判断坐标是否合法,不合法则重新输入,如果合法需要继续判断坐标是否被占用
//玩家下棋实现
void player_down(char board[ROW][COL], int row, int col)
{
printf("玩家下棋:>\n");
int x, y;
while (1)
{
printf("请输入下棋坐标:>\n");
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 PlayerMove(char board[ROW][COL], int row, int col)
{
printf("电脑下棋:>\n");
while (1)
{
int x = rand() % row;
int y = rand() % col;
//判断坐标是否被占用
if (board[x][y] == ' ')
{
board[x][y] = '#';
break;
}
}
}
电脑下棋需要生成随机坐标,rand是生成随机1-1024数字的库函数,这里将它% row或% col,是将它的随机值控制在1-3之间,同时为了保证它在每次启动程序的时候随机值都不一样,它会配合srand函数一起使用,如上述使用方法,因为是库函数要引用头文件,这里是#include<time.h>
第四部分判断游戏是否结束
假设游戏结束 情况1:玩家赢返回-'*' 电脑赢返回-'#' 平局返回 - 'Q'情况2:假设游戏继续返回 - 'C'
定义一个ret变量记录它的返回值,来判断游戏是那两种情况,最后并打印出棋盘
void game()
{
//初始化数组
char board[ROW][COL] = { 0 };
//初始化棋盘
InitBoard(board, ROW, COL);
//打印棋盘内容
DipiayBoard(board, ROW, COL);
//开始游戏
char ret = 0;
while (1)
{
//1.玩家下并打印出棋盘
player_down(board, ROW, COL);
DipiayBoard(board, ROW, COL);
//判断玩家是否赢得游戏
ret = Iiwin(board, ROW, COL);
//2.电脑下并打印出棋盘
PlayerMove(board, ROW, COL);
DipiayBoard(board, ROW, COL);
//判断电脑是否赢得游戏
ret = Iiwin(board, ROW, COL);
if (ret == '*')
{
printf("玩家获胜\n");
break;
}
if (ret == '#')
{
printf("电脑获胜\n");
break;
}
else if (ret == 'Q')
{
printf("平局\n");
break;
}
}
DipiayBoard(board, ROW, COL);
}
//判断游戏是否结束
//1.假设游戏结束
//玩家赢返回-'*'
//电脑赢返回-'#'
//平局返回 - 'Q'
//2.假设游戏继续
//游戏继续返回 - 'C'
//
char Iiwin(char board[ROW][COL], int row, int col);
在代码中需要判断三行三列,还有对角线交叉三个字符分别相等则返回该字符,InFin函数的返回值进行判断,如果是0返回'C',游戏继续,返回'Q'说明棋盘已经满了,平局结束游戏
int InFin(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 Iiwin(char board[ROW][COL], int row, int col)
{
//判断三行三列
int i = 0;
int j = 0;
for (i = 0; i < row; i++)
{
if (board[i][0] == board[i][1] && board[i][1] == board[i][2] && board[i][0] != ' ')
{
return board[i][0];
}
}
for (j = 0; j < col; j++)
{
if (board[0][j] == board[1][j] && board[1][j] == board[2][j] && board[0][j] != ' ')
{
return board[0][j];
}
}
//判断交叉线
if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[0][0] != ' ')
{
return board[0][0];
}
if (board[0][2] == board[1][1] && board[1][1] == board[2][0] && board[0][0] != ' ')
{
return board[0][2];
}
if (InFin(board,ROW,COL) == 1)
{
return 'Q';
}
return 'C';
}
完整代码如下:
game.h
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#define ROW 3
#define COL 3
#include <time.h>
//初始化棋盘声明
void InitBoard(char board[ROW][COL], int row, int col);
//打印棋盘声明
void DipiayBoard(char board[ROW][COL], int row, int col);
//玩家下棋声明
void player_down(char board[ROW][COL], int row, int col);
//电脑下棋声明
void PlayerMove(char board[ROW][COL], int row, int col);
//判断游戏是否结束
//1.假设游戏结束
//玩家赢返回-'*'
//电脑赢返回-'#'
//平局返回 - 'Q'
//2.假设游戏继续
//游戏继续返回 - 'C'
//
char Iiwin(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;
for (i = 0; i < row; i++)
{
int j = 0;
for (j = 0; j < col; j++)
{
board[i][j] = ' ';
}
}
}
//打印棋盘实现
void DipiayBoard(char board[ROW][COL], int row, int col)
{
int i = 0;
for (i = 0; i < row; i++)
{
int j = 0;
for (j = 0; j < col; j++)
{
printf(" %c ", board[i][j]);
if (j < col - 1)
{
printf("|");
}
}
printf("\n");
if (i < row - 1)
{
for (j = 0; j < row; j++)
{
printf("---");
if (j < col - 1)
{
printf("|");
}
}
printf("\n");
}
}
}
//玩家下棋实现
void player_down(char board[ROW][COL], int row, int col)
{
printf("玩家下棋:>\n");
int x, y;
while (1)
{
printf("请输入下棋坐标:>\n");
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 PlayerMove(char board[ROW][COL], int row, int col)
{
printf("电脑下棋:>\n");
while (1)
{
int x = rand() % row;
int y = rand() % col;
//判断坐标是否被占用
if (board[x][y] == ' ')
{
board[x][y] = '#';
break;
}
}
}
int InFin(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 Iiwin(char board[ROW][COL], int row, int col)
{
//判断三行三列
int i = 0;
int j = 0;
for (i = 0; i < row; i++)
{
if (board[i][0] == board[i][1] && board[i][1] == board[i][2] && board[i][0] != ' ')
{
return board[i][0];
}
}
for (j = 0; j < col; j++)
{
if (board[0][j] == board[1][j] && board[1][j] == board[2][j] && board[0][j] != ' ')
{
return board[0][j];
}
}
//判断交叉线
if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[0][0] != ' ')
{
return board[0][0];
}
if (board[0][2] == board[1][1] && board[1][1] == board[2][0] && board[0][0] != ' ')
{
return board[0][2];
}
if (InFin(board,ROW,COL) == 1)
{
return 'Q';
}
return 'C';
}
test.c
#include "game.h"
//菜单内容
void meun()
{
printf("**************************\n");
printf("******* 三子棋游戏 *******\n");
printf("****** 1.play 2.exit *****\n");
printf("**************************\n");
}
//实现游戏内容
void game()
{
//初始化数组
char board[ROW][COL] = { 0 };
//初始化棋盘
InitBoard(board, ROW, COL);
//打印棋盘内容
DipiayBoard(board, ROW, COL);
//开始游戏
char ret = 0;
while (1)
{
//1.玩家下并打印出棋盘
player_down(board, ROW, COL);
DipiayBoard(board, ROW, COL);
//判断玩家是否赢得游戏
ret = Iiwin(board, ROW, COL);
//2.电脑下并打印出棋盘
PlayerMove(board, ROW, COL);
DipiayBoard(board, ROW, COL);
//判断电脑是否赢得游戏
ret = Iiwin(board, ROW, COL);
if (ret == '*')
{
printf("玩家获胜\n");
break;
}
if (ret == '#')
{
printf("电脑获胜\n");
break;
}
else if (ret == 'Q')
{
printf("平局\n");
break;
}
}
DipiayBoard(board, ROW, COL);
}
//主函数
int main()
{
//打印菜单
meun();
int input = 0;
srand((unsigned int)time(NULL));
do
{
printf("请选择1/0是否进入游戏\n");
scanf("%d", &input);
switch (input)
{
case 1:
printf("三子棋游戏开始\n");
game();
break;
case 0:
printf("退出游戏\n");
break;
default:
printf("选择错误,请重新选择\n");
break;
}
} while (input);
return 0;
}