C语言---简单五子棋小游戏

效果图如下:
在这里插入图片描述

设计思路:
棋盘设计为15×15格,初始状态光标在棋盘的中央,白棋先走,轮流落子,当一方连成五子或下满棋盘时,游戏结束(连成五子的一方获胜,下满棋盘为和棋)。当游戏一方胜利后显示胜利信息,提示信息利用汉字点阵输出。
程序游戏是一个二维平面图,可用二维数组来实现,数组两个下标可以表示棋盘上的位置,数组元素的值代表棋格上的状态,共有三种情况,分别是0代表空格,1代表白棋,2代表黑棋。程序的主要工作是接收棋手按键操作,棋手1用设定四个键控制光标移动,回车键表示落子。棋手2用另四个键控制光标移动,空格键表示落子。接收到回车键或空格键,说明棋手落子,先判断是否是有效位置,即有棋子的位置不能重叠落子。落子成功后,马上判断以该位置为中心的八个方向:上、下、左、右、左上、左下、右上、右下是否有相同颜色的棋子连成五子,如果连成五子,则游戏结束。
在这里插入图片描述

#include<stdio.h>
#include<stdlib.h>
#include<iostream>
#include<graphics.h>
#include<windows.h>
#include <mmsystem.h>
#pragma comment(lib, "WINMM.LIB")
#include<conio.h>
#include<time.h>
#include<string.h>

#define width 32 //棋盘总宽度 
#define high 31  //棋盘总高度 
#define MAX_X 15 //棋盘横向格子数 
#define MAX_Y 15 //棋盘纵向格子数 
#define WIDTH (width+16) //游戏总宽度  
#define HIGH (high+4)    //游戏总高度 
#define player1 1 //玩家一 
#define player2 2 //玩家二
#define emptyPlayer 0//无子或无玩家 
#define Unplayer -2 //中途退出游戏,无玩家获胜 
#define MODEL_1 1//模式一
#define MODEL_2 2//模式二

typedef int position;
typedef int stackpointing;

typedef struct Stack {
	//记录下每次落子的坐标	 
	position x[MAX_X * MAX_Y];
	position y[MAX_X * MAX_Y];
	//相当于栈顶指针
	stackpointing top;
}Stack;

position pos[MAX_X][MAX_Y];//存储棋盘上各位置处的状态 比如有白子为1, 有黑子为2,无子为0 
position px, py; //光标位置  
int player = 1;//记录当前玩家 默认玩家从白方开始 
int flag1 = 0;//标志游戏开始 
int gameOver_player = -1;//判断结束的标志 
int pre_px = -1, pre_py = -1;//记录下上一次的坐标位置 

void gotoxy(int x, int y);//设置CMD窗口光标位置
void hide_cursor(); //隐藏CMD窗口光标
void map();//打印地图 
void game_Description();//打印动态游戏说明 
void initMapState();//初始化游戏位置数据 
void mapState(int qizi);//数组记录下对应位置的状态
int isGoPlay();//判断是否可以落子 
int hasGoPlay(int Player);//以落子处为中心,判断已经落子后的棋盘是否五子相连 
void goPlay(int Player, Stack* p);//落子 Player 1 2 0 
void yiDongKuang();//移动框 
void player1_move();//玩家1_移动 
void player2_move();//玩家2_移动 
int gameOver();//判断游戏是否结束
Stack* createStack();//创建空栈
void zhuJieMian();//主界面
void exit_WeiMu();//退出帷幕
void fengMian();//封面
void shuoming();//游戏帮助说明
int zhongJianJieMian();//中间界面,选择菜单
void fuXianQiZi(Stack* p);//复现棋子
void guangBiao_Limit();//光标限制
void touXiang();//投降
void push(Stack* p, int x, int y);//入栈 
void color(const unsigned short textColor);//自定义函根据参数改变颜色

//移动光标
void gotoxy(int x, int y)//设置CMD窗口光标位置
{
	COORD coord;
	coord.X = x;
	coord.Y = y;
	SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);
}
//隐藏光标
void hide_cursor() //隐藏CMD窗口光标
{
	CONSOLE_CURSOR_INFO cci;
	cci.bVisible = FALSE;
	cci.dwSize = sizeof(cci);
	HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
	SetConsoleCursorInfo(handle, &cci);
}
//颜色
void color(const unsigned short textColor) //自定义函根据参数改变颜色 
{
	if (textColor > 0 && textColor <= 15)     //参数在0-15的范围颜色
		SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), textColor);  //用一个参数,改变字体颜色
	else   //默认的字体颜色是白色
		SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 7);
}

