三子棋小游戏

三子棋游戏规则是三子成一行即可获得胜利,接下来讲解下如何用c语言编写三子棋

思路步骤

1.打印出游戏菜单
2.初始化游戏界面
3.设计游戏框架
4.玩家下棋
5.电脑下棋
6.判断输赢

分为三个源文件 test.c //测试 game.c //游戏设置 game.h //引用的函数和头文件

1.打印出游戏菜单

void menu(){
     
	printf("*****************\n");
	printf("*****1.play******\n");
	printf("*****0.exit******\n");
	printf("*****************\n");
}

简单的打印一个游戏菜单,视图如下:
在这里插入图片描述
2.初始化游戏界面
初始化二维数组的每个字符为‘ ’,为之后下棋子做铺垫,正好可以对应上去

//初始化界面
void initBoard(char board[ROW][COL], int row, int col){
     
	int i = 0;
	int j = 0;
	for (i = 0; i < row; i++){
     
		for (j = 0; j < col; j++){
     
			board[i][j] = ' ';
		}
	}
}

3.设计游戏框架
对应的每一行打印出“ %c | %c | %c ”和“—|---|—”
但是

注意:打印每一行的时候“ %c ”和“|”是单独分开写的,并且在最后一次没有“|”,此时得写到if语句,来使得最后一个“|”没有。同理,“—”和“|”一样。

void DisplayBoard(char board[ROW][COL], int row, int col){
     
	//   |   |   
	//- -|- -|- -
	int i = 0;
	int j = 0;
	for (i = 0; i < row; i++){
     
		for (j = 0; j < col; j++){
     
			printf(" %c ", board[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");
		}
	}
}

打印出来的页面如下:
三子棋小游戏_第1张图片
4.玩家下棋
设立好框架后就开始下棋了,分为玩家下棋和电脑下棋

注意事项:位置被占用的问题,玩家所对应的坐标,与程序员对应的左边两者之间是差1的关系,比如1,1,玩家想输入的是第一行第一列,而程序员的眼里是第二行第二个,所以此时在编写程序的时候就得在原来的基础上减去个1.

void PlayerMove(char board[ROW][COL], int row, int col){
     
	int i = 0;
	int j = 0;
	printf("玩家下棋->\n");
	while(1){
     
		printf("请输入你的坐标->");
		scanf("%d%d", &i, &j);
		if (i>=1 && i<=row && j>=1 && j<=col){
     
			if (board[i - 1][j - 1] != ' '){
     
				printf("此位置被占用,请重新选择!\n");
			}
			else{
     
				board[i - 1][j - 1] = '*';
				break;
			}
		}
		else{
     
			printf("下子错误!请重新选择!\n");
		}
		
	}
}

5.电脑下棋
电脑下棋是随机的,用到的有rand,srand,time函数,rand配合着srand函数一起使用。

srand(unsigned int),定rand随机值的起始位置。同时用到了time(NULL)时间戳的知识(时间戳是指现在的时间和计算机当时的时间差,计算机当时的时间是1970-1-1,8:00:00),srand((unsigned int)time(NULL))将时间强制转成无符号整形,放置于main函数中,在每次的程序开启中随机值不固定。

void ComputerMove(char board[ROW][COL], int row, int col){
     
	printf("电脑走->\n");
	int x = rand() % row;
	int y = rand() % col;
	while (1){
     
		if (board[x][y] == ' '){
     
			board[x][y] = '#';
			break;
		}
	}
}

三子棋小游戏_第2张图片

6.判断胜负
胜利的标志有一行成型,一列成型,斜对角成型
行成型:

for (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 (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];
		}
	}

斜对角成型:

if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[0][0] != ' '){
     
		return board[0][0];
	}
	if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[0][0] != ' '){
     
		return board[0][0];
	}

除了三种成型外,还有一种是平局,即棋盘下满无法分出胜负
用到了遍历,如果没有空格,则返回1,表示棋盘满了,平局,如果有空格,则返回0,表示棋盘还有空的位置。

int isfull(char board[ROW][COL], int row, int col){
     
	int i = 0;
	int j = 0;
	for (i = 0; i < row; i++){
     
		for (j = 0; j < col; j++){
     
			if (board[i][j] == ' '){
     
				return 0;
			}
		}
	}
	return 1;
}
if (isfull(board, row, col) == 1){
     
		return 'Q';
	}

通过以上四种情况的返回值,来判定玩家胜,还是电脑胜
返回其中的一种即可判定输赢

