基于EasyX的三子棋游戏

实现代码如下:

#include <graphics.h>
#include <mmSystem.h>
#include <stdio.h>
#include <conio.h>

#pragma comment(lib, "winmm.lib")

#define SCREEN_WIDTH  300
#define SCREEN_HEIGHT 300

// 对行和列以及斜对角进行判断,是否可以连成线
#define ONE_ROW		(map[0][0] != -1 && map[1][0] != -1 && map[2][0] != -1) && \
					((map[0][0] == map[1][0]) && (map[1][0] == map[2][0]))		//第一排

#define TWO_ROW		(map[0][1] != -1 && map[1][1] != -1 && map[2][1] != -1) && \
					((map[0][1] == map[1][1]) && (map[1][1] == map[2][1]))		//第二排

#define THREE_ROW   (map[0][2] != -1 && map[1][2] != -1 && map[2][2] != -1) && \
					((map[0][2] == map[1][2]) && (map[1][2] == map[2][2]))		//第三排

#define ONE_COLUMN		(map[0][0] != -1 && map[0][1] != -1 && map[0][2] != -1) && \
						((map[0][0] == map[0][1]) && (map[0][1] == map[0][2]))	//第一列

#define TWO_COLUMN		(map[1][0] != -1 && map[1][1] != -1 && map[1][2] != -1) && \
						((map[1][0] == map[1][1]) && (map[1][1] == map[1][2]))	//第二列

#define THREE_COLUMN	(map[2][0] != -1 && map[2][1] != -1 && map[2][2] != -1) && \
						((map[2][0] == map[2][1]) && (map[2][1] == map[2][2]))	//第三列

#define LEFT_OBLIQUE		(map[0][0] != -1 && map[1][1] != -1 && map[2][2] != -1) && \
							((map[0][0] == map[1][1]) && (map[1][1] == map[2][2]))	//左斜角

#define RIGHT_OBLIQUE		(map[2][0] != -1 && map[1][1] != -1 && map[0][2] != -1) && \
							((map[2][0] == map[1][1]) && (map[1][1] == map[0][2]))	//右斜角

// 棋盘地图, -1代表空位置
int map[3][3] = 
{ 
	-1, -1, -1,
	-1, -1, -1,
	-1, -1, -1
};

int x = 0, y = 0;	//当前下棋的坐标
int camp = 0;		//阵营(自己玩的图案) 0为O图形, 1为X图形
bool resWin[3];		//判断赢得是哪一条线

// 加载资源以及初始化棋盘
void initChessboard();

// 检查鼠标事件
void detectMouseMsg(MOUSEMSG &mouse, IMAGE *img);

// 检查游戏是否结束
bool chechEnd();

// 重置游戏
void resetGame();

int main(void)
{
	IMAGE img[2];
	MOUSEMSG mouse;

	initgraph(SCREEN_WIDTH, SCREEN_HEIGHT);			//初始化界面

	loadimage(&img[0], _T("o.png"), 0, 0, true);	//加载资源图
	loadimage(&img[1], _T("x.png"), 0, 0, true);

	initChessboard();	//初始化棋盘

	// 播放音乐
	mciSendString(_T("play 为你我受冷风吹.mp3 repeat"), 0, 0, 0);

	while (true)
	{
		// 检测鼠标位置, 走棋
		detectMouseMsg(mouse, img);
		
		if (chechEnd())		//判断是否结束游戏了
		{
			Sleep(500);
			cleardevice();		//清除窗口
			initChessboard();
			resetGame();		//重置游戏的参数
		}
	}

	system("pause");
	return 0;
}

void initChessboard()
{
	setlinecolor(WHITE);
	setlinestyle(PS_SOLID, 1);

	// 画棋盘
	for (int i = 1; i < 3; i++)
	{
		line(0, i * 100, 300, i * 100);
		line(i * 100, 0, i * 100, 300);
	}
	line(300, 0, 300, 300);
}

void detectMouseMsg(MOUSEMSG& mouse, IMAGE* img)
{
	int front = -1;
	mouse = GetMouseMsg();		// 获取鼠标信息

	if (mouse.uMsg == WM_LBUTTONDOWN)	//判断鼠标是否左键按下
	{
		// 计算坐标
		x = mouse.x / 100;
		y = mouse.y / 100;

		front = map[x][y];		//记录当前位置的值
		map[x][y] = camp;		//鼠标点击的区域

		if (front == -1) //-1代表空位, 即可以在当前位置下棋
		{	
			putimage(x * 100 + 5, y * 100 + 5, &img[map[x][y]]);
			(camp == 1) ? camp = 0 : camp = 1;	//交换阵营
		}
	}
}

bool chechEnd()
{
	setlinecolor(YELLOW);		//设置线的颜色
	setlinestyle(PS_SOLID, 5);	//设置线的风格

	if ((resWin[0] = ONE_ROW) || (resWin[1] = TWO_ROW) || (resWin[2] = THREE_ROW))
	{
		if (resWin[0] == true)
			line(5, 45, 295, 45);
		else if (resWin[1] == true)
			line(5, 155, 295, 155);
		else if (resWin[2] == true)
			line(5, 245, 295, 245);

		outtextxy(140, 140, "你赢了!");
		Sleep(100);
		return true;
	}
	else if ((resWin[0] = ONE_COLUMN) || (resWin[1] = TWO_COLUMN) || (resWin[2] = THREE_COLUMN))
	{
		if (resWin[0] == true)
			line(45, 5, 45, 295);
		else if (resWin[1] == true)
			line(155, 5, 155, 295);
		else if (resWin[2] == true)
			line(245, 5, 245, 295);

		outtextxy(140, 140, "你赢了!");
		Sleep(100);
		return true;
	}
	else if ((resWin[0] = LEFT_OBLIQUE) || (resWin[1] = RIGHT_OBLIQUE))
	{
		if (resWin[0] == true)
			line(5, 5, 295, 295);
		else if (resWin[1] == true)
			line(295, 5, 5, 295);

		outtextxy(140, 140, "你赢了!");
		Sleep(100);
		return true;
	}

	// 判断是否还有空位
	for (int i = 0; i < 3; i++)
		for (int j = 0; j < 3; j++)
			if (map[i][j] == -1) return false;

	outtextxy(140, 140, "平局!");
	Sleep(70);
	return true;
}