//播放音乐
void playMusic()
{
	//music.wav是放在代码文件中
	PlaySound(TEXT("music.wav"), 0, SND_FILENAME | SND_ASYNC | SND_LOOP);
}

//打印地图
void map()
{
	int x, y;
	color(02);
	/*开始打印棋盘格子*/
	//打印横向图格
	for (y = 2; y < high - 1; y += 2) {
		for (x = 1; x < width - 2; x += 2) {
			gotoxy(x, y);
			printf("-+");
		}
	}
	//打印竖向图格
	for (y = 1; y < high; y += 2) {
		for (x = 2; x < width - 2; x += 2) {
			gotoxy(x, y);
			printf("|");
		}
	}
	/*打印棋盘格子结束*/


	 /*开始打印图框*/

	 //打印棋盘图框 
	for (y = 0; y < high; y++)
	{
		for (x = 0; x < width; x += 2)
		{
			if (x == 0 || x == width - 2) {
				gotoxy(x, y);
				printf("|");
			}
			if (y == 0 || y == high - 1) {
				gotoxy(x, y);
				printf("--");
			}
		}
	}
	//打印右图框 
	for (y = 0; y < high; y++) {
		for (x = width; x < WIDTH; x += 2) {
			if (x == WIDTH - 2) {
				gotoxy(x, y);
				printf("|");
			}
			if (y == 0 || y == high - 1) {
				gotoxy(x, y);
				printf("--");
			}
		}
	}
	//打印下图框 y->high ~ HiGH-1 x->0 ~ WIDTH-2
	for (y = high; y < HIGH; y++) {
		for (x = 0; x < WIDTH; x += 2) {
			if (x == 0 || x == WIDTH - 2) {
				gotoxy(x, y);
				printf("|");
			}
			if (y == high || y == HIGH - 1) {
				gotoxy(x, y);
				printf("--");
			}
		}
	}
	//打印下图框内容
	gotoxy(1, high + 1);
	printf("           欢迎来到五子棋游戏!");

	//打印右图框内容
	gotoxy(width - 1, 1);
	printf("游戏说明:");
	gotoxy(width - 1, 3);
	printf("1)X表示玩家一棋");
	gotoxy(width - 1, 4);
	printf("子,而O表示玩家");
	gotoxy(width - 1, 5);
	printf("二棋子");
	gotoxy(width - 1, 7);
	printf("2)X先、O后,交替");
	gotoxy(width - 1, 8);
	printf("下子,每次只能下");
	gotoxy(width - 1, 9);
	printf("一子");
	gotoxy(width - 1, 11);
	printf("3)棋子下在棋盘");
	gotoxy(width - 1, 12);
	printf("的格子内,棋子下");
	gotoxy(width - 1, 13);
	printf("定后,不得向其它");
	gotoxy(width - 1, 14);
	printf("点移动");
	gotoxy(width - 1, 16);
	printf("4)最先连成五子");
	gotoxy(width - 1, 17);
	printf("的一方即为获胜");

	gotoxy(width - 1, 19);
	printf("玩家一 移动键:");
	gotoxy(width - 1, 20);
	printf("w上 s下 a左 d右");
	gotoxy(width - 1, 21);
	printf("下子: 空格键");

	gotoxy(width - 1, 23);
	printf("玩家二 移动键:");
	gotoxy(width - 1, 24);
	printf("i上 k下 j左 l右");
	gotoxy(width - 1, 25);
	printf("下子:回车键");

	gotoxy(width + 1, 27);
	color(4);
	printf("游戏说明: P");
	gotoxy(width + 1, 29);
	color(6);
	printf("悔棋键: G");
	/*打印图框结束*/
	color(02);
	/*打印棋盘上的四个标记点*/
	gotoxy(3 * 2 + 2, 3 * 2 + 2);
	printf("*");
	gotoxy((MAX_X - 4) * 2, 3 * 2 + 2);
	printf("*");
	gotoxy(3 * 2 + 2, (MAX_Y - 4) * 2);
	printf("*");
	gotoxy((MAX_X - 4) * 2, (MAX_Y - 4) * 2);
	printf("*");
	/*打印结束*/

	/*开始修边*/
	/*gotoxy(width - 1, 0);
	printf(" ");
	gotoxy(width - 1, high - 1);
	printf(" ");*/
	/*修边结束*/

   /*打印地图完成*/

}

