三子棋玩法:
三字棋的玩法(两个人下,一人下一次),直到满足横线或者竖线或者斜线是一样的3个字符,则表示对应的人胜利,或者直至棋盘满了还没人赢则表示是平局。三子棋赢法如下所示:
只要满足以上8种情况中的一种则对应标识这种符号的人赢。
实现思路:
本文章实现的是和电脑对局的情况,使用3*3的棋盘,由此想到用二维数组来实现,每个人下棋其实就是将数组中的字符给替换,由此想到一开始让二维数组全为空白字符,然后玩家下用一种字符表示,电脑下用另一种字符表示。简易三子棋的实现方式,我们可以使用函数的方式来实现,形成模块化更容易读写。实现该三子棋主要函数包括,初始化数组函数,打印棋盘函数,玩家下棋的函数,电脑下棋的函数以及最后输赢继续平局的判断函数。
初始化函数:
根据实现的思路,我们定义一个字符数组,该数组可以对玩家和电脑所下的位置进行记录,首先对该数组初始化,也就是将该数组中的每个位置都变为空白,以次来表示棋盘是空的。代码实现如下
void init(char board[N][N], int row, int col)
{
int i = 0;
for (i = 0; i < row; i++)
{
for (int j = 0; j < col; j++)
{
board[i][j] = ' ';//通过遍历将每个位置均变为空格字符,以便后续的视觉效果
}
}
}
打印函数:
该函数是实现棋盘的打印,打印每次玩家或电脑下的位置,前面下的也记录下来。代码实现如下:
void print(char board[N][N], 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");
for (j = 0; j < col; j++)
{
if (i < row - 1)
{
printf("---");
if (j < col - 1)
{
printf("|");
}
}
}
if (i < row - 1)
{
printf("\n");
}
}
}
打印效果如下:
玩家下棋函数:
玩家下的位置只能是1-3,代码实现如下:
void palyer_chess(char board[N][N], 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)//判断玩家输入坐标是否在1-3
{
if (board[x - 1][y - 1] == ' ')//判断该位置是否被占
{
board[x - 1][y - 1] = '#';//没别占用就用#表示玩家下的位置
break;//下好之后就退出这个循环
}
printf("该坐标已经被占用了,请重新输入坐标\n");
}
else
{
printf("坐标输入错误,请重新输入坐标\n");
}
}
}
电脑下棋函数:
void computer_chess(char board[N][N], int row, int col)
{
int x = 0;
int y = 0;
printf("电脑下:\n");
while (1)
{
y = rand() % col;//随机生成1-3的数
x = rand() % row;//随机生成1-3的数
if (board[x][y] == ' ')//首先需要判断该位置是否被占用
{
board[x][y] = '*';//没别占用就用*表示电脑下在该位置
break;//下好之后就退出循环,否则就会一直下
}
}
}
输赢继续平局的判断函数:
char is_win(char board[N][N], int row, int col)//三子棋输或赢或继续或平局的判断
{
//赢
if (board[0][0] == board[1][1] && board[0][0] == board[2][2] && board[0][0] != ' ')//对角线
return board[0][0];//返回对应字符,以便后续判断谁赢
else if(board[0][2]==board[1][1]&& board[2][0] == board[1][1] && board[0][2] != ' ')//副对角线
return board[0][2];//返回对应字符,以便后续判断谁赢
for (int 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 (int i = 0; i < col; i++)
{
if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[0][i] != ' ')//列线
return board[0][i];//返回对应字符,以便后续判断谁赢
}
//继续
for (int i = 0; i < row; i++)
{
for (int j = 0; j < col; j++)
{
if (board[i][j] == ' ')//经过上面的则表示没有人赢,如果还有空白位置,则游戏继续
return 'c';//返回字符'c',表示游戏继续
}
}
//平局
return 'p';//此时表明没有人赢,而且空白位置也没了,就表示平局,返回字符'p'
}
游戏进行的总逻辑:
void chess()
{
char board[N][N] = { 0 };
//1、初始化棋盘
init(board, N, N);//棋盘初始化
print(board, N, N);//打印棋盘
char ret = '0';
while (1)
{
palyer_chess(board,N,N);
print(board, N, N);
ret=is_win(board, N, N);
if (ret != 'c')//只要不是继续就退出循环
break;
computer_chess(board, N, N);
print(board, N, N);
ret = is_win(board, N, N);
if (ret != 'c')//只要不是继续就退出循环
break;
}
if (ret == 'p')
{
printf("平局\n");
}
else if (ret == '*')
{
printf("很遗憾,电脑赢\n");
}
else if (ret == '#')
{
printf("恭喜你赢了\n");
}
}
菜单打印:
void menu()
{
printf("************************\n");
printf("****** 1 play ******\n");
printf("****** 0 exit ******\n");
printf("************************\n");
}
测试游戏进行的代码:
int main()
{
//想要实现玩完一把不过瘾继续玩,直至选择退出
int a = 0;
srand((unsigned int)time(NULL));
do
{
//打印菜单
menu();
printf("请选择->:");
scanf("%d", &a);
switch (a)
{
case 0:
printf("退出游戏\n");
break;
case 1:
chess();//下棋
break;
default:
printf("输入错误,请重新输入\n");
break;
}
} while (a);//当选择0时退出
return 0;
}
完整的代码:
test.c代码如下:
#define _CRT_SECURE_NO_WARNINGS 1
#include "game.h"
int main()
{
//想要实现玩完一把不过瘾继续玩,直至选择退出
int a = 0;
srand((unsigned int)time(NULL));
do
{
//打印菜单
menu();
printf("请选择->:");
scanf("%d", &a);
switch (a)
{
case 0:
printf("退出游戏\n");
break;
case 1:
chess();
break;
default:
printf("输入错误,请重新输入\n");
break;
}
} while (a);
return 0;
}
game.c代码如下:
#define _CRT_SECURE_NO_WARNINGS 1
#include "game.h"
void chess()
{
char board[N][N] = { 0 };
//1、初始化棋盘
init(board, N, N);//棋盘初始化
print(board, N, N);//打印棋盘
char ret = '0';//用来接受是平局还是继续还是谁赢的字符变量
while (1)
{
palyer_chess(board,N,N);
print(board, N, N);
ret=is_win(board, N, N);
if (ret != 'c')
break;
computer_chess(board, N, N);
print(board, N, N);
ret = is_win(board, N, N);
if (ret != 'c')
break;
}
if (ret == 'p')
{
printf("平局\n");
}
else if (ret == '*')
{
printf("很遗憾,电脑赢\n");
}
else if (ret == '#')
{
printf("恭喜你赢了\n");
}
}
void menu()
{
printf("************************\n");
printf("****** 1 play ******\n");
printf("****** 0 exit ******\n");
printf("************************\n");
}
void init(char board[N][N], int row, int col)
{
int i = 0;
for (i = 0; i < row; i++)
{
for (int j = 0; j < col; j++)
{
board[i][j] = ' ';
}
}
}
void print(char board[N][N], 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");
for (j = 0; j < col; j++)
{
if (i < row - 1)
{
printf("---");
if (j < col - 1)
{
printf("|");
}
}
}
if (i < row - 1)
{
printf("\n");
}
}
}
void palyer_chess(char board[N][N], 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)//判断玩家输入坐标是否在1-3
{
if (board[x - 1][y - 1] == ' ')//判断该位置是否被占
{
board[x - 1][y - 1] = '#';//没别占用就用#表示玩家下的位置
break;//下好之后就退出这个循环
}
printf("该坐标已经被占用了,请重新输入坐标\n");
}
else
{
printf("坐标输入错误,请重新输入坐标\n");
}
}
}
void computer_chess(char board[N][N], int row, int col)
{
int x = 0;
int y = 0;
printf("电脑下:\n");
while (1)
{
y = rand() % col;//随机生成1-3的数
x = rand() % row;//随机生成1-3的数
if (board[x][y] == ' ')//首先需要判断该位置是否被占用
{
board[x][y] = '*';//没别占用就用*表示电脑下在该位置
break;//下好之后就退出循环,否则则会一直下
}
}
}
char is_win(char board[N][N], int row, int col)//三子棋输或赢或继续或平局的判断
{
//赢
if (board[0][0] == board[1][1] && board[0][0] == board[2][2] && board[0][0] != ' ')//对角线
return board[0][0];//返回对应字符,以便后续判断谁赢
else if(board[0][2]==board[1][1]&& board[2][0] == board[1][1] && board[0][2] != ' ')//副对角线
return board[0][2];//返回对应字符,以便后续判断谁赢
for (int 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 (int i = 0; i < col; i++)
{
if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[0][i] != ' ')//列线
return board[0][i];//返回对应字符,以便后续判断谁赢
}
//继续
for (int i = 0; i < row; i++)
{
for (int j = 0; j < col; j++)
{
if (board[i][j] == ' ')//经过上面的则表示没有人赢,如果还有空白位置,则游戏继续
return 'c';//返回字符'c',表示游戏继续
}
}
//平局
return 'p';//此时表明没有人赢,而且空白位置也没了,就表示平局,返回字符'p'
}
game.h代码如下:
#pragma once
#include<stdio.h>
#define N 3
#include<time.h>
#include<stdlib.h>
void menu();//声明菜单函数
void chess();//声明游戏总逻辑函数
void init(char board[N][N], int row, int col);//声明初始化函数
void print(char board[N][N], int row, int col);//声明打印函数
void palyer_chess(char board[N][N],int row,int col);//声明玩家下棋函数
void computer_chess(char board[N][N], int row, int col);//声明电脑下棋函数
char is_win(char board[N][N], int row, int col);//声明判断输,赢,继续,平局函数
实验的结果如下:
平局:
玩家赢:
电脑赢:
如有错误不足之处,欢迎大家批评指正,谢谢!!!