使用C++寫的中國象棋(單機版)

C++在遊戲領域應用很廣,其最大有點是運行效率高,對內存的操作比較直接,因此,我利用此有點寫了中國象棋的簡潔版,來進行一些簡單的下棋操作。接下來是代碼

#ifndef PUTTEXT_H_
#define PUTTEXT_H_
#include <windows.h>
#include <string>
#include <opencv2/opencv.hpp>
using namespace cv;
void GetStringSize(HDC hDC, const char* str, int* w, int* h);
void putTextZH(Mat &dst, const char* str, Point org, Scalar color, int fontSize,
	const char *fn = "Arial", bool italic = false, bool underline = false);
#endif

這是頭文件,包含用來處理漢字的一些函數,(opencv不可以直接處理漢字)
接下來便是具體實現過程了

#include<opencv2/opencv.hpp>
#include<highgui.hpp>
#include<imgcodecs.hpp>
#include<core.hpp>
#include<imgproc.hpp>
#include"標頭.h"
#include<vector>
#include<iostream>
#include<math.h>

using namespace cv;
using namespace std;

static Point NoCor;	//未修正的座標
static Point Cor;	//修正後的座標
static bool Select;	//是否被選中
int count = 0;	//回合次數
int Piece;	//判斷黑白雙方
int Type;	//棋子種類
int Corx;	//修正後的橫座標
int Cory;	//修正後的縱座標
int NUM1;
int NUM2;
static bool Lar;
vector<int>INFO{ 1100,1210,1420,1530,1740,1550,1460,1270,1180,1312,1372,1903,1923,1943,1963,1983,2606,2626,2646,2666,2686,
	2317,2377,2109,2219,2829,2539,2049,2559,2869,2279,2189 }; //儲存棋子的信息,第一位爲黑白方判斷,第二位爲棋子種類,第三位第四位分別爲橫縱座標
static vector<int>Help(90);	//輔助數組,判斷該處是否有棋子,並且判斷是否可以落子
static vector<Point>Judge{ Point(0,0),Point(0,0) };	//判斷

class Chess
{
public:
	static void Onmouse(int event, int x, int y, int flags, void* userdata);	//鼠標事件
	Chess();
	~Chess();
	Point FixCor(Point &NoCor);	//鼠標修正函數
	vector<int> Help;	//儲存落子的信息
};

class Chessboard
{
public:
	friend Chess;
	 Chessboard();
	~Chessboard();
	Mat chessboard;
	void inichessboard();	//初始化棋盤
private:
	int x = 60;
	int y = 40;
	int z = 140;
};

