c语言三子棋程序_将文本效果设置为棋盘下教程

c语言三子棋程序_将文本效果设置为棋盘下教程我觉得最好的就是第三个版本,因为要是想改变棋盘的大小只需要在game.h中修改对象宏的大小即可,前两个版本都有一定的缺陷,我建议使用第三个版本来实现棋盘的打印,这样可以使代码的可读性和后期的修改

一、整个程序的实现思路及设计

实现思路
1.打印一个简单的菜单供玩家选择如下:
image.png
2.玩家下棋
3.电脑下棋
4.判断输赢
5.循环菜单是否要继续游戏
使用多文件的方式编写

  • test.c文件游戏的框架
  • game.c文件游戏的实现
  • game.h文件游戏函数的声明

二、test.c文件的设计

在主函数(main)中的设计

int main()
{ 
   
	int input = 0;
	srand((unsigned int)time(NULL));
	do
	{ 
   
		menu();
		printf("请选择:>");
		scanf("%d", &input);
		switch (input)
		{ 
   
		case 1:
			//printf("三子棋\n");
			game();
			break;
		case 0:
			printf("退出游戏\n");
			break;
		default:
			printf("请输入合理的选择\n");
			break;
		}

	} while (input);
	return 0;
}

使用menu()函数来打印菜单;

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

}

使用do…while循环打印菜单;
使用srand()函数来随机生成电脑下的棋子;
使用switch根据玩家的选择来进行不同的实现;
游戏的实现放在game函数中;

void game()
{ 
   
	//char board[3][3] = { 0 };
	初始化棋盘
	//InitBoard(board, 3, 3);

	//定义一个数组用来存放数据
	char board[ROW][COL] = { 
    0 };
	//初始化棋盘
	InitBoard(board, ROW, COL);
	//打印棋盘
	DispalyBoard(board, ROW, COL);
	char ret = '0';
	while (1)
	{ 
   
		//玩家下棋
		PlayerMove(board, ROW, COL);
		//打印棋盘
		DispalyBoard(board, ROW, COL);
		ret=IsWin(board, ROW, COL);
		if (ret!='c')
		{ 
   
			break;
		}
		//电脑下棋
		ComputerMove(board, ROW, COL);
		//打印棋盘
		DispalyBoard(board, ROW, COL);
		ret=IsWin(board, ROW, COL);
		if (ret != 'c')
		{ 
   
			break;
		}
	}
	if (ret=='*')
	{ 
   
		printf("玩家赢\n");
	}
	else if (ret == '#')
	{ 
   
		printf("电脑赢\n");
	}
	else
	{ 
   
		printf("平局\n");
	}
}

整个test.c文件的代码如下:

#define _CRT_SECURE_NO_WARNINGS 1
#include"game.h"
void menu()
{ 
   
	printf("***********************************\n");
	printf("************ 1.paly ********\n");
	printf("************ 0.exit ********\n");
	printf("***********************************\n");

}

void game()
{ 
   
	//char board[3][3] = { 0 };
	初始化棋盘
	//InitBoard(board, 3, 3);

	//定义一个数组用来存放数据
	char board[ROW][COL] = { 
    0 };
	//初始化棋盘
	InitBoard(board, ROW, COL);
	//打印棋盘
	DispalyBoard(board, ROW, COL);
	char ret = '0';
	while (1)
	{ 
   
		//玩家下棋
		PlayerMove(board, ROW, COL);
		//打印棋盘
		DispalyBoard(board, ROW, COL);
		ret=IsWin(board, ROW, COL);
		if (ret!='c')
		{ 
   
			break;
		}
		//电脑下棋
		ComputerMove(board, ROW, COL);
		//打印棋盘
		DispalyBoard(board, ROW, COL);
		ret=IsWin(board, ROW, COL);
		if (ret != 'c')
		{ 
   
			break;
		}
	}
	if (ret=='*')
	{ 
   
		printf("玩家赢\n");
	}
	else if (ret == '#')
	{ 
   
		printf("电脑赢\n");
	}
	else
	{ 
   
		printf("平局\n");
	}
}

int main()
{ 
   
	int input = 0;
	srand((unsigned int)time(NULL));
	do
	{ 
   
		menu();
		printf("请选择:>");
		scanf("%d", &input);
		switch (input)
		{ 
   
		case 1:
			//printf("三子棋\n");
			game();
			break;
		case 0:
			printf("退出游戏\n");
			break;
		default:
			printf("请输入合理的选择\n");
			break;
		}

	} while (input);
	return 0;
}

三、game.h文件的设计

此文件主要用来声明函数如下:

#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#define ROW 3
#define COL 3
//版本一没有使用对象宏来定义,以后修改更加的麻烦,
//void InitBoard(char board[3][3], int row, int col);
//初始化棋盘,放置空格
void InitBoard(char board[ROW][COL], int row, int col);
//声明打印棋盘的函数
void DispalyBoard(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 IsWin(char board[ROW][COL],int row,int col);

四、game.c文件的设计

1.使用InitBoard()函数初始化棋盘

void InitBoard(char board[ROW][COL], int row, int col)
{ 
   
	int i = 0;
	//打印行
	for ( i = 0; i < row; i++)
	{ 
   
		//打印列
		int j = 0;
		for ( j = 0; j < col; j++)
		{ 
   
			board[i][j] = ' ';
		}
	}
}

2.使用DispalyBoard()函数打印棋盘
版本一:

void DispalyBoard(char board[ROW][COL], 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]);
		}
		printf("\n");
	}
}

版本二:

void DispalyBoard(char board[ROW][COL], int row, int col)
{ 
   
	int i = 0;
	for (i = 0; i < row; i++)
	{ 
   
		//打印数据
		printf(" %c | %c | %c ", board[i][0], board[i][1], board[i][2]);
		printf("\n"); 
		//打印分割行
		if (i<row-1)
		{ 
   
			printf("---|---|---");
			printf("\n");
		}
		
	}
}

版本三:

void DispalyBoard(char board[ROW][COL], 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");
		//打印分割行 最后一行不答应所以需要判断
		if (i < row - 1)
		{ 
   
			int j = 0;
			for ( j = 0; j < col; j++)
			{ 
   
				printf("---");
				//最后一个|不打印所以也需要判断
				if (j<col-1)
				{ 
   
					printf("|");
				}
			}
			printf("\n");
		}

	}
}

就以上三个版本来说:
我觉得最好的就是第三个版本,因为要是想改变棋盘的大小只需要在game.h中修改对象宏的大小即可,前两个版本都有一定的缺陷,我建议使用第三个版本来实现棋盘的打印,这样可以使代码的可读性和后期的修改更好。
3.使用PlayerMove()函数实现玩家下棋

void PlayerMove(char board[ROW][COL], int row, int col)
{ 
   
	int x = 0;
	int y = 0;
	printf("请输入坐标:\n");

	while (1)
	{ 
   
		printf("玩家请输入,左边使用空格隔开:>");
		scanf("%d %d", &x, &y);
		//判断坐标的合法性
		if (x >= 1 && x <= row && y >= 1 && y <= col)
		{ 
   
			//判断坐标是否被占用
			if (board[x-1][y-1]==' ')
			{ 
   
				board[x - 1][y - 1] = '*';
				break;
			}
			else
			{ 
   
				printf("坐标被占用,请重新输入。\n");
			}
		}
		else
		{ 
   
			printf("坐标不合法,请输入合法的坐标:\n");
		}
	}
}

以上的代码进行了两次判断:

  • 第一次是判断坐标输入是否合法(也就是坐标是否在棋盘的范围)
  • 第二次是判断坐标是否被占用,要是被占用就使用循环重新输入;

4.使用ComputerMove()函数实现电脑下棋

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

其中使用了rand()函数它的作用是生成随机的值

  • 使用rand()%row是来控制随机值的大小
  • 同时还要再主函数中使用srand()函数来声明
  • 再game.h头文件中还要引用两个头文件(stdlib.h和time.h)

5.使用IsWin()函数实现结果的判断
版本一:

char IsWin(char board[ROW][COL], int row, int col)
{ 
   
	//赢
	//行
	int i = 0;
	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][2] == board[1][1] && board[1][1] == board[2][0] && board[1][1] != ' ')
	{ 
   
		return board[1][1];
	}
	//平局
	if (IsFull(board,row,col)==1)
	{ 
   
		return 'Q';
	}
	//继续
	return 'c';
}

版本二:

char IsWin(char board[ROW][COL], int row, int col)
{ 
   
	//赢
	int i = 0;
	for (i = 0; i < row; i++) { 
   
		int j = 0;
		for (j = 0; j < col; j++) { 
   
			//不为空字符进入判断
			if (board[i][j] != ' ') { 
   
				//如果列上连续的三个值相等就返回,注意j+2不能超过列
				if (j < col - 2 && board[i][j] == board[i][j + 1] && board[i][j + 1] == board[i][j + 2]) { 
   
					return board[i][j];
				}
				//如果行上连续的三个值相等就返回,注意i+2不能超过行
				else if (i < col - 2 && board[i][j] == board[i + 1][j] && board[i + 1][j] == board[i + 2][j]) { 
   
					return board[i][j];
				}
				//如果左斜线上连续的三个值相等就返回
				else if (i < row - 2 && j < col - 2 && board[i][j] == board[i + 1][j + 1] && board[i + 1][j + 1] == board[i + 2][j + 2]) { 
   
					return board[i][j];
				}
				//如果右斜线上连续的三个值相等就返回
				else if (i >= 2 && j <= i && board[i][j] == board[i - 1][j + 1] && board[i - 1][j + 1] == board[i - 2][j +2]) { 
   
					return board[i][j];
				}
			}

		}
	}
	//平局
	if (IsFull(board, row, col) == 1)
	{ 
   
		return 'Q';
	}
	//继续
	return 'c';
}

