基于easyx的五子棋对战


以前写过一个,只不过写的比较繁琐,这个能简单实现,去掉了各种花里胡哨(虽然都是简单的知识),本来是打算用c++实现的,发现还是c写起来好理解,毕竟学艺不精,哈哈哈

代码风格偏奇葩,接触编程时间不长,还有许多可以优化的地方,例如下方显示文字可以使用内联函数疯狂调用之类。

注释有的地方不太明确,如有bug可以反馈。

本人使用vs2017,如有编译错误,可修改项目属性

项目->属性->常规->字符集->多字节字符集;

此处修改为outtextxy输出文字函数中的第三个参数在调用时出错。

#include
#include
#include
#include
#include
#include
#define MAX 1000

using namespace std;


//全局变量存储棋盘的属性
struct G_chess {
	int CHESS_R = 10;//每个棋子的半径
	int CHESS_R_C = 5;//五个点的半径
	int ROW = 35;//棋盘的行的长度
	int COLOMU = 35;//棋盘列的长度
	int start = 50;//棋盘的起始位置
	int menu_start_x = start + 14 * COLOMU + 10;//菜单栏的x轴开始位置
	int menu_start_y = start;//菜单栏的y轴开始位置
}G;
//每个棋子的位置属性
struct chess {
	int map_x;//棋子所在行的位置
	int map_y;//棋子所在列的位置
};
//棋盘上的各个棋子属性


class chess_piece {
public:
	//初始化棋盘上的棋子个数
	chess_piece() {
		buffer = MAX;
	}
	//每下一个棋子,获取所下棋子的信息,收入棋子的属性中
	void play(int x, int y) {
		chess temp;
		temp.map_x = x;
		temp.map_y = y;
		play_chess.push_back(temp);
	}
	friend ostream &operator<< (ostream& os, chess a);
	//每下一个棋子,画出棋子
	void down(int x, int y, int color) {
		setfillcolor(color);
		setlinecolor(color);
		fillcircle(x, y, G.CHESS_R);
		play(x, y);
	}
	void drow_back_line(vector& play_chess);//悔棋后,将棋盘复原
	//每悔一次棋,将所下的棋子删除
	void back() {
		if (play_chess.empty()) { 
			setbkmode(TRANSPARENT);
			settextstyle(30, 0, _T("楷体"));
			outtextxy(G.start + 3 * G.COLOMU, G.start + 14 * G.COLOMU + 1, _T("请落子后再进行操作"));
			return;
		}
		drow_back_line(play_chess);
		play_chess.pop_back();
	}
	~chess_piece() { }
private:
	int buffer;
	vector play_chess;
};

int flag = BLACK;

void map();//生成地图
int mouse();//鼠标操作
inline int mouse_menu(MOUSEMSG &mou);//菜单处的鼠标操作
void drow_menu(int x, int y, const char *name, int UOD);//菜单框
bool judge(int x, int y);//判断游戏是否有一方获胜