//打印动态游戏说明 
void game_Description()
{
	//打印下图框内容
	gotoxy(1, high + 1);
	printf("                               ");

	if (player == player1) {
		gotoxy(1, high + 1);
		color(2);
		printf("             玩家一下棋中...");

	}
	else if (player == player2) {
		gotoxy(1, high + 1);
		color(2);
		printf("             玩家二下棋中...");

	}
}
//初始化游戏位置数据 
void initMapState()
{
	for (int i = 0; i < MAX_Y; i++) {
		for (int j = 0; j < MAX_X; j++) {
			pos[i][j] = 0;//初始状态全为空
		}
	}

	//注意 光标的位置和存储在数组中的位置是不同的 
	px = 7;
	py = 7;

	gotoxy(py * 2 + 1, px * 2 + 1);//初始位置 
}

//数组记录下对应位置的状态 
void mapState(int qizi)
{ //2*px+1 = x //2*py+1 = y //px->0~14 //py->0~14 
	if (px >= MAX_X || px < 0 || py >= MAX_Y || py < 0)
		return;//其他情况不可以记录状态 

	pos[px][py] = qizi;
}

//判断是否可以落子 
int isGoPlay()
{
	if (px >= MAX_X || px < 0 || py >= MAX_Y || py < 0)
		return 0;//其他情况不可以记录状态 


	if (pos[px][py] == emptyPlayer) {//说明无子 
		return 1;
	}
	else {//说明有子 
		return 0;
	}

}

//以落子处为中心,判断已经落子后的棋盘是否五子相连 
int hasGoPlay(int Player)
{   //分为两部分,先记录一部分的相同Player的个数
	//再记录下另余部分的个数,相加为相连棋子总个数 
	int port1 = 0, port2 = 0;
	int x, y, count;
	//上下查找
	x = px, y = py - 1;
	while (y >= 0 && pos[x][y] == Player) {
		++port1;//上部分个数 
		--y;//上移 
	}
	y = py + 1;
	while (y < MAX_Y && pos[x][y] == Player) {
		++port2;//下部分个数 
		++y;//下移 
	}
	//计算总数 
	count = port1 + port2 + 1;
	if (count >= 5) return 1;

	//左右查找
	port1 = 0, port2 = 0;
	x = px - 1, y = py;
	while ( x >= 0 && pos[x][y] == Player ) {
		++port1;//上部分个数 
		--x;//左移 
	}
	x = px + 1;
	while (x < MAX_X && pos[x][y] == Player) {
		++port2;//下部分个数 
		++x;//右移 
	}
	//计算总数 
	count = port1 + port2 + 1;
	if (count >= 5) return 1;

	//左上右下查找
	port1 = 0, port2 = 0;
	x = px - 1, y = py - 1;
	while (  x >= 0 && y >= 0 && pos[x][y] == Player) {
		++port1;//上部分个数 
		--x;//左移
		--y;//上移 
	}
	x = px + 1, y = py + 1;
	while ( x < MAX_X && y < MAX_Y && pos[x][y] == Player ) {
		++port2;//下部分个数 
		++x;//右移 
		++y;//下移 
	}
	//计算总数 
	count = port1 + port2 + 1;
	if (count >= 5) return 1;

	//右上左下查找
	port1 = 0, port2 = 0;
	x = px + 1, y = py - 1;
	while ( x < MAX_X && y >= 0 && pos[x][y] == Player ) {
		++port1;//上部分个数 
		++x;//左移
		--y;//上移 
	}
	x = px - 1, y = py + 1;
	while ( x >= 0 && y < MAX_Y && pos[x][y] == Player ) {
		++port2;//下部分个数 
		--x;//右移 
		++y;//下移 
	}
	//计算总数 
	count = port1 + port2 + 1;
	if (count >= 5) return 1;

	return 0;
}

