[c language] backgammon (EasyX graphics library + background music)

Hello everyone, do you feel that you have written a lot of C language codes, and you are faced with black-framed consoles. When we have learned the basics of C language knowledge and the EasyX graphics library, we can finally say goodbye to the black-framed frames. Today I want to share with you Everyone’s is a small game of backgammon, let’s learn together with Xiao Zhang


EasyX graphics library installation

Graphics library link

insert image description here
1. Click to download

insert image description here
2. Install the installation package corresponding to your integrated development environment, I use vs2019

insert image description here
3.ok, we use the library function and add the header file

Drawing of the chessboard

Note that the creation must be .cpp, otherwise the graphics library will not be used

insert image description hereThe size of the chessboard is 15*15. The length and width of each grid are 30. The radius of each chess piece is 13. The length of the checkerboard is 450 and the width is 450. Extension application 15, the total interface size is 480×480
insert image description here

1.chess board

initgraph(480, 480);//初始化一个窗口(窗口大小480*480);

At this time, the window disappears after a flash, try adding a while loop

#include<graphics.h>//包含图形库头文件
int main()
{
    
    
	initgraph(480, 480);
	while (1)
	{
    
    
	}


}

Compile and run: insert image description here
this is not the black frame of the console

The backgammon background is usually brown, we need to draw a brown background image and paste it, the size is the same as the interface size 480*480Please add a picture description

IMAGE p;//定义一个图片变量
loadimage(&p, "./background.png", 480, 480);//加载图片函数,(参数1图片地址,参数2图片的位置,图片大小)

./ is the current directory, and the .c file is placed under the same directory
insert image description here

putimage(0, 0, &p);//贴图片到界面上去(参数1,2为图片从界面的哪个位置开始贴)

insert image description here

#include<graphics.h>//包含图形库头文件
IMAGE p;
int main()
{
    
    
	initgraph(480, 480);
	loadimage(&p, "./background.png", 480, 480);
	putimage(0, 0, &p);
	while (1)
	{
    
    
	}


}

insert image description hereIf this problem occurs, just change Debug>Properties>Advanced>Character Set to Multi-Character Set

Compile and run:insert image description here


2. Start drawing lines

setlinecolor(BLACK);//设置线颜色的函数(黑线)
for (int x = 15; x < 480; x += 30)//循环画竖线
	{
    
    
		line(x, 15, x, 465);//画线函数,前两个参数为起始点x,y,后两个参数为终点x,y
	}
	for (int y= 15; y < 480; y+= 30)//循环画横线
	{
    
    
		line(15, y, 465,y);
	}
#include<graphics.h>//包含图形库头文件
IMAGE p;
int main()
{
    
    
	initgraph(480, 480);
	loadimage(&p, "./background.png", 480, 480);
	putimage(0, 0, &p);
	setlinecolor(BLACK);
	for (int x = 15; x < 480; x += 30)
	{
    
    
		line(x, 15, x, 465);
	}
	for (int y = 15; y < 480; y += 30)
	{
    
    
		line(15, y, 465, y);
	}
	while (1)
	{
    
    
	}


}

Compile and run
insert image description here

3. The professional chessboard seems to have 5 black dots (circles)

insert image description hereCoordinates corresponding to five points

setfillcolor(BLACK);//设置圆的颜色
	fillcircle(15 + 3 * 30, 15 + 3 * 30, 3);前两个参数为圆的圆心坐标,第三个参数为圆的半径
	fillcircle(15 + 3 * 30, 15 + 11 * 30, 3);
	fillcircle(15 + 11 * 30, 15 + 3 * 30, 3);
	fillcircle(15 + 7 * 30, 15 + 7 * 30, 3);
	fillcircle(15 + 11 * 30, 15 + 11 * 30, 3);

Compile and run
insert image description here

#include<graphics.h>//包含图形库头文件
IMAGE p;
int main()
{
    
    
	initgraph(480, 480);
	loadimage(&p, "./background.png", 480, 480);
	putimage(0, 0, &p);
	setlinecolor(BLACK);
	for (int x = 15; x < 480; x += 30)
	{
    
    
		line(x, 15, x, 465);
	}
	for (int y = 15; y < 480; y += 30)
	{
    
    
		line(15, y, 465, y);
	}
	setfillcolor(BLACK);
	fillcircle(15 + 3 * 30, 15 + 3 * 30, 3);
	fillcircle(15 + 3 * 30, 15 + 11 * 30, 3);
	fillcircle(15 + 11 * 30, 15 + 3 * 30, 3);
	fillcircle(15 + 7 * 30, 15 + 7 * 30, 3);
	fillcircle(15 + 11 * 30, 15 + 11 * 30, 3);
	while (1)
	{
    
    
	}


}