以上的两个版本我更加喜欢第二个版本:

  • 当棋盘的大小改变的时候,也可以进行判断不需要再次修改代码
  • 版本一只适合3*3的棋盘

综上考虑个人觉得第二个版本更加的好
6.使用IsFull()函数判断棋盘是否下满

int IsFull(char board[ROW][COL], int row, int col)
{ 
   
    //遍历整个数组看数组中是否存放有空格
	int i = 0;
	for ( i = 0; i < row; i++)
	{ 
   
		int j = 0;
		for ( j = 0; j < col; j++)
		{ 
   
			if (board[i][j]==' ')
			{ 
   
				return 0;
			}
		}
	}
	return 1;
}

下面是game.c完整的代码:

#define _CRT_SECURE_NO_WARNINGS 1
#include "game.h"

//初始化棋盘
void InitBoard(char board[ROW][COL], int row, int col)
{ 
   
	int i = 0;
	//打印行
	for ( i = 0; i < row; i++)
	{ 
   
		//打印列
		int j = 0;
		for ( j = 0; j < col; j++)
		{ 
   
			board[i][j] = ' ';
		}
	}
}
//版本1
//void DispalyBoard(char board[ROW][COL], 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]);
// }
// printf("\n");
// }
//}

//版本二
//void DispalyBoard(char board[ROW][COL], int row, int col)
//{ 
   
// int i = 0;
// for (i = 0; i < row; i++)
// { 
   
// 打印数据
// printf(" %c | %c | %c ", board[i][0], board[i][1], board[i][2]);
// printf("\n"); 
// 打印分割行
// if (i<row-1)
// { 
   
// printf("---|---|---");
// printf("\n");
// }
// 
// }
//}

//版本三
void DispalyBoard(char board[ROW][COL], 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");
		//打印分割行 最后一行不答应所以需要判断
		if (i < row - 1)
		{ 
   
			int j = 0;
			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 x = 0;
	int y = 0;
	printf("请输入坐标:\n");

	while (1)
	{ 
   
		printf("玩家请输入,左边使用空格隔开:>");
		scanf("%d %d", &x, &y);
		//判断坐标的合法性
		if (x >= 1 && x <= row && y >= 1 && y <= col)
		{ 
   
			//判断坐标是否被占用
			if (board[x-1][y-1]==' ')
			{ 
   
				board[x - 1][y - 1] = '*';
				break;
			}
			else
			{ 
   
				printf("坐标被占用,请重新输入。\n");
			}
		}
		else
		{ 
   
			printf("坐标不合法,请输入合法的坐标:\n");
		}
	}
}

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

//判断棋盘是否下满
int IsFull(char board[ROW][COL], int row, int col)
{ 
   
	int i = 0;
	for ( i = 0; i < row; i++)
	{ 
   
		int j = 0;
		for ( j = 0; j < col; j++)
		{ 
   
			if (board[i][j]==' ')
			{ 
   
				return 0;
			}
		}
	}
	return 1;
}



//判断结果的第二个版本
char IsWin(char board[ROW][COL], int row, int col)
{ 
   
	//赢
	int i = 0;
	for (i = 0; i < row; i++) { 
   
		int j = 0;
		for (j = 0; j < col; j++) { 
   
			//不为空字符进入判断
			if (board[i][j] != ' ') { 
   
				//如果列上连续的三个值相等就返回,注意j+2不能超过列
				if (j < col - 2 && board[i][j] == board[i][j + 1] && board[i][j + 1] == board[i][j + 2]) { 
   
					return board[i][j];
				}
				//如果行上连续的三个值相等就返回,注意i+2不能超过行
				else if (i < col - 2 && board[i][j] == board[i + 1][j] && board[i + 1][j] == board[i + 2][j]) { 
   
					return board[i][j];
				}
				//如果左斜线上连续的三个值相等就返回
				else if (i < row - 2 && j < col - 2 && board[i][j] == board[i + 1][j + 1] && board[i + 1][j + 1] == board[i + 2][j + 2]) { 
   
					return board[i][j];
				}
				//如果右斜线上连续的三个值相等就返回
				else if (i >= 2 && j <= i && board[i][j] == board[i - 1][j + 1] && board[i - 1][j + 1] == board[i - 2][j +2]) { 
   
					return board[i][j];
				}
			}

		}
	}
	//平局
	if (IsFull(board, row, col) == 1)
	{ 
   
		return 'Q';
	}
	//继续
	return 'c';
}

以上就是我关于使用C语言怎么自定义棋盘大小来实现三子棋的代码,希望能帮到大家,更好的掌握这门语言,请大家给我多评论,让我知道自己的不足,从而大家共同进步。谢谢大家的点赞!!!!!!!!!!!

今天的文章c语言三子棋程序_将文本效果设置为棋盘下教程分享到此就结束了,感谢您的阅读。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/88438.html

(0)
编程小号编程小号

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注