三子棋(可拓展成五子棋)

一、game.h头文件

在这里有主要使用到的一些函数库和我定义的宏,以及一些使用到的函数的声明。

#define _CRT_SECURE_NO_WARNINGS 1

#include<stdio.h>
#include<time.h>
#include<stdlib.h>

#define N 3//胜利条件,即几颗棋子相连时胜利
#define ROW 3//行数
#define COL 3//列数
#define PLAYER '*'//玩家的棋子
#define COMPUTER '#'//电脑的棋子
#define CONTINUE 'C'//用于函数返回,表示继续
#define END 'Q'//表示游戏结束

void Menu();//打印菜单
void Play();//游戏函数,主要用于调用定义的各种函数
void Display(char board[ROW][COL], int row, int col);//打印棋盘
void PlayerMove(char board[ROW][COL], int row, int col);//玩家下棋
void ComputerMove(char board[ROW][COL], int row, int col);//电脑下棋
char CheckWin(char board[ROW][COL], int row, int col);//判断胜利条件是否满足

二、主要函数

1、主函数和菜单函数

如下:

#define "game.h"

void Menu()
{
 printf("****************************************************\n");
 printf("**********               0、 exit         **********\n");
 printf("**********               1、 play         **********\n");
 printf("****************************************************\n");
}

int main()
{
 	int input = -1;
 	srand((unsigned int)time(NULL));
 	while (input)
 	{
  		Menu();
  		printf("请输入您要进行的操作:>");
  		if (!scanf("%d", &input))
  		{
   			getchar();
  		}
  		switch (input)
  		{
  		case 1:
   			Play();
   			break;
  		case 0:
   			printf("游戏结束\n");
   			break;
  		default:
   			printf("输入错误请重新输入\n");
   			break;
  		}
 	}
 	
 	return 0;
}

2、游戏函数

在这里实现各种函数的调用,并对CheckWin()返回的值做出反应。

void Play()
{
	char ch;
	char board[ROW][COL] = { 0 };
	system("cls");

	printf("游戏开始:>\n");
	Display(board, ROW, COL);

	while( 1 )
	{
		PlayerMove(board, ROW, COL);
		system("cls");
		Display(board, ROW, COL);
		ch = CheckWin(board, ROW, COL);
		if(ch != CONTINUE)
		{
			break;
		}
		ComputerMove(board, ROW, COL);
		system("cls");
		Display(board, ROW, COL);
		ch = CheckWin(board, ROW, COL);
		if(ch != CONTINUE)
		{
			break;
		}
	}
	if (ch == COMPUTER)
 	{
  		printf("电脑赢!\n");
 	}
 	else if (ch == PLAYER)
 	{
  		printf("玩家赢!\n");
 	}
 	else if(ch == END)
 	{
  		printf("平局!\n");
 	}
 }
 

3、棋盘

我们通过定义一个数组来记录棋盘中落子的情况,并通过一个函数来打印出当前棋盘的情况。

void Display(char board[ROW][COL], int row, int col)
{
 	int i, j
 	//打印棋盘
 	for (i = 0; i < row; i++)
 	{
 		//行标
  		for (j = 0; j < col; j++)
  		{
   			if (j != col - 1)
   			{
    				printf("     |");
   			}
   			else
   			{
    				printf("     \n");
   			}
  		}
  		for (j = 0; j < col; j++)
  		{
   			if (j != col - 1)
   			{
    				printf("  %c  |", board[i][j]);
   			}
   			else
   			{
    				printf("  %c   %d \n", board[i][j], i + 1);//i+1是行标
   			}
  		}
  		for (j = 0; j < col; j++)
  		{
   			if (j != col - 1)
   			{
    				printf("     |");
   			}
   			else
   			{
    				printf("     \n");
   			}
  		}
  		for (j = 0; j < col && i != col - 1; j++)
  		{
   			if (j != col - 1)
   			{
    				printf("-----|");
   			}
   			else
   			{
    				printf("-----\n");
   			}
  		}
 	}
 	//打印列标
 	for (j = 0; j < col; j++)
 	{
  		printf("  %d   ", j + 1);//j+1是列标
 	}
 	putchar('\n');
}

4、玩家下棋

玩家下棋,并检查坐标的合法性。