get mouse click

ExMessage msg;//消息结构体变量
if (peekmessage(&msg, EX_MOUSE)) //偷瞄消息,第一个消息结构体地址,第二个参数,鼠标消息
		{
    
    
			switch (msg.message)   //鼠标消息
			{
    
    
			case WM_LBUTTONDOWN:                      //左键
				draw(msg.x, msg.y);//鼠标光标位置坐标
				break;
			
			}
		}

When the left button of the mouse is pressed, the coordinates of the mouse on the corresponding interface are passed to the draw function. It is necessary to obtain the news of the mouse at any time, and put the above code in the loop

	while (1)
	{
    
    
		if (peekmessage(&msg, EX_MOUSE))              //偷瞄消息,第一个消息结构体地址,鼠标消息
		{
    
    
			switch (msg.message)                      //鼠标消息
			{
    
    
			case WM_LBUTTONDOWN:                      //左键
				draw(msg.x, msg.y);
				break;
			
			}
		}
		



	}

draw chess pieces

Pass the coordinates of the mouse click to the draw function, define a global variable num, and judge whether it is a black stone or a white stone, num=1, the black stone is down, num=-1, the white stone is down.

int num = 1;
void draw(int m, int n)
{
    
    
	if (num == -1)
	{
    
    
		setfillcolor(WHITE);//设置圆的填充色(白色)白棋
    }
	else if (num == 1)
	{
    
    
		setfillcolor(BLACK);//设置圆的填充色(黑色)黑棋
    }
    fillcircle(m - m % 30 + 15, n - n % 30 + 15, 13);//画圆,圆的x,y,半径,棋子的绘制
    num *= -1;//黑白棋轮着下,每次调用draw,改变num值,实现黑白黑白黑白


}

Why the coordinates of the chess pieces are (m - m % 30 + 15, n - n % 30 + 15), because it is impossible to point the mouse to the coordinates to be placed, and the mouse can only be placed in a certain range, and the chess piece will be placed away from the mouse The closest position of the point, if the coordinates of the mouse are 48, when 48 is passed to draw, insert image description here
we know that this position should be placed, after processing, it is 45, 45, which is exactly the position to be placed, to avoid the chess piece falling where it should not be. s position.

Compile and run
insert image description here

Solve the problem that chess pieces can be placed on top of chess pieces

insert image description here>
We can define a two-dimensional array, 15*15, and initialize it to 0 at the beginning. If there is a black chess piece on the place where the array subscript corresponds to the chessboard, put the value in the corresponding two-dimensional array to 1. If The array subscript corresponds to a white piece on the chessboard, and puts -1 in the value corresponding to the two-dimensional array; if there is a piece at the position where the mouse is clicked, return it directly without drawing the piece

Initialization of a two-dimensional array:

int arr[15][15];//全局变量好操作
void initboard()
{
    
    
	for (int i = 0; i < 15; i++)
	{
    
    
		for (int j = 0; j < 15; j++)
		{
    
    
			arr[i][j] = 0;//循环初始化二维数组
       }
       }
}
int full(int x, int y)
{
    
    
	if (arr[x][y] != 0)//如果不等于0,表示下过棋了return 0;
		return 0;
	else//如果等于0,表示没下过棋了,将该数组对应位置放num,return 1;
		arr[x][y] = num;
	     return 1;
}
void draw(int m,int n)
{
    
    
	if (num == -1)
	{
    
           setfillcolor(WHITE);
	         
			
		
	}
	else if (num == 1)
	{
    
           setfillcolor(BLACK);
			
		
	}
	
	
	int x;
	int y;y
	x = m / 30;//二维数组横坐标,m鼠标横坐标,如果m=48,x就是1,
	y = n / 30;//二维数组纵坐标n鼠标纵坐标,如果n=48,y就是1,
	if (full(x,y) == 0)//等于0表示下过棋了,直接return;跳出draw,如果=1,跳过这个条件判断语句,开始下棋
		return;


	fillcircle(m - m % 30 + 15, n - n % 30 + 15, 13);//下棋

	num *= -1;


}


A position that cannot be lowered at this time

judge win or lose

