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;
}
这就是简单的中国象棋的实现,但是其中仍有很多漏洞,希望各位大佬积极批评指正。