目录
游戏菜单的创建主要有这几个功能
1.进入游戏
2.退出游戏
3.非法输入提示
代码如下
//菜单打印
void menu()
{
printf(" 1. play \n");
printf(" 0. exit \n");
}
int main()
{
int a = 0;
do
{
menu();
printf("请选择 -->");
scanf("%d", &a);
switch (a)
{
case 0:
break;
case 1:
game();
break;
default:
printf("选择错误\n");
break;
}
}
while (a);
return 0;
}
菜单运行结果
接下来开始实现各个游戏函数接口的功能
将组成棋盘的二维数组全部初始化为空格‘ ’
//通过控制二维数组的行row和列col来实现初始化
void init(char arr[ROW][COL], int row, int col)
{
int i = 0;
for (i = 0; i < row; i++)
{
int j = 0;
for (j = 0; j < col; j++)
{
arr[i][j] = ' ';
}
}
}
接下来是棋盘打印,这个可以根据自己的喜好来设置,根据控制二维数组的行和列呈现不同的效果
void chessboard(char arr[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 ", arr[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");
}
}
}
棋盘打印效果
由于数组是以0开头的,与玩家们平时的认知不同,所以实现时要将输入的行和列的值减1,让棋盘可以从1开始
下棋的时候还需要注意
落子的位置是否超出棋盘或位置已经被占用,可以通过两个if语句控制落子的位置,
void playermove(char arr[ROW][COL], int row, int col)
{
int x = 0;
int y = 0;
//通过循环控制玩家下棋,只有当玩家落子位置合法时才跳出循环
while (1)
{
printf("请输入落子坐标-->");
scanf("%d %d", &x, &y);
if (x < 1 || x > row || y < 1 || y > col)
{
printf("坐标错误,请重新输入\n");
continue;
}
if (arr[x-1][y-1] != ' ')
{
printf("该坐标已被占用\n");
continue;
}
arr[x-1][y-1] = '*';
break;
}
}
运行效果
电脑下棋需要生成随机值,这里可以利用时间戳来实现
首先需要包含对应的头文件#include<time.h>
同时还需要使用
- srand((unsigned int)time(NULL)); 来进行初始化
- x = rand() % row;
y = rand() % col; 来进行创建坐标的随机数
通过取模操作符来让电脑生成的随机数不超出棋盘的范围
同时也需要判断一下电脑落子位置是否已经被占用,逻辑与玩家下棋相似
void computermove(char arr[ROW][COL], int row, int col)
{
while (1)
{
int x = rand() % ROW;//生成0-2的随机数字
int y = rand() % COL;
printf("电脑下棋\n");
if (arr[x][y] == ' ')
{
arr[x][y] = '#';
break;
}
}
}
判定赢家的方法有三种
- 判断行
- 判断列
- 判断对角线
胜负判定需要玩家或电脑每下一次就判定一次,来确保程序的逻辑正确性;可以通过函数返回值来控制以下几种情况
- 玩家赢 --> 返回'*'
- 电脑赢 --> 返回'#'
- 平局 --> 返回'b'
- 游戏继续 --> 返回'a'
代码实现
char win(char arr[ROW][COL], int row, int col)
{
for (int a = 0; a < row; a++)
{
if (arr[a][0] != ' ' && arr[a][0] == arr[a][1] && arr[a][1] == arr[a][2])
return arr[a][0];
}
for (int b = 0; b < col; b++)
{
if (arr[0][b] != ' ' && arr[0][b] == arr[1][b] && arr[1][b] == arr[2][b])
return arr[b][0];
}
if (arr[0][0] != ' ' && arr[0][0] == arr[1][1] && arr[1][1] == arr[2][2])
return arr[0][0];
if (arr[0][2] != ' ' && arr[0][2] == arr[1][1] && arr[1][1] == arr[2][0])
return arr[0][2];
int i = 0;
for (i = 0; i < row; i++)
{
int j = 0;
for (j = 0; j < col; j++)
{
if (arr[i][j] == ' ')
return 'a';
}
}
return 'b';
}
while (1)
{
chessboard(arr, ROW, COL);
playermove(arr, ROW, COL);
ret = win(arr, ROW, COL);//判定胜负
if (ret != 'a')
break;
chessboard(arr, ROW, COL);
computermove(arr, ROW, COL);
ret = win(arr, ROW, COL);//判定胜负
if (ret != 'a')
break;
}
if (ret == '*')
printf("玩家赢\n");
if (ret == '#')
printf("电脑赢\n");
if(ret == 'b')
printf("平局\n");
}
整体代码整理
1:头文件包含与函数接口的声明
#pragma once
#define ROW 3
#define COL 3
#include <stdio.h>
#include <time.h>
//棋盘打印
void chessboard(char arr[ROW][COL], int row, int col);
//棋盘初始化
void init(char arr[ROW][COL], int row, int col);
//玩家下棋
void playermove(char arr[ROW][COL], int row, int col);
//电脑下棋
void computermove(char arr[ROW][COL], int row, int col);
//判定胜负
char win(char arr[ROW][COL], int row, int col);
2.函数接口的实现
void init(char arr[ROW][COL], int row, int col)
{
int i = 0;
for (i = 0; i < row; i++)
{
int j = 0;
for (j = 0; j < col; j++)
{
arr[i][j] = ' ';
}
}
}
void chessboard(char arr[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 ", arr[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");
}
}
}
void playermove(char arr[ROW][COL], int row, int col)
{
int x = 0;
int y = 0;
while (1)
{
printf("请输入落子坐标-->");
scanf("%d %d", &x, &y);
if (x < 1 || x > row || y < 1 || y > col)
{
printf("坐标错误,请重新输入\n");
continue;
}
if (arr[x-1][y-1] != ' ')
{
printf("该坐标已被占用\n");
continue;
}
arr[x-1][y-1] = '*';
break;
}
}
void computermove(char arr[ROW][COL], int row, int col)
{
while (1)
{
int x = rand() % ROW;//生成0-2的随机数字
int y = rand() % COL;
printf("电脑下棋\n");
if (arr[x][y] == ' ')
{
arr[x][y] = '#';
break;
}
}
}
char win(char arr[ROW][COL], int row, int col)
{
for (int a = 0; a < row; a++)
{
if (arr[a][0] != ' ' && arr[a][0] == arr[a][1] && arr[a][1] == arr[a][2])
return arr[a][0];
}
for (int b = 0; b < col; b++)
{
if (arr[0][b] != ' ' && arr[0][b] == arr[1][b] && arr[1][b] == arr[2][b])
return arr[b][0];
}
if (arr[0][0] != ' ' && arr[0][0] == arr[1][1] && arr[1][1] == arr[2][2])
return arr[0][0];
if (arr[0][2] != ' ' && arr[0][2] == arr[1][1] && arr[1][1] == arr[2][0])
return arr[0][2];
int i = 0;
for (i = 0; i < row; i++)
{
int j = 0;
for (j = 0; j < col; j++)
{
if (arr[i][j] == ' ')
return 'a';
}
}
return 'b';
}
3:最后是游戏整体逻辑以及菜单和主函数的实现
void menu()
{
printf(" 1. play \n");
printf(" 0. exit \n");
}
void game()
{
char ret = 0;
printf("三子棋游戏\n");
char arr[ROW][COL] = { 0 };//创建棋盘数组
init(arr, ROW, COL);//初始化棋盘
while (1)
{
chessboard(arr, ROW, COL);
playermove(arr, ROW, COL);
ret = win(arr, ROW, COL);//判定胜负
if (ret != 'a')
break;
chessboard(arr, ROW, COL);
computermove(arr, ROW, COL);
ret = win(arr, ROW, COL);//判定胜负
if (ret != 'a')
break;
}
if (ret == '*')
printf("玩家赢\n");
if (ret == '#')
printf("电脑赢\n");
if(ret == 'b')
printf("平局\n");
}
int main()
{
int a = 0;
do
{
menu();
srand(((unsigned int)time(NULL)));
printf("请选择 -->");
scanf("%d", &a);
switch (a)
{
case 0:
break;
case 1:
game();
break;
}
}
while (a);
return 0;
}
完成之后来看一下游戏效果吧
以上就是三子棋游戏的全部内容,希望对大家能有所帮助,如有错误,还请指正。