int check_over()
{
    
    
	for (int i = 0; i < 15; i++)
	{
    
    
		for (int j = 0; j < 15; j++)
		{
    
    
			if (arr[i][j] == 0)
				continue;
			if (check_five(i, j) == 1)
			{
    
    
				q = arr[i][j];
				return 1;
			}




		}


	}

}

Because the two-dimensional array records the status of playing chess, the corresponding position is 1 is black chess, -1 is white chess, 0 is not played, loop through each array element, first find the position where chess has been played, and has not played chess directly skip the position, because we pass the coordinates of chess played to
check_five(int x, int y) through this function, and then according to whether the next five adjacent x and y coordinates are the same, if not, jump directly However, to prevent the five adjacent positions from being 0 without playing chess, enter check_five(int x, int y), the same is true for five 0s, and then the game is over

int check_five(int x, int y)
{
    
    //检查一个下过棋的坐标相邻五个是否一样
	
	if (arr[x][y] == arr[x - 1][y] && arr[x][y] == arr[x - 2][y] && arr[x][y] == arr[x + 1][y] && arr[x][y] == arr[x + 2][y])//横行判断
		return 1;
	if (arr[x][y] == arr[x][y-1] && arr[x][y] == arr[x][y-2] && arr[x][y] == arr[x][y+1] && arr[x][y] == arr[x][y+2])//纵行判断
		return 1;
	if (arr[x][y] == arr[x - 1][y-1] && arr[x][y] == arr[x - 2][y-2] && arr[x][y] == arr[x + 1][y+1] && arr[x][y] == arr[x + 2][y+2])以该坐标为中心,主对角线判断
		return 1;
	if (arr[x][y] == arr[x - 1][y+1] && arr[x][y] == arr[x+2][y-2] && arr[x][y] == arr[x + 1][y-1] && arr[x][y] == arr[x-2][y+2])以该坐标为中心,副对角线判断
		return 1;
//相同则返回1
//不同返回0
	
	return 0;
}

In check_over(), if check_five(i, j) returns 1, then there are five links, and the value corresponding to the coordinate in the two-dimensional array is saved in the q global variable, and then check_over() returns 1

if (check_over() == 1)
		{
    
    
			outtextxy(180, 180, "游戏结束");//输出文字,参数一参数二为文字左上角坐标,参数三为文字内容
			//change();//消息盒子函数,提示谁赢了
			system("pause");//退出程序,头文件windows.h

		}

must be called before

	settextstyle(40, 20, "隶书");//设置字体高度,宽度,字体的格式
	setbkmode(TRANSPARENT);//字体后面设置透明,背景模式

Compile and run
insert image description here

tips win or lose

void change()//消息盒子函数,提示谁赢了
{
    
    

	HWND hnd = GetHWnd();  //获取窗口句柄(相当于窗口的指针)
	SetWindowText(hnd, "五子棋"); //设置窗口标题
	int isok;
				if(q==1)//q获取的是赢家对应二维数组的消息,黑子为1											//
	       isok = MessageBox(NULL, "黑子胜", "提示", MB_OKCANCEL); //弹出消息盒子,提示用户操作
			else if(q==-1)
				isok = MessageBox(NULL, "白子胜", "提示", MB_OKCANCEL);
			

	if (IDOK== isok)                                             //返回点了哪里
	{
    
                                                                //点了ok
		
	}
	else if (IDCANCEL == isok)                               //点了取消
	{
    
    
		
		

	}
}

Compile and run
insert image description here
insert image description here

background music function

Here you can read the dynamic address book article, there are specific steps for adding music

#include<graphics.h>//包含图形库头文件
#include<mmsystem.h>//包含多媒体设备接口头文件

#pragma comment(lib,"winmm.lib")//加载静态库
void bgm()
{
    
        //打开音乐
	mciSendString("open ./music.MP3", 0, 0, 0);//后面参数不用管
	//播放音乐
	mciSendString("play ./music.MP3", 0, 0, 0);//后面参数不用管
}

Overall code display


#include <windows.h>
#include<graphics.h>//包含图形库头文件
#include<mmsystem.h>//包含多媒体设备接口头文件