int main()
{
	
	int s = 1;
	while (s) {
		s = mouse();
	}
	closegraph();
	return 0;
}
ostream & operator<<(ostream & os, chess a)
{
	os << a.map_x << " " << a.map_y;
	return os;
}
void map() {
	chess_piece a;
	initgraph(700, 640);
	setfillcolor(RGB(172, 81, 24));
	setfillstyle(BS_SOLID);
	fillrectangle(0, 0, 700, 640);
	setlinecolor(BLUE);
	for (int i = 0; i <= G.start + 13 * G.COLOMU; i = i + G.COLOMU)
	{
		line(G.start + i, G.start, G.start + i, G.start + G.COLOMU * 14);
		line(G.start, G.start + i, G.start + G.COLOMU * 14, G.start + i);
	}
	setfillcolor(GREEN);
	fillcircle(G.start + 7 * G.COLOMU, G.start + 7 * G.COLOMU, G.CHESS_R_C);//画出天元点
	fillcircle(G.start + 3 * G.COLOMU, G.start + 3 * G.COLOMU, G.CHESS_R_C);//画出四个星点
	fillcircle(G.start + 3 * G.COLOMU, G.start + 11 * G.COLOMU, G.CHESS_R_C);
	fillcircle(G.start + 11 * G.COLOMU, G.start + 3 * G.COLOMU, G.CHESS_R_C);
	fillcircle(G.start + 11 * G.COLOMU, G.start + 11 * G.COLOMU, G.CHESS_R_C);
	settextstyle(30, 0, _T("楷体"));
	setbkmode(TRANSPARENT);
	settextcolor(BLACK);
	outtextxy(G.start + 5 * G.COLOMU, G.start / 3, _T("欢乐五子棋"));
	drow_menu(G.menu_start_x, G.menu_start_y, "新局", 1);
	drow_menu(G.menu_start_x, G.menu_start_y + G.COLOMU + 2, "悔棋", 1);
	drow_menu(G.menu_start_x, G.menu_start_y + (G.COLOMU + 2) * 2, "退出", 1);
}
void chess_piece::drow_back_line(vector& play_chess) {
	if (flag == BLACK)
	{
		settextstyle(60, 0, _T("楷体"));
		setfillcolor(RGB(172, 81, 24));
		solidrectangle(G.start + 4 * G.COLOMU, G.start + 15 * G.COLOMU, G.start + 8 * G.COLOMU, G.start + 15 * G.COLOMU + 60);
		outtextxy(G.start + 4 * G.COLOMU, G.start + 15 * G.COLOMU, _T("白棋下!"));
		flag = WHITE;
	}
	else {
		settextstyle(60, 0, _T("楷体"));
		setfillcolor(RGB(172, 81, 24));
		solidrectangle(G.start + 4 * G.COLOMU, G.start + 15 * G.COLOMU, G.start + 8 * G.COLOMU, G.start + 15 * G.COLOMU + 60);
		outtextxy(G.start + 4 * G.COLOMU, G.start + 15 * G.COLOMU, _T("黑棋下!"));
		flag = BLACK;
	}
	vector::iterator iter = play_chess.end() - 1;
	setfillcolor(RGB(172, 81, 24));
	setlinecolor(RGB(172, 81, 24));
	fillcircle(iter->map_x, iter->map_y, G.CHESS_R);
	setlinecolor(BLUE);
	int R = (iter->map_x - G.start) / G.COLOMU + 1;
	int C = (iter->map_y - G.start) / G.COLOMU + 1;
	cout << R << " " << C << endl;
	if (R == 1 && C == 1)
	{
		line(iter->map_x, iter->map_y, iter->map_x + G.COLOMU / 2 + 1, iter->map_y);
		line(iter->map_x, iter->map_y, iter->map_x, iter->map_y + G.COLOMU / 2 + 1);
	}
	else if (R == 15 && C == 1)
	{
		line(iter->map_x - G.COLOMU / 2 + 1, iter->map_y, iter->map_x, iter->map_y);
		line(iter->map_x, iter->map_y, iter->map_x, iter->map_y + G.COLOMU / 2 + 1);
	}
	else if (R == 1 && C == 15) {
		line(iter->map_x, iter->map_y, iter->map_x + G.COLOMU / 2 + 1, iter->map_y);
		line(iter->map_x, iter->map_y - G.COLOMU / 2 + 1, iter->map_x, iter->map_y);
	}
	else if (R == 15 && C == 15) {
		line(iter->map_x - G.COLOMU / 2 + 1, iter->map_y, iter->map_x, iter->map_y);
		line(iter->map_x, iter->map_y - G.COLOMU / 2 + 1, iter->map_x, iter->map_y);
	}
	else if (R == 1) {
		line(iter->map_x, iter->map_y, iter->map_x + G.COLOMU / 2 + 1, iter->map_y);
		line(iter->map_x, iter->map_y - G.COLOMU / 2 + 1, iter->map_x, iter->map_y + G.COLOMU / 2 + 1);
	}
	else if (R == 15) {
		line(iter->map_x - G.COLOMU / 2 + 1, iter->map_y, iter->map_x, iter->map_y);
		line(iter->map_x, iter->map_y - G.COLOMU / 2 + 1, iter->map_x, iter->map_y + G.COLOMU / 2 + 1);
	}
	else if (C == 1) {
		line(iter->map_x - G.COLOMU / 2 + 1, iter->map_y, iter->map_x + G.COLOMU / 2 + 1, iter->map_y);
		line(iter->map_x, iter->map_y, iter->map_x, iter->map_y + G.COLOMU / 2 + 1);
	}
	else if (C == 15) {
		line(iter->map_x - G.COLOMU / 2 + 1, iter->map_y, iter->map_x + G.COLOMU / 2 + 1, iter->map_y);
		line(iter->map_x, iter->map_y - G.COLOMU / 2 + 1, iter->map_x, iter->map_y);
	}
	else {
		line(iter->map_x - G.COLOMU / 2 + 1, iter->map_y, iter->map_x + G.COLOMU / 2 + 1, iter->map_y);
		line(iter->map_x, iter->map_y - G.COLOMU / 2 + 1, iter->map_x, iter->map_y + G.COLOMU / 2 + 1);
	}
	if ((R == 8 && C == 8) || (R == 4 && C == 4) || (R == 4 && C == 12) || (R == 12 && C == 12) || (R == 12 && C == 4)) {
		setfillcolor(GREEN);
		setlinecolor(BLACK);
		fillcircle(iter->map_x, iter->map_y, G.CHESS_R_C);
	}
}