Chessboard::Chessboard()
{
	Mat chessboard = Mat(800, 800, CV_8UC3, Scalar(145, 197, 238));
	for (int i = 0; i <= 9; i++)
	{
		line(chessboard, Point(60, y), Point(700, y), Scalar(0, 0, 0), 2);
		y += 80;
	}
	for (int i = 0; i < 9; i++)
	{
		line(chessboard, Point(x, 40), Point(x, 760), Scalar(0, 0, 0), 2);
		x += 80;
	}
	for (int i = 0; i < 7; i++)
	{
		line(chessboard, Point(z, 361), Point(z, 439), Scalar(145, 197, 238), 2);
		z += 80;
	}
	line(chessboard, Point(50, 30), Point(710, 30), Scalar(0, 0, 0), 3);
	line(chessboard, Point(50, 770), Point(710, 770), Scalar(0, 0, 0), 3);
	line(chessboard, Point(50, 30), Point(50, 770), Scalar(0, 0, 0), 3);
	line(chessboard, Point(710, 30), Point(710, 770), Scalar(0, 0, 0), 3);
	line(chessboard, Point(300, 40), Point(460, 200), Scalar(0, 0, 0), 2);
	line(chessboard, Point(300, 200), Point(460, 40), Scalar(0, 0, 0), 2);
	line(chessboard, Point(300, 760), Point(460, 600), Scalar(0, 0, 0), 2);
	line(chessboard, Point(300, 600), Point(460, 760), Scalar(0, 0, 0), 2);
	putTextZH(chessboard, "楚河", Point(180, 380), (0, 0, 0), 50, "楷體", false, false);
	putTextZH(chessboard, "漢界", Point(480, 380), (0, 0, 0), 50, "楷體", false, false);
	for (int i = 0; i < 32; i++)
	{
		if (INFO[i] > 1000)
		{
			Piece = INFO[i] / 1000;
			Type = (INFO[i] - 1000 * Piece) / 100;
			Corx = (INFO[i] - 1000 * Piece - 100 * Type) / 10;
			Cory = INFO[i] - 1000 * Piece - 100 * Type - 10 * Corx;
			Point CornC,CornW;
			/*棋子顯示位置*/
			CornC.x = 60 + 80 * Corx;
			CornC.y = 40 + 80 * Cory;
			/*文字顯示位置*/
			CornW.x = CornC.x - 20;
			CornW.y = CornC.y - 20;
			circle(chessboard, CornC, 40, Scalar(75, 125, 177), -1, 8, 0);
			switch (Type)
			{
			case 0:
				putTextZH(chessboard, "帥", CornW, Scalar(0, 0, 255), 50, "楷體", false, false);
				break;
			case 1:
				if (Piece==1)
				{
					putTextZH(chessboard, "車", CornW, Scalar(0, 0, 0), 50, "楷體", false, false);
					break;
				}
				else
				{
					putTextZH(chessboard, "車", CornW, Scalar(0, 0, 255), 50, "楷體", false, false);
					break;
				}
			case 2:
				if (Piece == 1)
				{
					putTextZH(chessboard, "馬", CornW, Scalar(0, 0, 0), 50, "楷體", false, false);
					break;
				}
				else if (Piece==2)
				{
					putTextZH(chessboard, "馬", CornW, Scalar(0, 0, 255), 50, "楷體", false, false);
					break;
				}
			case 3:
				if (Piece == 1)
				{
					putTextZH(chessboard, "炮", CornW, Scalar(0, 0, 0), 50, "楷體", false, false);
					break;
				}
				else
				{
					putTextZH(chessboard, "炮", CornW, Scalar(0, 0, 255), 50, "楷體", false, false);
					break;
				}
			case 4:
				putTextZH(chessboard, "象", CornW, Scalar(0, 0, 0), 50, "楷體", false, false);
				break;
			case 5:
				if (Piece == 1)
				{
					putTextZH(chessboard, "士", CornW, Scalar(0, 0, 0), 50, "楷體", false, false);
					break;
				}
				else
				{
					putTextZH(chessboard, "士", CornW, Scalar(0, 0, 255), 50, "楷體", false, false);
					break;
				}
			case 6:
				putTextZH(chessboard, "兵", CornW, Scalar(0, 0, 255), 50, "楷體", false, false);
				break;
			case 7:
				putTextZH(chessboard, "將", CornW, Scalar(0, 0, 0), 50, "楷體", false, false);
				break;
			case 8:
				putTextZH(chessboard, "相", CornW, Scalar(0, 0, 255), 50, "楷體", false, false);
				break;
			case 9:
				putTextZH(chessboard, "卒", CornW, Scalar(0, 0, 0), 50, "楷體", false, false);
				break;
			}
		}
	}
	imshow("Playchess", chessboard);
}

Chessboard::~Chessboard()
{
}

void Chessboard::inichessboard()
{
	for (int i = 0; i <= 9; i++)
	{
		line(chessboard, Point(60, y), Point(700, y), Scalar(0, 0, 0), 2);
		y += 80;
	}
	for (int i = 0; i < 9; i++)
	{
		line(chessboard, Point(x, 40), Point(x, 760), Scalar(0, 0, 0), 2);
		x += 80;
	}
	for (int i = 0; i < 7; i++)
	{
		line(chessboard, Point(z, 361), Point(z, 439), Scalar(145, 197, 238), 2);
		z += 80;
	}
	line(chessboard, Point(50, 30), Point(710, 30), Scalar(0, 0, 0), 3);
	line(chessboard, Point(50, 770), Point(710, 770), Scalar(0, 0, 0), 3);
	line(chessboard, Point(50, 30), Point(50, 770), Scalar(0, 0, 0), 3);
	line(chessboard, Point(710, 30), Point(710, 770), Scalar(0, 0, 0), 3);
	line(chessboard, Point(300, 40), Point(460, 200), Scalar(0, 0, 0), 2);
	line(chessboard, Point(300, 200), Point(460, 40), Scalar(0, 0, 0), 2);
	line(chessboard, Point(300, 760), Point(460, 600), Scalar(0, 0, 0), 2);
	line(chessboard, Point(300, 600), Point(460, 760), Scalar(0, 0, 0), 2);
}