#pragma comment(lib,"winmm.lib")//加载静态库
IMAGE p;
int num = 1;
int q;
int arr[15][15];
void change()
{
    
    

	HWND hnd = GetHWnd();                                             //获取窗口句柄(相当于窗口的指针)
	SetWindowText(hnd, "五子棋"); 
	int isok;//设置窗口标题
				if(q==1)											//
	       isok = MessageBox(NULL, "黑子胜", "提示", MB_OKCANCEL); //弹出消息盒子,提示用户操作
			else if(q==-1)
				isok = MessageBox(NULL, "白子胜", "提示", MB_OKCANCEL);
			

	if (IDOK== isok)                                             //返回点了哪里
	{
    
                                                                //点了ok
		
	}
	else if (IDCANCEL == isok)                               //点了取消
	{
    
    
		
		

	}
}
void bgm()
{
    
        //打开音乐
	mciSendString("open ./music.MP3", 0, 0, 0);//后面参数不用管
	//播放音乐
	mciSendString("play ./music.MP3", 0, 0, 0);//后面参数不用管
}
void initboard()
{
    
    
	for (int i = 0; i < 15; i++)
	{
    
    
		for (int j = 0; j < 15; j++)
		{
    
    
			arr[i][j] = 0;




		}



	}
}
int full(int x, int y)
{
    
    
	if (arr[x][y] != 0)
		return 0;
	else
		arr[x][y] = num;
	     return 1;
}
void draw(int m,int n)
{
    
    
	if (num == -1)
	{
    
           setfillcolor(WHITE);
	         
			
		
	}
	else if (num == 1)
	{
    
           setfillcolor(BLACK);
			
		
	}
	
	
	int x;
	int y;
	x = m / 30;
	y = n / 30;
	if (full(x,y) == 0)
		return;


	fillcircle(m - m % 30 + 15, n - n % 30 + 15, 13);

	num *= -1;


}
int check_five(int x, int y)
{
    
    
	//if (x < 2 || y < 2 || x>12 || y>12)
		//return 0;
	if (arr[x][y] == arr[x - 1][y] && arr[x][y] == arr[x - 2][y] && arr[x][y] == arr[x + 1][y] && arr[x][y] == arr[x + 2][y])
		return 1;
	if (arr[x][y] == arr[x][y-1] && arr[x][y] == arr[x][y-2] && arr[x][y] == arr[x][y+1] && arr[x][y] == arr[x][y+2])
		return 1;
	if (arr[x][y] == arr[x - 1][y-1] && arr[x][y] == arr[x - 2][y-2] && arr[x][y] == arr[x + 1][y+1] && arr[x][y] == arr[x + 2][y+2])
		return 1;
	if (arr[x][y] == arr[x - 1][y+1] && arr[x][y] == arr[x+2][y-2] && arr[x][y] == arr[x + 1][y-1] && arr[x][y] == arr[x-2][y+2])
		return 1;

	
	return 0;
}
int check_over()
{
    
    
	for (int i = 0; i < 15; i++)
	{
    
    
		for (int j = 0; j < 15; j++)
		{
    
    
			if (arr[i][j] == 0)
				continue;
			if (check_five(i, j) == 1)
			{
    
    
				q = arr[i][j];
				return 1;
			}




		}


	}

}
int main()
{
    
    
	bgm();
	ExMessage msg;
	
	initgraph(480, 480);
	loadimage(&p,"./background.png",480,480);
	putimage(0, 0, &p);
	setlinecolor(BLACK);
	for (int x = 15; x < 480; x += 30)
	{
    
    
		line(x, 15, x, 465);
	}
	for (int y= 15; y < 480; y+= 30)
	{
    
    
		line(15, y, 465,y);
	}
	setfillcolor(BLACK);
	fillcircle(15 + 3 * 30, 15 + 3 * 30, 3);
	fillcircle(15 + 3 * 30, 15 + 11 * 30, 3);
	fillcircle(15 + 11 * 30, 15 + 3 * 30, 3);
	fillcircle(15 + 7 * 30, 15 + 7 * 30, 3);
	fillcircle(15 + 11 * 30, 15 + 11 * 30, 3);
	settextstyle(40, 20, "隶书");
	setbkmode(TRANSPARENT);
	





	while (1)
	{
    
    
		if (peekmessage(&msg, EX_MOUSE))              //偷瞄消息,第一个消息结构体地址,鼠标消息
		{
    
    
			switch (msg.message)                      //鼠标消息
			{
    
    
			case WM_LBUTTONDOWN:                      //左键
				draw(msg.x, msg.y);
				break;
			
			}
		}
		if (check_over() == 1)
		{
    
    
			outtextxy(180, 180, "游戏结束");
			change();
			system("pause");

		}



	}
}

Show results

20230821_194813

Guess you like

Origin blog.csdn.net/yyqzjw/article/details/132408869