bool judge(int x, int y)
{
	int color = getpixel(x, y);
	int count = 1;
	//横向检测
	for (int i = x - G.COLOMU; i >= G.start; i -= G.COLOMU) {
		if (getpixel(i, y) == color) count++;
		else break;
	}
	for (int i = x + G.COLOMU; i <= G.start + 14 * G.COLOMU; i += G.COLOMU) {
		if (getpixel(i, y) == color) count++;
		else break;
	}
	if (count >= 5) return true;
	count = 1;
	//纵向检测
	for (int i = y - G.COLOMU; i >= G.start; i -= G.COLOMU) {
		if (getpixel(x, i) == color) count++;
		else break;
	}
	for (int i = y + G.COLOMU; i <= G.start + 14 * G.COLOMU; i += G.COLOMU) {
		if (getpixel(x, i) == color) count++;
		else break;
	}
	if (count >= 5) return true;
	count = 1;
	//从右上到左下检测
	for (int i = x - G.COLOMU, j = y - G.COLOMU; i >= G.start && j >= G.start; i -= G.COLOMU, j -= G.COLOMU) {
		if (getpixel(i, j) == color) count++;
		else break;
	}
	for (int i = x + G.COLOMU, j = y + G.COLOMU; i >= G.start && j >= G.start; i += G.COLOMU, j += G.COLOMU) {
		if (getpixel(i, j) == color) count++;
		else break;
	}
	if (count >= 5) return true;
	count = 1;
	//从左上到右下检测
	for (int i = x + G.COLOMU, j = y - G.COLOMU; i >= G.start && j >= G.start; i += G.COLOMU, j -= G.COLOMU) {
		if (getpixel(i, j) == color) count++;
		else break;
	}
	for (int i = x - G.COLOMU, j = y + G.COLOMU; i >= G.start && j >= G.start; i -= G.COLOMU, j += G.COLOMU) {
		if (getpixel(i, j) == color) count++;
		else break;
	}
	if (count >= 5) return true;
	return false;
}
int mouse() {
	map();
	chess_piece P;
	while (1) {
		MOUSEMSG mou = GetMouseMsg();
		switch (mouse_menu(mou)) {
		case 1: return 1;
		case 2: P.back(); break;
		case 3: return 0;
		}
		if (mou.uMsg == WM_LBUTTONDOWN) {
			int x = ((mou.x - G.start + G.COLOMU / 2) / G.COLOMU)*G.COLOMU + G.start;
			int y = ((mou.y - G.start + G.COLOMU / 2) / G.COLOMU)*G.COLOMU + G.start;
			if (getpixel(x, y) == BLUE || getpixel(x, y) == GREEN)
			{
				setfillcolor(RGB(172, 81, 24));
				solidrectangle(G.start + 3 * G.COLOMU, G.start + 14 * G.COLOMU + 1, G.start + 10 * 30 + 3 * G.COLOMU, +G.start + 14 * G.COLOMU + 1 + 30);
				if (flag == WHITE) {
					P.down(x, y, flag);
					if (judge(x, y)) {
						setbkmode(TRANSPARENT);
						settextstyle(60, 0, _T("楷体"));
						outtextxy(G.start + 4 * G.COLOMU, G.start + 4 * G.COLOMU, _T("白棋胜!"));
						settextstyle(30, 0, _T("楷体"));
						outtextxy(G.start + 3 * G.COLOMU, G.start + 14 * G.COLOMU + 1, _T("点击新局继续进行对局"));
						break;
					}
					settextstyle(60, 0, _T("楷体"));
					setfillcolor(RGB(172, 81, 24));
					solidrectangle(G.start + 4 * G.COLOMU, G.start + 15 * G.COLOMU, G.start + 8 * G.COLOMU, G.start + 15 * G.COLOMU + 60);
					outtextxy(G.start + 4 * G.COLOMU, G.start + 15 * G.COLOMU, _T("黑棋下!"));
					flag = BLACK;
				}
				else {
					P.down(x, y, flag);
					if (judge(x, y)) {
						setbkmode(TRANSPARENT);
						settextstyle(60, 0, _T("楷体"));
						outtextxy(G.start + 4 * G.COLOMU, G.start + 6 * G.COLOMU, _T("黑棋胜!"));
						settextstyle(30, 0, _T("楷体"));
						outtextxy(G.start + 3 * G.COLOMU, G.start + 14 * G.COLOMU + 1, _T("点击新局继续进行对局"));
						break;
					}
					settextstyle(60, 0, _T("楷体"));
					setfillcolor(RGB(172, 81, 24));
					solidrectangle(G.start + 4 * G.COLOMU, G.start + 15 * G.COLOMU, G.start + 8 * G.COLOMU, G.start + 15 * G.COLOMU + 60);
					outtextxy(G.start + 4 * G.COLOMU, G.start + 15 * G.COLOMU, _T("白棋下!"));
					flag = WHITE;
				}
			}
		}
	}
	while (1) {
		MOUSEMSG m = GetMouseMsg();
		switch (mouse_menu(m)) {
		case 1:
			return 1;
		case 2:  
			setfillcolor(RGB(172, 81, 24));
			solidrectangle(G.start + 3 * G.COLOMU, G.start + 14 * G.COLOMU + 1, G.start + 10 * 30 + 3 * G.COLOMU, +G.start + 14 * G.COLOMU + 1 + 30);
			settextstyle(30, 0, _T("楷体"));
			outtextxy(G.start + 3 * G.COLOMU, G.start + 14 * G.COLOMU + 1, _T("胜负乃兵家常事,再来!")); 
			break;
		case 3: return 0;
		}
	}
	return mouse();
}