//落子 Player 1 2 0 
void goPlay(int Player, Stack* p)
{
	if (isGoPlay()) {//说明可以落子 
		mapState(Player);//将对应位置的情况记录在数组中 

		if (hasGoPlay(Player)) {//如果五子相连,则 gameover
			gameOver_player = Player;  //记录此刻胜利玩家,结束游戏 
		}

		/*入栈*/
		push(p, px, py);

		/*角色切换*/
		if (Player == player1) {
			player = player2;//切换成玩家1 
			gotoxy(px * 2 + 1, py * 2 + 1);//将光标移动到对应位置 
			color(07);
			printf("X");//打印玩家1 
			game_Description();// 动态说明 
		}
		else if (Player == player2) {
			player = player1;//切换成另一个玩家2
			gotoxy(px * 2 + 1, py * 2 + 1);//将光标移动到对应位置 
			color(07);
			printf("O");//打印玩家2 
			game_Description();// 动态说明 
		}

	}
}

//入栈 
void push(Stack* p, int x, int y)
{
	//将此刻的坐标入栈 
	int top = p->top;
	++p->top;//移动栈针 

	p->x[top] = x;
	p->y[top] = y;

	return;
}

//出栈 
void pop(Stack* p)
{
	int x, y;
	//出栈,移动栈顶指针 
	//如果栈为空,则不弹出 
	if (p->top <= 0) return;

	--p->top;
	int top = p->top;
	//记录下弹出的位置 
	x = p->x[top];
	y = p->y[top];
	//在弹出位置打印空格 
	gotoxy(x * 2 + 1, y * 2 + 1);
	printf(" ");
	//抹除记录 
	pos[x][y] = 0;
}

//移动框 
void yiDongKuang()
{
	//限制光标范围 
	if (py < 0) py = 0;
	else if (py > MAX_Y - 1) py = MAX_Y - 1;
	else if (px < 0) px = 0;
	else if (px > MAX_X - 1) px = MAX_X - 1;

	//打印移动框 
	gotoxy(px * 2, py * 2 + 1);
	color(11);
	printf("[");
	gotoxy(px * 2 + 2, py * 2 + 1);
	printf("]");
	//打印移动框结束 
	if (pre_px != -1 && pre_py != -1) {
		if (pre_px > px && pre_py == py) {//当向左移动时 
			//将上一个位置的右边保持原样 
			gotoxy(pre_px * 2 + 2, pre_py * 2 + 1);
			color(2);
			printf("|");
		}
		else if (pre_px < px && pre_py == py) {//当向右移动时 
		   //将上一个位置的左边保持原样 
			gotoxy(pre_px * 2, pre_py * 2 + 1);
			color(2);
			printf("|");
		}
		else {//当向上下移动时 
		   //将上一个位置的左右边保持原样 
			gotoxy(pre_px * 2 + 2, pre_py * 2 + 1);
			color(2);
			printf("|");
			gotoxy(pre_px * 2, pre_py * 2 + 1);
			color(2);
			printf("|");
		}
	}
	pre_px = px;
	pre_py = py;
}

//复现全部玩家棋子
void fuXianQiZi(Stack* p)
{
	if (p->top <= 0) return;
	int top = p->top - 1;//注意栈顶指针不移动,只是被记录下来了
	int x, y, flag;
	
	if (player == player1) flag = 1;
	else if (player == player2) flag = 2;
	else return;

	while (top>=0) {
		//记录下弹出的位置 
		x = p->x[top];
		y = p->y[top];
		//在弹出位置打印空格 
		if (flag == 1) {
           gotoxy(x * 2 + 1, y * 2 + 1);
		   color(7);
		   printf("O");
		   flag = 2;
		}
		else {
		   gotoxy(x * 2 + 1, y * 2 + 1);
		   color(7);
		   printf("X");
		   flag = 1;
		}
		--top;//记录位置向后移动
	}
}