while (1){
     
		//玩家下棋
		PlayerMove(board, ROW, COL);
		ret = CheckWin(board, ROW, COL);
		if (ret != 'C'){
     
			break;
		}
		DisplayBoard(board, ROW, COL);
		//电脑下棋
		ComputerMove(board, ROW, COL);
		ret = CheckWin(board, ROW, COL);
		if (ret != 'C'){
     
			break;
		}
		DisplayBoard(board, ROW, COL);
		//判断输赢
	}
	if (ret == '*'){
     
		printf("玩家赢!\n");
	}
	if (ret == '#'){
     
		printf("电脑赢!\n");
	}
	if (ret == 'Q'){
     
		printf("平局!\n");
	}
}

最后是总的代码,分别是两个c源文件,和一个头文件
test.c

#include "game.h"
void menu(){
     
	printf("*****************\n");
	printf("*****1.play******\n");
	printf("*****0.exit******\n");
	printf("*****************\n");
}
void game(){
     
	char board[ROW][COL];
	//初始化游戏界面
	char ret;
	initBoard(board,ROW,COL);
	DisplayBoard(board, ROW, COL);
	//游戏框架
	while (1){
     
		//玩家下棋
		PlayerMove(board, ROW, COL);
		ret = CheckWin(board, ROW, COL);
		if (ret != 'C'){
     
			break;
		}
		DisplayBoard(board, ROW, COL);
		//电脑下棋
		ComputerMove(board, ROW, COL);
		ret = CheckWin(board, ROW, COL);
		if (ret != 'C'){
     
			break;
		}
		DisplayBoard(board, ROW, COL);
		//判断输赢
	}
	if (ret == '*'){
     
		printf("玩家赢!\n");
	}
	if (ret == '#'){
     
		printf("电脑赢!\n");
	}
	if (ret == 'Q'){
     
		printf("平局!\n");
	}
}
int main(){
     
	srand((unsigned int)time(NULL));
	int input = 0;
	do{
     
		menu();//菜单显示
		printf("请选择:>");
		scanf("%d", &input);//选择
		switch (input){
     
		case 1:game();
			break;
		case 0:printf("退出游戏!\n");
			break;
		default:printf("输入错误,请重新输入!\n");
			break;
		}
	} while (input);
	return 0;
}

game.c

#include "game.h"
//初始化界面
void initBoard(char board[ROW][COL], int row, int col){
     
	int i = 0;
	int j = 0;
	for (i = 0; i < row; i++){
     
		for (j = 0; j < col; j++){
     
			board[i][j] = ' ';
		}
	}
}
//打印界面
void DisplayBoard(char board[ROW][COL], int row, int col){
     
	//   |   |   
	//- -|- -|- -
	int i = 0;
	int j = 0;
	for (i = 0; i < row; i++){
     
		for (j = 0; j < col; j++){
     
			printf(" %c ", board[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 board[ROW][COL], int row, int col){
     
	int i = 0;
	int j = 0;
	printf("玩家下棋->\n");
	while(1){
     
		printf("请输入你的坐标->");
		scanf("%d%d", &i, &j);
		if (i>=1 && i<=row && j>=1 && j<=col){
     
			if (board[i - 1][j - 1] != ' '){
     
				printf("此位置被占用,请重新选择!\n");
			}
			else{
     
				board[i - 1][j - 1] = '*';
				break;
			}
		}
		else{
     
			printf("下子错误!请重新选择!\n");
		}
		
	}
}
//电脑走
void ComputerMove(char board[ROW][COL], int row, int col){
     
	printf("电脑走->\n");
	int x = rand() % row;
	int y = rand() % col;
	while (1){
     
		if (board[x][y] == ' '){
     
			board[x][y] = '#';
			break;
		}
	}
}
//判断
int isfull(char board[ROW][COL], int row, int col){
     
	int i = 0;
	int j = 0;
	for (i = 0; i < row; i++){
     
		for (j = 0; j < col; j++){
     
			if (board[i][j] == ' '){
     
				return 0;
			}
		}
	}
	return 1;
}
char CheckWin(char board[ROW][COL], int row, int col){
     
	int i;
	//行成型
	for (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 (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];
		}
	}
	//对角线成型
	if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[0][0] != ' '){
     
		return board[0][0];
	}
	if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[0][0] != ' '){
     
		return board[0][0];
	}
	//平局
	if (isfull(board, row, col) == 1){
     
		return 'Q';
	}
	//游戏继续
	return 'C';
}

game.h

#define _CRT_SECURE_NO_WARNINGS 1
#include
#define ROW 3
#define COL 3
#include
#include
void initBoard(char board[ROW][COL],int row,int col);
void DisplayBoard(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);

三子棋小游戏_第3张图片

以上是我对于三子棋的大致讲解,作为初学者的小白,在写这个程序的时候花费了不少的时间,慢慢的有了大致的思路,当然,还有不少需要改进的地方,比如电脑不能够只能的阻拦玩家的棋子,在判断输赢这一块只能应用于三子棋。日后随着知识的积累,慢慢改进。如果还有需要改进的地方欢迎大家评论指出。

你可能感兴趣的:(编程,算法,c语言)