int mouse_menu(MOUSEMSG &mou)
{
	if (mou.uMsg == WM_LBUTTONDOWN) {
		if (mou.x >= G.menu_start_x && mou.x <= (G.menu_start_x + G.COLOMU * 2) && mou.y >= G.menu_start_y && mou.y <= (G.menu_start_y + G.COLOMU))
		{
			drow_menu(G.menu_start_x, G.menu_start_y, "新局", 0);
		}
		if (mou.x >= G.menu_start_x && mou.x <= (G.menu_start_x + G.COLOMU * 2) && mou.y >= (G.menu_start_y + G.COLOMU + 2) && mou.y <= (G.menu_start_y + G.COLOMU * 2)) {
			drow_menu(G.menu_start_x, G.menu_start_y + G.COLOMU + 2, "悔棋", 0);
		}
		if (mou.x >= G.menu_start_x && mou.x <= (G.menu_start_x + G.COLOMU * 2) && mou.y >= (G.menu_start_y + (G.COLOMU + 2) * 2) && mou.y <= (G.menu_start_y + G.COLOMU * 3)) {
			drow_menu(G.menu_start_x, G.menu_start_y + (G.COLOMU + 2) * 2, "退出", 0);
		}
	}
	if (mou.uMsg == WM_LBUTTONUP) {
		drow_menu(G.menu_start_x, G.menu_start_y + (G.COLOMU + 2) * 2, "退出", 1);
		drow_menu(G.menu_start_x, G.menu_start_y + G.COLOMU + 2, "悔棋", 1);
		drow_menu(G.menu_start_x, G.menu_start_y, "新局", 1);
		if (mou.x >= G.menu_start_x && mou.x <= (G.menu_start_x + G.COLOMU * 2) && mou.y >= G.menu_start_y&&mou.y <= (G.menu_start_y + G.COLOMU + 2))
		{
			drow_menu(G.menu_start_x, G.menu_start_y, "新局", 1);
			return 1;
		}
		if (mou.x >= G.menu_start_x && mou.x <= (G.menu_start_x + G.COLOMU * 2) && mou.y >= (G.menu_start_y + G.COLOMU + 2) && mou.y <= (G.menu_start_y + (G.COLOMU + 2) * 2)) {
			drow_menu(G.menu_start_x, G.menu_start_y + G.COLOMU + 2, "悔棋", 1);
			return 2;
		}
		if (mou.x >= G.menu_start_x && mou.x <= (G.menu_start_x + G.COLOMU * 2) && mou.y >= (G.menu_start_y + (G.COLOMU + 2) * 2) && mou.y <= (G.menu_start_y + (G.COLOMU + 2) * 3)) {
			drow_menu(G.menu_start_x, G.menu_start_y + (G.COLOMU + 2) * 2, "退出", 1);
			return 3;
		}
	}
	return 0;
}

inline void drow_menu(int x, int y, const char * name, int UOD)//UOD意为up or dowm
{
	setfillcolor(LIGHTGRAY);
	solidrectangle(x, y, x + G.COLOMU * 2, y + G.COLOMU * 1);
	setfillcolor(WHITE);
	settextstyle(30, 0, _T("宋体"));
	if (UOD == 0) {
		outtextxy(x + 4, y + 4, name);
		solidrectangle(x, y + G.COLOMU - 2, x + G.COLOMU * 2, y + G.COLOMU);
		solidrectangle(x + G.COLOMU * 2 - 2, y, x + G.COLOMU * 2, y + G.COLOMU * 1);
	}
	else if (UOD == 1) {
		outtextxy(x + 2, y + 2, name);
		solidrectangle(x, y, x + G.COLOMU * 2, y + 2);
		solidrectangle(x, y, x + 2, y + G.COLOMU * 1);
	}
}

你可能感兴趣的:(基于easyx的五子棋对战)