//玩家1 移动 
void player1_move(Stack* p)
{
	char key;
	if (_kbhit())//检测是否按键 
	{
		fflush(stdin);
        key = _getch();//保存按键
		
        switch (key)
	    {
	       case 'w': py--; yiDongKuang(); break;//上 
	       case 'a': px--; yiDongKuang(); break;//左 
	       case 'd': px++; yiDongKuang(); break;//右 
	       case 's': py++; yiDongKuang(); break;//下	
	       case ' ': goPlay(player1, p); game_Description();break;//落子//动态说明 
	       case 'y': gameOver_player = -2; gameOver();//退出游戏
	       case 'Y': gameOver_player = -2; gameOver();//退出游戏
	       case 'g': pop(p); pop(p); break;//悔棋 
	       case 'G': pop(p); pop(p); break;//悔棋 
		   case 'p': shuoming(); system("cls"); map(); fuXianQiZi(p); break;//查看说明书
		   case 'P': shuoming(); system("cls"); map(); fuXianQiZi(p); break;//查看说明书
		   case 'f': touXiang(); break;//投降
		   case 'F': touXiang(); break;//投降
		   default: break;
	    }
	}

	
}

//玩家2 移动 
void player2_move(Stack* p)
{
	char key;
	if (_kbhit())//检测是否按键,用来强制将缓冲区中的内容写入文件。
	{
		fflush(stdin);//清除一个流,即清除文件缓冲区
        key = _getch();//保存按键
		
		switch (key)
	    {
	       case 'i': py--; yiDongKuang(); break;//上 
	       case 'j': px--; yiDongKuang(); break;//左 
	       case 'l': px++; yiDongKuang(); break;//右 
	       case 'k': py++; yiDongKuang(); break;//下
	       case '\r': goPlay(player2, p); game_Description(); break;//落子//动态说明
	       case 'y': gameOver_player = -2; gameOver();//退出游戏
	       case 'Y': gameOver_player = -2; gameOver();//退出游戏 
	       case 'g': pop(p); pop(p); break;//悔棋 
	       case 'G': pop(p); pop(p); break;//悔棋
		   case 'p': shuoming();  system("cls"); map(); fuXianQiZi(p); break;//查看说明书
		   case 'P': shuoming();  system("cls"); map(); fuXianQiZi(p); break;//查看说明书
		   case 'f': touXiang(); break;//投降
		   case 'F': touXiang(); break;//投降
		   default: break;
	    }

	}

	
}

//创建空栈 
Stack* createStack() {
	//申请空间 
	Stack* p = (Stack*)malloc(sizeof(Stack));
	//如果未申请到空间 
	if (p == NULL) return NULL;

	p->top = 0;//初始化栈顶 
	return p;
}

//判断游戏是否结束 
int gameOver()
{    //gamerOver_player -1 表示继续游戏 1 表示白方胜利 2 表示黑方胜利 0 表示平局  
	//五子相连 一方取胜 y->high ~ HiGH-1 x->0 ~ WIDTH-2
	if (gameOver_player == -1) {
		return 1;
	}
	else if (gameOver_player == player1) {//白方胜利 
		gotoxy(1, high + 1);
		color(04);
		printf("              玩家1胜利!!!               ");
		color(02);
		return 0;
	}
	else if (gameOver_player == player2) {//黑方胜利 
		gotoxy(1, high + 1);
		color(04);
		printf("              玩家2胜利!!!               ");
		color(02);
		return 0;
	}
	else if (gameOver_player == emptyPlayer) {//棋盘满棋 平局 
		gotoxy(1, high + 1);
		color(06);
		printf("                   平局!!!               ");
		color(02);
		return 0;
	}
	else if (gameOver_player == Unplayer) {//中途退出 
		color(02);
		exit_WeiMu();//退出游戏的帷幕 

		system("cls");
		gotoxy(WIDTH / 2 - 10, HIGH / 2);
		printf("退出游戏成功!!!");
		gotoxy(WIDTH / 2 - 10, HIGH / 2 - 2);
		printf("再次感谢您的支持!");
		gotoxy(0, 0);
		exit(1);
		exit(1);
	}
	return 1;
}