Chess::Chess()
{
	setMouseCallback("Playchess", Onmouse, NULL);
	Chessboard CB;
	vector<int>Help(90);
	for (int k = 0; k < 9; k++)
	{
		Help[k] = 1;
	}
	for (int i = 81; i < 90; i++)
	{
		Help[i] = 2;
	}
	Help[19] = 1;
	Help[25] = 1;
	Help[27] = 1;
	Help[29] = 1;
	Help[31] = 1;
	Help[33] = 1;
	Help[35] = 1;
	Help[54] = 2;
	Help[56] = 2;
	Help[58] = 2;
	Help[60] = 2;
	Help[62] = 2;
	Help[64] = 2;
	Help[70] = 2;
	int Fabsx, Fabsy;
	Point Circle;
	if (Lar==true)
	{
		for (int i = 0; i < INFO.size(); i++)
		{
			int EYE,leg1,leg2;
			EYE = (Judge[0].x + Judge[1].x) / 2 + 9 * (Judge[0].y + Judge[1].y) / 2;
			leg1 = (Judge[0].x + Judge[1].x) / 2 + 9 * Judge[0].y;
			leg2 = Judge[0].x + 9 * (Judge[0].y + Judge[1].y) / 2;
			cout << leg2 << endl;
			cout << Help[leg2] << endl;
			Piece = INFO[i] / 1000;
			Type = (INFO[i] - 1000 * Piece) / 100;
			Corx = (INFO[i] - 1000 * Piece - 100 * Type) / 10;
			Cory = INFO[i] - 1000 * Piece - 100 * Type - 10 * Corx;
			Fabsx = abs(Judge[1].x - Judge[0].x);
			Fabsy = abs(Judge[1].y - Judge[0].y);
			NUM1 = Judge[0].x + 9 * Judge[0].y;
			NUM2 = Judge[1].x + 9 * Judge[1].y;
			if (Corx == Judge[0].x&&Cory == Judge[0].y)
			{
				switch (Type)
				{
				case 7:
					if (Judge.back().x < 6 && Judge.back().x>2 && Judge.back().y < 3 && (Fabsx + Fabsy) == 1)
					{
						if (Help[NUM2] == 0)
						{
							INFO[i] = 1000 * Piece + 100 * Type + 10 * Judge[1].x + Judge[1].y;
							Help[NUM1] = 0;
							Help[NUM2] = Piece;
							break;
						}
					}
				case 0:
					if (Judge.back().x < 6 && Judge.back().x>2 && Judge.back().y < 10&&Judge.back().y>6 && (Fabsx + Fabsy) == 1)
					{
						if (Help[NUM2]==0)
						{
							INFO[i] = 1000 * Piece + 100 * Type + 10 * Judge[1].x + Judge[1].y;
							Circle.x = 60 + 80 * Judge[1].x;
							Circle.y = 40 + 80 * Judge[1].y;
							Help[NUM1] = 0;
							Help[NUM2] = Piece;
							break;
						}
					}
				case 6:
					if ((Fabsx + Fabsy) == 1)
					{
						if ((Help[NUM2]+Help[NUM1])==3)
						{
							INFO[i] = 1000*Piece+100 * Type + 10 * Judge.back().x + Judge.back().y; //Change
							Help[NUM1] = 0;
							Help[NUM2] = 2;
							for (int k = 0; k < INFO.size(); k++)
							{
								Piece = INFO[k] / 1000;
								Type = (INFO[k] - 1000 * Piece) / 100;
								Corx = (INFO[k] - 1000 * Piece - 100 * Type) / 10;
								Cory = INFO[k] - 1000 * Piece - 100 * Type - 10 * Corx;
								if ((Corx==Judge[1].x)&&(Cory==Judge[1].y))
								{
									INFO[k] = 100 * Type + 10 * Corx + Cory;
									break;
								}
							}
						}
						else
						{
							INFO[i] = 1000 * Piece + 100 * Type + 10 * Judge.back().x + Judge.back().y;
							Help[NUM1] = 0;
							Help[NUM2] = 2;
							break;
						}
					}
				case 9:
					if ((Fabsx + Fabsy) == 1)
					{
						if ((Help[NUM2] + Help[NUM1])==3)
						{
							INFO[i] = 1000 * Piece + 100 * Type + 10 * Judge[1].x + Judge[1].y; //Change
							Help[NUM1] = 0;
							Help[NUM2] = Piece;
							for (int k = 0; k < INFO.size(); k++)
							{
								Piece = INFO[k] / 1000;
								Type = (INFO[k] - 1000 * Piece) / 100;
								Corx = (INFO[k] - 1000 * Piece - 100 * Type) / 10;
								Cory = INFO[k] - 1000 * Piece - 100 * Type - 10 * Corx;
								if (Corx == Judge[1].x&&Cory == Judge[1].y)
								{
									INFO[k] = 100 * Type + 10 * Corx + Cory;
									break;
								}
							}
						}
						else
						{
							INFO[i] = 1000 * Piece + 100 * Type + 10 * Judge.back().x + Judge.back().y;
							Help[NUM1] = 0;
							Help[NUM2] = 2;
							break;
						}
					}
				case 1:
					if (Judge[1].y==Judge[0].y)
					{
						int count = 0;
						int k = Judge[0].x > Judge[1].x ? Judge[0].x : Judge[1].x;
						for (k ; k < fabs(Judge[1].x-Judge[0].x); k++)
						{
							if (Help[k]!=0)
							{
								count++;
							}
						}
						if (count==0)
						{
							if (Help[NUM1] == Help[NUM2])
							{
								break;
							}
							else if (Help[NUM2] != Help[NUM1]&&Help[NUM2!=0&&Help[NUM1]!=0])
							{
								for (int k = 0; k < INFO.size(); k++)
								{
									Piece = INFO[k] / 1000;
									Type = (INFO[k] - 1000 * Piece) / 100;
									Corx = (INFO[k] - 1000 * Piece - 100 * Type) / 10;
									Cory = INFO[k] - 1000 * Piece - 100 * Type - 10 * Corx;
									if (Corx == Judge[1].x&&Cory == Judge[1].y)
									{
										INFO[k] = 100 * Type + 10 * Corx + Cory;
										break;
									}
								}
							}
							else
							{
								INFO[i] = 1000 * Piece + 100 * Type + 10 * Judge[1].x + Judge[1].y;
								Circle.x = 60 + 80 * Judge[1].x;
								Circle.y = 40 + 80 * Judge[1].y;
								Help[NUM1] = 0;
								Help[NUM2] = Piece;
								break;
							}
						}
					}
					if (Judge[1].x == Judge[0].x)
					{
						int count = 0;
						int k = Judge[0].y > Judge[1].y ? Judge[0].y : Judge[1].y;
						for (k; k < fabs(Judge[1].y - Judge[0].y); k++)
						{
							if (Help[k] != 0)
							{
								k+=8;
								count++;
							}
						}
						if (count == 0)
						{
							if (Help[NUM1] == Help[NUM2])
							{
								break;
							}
							else if ((Help[NUM2] + Help[NUM1])==3)
							{
								for (int k = 0; k < INFO.size(); k++)
								{
									Piece = INFO[k] / 1000;
									Type = (INFO[k] - 1000 * Piece) / 100;
									Corx = (INFO[k] - 1000 * Piece - 100 * Type) / 10;
									Cory = INFO[k] - 1000 * Piece - 100 * Type - 10 * Corx;
									if (Corx == Judge[1].x&&Cory == Judge[1].y)
									{
										INFO[k] = 100 * Type + 10 * Corx + Cory;
										break;
									}
								}
							}
							else
							{
								INFO[i] = 1000 * Piece + 100 * Type + 10 * Judge[1].x + Judge[1].y;
								Circle.x = 60 + 80 * Judge[1].x;
								Circle.y = 40 + 80 * Judge[1].y;
								Help[NUM1] = 0;
								Help[NUM2] = Piece;
								break;
							}
						}
					}
				case 3:
					if (Judge[1].y == Judge[0].y)
					{
						int count = 0;
						int k = Judge[0].x > Judge[1].x ? Judge[0].x : Judge[1].x;
						for (k; k < fabs(Judge[1].x - Judge[0].x); k++)
						{
							if (Help[k] != 0)
							{
								count++;
							}
						}
						if (count == 0)
						{
							INFO[i] = 1000 * Piece + 100 * Type + 10 * Judge[1].x + Judge[1].y;
							Circle.x = 60 + 80 * Judge[1].x;
							Circle.y = 40 + 80 * Judge[1].y;
							Help[NUM1] = 0;
							Help[NUM2] = Piece;
							break;
						}
						if (count == 1)
						{
							if (Help[NUM1] == Help[NUM2])
							{
								break;
							}
							else if ((Help[NUM1] + Help[NUM2]) == 2)
							{
								for (int k = 0; k < INFO.size(); k++)
								{
									Piece = INFO[k] / 1000;
									Type = (INFO[k] - 1000 * Piece) / 100;
									Corx = (INFO[k] - 1000 * Piece - 100 * Type) / 10;
									Cory = INFO[k] - 1000 * Piece - 100 * Type - 10 * Corx;
									if (Corx == Judge[1].x&&Cory == Judge[1].y)
									{
										INFO[k] = 100 * Type + 10 * Corx + Cory;
										Help[NUM2] = Help[NUM1];
										Help[NUM1] = 0;
										break;
									}
								}
							}
						}
					}
					if (Judge[1].x == Judge[0].x)
					{
						int count = 0;
						int k = Judge[0].y > Judge[1].y ? Judge[0].y : Judge[1].y;
						for (k; k < fabs(Judge[1].y - Judge[0].y); k++)
						{
							if (Help[k] != 0)
							{
								k += 8;
								count++;
							}
						}
						if (count == 0)
						{
							INFO[i] = 1000 * Piece + 100 * Type + 10 * Judge[1].x + Judge[1].y;
							Circle.x = 60 + 80 * Judge[1].x;
							Circle.y = 40 + 80 * Judge[1].y;
							Help[NUM1] = 0;
							Help[NUM2] = 1;
							break;
						}
						if (count==1)
						{
							if (Help[NUM1] == Help[NUM2])
							{
								break;
							}
							if ((Help[NUM1]+Help[NUM2])==3)
							{
								for (int k = 0; k < INFO.size(); k++)
								{
									Piece = INFO[k] / 1000;
									Type = (INFO[k] - 1000 * Piece) / 100;
									Corx = (INFO[k] - 1000 * Piece - 100 * Type) / 10;
									Cory = INFO[k] - 1000 * Piece - 100 * Type - 10 * Corx;
									if (Corx == Judge[1].x&&Cory == Judge[1].y)
									{
										Help[NUM2] = Help[NUM1];
										Help[NUM1] = 0;
										INFO[k] = 100 * Type + 10 * Corx + Cory;
										break;
									}
								}
							}
						}
					}
				case 5:
					if ((Fabsx+Fabsy)==2&&Fabsx==Fabsy)
					{
						if (Piece==1&& Judge.back().x < 6 && Judge.back().x>2 && Judge.back().y < 3)
						{
							INFO[i] = 1000 * Piece + 100 * Type + 10 * Judge[1].x + Judge[1].y;							
							Help[NUM1] = 0;
							Help[NUM2] = Piece;
							break;
						}
						if (Piece==2&&Judge.back().x < 6 && Judge.back().x>2 && Judge.back().y < 10 && Judge.back().y>6)
						{
							INFO[i] = 1000 * Piece + 100 * Type + 10 * Judge.back().x + Judge.back().y;						
							Help[NUM1] = 0;
							Help[NUM2] = 1;
							break;
						}
					}
				case 2:
					if ((Fabsx+Fabsy)==3)
					{
						if (Fabsx==2)
						{
							if (Help[leg1] == 0)
							{
								if ((Help[NUM1] + Help[NUM2]) == 3)
								{
									INFO[i] = 1000 * Piece + 100 * Type + 10 * Judge.back().x + Judge.back().y;
									for (int k = 0; k < INFO.size(); k++)
									{
										Piece = INFO[k] / 1000;
										Type = (INFO[k] - 1000 * Piece) / 100;
										Corx = (INFO[k] - 1000 * Piece - 100 * Type) / 10;
										Cory = INFO[k] - 1000 * Piece - 100 * Type - 10 * Corx;
										if (Corx == Judge.back().x&&Cory == Judge.back().y)
										{
											INFO[k] = 100 * Type + 10 * Corx + Cory;
											Help[NUM2] = Help[NUM1];
											Help[NUM1] = 0;
											break;
										}
									}
								}
								else
								{
									INFO[i] = 1000 * Piece + 100 * Type + 10 * Judge.back().x + Judge.back().y;
									cout << INFO[i] << endl;
									Circle.x = 60 + 80 * Judge[1].x;
									Circle.y = 40 + 80 * Judge[1].y;
									Help[NUM1] = 0;
									Help[NUM2] = Piece;
									break;
								}
							}
						}
						if (Fabsy==2)
						{
							if (Help[leg2]==0)
							{
								if ((Help[NUM1] + Help[NUM2]) == 3)
								{
									INFO[i] = 1000 * Piece + 100 * Type + 10 * Judge.back().x + Judge.back().y;
									for (int k = 0; k < INFO.size(); k++)
									{
										Piece = INFO[k] / 1000;
										Type = (INFO[k] - 1000 * Piece) / 100;
										Corx = (INFO[k] - 1000 * Piece - 100 * Type) / 10;
										Cory = INFO[k] - 1000 * Piece - 100 * Type - 10 * Corx;
										if (Corx == Judge[1].x&&Cory == Judge[1].y)
										{
											INFO[k] = 100 * Type + 10 * Corx + Cory;
											Help[NUM2] = Help[NUM1];
											Help[NUM1] = 0;
											break;
										}
									}
								}
								else
								{
									INFO[i] = 1000 * Piece + 100 * Type + 10 * Judge.back().x + Judge.back().y;
									cout << INFO[i] << endl;
									Circle.x = 60 + 80 * Judge[1].x;
									Circle.y = 40 + 80 * Judge[1].y;
									Help[NUM1] = 0;
									Help[NUM2] = Piece;
									break;
								}								
							}
						}
					}
				case 4:
					if (Fabsx==2&&Fabsy==2&&Help[EYE]==0)
					{
						if (Help[NUM1] == Help[NUM2])
							{
								break;
							}
						if ((Help[NUM1] + Help[NUM2]) == 3)
							{
								INFO[i] = 1000 * Piece + 100 * Type + 10 * Judge.back().x + Judge.back().y; //Change
								Help[NUM1] = 0;
								Help[NUM2] = 1;
								for (int k = 0; k < INFO.size(); k++)
								{
									Piece = INFO[k] / 1000;
									Type = (INFO[k] - 1000 * Piece) / 100;
									Corx = (INFO[k] - 1000 * Piece - 100 * Type) / 10;
									Cory = INFO[k] - 1000 * Piece - 100 * Type - 10 * Corx;
									if (Corx == Judge[1].x&&Cory == Judge[1].y)
									{
										INFO[k] = 100 * Type + 10 * Corx + Cory;
										break;
									}
								}

							}
						INFO[i] = 1000 * Piece + 100 * Type + 10 * Judge.back().x + Judge.back().y;
						Help[NUM1] = 0;
						Help[NUM2] = 1;
						break;						
					}
				case 8:
					if (Fabsx == 2 && Fabsy == 2 && Help[EYE] == 0)
					{
						if ((Help[NUM1] + Help[NUM2]) == 3)
							{
								INFO[i] = 1000 * Piece + 100 * Type + 10 * Judge[1].x + Judge[1].y; //Change
								Help[NUM1] = 0;
								Help[NUM2] = 2;
								for (int k = 0; k < INFO.size(); k++)
								{
									Piece = INFO[k] / 1000;
									Type = (INFO[k] - 1000 * Piece) / 100;
									Corx = (INFO[k] - 1000 * Piece - 100 * Type) / 10;
									Cory = INFO[k] - 1000 * Piece - 100 * Type - 10 * Corx;
									if (Corx == Judge[1].x&&Cory == Judge[1].y)
									{
										INFO[k] = 100 * Type + 10 * Corx + Cory;
										break;
									}
								}
							}
						if (Help[NUM2] == 0)
						{
							INFO[i] = 1000 * Piece + 100 * Type + 10 * Judge.back().x + Judge.back().y;
							Help[NUM1] = 0;
							Help[NUM2] = 2;;
							break;
						}
						
					}
				}
				Select = false;
				Lar = false;
				if (INFO[4]<1000)
				{
					exit(0);
					cout << "紅方勝利" << endl;
				}
				if (INFO[27]<1000)
				{
					exit(0);
					cout << "黑方勝利" << endl;
				}
				break;
			}
		}
	}
}

