C语言实现三子棋(井字棋)
Posted old_old_boy
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C语言实现三子棋(井字棋)相关的知识,希望对你有一定的参考价值。
C语言实现三子棋
使用工具
- Visual Studio 2019
基本思路和流程
三子棋游戏规则
- `在3X3的棋盘里,率先将三个棋子连成一条直线则胜出
代码实现思路
- 菜单界面:选择开始或者退出游戏
- 初始化棋盘并打印棋盘
- 玩家选择落子坐标
- 电脑落子
- 每次落子判断输赢平还是继续
- 结束之后选择继续游戏还是退出游戏
实现步骤(具体步骤)
使用多文件形式
- test.c文件(源文件):
写整个游戏的大致过程
- game.h文件:
引用所需的头文件,以及对各个函数的声明
- game.c文件(源文件):
定义在game.h中声明的函数,实现各个模块的功能
(源文件上方只需加上#include “game.h” 即可)
代码实现
菜单界面
- 代码:
void meau()
{
printf("***********************************\\n");
printf("********* 1 . play **********\\n");
printf("********* 0 . exit **********\\n");
printf("***********************************\\n");
}
- 实现后效果:
-
选择实现
- 玩家可3通过选择(0/1)来选择退出或进行游戏
- 代码:
int main()
{
int input = 0;
srand((unsigned)time(NULL));
do
{
meau();
printf("请选择:>");
scanf("%d", &input);
switch (input)
{
case 1:
game();
break;
case 0:
printf("退出游戏\\n");
break;
default:
printf("选择错误\\n");
break;
}
} while (input);
return 0;
}
- 与菜单界面共同实现后的效果:
初始化和打印棋盘
棋盘
- 使用3*3的二维数组,元素类型为char
- 将数组初始化为 ‘ ’
char board[ROW][COL];
使用宏定义(重点)
- 提高代码可读性
- 若以后想要修改棋盘大小,可直接修改
#define ROW 3
#define COL 3
初始化棋盘
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 DisplayBoard(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 < col; j++)
{
printf("---");
if (j != col - 1)
printf("|");
}
}
printf("\\n");
}
}
- 实现后效果
玩家下子
玩家下子会遇到的问题
- 人的思维中,坐标是从1开始的,而数组中的坐标是从0开始的,因此我们需要将玩家输入的坐标进行-1处理
- 落子范围(不能超出坐标的范围)
- 选择的坐标是否已被占用
从2,3两点可以得出,我们需要用到一个循环来解决这两个问题,当这两个问题不存在时,便跳出循环
- 代码实现:
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)
{
int x = 0;
int y = 0;
printf("电脑走\\n");
//随机生成坐标
while (1)
{
x = rand() % row;
y = rand() % col;
if (board[x][y] == ' ')
{
board[x][y] = '#';
break;
}
}
}
判断结果
采取返回值(char 型)
- 玩家赢——‘*’
- 电脑赢——‘#’
- 平局——‘Q’
- 游戏继续——‘c’
- 代码实现:
char Iswin(char board[ROW][COL], int row, int col)
{
//1.判断输赢
if (board[0][0] == '*' && board[0][1] == '*' && board[0][2] == '*')
return '*';
else if (board[0][0] == '#' && board[0][1] == '#' && board[0][2] == '#')
return '#';
else if (board[1][0] == '*' && board[1][1] == '*' && board[1][2] == '*')
return '*';
else if (board[1][0] == '#' && board[1][1] == '#' && board[1][2] == '#')
return '#';
else if (board[2][0] == '*' && board[2][1] == '*' && board[2][2] == '*')
return '*';
else if (board[2][0] == '#' && board[2][1] == '#' && board[2][2] == '#')
return '#';
else if (board[0][0] == '*' && board[1][1] == '*' && board[2][2] == '*')
return '*';
else if (board[0][0] == '#' && board[1][1] == '#' && board[2][2] == '#')
return '#';
//2.判断平局
int flag = 0;
int i = 0;
for (i = 0; i < row; i++)
{
int j = 0;
for (j = 0; j < col; j++)
{
if (board[i][j] == ' ')
{
flag = 1;
break;
}
}
}
if (flag == 0)
return 'Q';
//3.游戏继续
return 'c';
}
整体游戏流程
- 代码:
void game()
{
char board[ROW][COL];//棋盘数组
//初始化棋盘
InitBoard(board, ROW, COL);
//打印棋盘
DisplayBoard(board, ROW, COL);
//下棋
char ret = 0;
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);//打印棋盘
if (ret != 'c')
break;
}
if (ret == '*')
printf("玩家赢\\n");
else if (ret == "#")
printf("电脑赢\\n");
else
printf("平局\\n");
//DisplayBoard(board, ROW, COL);//打印棋盘
}
附上所有代码
test.c文件
#include "game.h"
void meau()
{
printf("***********************************\\n");
printf("********* 1 . play **********\\n");
printf("********* 0 . exit **********\\n");
printf("***********************************\\n");
}
void game()
{
char board[ROW][COL];//棋盘数组
//初始化棋盘
InitBoard(board, ROW, COL);
//打印棋盘
DisplayBoard(board, ROW, COL);
//下棋
char ret = 0;
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);//打印棋盘
if (ret != 'c')
break;
}
if (ret == '*')
printf("玩家赢\\n");
else if (ret == "#")
printf("电脑赢\\n");
else
printf("平局\\n");
//DisplayBoard(board, ROW, COL);//打印棋盘
}
int main()
{
int input = 0;
srand((unsigned)time(NULL));
do
{
meau();
printf("请选择:>");
scanf("%d", &input);
switch (input)
{
case 1:
game();
break;
case 0:
printf("退出游戏\\n");
break;
default:
printf("选择错误\\n");
break;
}
} while (input);
return 0;
}
game.h文件
#pragma once
#include <stdio.h>
#include <stdlib.h>
#define ROW 3
#define COL 3
//初始化棋盘
extern void InitBoard(char board[ROW][COL], int row, int col);
//打印棋盘
extern void DisplayBoard(char board[ROW][COL], int row, int col);
//玩家下棋
extern void PlayerMove(char board[ROW][COL], int row, int col);
//电脑下棋
extern void ComputerMove(char board[ROW][COL], int row, int col);
//判断输赢
//要返回四种不同的状态
//玩家赢 ——'*'
//电脑赢 ——'#'
//平局 ——'Q'
//继续 ——'c'
extern 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;
for (i = 0; i < row; i++)
{
int j = 0;
for (j = 0; j < col; j++)
{
board[i][j] = ' ';
}
}
}
void DisplayBoard(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 <以上是关于C语言实现三子棋(井字棋)的主要内容,如果未能解决你的问题,请参考以下文章