//游戏帮助说明
void shuoming()		
{
	int x, y;
	system("cls");
	color(02);
	//打印边框 
	for (y = 0; y < HIGH; y++){
		for (x = 0; x < WIDTH; x += 2){

			if (x == 0 || x == WIDTH - 2) {
				gotoxy(x, y);
				printf("*");
			}
			if (y == 0 || y == HIGH - 1) {
				gotoxy(x, y);
				printf("* ");
			}
		}
	}
	//打印完成 
	//打印内容    
	while (1)
	{
		gotoxy(4, 3);
		printf("游戏规则如下:\n");
		gotoxy(6, 5);
		printf("游戏双方轮流下子,o表示玩家一");
		gotoxy(6, 7);
		printf(",x表示玩家二,先由玩家一在方");
		gotoxy(6, 9);
		printf("框内下子,再由玩家二在方框内下");
		gotoxy(6, 11);
		printf("子,最先下满五子的玩家胜利!(");
		gotoxy(6, 13);
		printf("游戏只支持无禁手)o( ̄┰ ̄*)ゞ");
		
		gotoxy(4, 15);
		printf("相关按键说明:");
		gotoxy(6, 17);
		printf("< Y 键 :退 出 游 戏 >");
		gotoxy(6, 18);
		printf("< G 键 :悔 棋 >");
		gotoxy(6, 19);
		printf("< P 键 :查 看 游 戏 说 明 >");
		gotoxy(6, 20);
		printf("< F 键 :投 降 >");
       
	
		gotoxy(WIDTH / 2 - 10, HIGH - 4);
		printf("<  U 键 :返 回  >");
		
		if (_kbhit())//检测是否按键 
		{
			fflush(stdin);
			if (_getch() == 'u' || _getch() == 'U')
			{
				//如果按下空格键,则退出说明界面 
				return;
			}
		}

	}
	//打印完成 
}

//退出游戏界面的帷幕 
void exit_WeiMu()
{
	int x, y;
	color(2);
	for ( y = 0; y < HIGH; y++) {
		for ( x = 0; x < WIDTH; x += 2) {
			gotoxy(x, y);
			printf("■");

		}
		Sleep(100);
	}

	for ( y = HIGH - 1; y >= 0; y--) {
		for ( x = WIDTH; x >= 0; x -= 2) {
			gotoxy(x, y);
			printf("  ");
		}
		Sleep(100);
	}

}

//打印主界面封面
void fengMian()
{
	int x, y, z, add = 0;
	//点阵打印五子棋
	color(06);
	gotoxy(6, 3);
	printf("******");
	gotoxy(8, 4);
	printf("* ");
	gotoxy(6, 5);
	printf("*****");
	gotoxy(8, 6);
	printf("* *");
	gotoxy(5, 7);
	printf("********");
	
	color(04);
	gotoxy(17, 3);
	printf("*****");
	gotoxy(20, 4);
	printf("*  ");
	gotoxy(16, 5);
	printf("*********");
	gotoxy(20, 6);
	printf("*  ");
	gotoxy(19, 7);
	printf("**  ");

	color(3);
	gotoxy(30, 3);
	printf("*     * * ");
	gotoxy(28, 4);
	printf("***** *******");
	gotoxy(29, 5);
	printf("***    * *  ");
	gotoxy(28, 6);
	printf("* * * * *** *");
	gotoxy(28, 7);
	printf("* * *  *   * ");

	color(10);
	gotoxy(1, 10);
	printf(" * * * * * * * * * * * * * * * * * * * * * * ");

	//打印完成 
	//打印封面 
	//建一个房子 
	
	for (z = 0; z < 14; z++, add++) {
        color(3);
		gotoxy(WIDTH / 2 - 6, HIGH - 2 - add);
		printf("┌");
		color(4);
		gotoxy(WIDTH / 2 - 4, HIGH - 2 - add);
		printf("╀");
		color(6);
		gotoxy(WIDTH / 2 - 2, HIGH - 2 - add);
		printf("┣");
	}
	color(1);
	gotoxy(WIDTH / 2 - 4, HIGH - 2 - add);
	printf("┬╂┬");

	color(2);
	gotoxy(WIDTH / 2 - 4, HIGH - 3 - add);
	printf(" ╳");
	// 另建一个房子 
	add = 0;
	for (z = 0; z < 8; z++, add++) {
		color(3);
		gotoxy(WIDTH / 2 + 4, HIGH - 2 - add);
		printf("┌");
		color(4);
		gotoxy(WIDTH / 2 + 6, HIGH - 2 - add);
		printf("╀");
		color(6);
		gotoxy(WIDTH / 2 + 8, HIGH - 2 - add);
		printf("┣");
	}
	color(1);
	gotoxy(WIDTH / 2 + 6, HIGH - 2 - add);
	printf("┬╂┬");

	color(2);
	gotoxy(WIDTH / 2 + 6, HIGH - 3 - add);
	printf(" ╳");
	
	//房子建完
	//建几棵树 
	color(3);
   	gotoxy(WIDTH / 2 + 16, HIGH - 3);
	printf("○");

	gotoxy(WIDTH / 2 + 16, HIGH - 2);
	printf("|");

	gotoxy(WIDTH / 2 + 18, HIGH - 3);
	printf("○");

	gotoxy(WIDTH / 2 + 18, HIGH - 2);
	printf("|");

	for (int i = 0; i < 10; i += 2)
	{
		gotoxy(WIDTH / 2 - 10 - i, HIGH - 3);
		printf("○");

		gotoxy(WIDTH / 2 - 10 - i, HIGH - 2);
		printf("|");
	}
	gotoxy(WIDTH / 2 - 22, HIGH - 3);
	printf("○");

	gotoxy(WIDTH / 2 - 22, HIGH - 2);
	printf("|");

	hide_cursor();//隐藏光标 
	//建树完成 
	

	//打印边框 
	color(2);
	for (y = 0; y < HIGH; y++)
	{
		for (x = 0; x < WIDTH; x += 2)
		{
			if (x == 0 || x == WIDTH - 2) {
				gotoxy(x, y);
				printf("*");
			}
			if (y == 0 || y == HIGH - 1) {
				gotoxy(x, y);
				printf("* ");
			}
		}
	}
	//打印边框完成 
	//打印封面完成   
}

