头文件
game.h
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#include<Windows.h>
#ifndef __GAME_H__
#define __GAME_H__
#define R 3//行
#define C 3//列
#define Ex 0//增加量
void is_Board(char arr[R+Ex][C+Ex], int r, int c); //初始化棋盘
void display_Board(char arr[R + Ex][C + Ex], int r, int c); //打印棋盘
void play_person(char arr[R + Ex][C + Ex], int r, int c); //玩家走
void play_computer(char arr[R + Ex][C + Ex], int r, int c); //电脑走
char Judge(char arr[R + Ex][C + Ex], int r, int c); //判断输赢函数
int is_all_equal_without_blank(char arr[R + Ex]); //判断成每一条直线上元素是否全都相等并且不为空
int full(char arr[R + Ex][C + Ex], int r, int c); //判断棋盘是否满了
#endif //__GAME_H__
这里的Ex表示的是增加量,我们先定义的是三子棋,如果我们想玩五子棋的话,只需要把Ex后边的0改为2我们就可以玩五子棋了。
源文件
game.c
#define _CRT_SECURE_NO_WARNINGS 1
#include"game.h"
void is_Board(char arr[R+Ex][C+Ex], int r, int c)
{
int i = 0;
int j = 0;
for (i = 0; i < R + Ex; i++)
{
for (j = 0; j < C + Ex; j++)
{
arr[i][j] = ' ';
}
}
}
void display_Board(char arr[R + Ex][C + Ex], int r, int c)
{
int i = 0;
int j = 0;
for (i = 0; i < R + Ex; i++)
{
for (j = 0; j < C + Ex; j++)
{
printf("_%c_|", arr[i][j]);
}
printf("\n");
}
printf("\n");
}
void play_person(char arr[R + Ex][C + Ex], int r, int c)
{
int i = 0;
int j = 0;
while (1)
{
printf("请选择要走哪:\n");
scanf("%d %d", &i, &j);
i--; //因为数组下标是从0开始
j--;
if ((i >= 0 && i <= R + Ex - 1) && (j >= 0 && j <= C + Ex - 1)) //判断输入坐标是否合法
{
if (arr[i][j] == ' ')
{
arr[i][j] = 'X';
break;
}
else
{
printf("输入错误,请重新输入!\n");
}
}
else
{
printf("输入错误,请重新输入!\n");
}
}
}
void play_computer(char arr[R + Ex][C + Ex], int r, int c)
{
srand((unsigned int)time(NULL)); //生成随机数
while (1)
{
int x = rand() % (R + Ex); //使生成的随机数在坐标范围内
int y = rand() % (C + Ex);
if (arr[x][y] == ' ')
{
arr[x][y] = 'O';
break;
}
}
}
int full(char arr[R + Ex][C + Ex], int r, int c)
{
int i = 0;
int j = 0;
for (i = 0; i < R + Ex; i++)
{
for (j = 0; j < C + Ex; j++)
{
if (arr[i][j] == ' ')
{
return 0;
}
}
}
return 1;
}
int is_all_equal_without_blank(char arr[R + Ex])
{
char empty = arr[0];
for (int i = 1; i < R + Ex; i++)
{
if (empty != arr[i] || empty == ' ') //empty == ' '是为了防止全为空的情况
{
return 0;
}
else
{
empty = arr[i];
}
}
return 1;
}
char Judge(char arr[R + Ex][C + Ex], int r, int c)
{
int i;
int j;
char tmp[R + Ex];
//判断行相等
for (i = 0; i < R + Ex; i++)
{
for (j = 0; j < C + Ex; j++)
{
tmp[j] = arr[i][j];
}
if (is_all_equal_without_blank(tmp))
{
return tmp[0];
}
}
//判断列相等
for (j = 0; j < C + Ex; j++)
{
for (i = 0; i < R + Ex; i++)
{
tmp[i] = arr[i][j];
}
if (is_all_equal_without_blank(tmp))
{
return tmp[0];
}
}
//判断正交
for (i = 0; i < R + Ex; i++)
{
tmp[i] = arr[i][i];
}
if (is_all_equal_without_blank(tmp))
{
return tmp[0];
}
//判断反交
for (i = 0; i < R + Ex; i++)
{
tmp[i] = arr[i][C + Ex - i - 1];
if (is_all_equal_without_blank(tmp))
{
return tmp[0];
}
}
//判断平局
if (full(arr , R+Ex, C+Ex))
{
return 'q';
}
return ' ';
}
在char Judge(char arr[R + Ex][C + Ex], int r, int c)函数中我们先定义一个tmp空数组,在判断行/列/正交线/反交线上的数组元素相等时,先把那一行/列/正交/反交的数组元素全部存进tmp数组中,然后把tmp数组作为实参传入int is_all_equal_without_blank(char arr[R + Ex])函数中,进行判断,看数组中的每个元素相等且不为空,如果那一行/列/正交/反交线上的数组元素相等且不为空,则反回tmp数组中的第一个元素就行。
在int is_all_equal_without_blank(char arr[R + Ex])函数中,我们先把传进来的数组的第一个元素赋给empty,然后进行for循环,先用数组中的第一个元素和第二个元素相比较,如果它们两不等,或者都为空,则return 0,直接跳出,不用再进行后边的比较了,如果第一个元素和第二个元素相等,则把第二个元素的值赋给tmp,进入for循环,让第二个元素和第三个元素相比较,依次往后推,直到tmp数组中所以元素都相等,则return 1。
在char Judge(char arr[R + Ex][C + Ex], int r, int c)函数中我们还需要判断是否会平局,平局是放在判断行/列/正交/反交线上所以元素相等的后边,如果没有连成一条线,我们再判断是否平局,在int full(char arr[R + Ex][C + Ex], int r, int c)函数中,我们只需要判断棋盘是否满了,若棋盘满了,并且前边的判断并没有返回任何值,则return ‘q’,表示平局。
测试函数
test.c
#define _CRT_SECURE_NO_WARNINGS 1
#include"game.h"
void menu()
{
printf("*************************\n");
printf("********1. play**********\n");
printf("********0. error**********\n");
printf("*************************\n");
}
void game()
{
char arr[R+Ex][C+Ex] = { 0 };
char ret = 0;
is_Board(arr, R+Ex, C+Ex);
display_Board(arr, R + Ex, C + Ex);
while (1)
{
play_person(arr, R + Ex, C + Ex);
display_Board(arr, R + Ex, C + Ex);
ret = Judge(arr, R + Ex, C + Ex);
if (ret != ' ')
{
break;
}
play_computer(arr, R + Ex, C + Ex);
display_Board(arr, R + Ex, C + Ex);
ret = Judge(arr, R + Ex, C + Ex);
if (ret != ' ')
{
break;
}
}
if (ret == 'X')
{
printf("恭喜你,你赢了!\n");
}
else if(ret == 'O')
{
printf("真遗憾,你输了!\n");
}
else if (ret == 'q')
{
printf("平局!\n");
}
display_Board(arr, R + Ex, C + Ex);
}
int main()
{
int num = 0;
do
{
menu();
printf("请选择:\n");
scanf("%d", &num);
switch (num)
{
case 1:
game();
//printf("开始玩游戏!\n");
break;
case 0:
printf("退出游戏!!!\n");
break;
default:
printf("enter data error!\n");
}
}while (num);
return 0;
}
在测试函数中呢,我们需要先把棋盘打印出来,然后用一个while循环,先让玩家走一步,打印出来,再进行判断,若返回的是空,则让电脑走,然后打印,再进行判断,一直循环,直到判断函数有一个返回值,根据返回值判断谁输谁赢或是平局。