void PlayerMove(char board[ROW][COL], int row, int col)
{
 	int x, y;

	printf("玩家下:>\n");

	while (1)
 	{
 		printf("请输入你要下的坐标:>");
  		while (!scanf("%d%d", &x, &y))
  		{
   			getchar();
  		}
  		if (x <= ROW && x >= 1 && y <= COL && y >= 1)
  		{
   			if (board[x - 1][y - 1] == '\0')
   			{
    				board[x - 1][y - 1] = PLAYER;
    				break;
   			}
   			else
   			{
    				printf("输入错误,请重新输入!a\n");
   			}
  		}
  		else
  		{
   			printf("输入错误,请重新输入!b\n");
  		}
  	}
  }

5、电脑下棋

电脑通过(伪)随机数下棋。

void ComputerMove(char board[ROW][COL], int row, int col)
{
 	int x, y;

	printf("电脑下:>\n");

	while (1)
 	{
 	 	x = rand() % row;
  		y = rand() % col;
  		if (board[x][y] == '\0')
  		{
  			board[x][y] = COMPUTER;
   			break;
  		}
  	}
  }
  

6、判断胜利条件

通过在横竖行上和斜线上的计数来实现。

char CheckWin(char board[ROW][COL], int row, int col)
{
 	int ch;
 	int i, j;
	//调用检验函数
	if ((ch = CheckCross(board, row, col)) != CONTINUE)
 	{
  		return ch;
 	}
	if ((ch = CheckXCross(board, row, col)) != CONTINUE)
 	{
  		return ch;
 	}
	//判断棋盘是否已经下满
	for (i = 0; i < row; i++)
 	{
  		for (j = 0; j < col; j++)
  		{
  	 		if (board[i][j] == '\0')
   			{
    				return CONTINUE;
   			}
  		}
 	}
 	return END;
}

CheckWin()调用的函数。

//检验横竖行上的棋子
char CheckCross(char board[ROW][COL], int row, int col)
{
 	int i, j, flag;

	for (i = 0; i < row; i++)
 	{
  		flag = 0;
  		for (j = 0; j < col - 1; j++)
  		{
   			flag++;
   			if (board[i][j] == '\0' || board[i][j] != board[i][j + 1])
   			{
    				flag = 0;
   			}
   			if (flag == N - 1)
   			{
    				return board[i][j];
   			}
  		}
 	}
 	for (j = 0; j < col; j++)
 	{
  		flag = 0;
  		for (i = 0; i < row - 1; i++)
  		{
   			flag++;
   			if (board[i][j] == '\0' || board[i][j] != board[i + 1][j])
   			{
    				flag = 0;
   			}
   			if (flag == N - 1)
   			{
    				return board[i][j];
   			}
  		}
 	}

	return CONTINUE;
}
//所有斜线上棋子都能检测
char CheckXCross(char board[ROW][COL], int row, int col)
{
 	int i, j, k, flag;
 	for (k = 0; k < col; k++)
 	{
  		for (i = 0, flag = 0; i + 1 < row; i++)
  		{
  	 		flag++;
   			if (board[i][i + k] == '\0' || board[i][i + k] != board[i + 1][i + k + 1])
   			{
    				flag = 0;
   			}
   			if (flag == N - 1)
   			{
    				return board[i][i + k];
   			}
  		}
  		for (i = 0, flag = 0; i + k + 1 < row; i++)
  		{
   			flag++;
   			if (board[i + k][i] == '\0' || board[i + k][i] != board[i + k + 1][i + 1])
   			{
    				flag = 0;
   			}
   			if (flag == N - 1)
   			{
    				return board[i + k][i];
   			}
  		}
  		for (i = row - 1, j = 0, flag = 0; i - k - 1 >= 0 && j + 1 < col; i--, j++)
  		{
   			flag++;
   			if (board[i - k][j] == '\0' || board[i - k][j] != board[i - k - 1][j + 1])
   			{
    				flag = 0;
   			}
   			if (flag == N - 1)
   			{
    				return board[i - k][j];
   			}
  		}
  		for (i = row - 1, j = 0, flag = 0; i - 1 >= 0 && j + k + 1 < col; i--, j++)
  		{
   			flag++;
   			if (board[i][j + k] == '\0' || board[i][j + k] != board[i - 1][j + k + 1])
   			{
    				flag = 0;
   			}
   			if (flag == N - 1)
   			{
    				return board[i][j + k];
   			}
  		}
 	}

	return CONTINUE;
}

三、补充

在头文件中,我定义了行(ROW)和列(COL)以及胜利条件(N),通过修改N为5,并扩大棋盘的大小,就可以将三子棋扩展成五子棋。

猜你喜欢

转载自blog.csdn.net/shiawaseli/article/details/88959452