//中间界面
int zhongJianJieMian()
{
	system("cls");

	int x, y, a = 0, choice = 0;
	//打印边框 
	for (y = 0; y < HIGH; y++)
	{
		for (x = 0; x < WIDTH; x += 2)
		{
			if (x == 0 || x == WIDTH - 2) {
				gotoxy(x, y);
				printf("*");
			}
			if (y == 0 || y == HIGH - 1) {
				gotoxy(x, y);
				printf("* ");
			}
		}
	}
	//打印完成 

	while (1) {
		//不断检测是否存在按键操作,如果存在,就根据不同的按键操作,表示不同状态 
		if (GetAsyncKeyState(VK_UP) || GetAsyncKeyState(87) || GetAsyncKeyState(119))		//按上
		{
			if (a == 0)
				a = 2;
			else if (a == 1)
				a = 0;
			else if (a == 2)
				a = 1;
		}
		if (GetAsyncKeyState(VK_DOWN) || GetAsyncKeyState(83) || GetAsyncKeyState(115))		//按下
		{
			if (a == 0)
				a = 1;
			else if (a == 1)
				a = 2;
			else if (a == 2)
				a = 0;
		}
		if (GetAsyncKeyState('\r'))
		{
			if (a == 0) {
				return MODEL_1;//返回模式一
			}
			else if (a == 1) {
				return MODEL_2;//返回模式二
			}
			else{
				system("cls");//回到主界面
				return 0;
			}
		}

		if (a == 0) {
			gotoxy(WIDTH / 2 - 8, 12);
			printf("△ 模式一:双人模式");
		}
		else {
			gotoxy(WIDTH / 2 - 8, 12);
			printf("   模式一:双人模式");
		}
		if (a == 1) {
			gotoxy(WIDTH / 2 - 8, 14);
			printf("△ 模式二:单机模式");
		}
		else {
			gotoxy(WIDTH / 2 - 8, 14);
			printf("   模式二:单机模式");
		}
		if (a == 2) {
			gotoxy(WIDTH / 2 - 8, 16);
			printf("△ 返回主界面 ");
		}
		else {
			gotoxy(WIDTH / 2 - 8, 16);
			printf("   返回主界面 ");
		}
		//提示闪烁文字 
		if (choice == 2) {
			gotoxy(WIDTH / 2 - 10, HIGH - 4);
			printf(" <回车键确认> ");
			Sleep(200);//防止闪屏 
			choice = 0;
		}
		else {
			gotoxy(WIDTH / 2 - 10, HIGH - 4);
			printf("               ");
			Sleep(200);
			choice++;
		}
	}

}