Chess::~Chess()
{

}

Point Chess::FixCor(Point &NoCor)
{
	int m, n;
	m = (NoCor.x - 60) % 80;
	n = (NoCor.y - 40) % 80;
	if (m <= 40)
	{
		Cor.x = (NoCor.x - m - 60) / 80;
	}
	else
	{
		Cor.x = (NoCor.x - m + 20) / 80;
	}
	if (n <= 40)
	{
		Cor.y = (NoCor.y - n - 40) / 80;
	}
	else
	{
		Cor.y = (NoCor.y - n + 40) / 80;
	}
	return Cor;

}

void Chess::Onmouse(int event, int x, int y, int flags, void* userdata)
{
	if (event==EVENT_LBUTTONDOWN)
	{
		Chess *p = new Chess();
		if (Select == true && Lar == false)
		{
			NoCor.x = x;
			NoCor.y = y;
			Cor = p->FixCor(NoCor);
			Judge[1] = Cor;
			Lar = true;
		}
		if (Lar == false && Select == false)
		{
			NoCor.x = x;
			NoCor.y = y;
			Cor = p->FixCor(NoCor);
			for (int i = 0; i < INFO.size(); i++)
			{
				Piece = INFO[i] / 1000;
				Type = (INFO[i] - 1000 * Piece) / 100;
				Corx = (INFO[i] - 1000 * Piece - 100 * Type) / 10;
				Cory = INFO[i] - 1000 * Piece - 100 * Type - 10 * Corx;
				if (Cor.x == Corx && Cor.y == Cory)
				{
					Judge[0] = Cor;
					cout << "Select==false" << endl;
					Select = true;
					break;
				}
			}
		}
	}
	if (event==EVENT_RBUTTONDOWN)
	{
		Select = false;
		Lar = false;
	}
}
static void GetStringSize(HDC hDC, const char* str, int* w, int* h)
{
	SIZE size;
	GetTextExtentPoint32A(hDC, str, strlen(str), &size);
	if (w != 0) *w = size.cx;
	if (h != 0) *h = size.cy;
}
static void putTextZH(Mat &dst, const char* str, Point org, Scalar color, int fontSize, const char* fn, bool italic, bool underline)
{
	CV_Assert(dst.data != 0 && (dst.channels() == 1 || dst.channels() == 3));
	int x, y, r, b;
	if (org.x > dst.cols || org.y > dst.rows) return;
	x = org.x < 0 ? -org.x : 0;
	y = org.y < 0 ? -org.y : 0;
	LOGFONTA lf;
	lf.lfHeight = -fontSize;
	lf.lfWidth = 0;
	lf.lfEscapement = 0;
	lf.lfOrientation = 0;
	lf.lfWeight = 5;
	lf.lfItalic = italic; //斜體
	lf.lfUnderline = underline; //下劃線
	lf.lfStrikeOut = 0;
	lf.lfCharSet = DEFAULT_CHARSET;
	lf.lfOutPrecision = 0;
	lf.lfClipPrecision = 0;
	lf.lfQuality = PROOF_QUALITY;
	lf.lfPitchAndFamily = 0;
	strcpy_s(lf.lfFaceName, fn);
	HFONT hf = CreateFontIndirectA(&lf);
	HDC hDC = CreateCompatibleDC(0);
	HFONT hOldFont = (HFONT)SelectObject(hDC, hf);
	int strBaseW = 0, strBaseH = 0;
	int singleRow = 0;
	char buf[1 << 12];
	strcpy_s(buf, str);
	char *bufT[1 << 12]; // 這個用於分隔字符串後剩餘的字符,可能會超出。
	//處理多行
	{
		int nnh = 0;
		int cw, ch;
		const char* ln = strtok_s(buf, "\n", bufT);
		while (ln != 0)
		{
			GetStringSize(hDC, ln, &cw, &ch);
			strBaseW = max(strBaseW, cw);
			strBaseH = max(strBaseH, ch);
			ln = strtok_s(0, "\n", bufT);
			nnh++;
		}
		singleRow = strBaseH;
		strBaseH *= nnh;
	}
	if (org.x + strBaseW < 0 || org.y + strBaseH < 0)
	{
		SelectObject(hDC, hOldFont);
		DeleteObject(hf);
		DeleteObject(hDC);
		return;
	}
	r = org.x + strBaseW > dst.cols ? dst.cols - org.x - 1 : strBaseW - 1;
	b = org.y + strBaseH > dst.rows ? dst.rows - org.y - 1 : strBaseH - 1;
	org.x = org.x < 0 ? 0 : org.x;
	org.y = org.y < 0 ? 0 : org.y;
	BITMAPINFO bmp = { 0 };
	BITMAPINFOHEADER& bih = bmp.bmiHeader;
	int strDrawLineStep = strBaseW * 3 % 4 == 0 ? strBaseW * 3 : (strBaseW * 3 + 4 - ((strBaseW * 3) % 4));
	bih.biSize = sizeof(BITMAPINFOHEADER);
	bih.biWidth = strBaseW;
	bih.biHeight = strBaseH;
	bih.biPlanes = 1;
	bih.biBitCount = 24;
	bih.biCompression = BI_RGB;
	bih.biSizeImage = strBaseH * strDrawLineStep;
	bih.biClrUsed = 0;
	bih.biClrImportant = 0;
	void* pDibData = 0;
	HBITMAP hBmp = CreateDIBSection(hDC, &bmp, DIB_RGB_COLORS, &pDibData, 0, 0);
	CV_Assert(pDibData != 0);
	HBITMAP hOldBmp = (HBITMAP)SelectObject(hDC, hBmp);
	//color.val[2], color.val[1], color.val[0]
	SetTextColor(hDC, RGB(255, 255, 255));
	SetBkColor(hDC, 0);
	//SetStretchBltMode(hDC, COLORONCOLOR);
	strcpy_s(buf, str);
	const char* ln = strtok_s(buf, "\n", bufT);
	int outTextY = 0;
	while (ln != 0)
	{
		TextOutA(hDC, 0, outTextY, ln, strlen(ln));
		outTextY += singleRow;
		ln = strtok_s(0, "\n", bufT);
	}
	uchar* dstData = (uchar*)dst.data;
	int dstStep = dst.step / sizeof(dstData[0]);
	unsigned char* pImg = (unsigned char*)dst.data + org.x * dst.channels() + org.y * dstStep;
	unsigned char* pStr = (unsigned char*)pDibData + x * 3;
	for (int tty = y; tty <= b; ++tty)
	{
		unsigned char* subImg = pImg + (tty - y) * dstStep;
		unsigned char* subStr = pStr + (strBaseH - tty - 1) * strDrawLineStep;
		for (int ttx = x; ttx <= r; ++ttx)
		{
			for (int n = 0; n < dst.channels(); ++n) {
				double vtxt = subStr[n] / 255.0;
				int cvv = vtxt * color.val[n] + (1 - vtxt) * subImg[n];
				subImg[n] = cvv > 255 ? 255 : (cvv < 0 ? 0 : cvv);
			}
			subStr += 3;
			subImg += dst.channels();
		}
	}
	SelectObject(hDC, hOldBmp);
	SelectObject(hDC, hOldFont);
	DeleteObject(hf);
	DeleteObject(hBmp);
	DeleteDC(hDC);
}
int main()
{
	Chessboard chessboard;
	Chess chess;
	waitKey(0);
	return 0;
}


這就是簡單的中國象棋的實現,但是其中仍有很多漏洞,希望各位大佬積極批評指正。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章