可以通过修改ROW和COL后面的值来改变棋盘的大小,如图中ROW和COL后面的值为3表示棋盘的大小为3行3列,通过修改CHESS后面的值来改变游戏方式,如CHESS后面的值为3表示游戏方式是三子棋。
在输入时,PVP表示双人对战,PVE表示人机对战
PVE模式的电脑没有智商,所以可玩性不大
此程序比较麻烦的地方集中于win_game()函数,该函数用于判断是否有玩家或者电脑获胜。
程序采用分文件方式编写,代码如下:
text.c文件:
#define _CRT_SECURE_NO_WARNINGS 1
#include"game.h"
void vext()
{
int n=0;
int n1 = 0;
do
{
Menu();
scanf("%d", &n);
switch (n)
{
case 1:
srand((unsigned int)time(NULL));
do
{
Menu1();
scanf("%d", &n1);
switch (n1)
{
case 0:
printf("欢迎下次游玩\n");
break;
case 1:
GamePVP();
break;
case 2:
GamePVE();
break;
default:
printf("输入有误,请重新输入\n");
break;
}
} while (n1);
break;
case 0:
printf("欢迎下次游玩\n");
break;
default:
printf("输入有误,请重新输入\n");
break;
}
system("pause");
system("cls");
} while (n);
}
int main()
{
vext();
return 0;
}
函数功能头文件game.h
#pragma once
#include<stdio.h>
#include<Windows.h>
#include<stdlib.h>
#include<time.h>
#define ROW 3 //行
#define COL 3 //列
#define CHESS 3 //下棋类型(如三子棋)
//菜单
void Menu();
//次菜单
void Menu1();
//进行人机游戏
void GamePVE();
//进行双人游戏
void GamePVP();
//打印棋盘
void print_board(char arr[ROW][COL], int row, int col);
//初始化棋盘
void initboard(char arr[ROW][COL],int row,int col);
//玩家1操作
void player_operate1(char arr[ROW][COL], int row, int col);
//玩家2操作
void player_operate2(char arr[ROW][COL], int row, int col);
//电脑操作
void computer_operate(char arr[ROW][COL], int row, int col);
//判断胜利(电脑胜利返回#,玩家胜利返回*)
char win_game(char arr[ROW][COL], int row, int col,int chess);
//判断平局(平局返回false,没有平局返回true)
bool dogfall_game(char arr[ROW][COL], int row, int col);
函数功能源文件game.c
#define _CRT_SECURE_NO_WARNINGS 1
#include"game.h"
void Menu()
{
printf("**************************\n");
printf("********** 1.game ********\n");
printf("********** 0.exit ********\n");
printf("**************************\n");
}
void Menu1()
{
printf("**************************\n");
printf("********** 1.PVP *********\n");
printf("********** 2.PVE *********\n");
printf("********** 0.exit ********\n");
printf("**************************\n");
}
void initboard(char arr[ROW][COL], int row, int col)
{
for (int i = 0; i < row; i++)
{
for (int j = 0; j < col; j++)
{
arr[i][j] = ' ';
}
}
}
void print_board(char arr[ROW][COL], int row, int col)
{
for (int i = 0; i < row; i++)
{
for (int j = 0; j < col; j++)
{
printf(" %c ",arr[i][j]);
if (j < col - 1)
{
printf("|");
}
}
printf("\n");
if (i < row - 1)
{
for (int j = 0; j < col; j++)
{
printf("---");
if (j < col - 1)
{
printf("|");
}
}
printf("\n");
}
}
}
void player_operate1(char arr[ROW][COL], int row, int col)
{
printf("玩家1输入\n");
while (true)
{
printf("请输入要下棋的坐标 (如1 3)\n");
int m = 0, n = 0;
scanf("%d %d", &m, &n);
if (m >= 1 && n >=1 && m <= row && n <=col&&arr[m-1][n-1]==' ')
{
arr[m - 1][n - 1] = '*';
break;
}
else
{
printf("输入失败\n");
}
}
}
void player_operate2(char arr[ROW][COL], int row, int col)
{
printf("玩家2输入\n");
while (true)
{
printf("请输入要下棋的坐标 (如1 3)\n");
int m = 0, n = 0;
scanf("%d %d", &m, &n);
if (m >= 1 && n >= 1 && m <= row && n <= col && arr[m - 1][n - 1] == ' ')
{
arr[m - 1][n - 1] = '#';
break;
}
else
{
printf("输入失败\n");
}
}
}
void computer_operate(char arr[ROW][COL], int row, int col)
{
printf("电脑输入\n");
while (true)
{
int m = rand() % row;
int n = rand() % col;
if (arr[m][n] == ' ')
{
arr[m][n] = '#';
break;
}
}
}
char win_game(char arr[ROW][COL], int row, int col,int chess)
{
int count;
//判断行是否获胜
for (int i = 0; i < row; i++)
{
for (int j = 0; j<=col-chess;j++) //比col-chess下标大的位置已经凑不出chess个格子
{
count = 1;
if (arr[i][j] == ' ')
{
continue;
}
for (int k = j + 1; k <=j+chess-1; k++)
{
if (arr[i][j] == arr[i][k])
{
count++;
}
}
if (count == chess)
{
return arr[i][j];
}
}
}
//判断列是否获胜
for (int j = 0; j < col; j++)
{
for (int i = 0; i <= row - chess; i++)
{
count = 1;
if (arr[i][j] == ' ')
{
continue;
}
for (int k = i + 1; k <= i + chess - 1; k++)
{
if (arr[i][j] == arr[k][j])
{
count++;
}
}
if (count == chess)
{
return arr[i][j];
}
}
}
//判断单调递减的斜边是否获胜
for (int i = 0; i < row; i++)
{
for (int j = 0; j <= col; j++)
{
if (i + chess <= row && j + chess <= col) //当以arr[i][j]为起点判断发现无法构成chess个数据的单调递减的斜边
{ //j之后的列数肯定都不能构成,i之后的行数不一定
if (arr[i][j] == ' ')
{
continue;
}
else
{
count = 1;
for (int k = 1; k < chess; k++)
{
if (arr[i][j] == arr[i + k][j + k])
{
count++;
}
}
if (count == chess)
{
return arr[i][j];
}
}
}
else
{
break;
}
}
}
//判断单调递增的斜边是否获胜
for (int i = 0; i < row; i++)
{
for (int j = 0; j <= col; j++)
{
if (i - chess <= row && j + chess <= col)
{
if (arr[i][j] == ' ')
{
continue;
}
else
{
count = 1;
for (int k = 1; k < chess; k++)
{
if (arr[i][j] == arr[i -k][j + k])
{
count++;
}
}
if (count == chess)
{
return arr[i][j];
}
}
}
else
{
continue;
}
}
}
}
bool dogfall_game(char arr[ROW][COL], int row, int col)
{
for (int i = 0; i < row; i++)
{
for (int j = 0; j <= col; j++)
{
if (arr[i][j] == ' ')
{
return true;
}
}
}
return false;
}
void GamePVE()
{
char arr[ROW][COL];
initboard(arr, ROW, COL);
print_board(arr, ROW, COL);
while (true)
{
player_operate1(arr, ROW, COL);
print_board(arr, ROW, COL);
if ('*' == win_game(arr, ROW, COL, CHESS))
{
printf("恭喜玩家!\n");
break;
}
if (false == dogfall_game(arr, ROW, COL))
{
printf("平局喽!\n");
break;
}
system("cls");
computer_operate(arr, ROW, COL);
print_board(arr, ROW, COL);
if ('#' == win_game(arr, ROW, COL,CHESS))
{
printf("恭喜电脑!\n");
break;
}
if (false == dogfall_game(arr, ROW, COL))
{
printf("平局喽!\n");
break;
}
}
}
void GamePVP()
{
char arr[ROW][COL];
initboard(arr, ROW, COL);
print_board(arr, ROW, COL);
while (true)
{
player_operate1(arr, ROW, COL);
print_board(arr, ROW, COL);
if ('*' == win_game(arr, ROW, COL, CHESS))
{
printf("恭喜玩家1!\n");
break;
}
if (false == dogfall_game(arr, ROW, COL))
{
printf("平局喽!\n");
break;
}
player_operate2(arr, ROW, COL);
print_board(arr, ROW, COL);
if ('#' == win_game(arr, ROW, COL, CHESS))
{
printf("恭喜玩家2!\n");
break;
}
if (false == dogfall_game(arr, ROW, COL))
{
printf("平局喽!\n");
break;
}
}
}