//主界面 
void zhuJieMian()
{
	int a = 0;
	int choice = 1;
	fengMian();//打印主界面封面 

	while (1) {
		//不断检测是否存在按键操作,如果存在,就根据不同的按键操作,表示不同状态 
		if (GetAsyncKeyState(VK_UP) || GetAsyncKeyState(87) || GetAsyncKeyState(119))		//按上
		{
			if (a == 0)
				a = 2;
			else if (a == 1)
				a = 0;
			else if (a == 2)
				a = 1;
		}
		if (GetAsyncKeyState(VK_DOWN) || GetAsyncKeyState(83) || GetAsyncKeyState(115))		//按下
		{
			if (a == 0)
				a = 1;
			else if (a == 1)
				a = 2;
			else if (a == 2)
				a = 0;
		}
		if (GetAsyncKeyState('\r'))
		{
			if (a == 0) {//进入游戏
                   
					system("cls");//清屏
					return ;
			}
			else if (a == 1) {
				shuoming();//游戏帮助说明 
				system("cls");//清屏 
				fengMian();//重新打印封面 
			}
			else if (a == 2) {

				exit_WeiMu();//退出游戏的帷幕 

				system("cls");
				gotoxy(WIDTH / 2 - 10, HIGH / 2);
				printf("退出游戏成功!!!");
				gotoxy(WIDTH / 2 - 10, HIGH / 2 - 2);
				printf("再次感谢您的支持!");
				gotoxy(6, 22);
				printf("当然,后续将会开发新的模式,比");
				gotoxy(6, 24);
				printf("单机模式,禁手模式等等。在此感");
				gotoxy(6, 26);
				printf("谢大家的支持,敬请期待!!!");

				gotoxy(0, 0);
				exit(1);
			}
		}

		if (a == 0) {
			gotoxy(WIDTH / 2 - 8, 12);
			color(4);
			printf("△ 开始游戏 ");
		}
		else {
			gotoxy(WIDTH / 2 - 8, 12);
			color(2);
			printf("   开始游戏 ");
		}
		if (a == 1) {
			gotoxy(WIDTH / 2 - 8, 14);
			color(4);
			printf("△ 游戏帮助 ");
		}
		else {
			gotoxy(WIDTH / 2 - 8, 14);
			color(2);
			printf("   游戏帮助 ");
		}
		if (a == 2) {
			gotoxy(WIDTH / 2 - 8, 16);
			color(4);
			printf("△ 退出游戏 ");
		}
		else {
			gotoxy(WIDTH / 2 - 8, 16);
			color(2);
			printf("   退出游戏 ");
		}
		//闪烁提示文字 
		if (choice == 2) {
			gotoxy(WIDTH / 2 + 4, 12);
			color(7);
			printf(" <回车键确认> ");
			Sleep(200);//防止闪屏 
			choice = 0;
		}
		else {
			gotoxy(WIDTH / 2 + 4, 12);
			printf("               ");
			Sleep(200);
			choice++;
		}
	}
}

//投降
void touXiang()
{
	if (player == player1) {//玩家1投降
		
		gameOver_player = 2;//玩家2胜利
	}
	else {//玩家2投降
		gameOver_player = 1;//玩家1胜利
	}
}

int main() {

	//设置标题
	system("title 五子棋小游戏");
	//调整游戏框 
	system("mode con cols=48 lines=35");
	//启动背景音乐//这个需要有相应的 .wav文件 
	playMusic();
     //主界面
	zhuJieMian();
    //中间界面--选择模式
	while (!zhongJianJieMian()) {  
		Sleep(100);
	    //主界面
		zhuJieMian();
	}
	//打印地图    
	map();
	//初始化游戏位置数据	
	initMapState();
	//创建空栈
	Stack* p = createStack();
	//隐藏光标	
	hide_cursor();
   
	//游戏循环 控制移动	
	while (gameOver()) {
		//不断调换人物 
		if (player == player1)
			player1_move(p);// 切换玩家1 
		else if (player == player2)
			player2_move(p);// 切换玩家2 
	}

	free(p);
}
  • 27
    点赞
  • 115
    收藏
    觉得还不错? 一键收藏
  • 12
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值