void resetGame()
{
	// 擦除界面,重置map值
	setfillcolor(BLACK);
	for (int i = 0; i < 3; i++)
	{
		for (int j = 0; j < 3; j++)
		{
			map[i][j] = -1;
			solidrectangle(i * 100 + 5, j * 100 + 5, i * 100 + 95, j * 100 + 95);
		}
	}
}

运行效果图:
在这里插入图片描述
游戏中所用的图片大小是90*90像素的。

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,下面我给你讲一下如何使用EASYX库设计井字棋游戏的思路。 首先,我们需要在程序中引入EASYX库,然后通过 `initgraph` 函数初始化窗口。接着,我们需要设计界面,可以使用 `rectangle` 函数绘制出棋盘和棋子。其中,棋盘可以用一个 3x3 的矩形数组来表示,每个矩形代表一个棋子的位置,初始时可以将数组中的值全部设为 0。 然后,我们需要设计游戏逻辑。每当玩家点击某个位置时,程序需要判断该位置是否已经被占据。如果已经被占据,则提示玩家重新选择;否则,将该位置设置为当前玩家的棋子(可以用 1 表示玩家 1 的棋子,用 2 表示玩家 2 的棋子),然后判断是否满足胜利条件(即同一行、同一列或同一对角线上有三个相同的棋子)。如果满足胜利条件,则游戏结束,否则交换玩家并进入下一轮。 最后,我们需要在程序中加入音效和背景音乐,可以使用 `mciSendString` 函数来实现。 下面是一份简单的代码示例,帮助你更好地理解上述思路: ```c #include <graphics.h> #include <conio.h> #include <stdio.h> #include <stdlib.h> #include <windows.h> #include <mmsystem.h> #pragma comment(lib,"Winmm.lib") #define ROW 3 #define COL 3 int chessboard[ROW][COL] = {0}; // 棋盘数组 int player = 1; // 当前玩家 void drawChessboard() // 绘制棋盘 { for(int i = 0; i < ROW; i++) { for(int j = 0; j < COL; j++) { rectangle(j * 50 + 50, i * 50 + 50, j * 50 + 100, i * 50 + 100); } } } void drawChessman(int x, int y) // 绘制棋子 { if(chessboard[x][y] == 1) { setfillcolor(BLACK); fillellipse(y * 50 + 75, x * 50 + 75, 20, 20); } else if(chessboard[x][y] == 2) { setfillcolor(WHITE); fillellipse(y * 50 + 75, x * 50 + 75, 20, 20); } } int checkWin() // 判断胜利条件 { for(int i = 0; i < ROW; i++) { if(chessboard[i][0] == chessboard[i][1] && chessboard[i][1] == chessboard[i][2] && chessboard[i][0] != 0) { return chessboard[i][0]; } } for(int j = 0; j < COL; j++) { if(chessboard[0][j] == chessboard[1][j] && chessboard[1][j] == chessboard[2][j] && chessboard[0][j] != 0) { return chessboard[0][j]; } } if(chessboard[0][0] == chessboard[1][1] && chessboard[1][1] == chessboard[2][2] && chessboard[0][0] != 0) { return chessboard[0][0]; } if(chessboard[0][2] == chessboard[1][1] && chessboard[1][1] == chessboard[2][0] && chessboard[0][2] != 0) { return chessboard[0][2]; } return 0; } int main() { initgraph(400, 400); // 初始化窗口 drawChessboard(); // 绘制棋盘 PlaySound(TEXT("bgm.wav"), NULL, SND_FILENAME | SND_ASYNC | SND_LOOP); // 播放背景音乐 int x, y; while(1) { if(player == 1) { settextcolor(BLACK); outtextxy(250, 100, "Black's turn"); } else { settextcolor(WHITE); outtextxy(250, 100, "White's turn"); } if(kbhit()) // 判断是否有键盘输入 { int key = getch(); if(key == 27) // 按下 ESC 键退出游戏 { break; } else if(key == 32) // 按下空格键重新开始游戏 { cleardevice(); drawChessboard(); memset(chessboard, 0, sizeof(chessboard)); player = 1; continue; } x = (GetCursorPos().y - 50) / 50; y = (GetCursorPos().x - 50) / 50; if(x >= 0 && x < ROW && y >= 0 && y < COL && chessboard[x][y] == 0) // 判断是否是有效位置 { chessboard[x][y] = player; drawChessman(x, y); int result = checkWin(); if(result != 0) // 判断游戏是否结束 { if(result == 1) { settextcolor(BLACK); outtextxy(250, 200, "Black wins!"); } else { settextcolor(WHITE); outtextxy(250, 200, "White wins!"); } Sleep(1000); cleardevice(); drawChessboard(); memset(chessboard, 0, sizeof(chessboard)); player = 1; continue; } player = 3 - player; // 交换玩家 } } } closegraph(); // 关闭窗口 return 0; } ``` 上述代码仅供参考,你可以根据自己的需求进行修改和优化。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值