中国象棋控件 2.0.15
载入中...
搜索中...
未找到
FrmChineseChess.cpp
1// 作者:康林 <kl222@126.com>
2
3#include "FrmChineseChess.h"
4#include "ui_FrmChineseChess.h"
5#include "DlgAbout/DlgAbout.h"
6#include "RabbitCommonTools.h"
7
8#include <QResizeEvent>
9#include <QMouseEvent>
10#include <QPoint>
11#include <QMessageBox>
12#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
13 #include <QSoundEffect>
14#else
15 #include <QSound>
16#endif
17#include <QBitmap>
18
19CFrmChineseChess::CFrmChineseChess(QWidget *parent) :
20 QWidget(parent),
22 ui(new Ui::CFrmChineseChess),
23 m_QiPangColor(0, 0, 0),
24 m_TiShiBoxColor(0, 255, 0)
25{
26 ui->setupUi(this);
27
28 m_QiPangStartX = m_QiPangStartY = 0;
29 m_QiPangDistance = 0;
30
31 m_QiPangPicture.load(":/image/QIPANG");
32 SetTransparentImage(m_QiPangPicture);
33 m_RedShuai.load(":/image/RSHUAI");
34 //SetTransparentImage(m_RedShuai);
35 m_RedShi.load(":/image/RSHI");
36 //SetTransparentImage(m_RedShi);
37 m_RedXiang.load(":/image/RXIANG");
38 //SetTransparentImage(m_RedXiang);
39 m_RedMa.load(":/image/RMA");
40 //SetTransparentImage(m_RedMa);
41 m_RedChe.load(":/image/RCHE");
42 //SetTransparentImage(m_RedChe);
43 m_RedBing.load(":/image/RBING");
44 //SetTransparentImage(m_RedBing);
45 m_RedPao.load(":/image/RPAO");
46 //SetTransparentImage(m_RedPao);
47 m_BlackShuai.load(":/image/BSHUAI");
48 //SetTransparentImage(m_BlackShuai);
49 m_BlackShi.load(":/image/BSHI");
50 //SetTransparentImage(m_BlackShi);
51 m_BlackXiang.load(":/image/BXIANG");
52 //SetTransparentImage(m_BlackXiang);
53 m_BlackMa.load(":/image/BMA");
54 //SetTransparentImage(m_BlackMa);
55 m_BlackChe.load(":/image/BCHE");
56 //SetTransparentImage(m_BlackChe);
57 m_BlackBing.load(":/image/BZU");
58 //SetTransparentImage(m_BlackBing);
59 m_BlackPao.load(":/image/BPAO");
60 //SetTransparentImage(m_BlackPao);
61
62 m_Chu.load(":/image/CHU");
63 SetTransparentImage(m_Chu);
64 m_He.load(":/image/HE");
65 SetTransparentImage(m_He);
66 m_Han.load(":/image/HAN");
67 SetTransparentImage(m_Han);
68 m_Jie.load(":/image/JIE");
69 SetTransparentImage(m_Jie);
70 m_KL.load(":/image/KL");
71}
72
73CFrmChineseChess::~CFrmChineseChess()
74{
75 delete ui;
76}
77
78static QSharedPointer<QTranslator> g_Translator;
79int CFrmChineseChess::InitResource(const QString szLanguage)
80{
81 Q_INIT_RESOURCE(ResourceChineseChess);
82#if (defined(DEBUG) || defined(_DEBUG)) && !defined (BUILD_SHARED_LIBS)
83 Q_INIT_RESOURCE(translations_ChineseChessQt);
84#endif
85 g_Translator = RabbitCommon::CTools::Instance()->InstallTranslator(
86 "ChineseChessQt",
87 RabbitCommon::CTools::TranslationType::Library,
88 "",
89 szLanguage);
90 if(g_Translator)
91 return 0;
92 return -1;
93}
94
96{
97 RabbitCommon::CTools::Instance()->RemoveTranslator(g_Translator);
98
99#if (defined(DEBUG) || defined(_DEBUG)) && !defined (BUILD_SHARED_LIBS)
100 Q_CLEANUP_RESOURCE(translations_ChineseChessQt);
101#endif
102 Q_CLEANUP_RESOURCE(ResourceChineseChess);
103 return 0;
104}
105
106void CFrmChineseChess::mouseReleaseEvent(QMouseEvent *event)
107{
108 int i = 0, j = 0;
109 long x = 0, y = 0;
110 QPoint p = event->pos();
111 x = p.x();
112 y = p.y();
113 ConvertCoordinate(&x, &y, &i, &j);
114 if (GoChess(i, j))
115 {
116
117 }
118}
119
120void CFrmChineseChess::paintEvent(QPaintEvent *event)
121{
122 QPainter painter(this);
123
124 // 设置平滑模式
125 painter.setRenderHint(QPainter::SmoothPixmapTransform);
126
127 DrawQiPang(&painter, rect());
128}
129
130void CFrmChineseChess::resizeEvent(QResizeEvent *event)
131{
132 QSize s = event->size();
133 SetQiPang(s.width(), s.height());
134}
135
136int CFrmChineseChess::onPromptSound(PROMPT_SOUND sound)
137{
138 QString szFile;
139 switch (sound)
140 {
141 case JiangJun:
142 szFile = ":/sound/CHECK";
143 break;
144 case Eat:
145 szFile = ":/sound/EAT";
146 break;
147 case Go:
148 szFile = ":/sound/GO";
149 break;
150 case NoGo:
151 szFile = ":/sound/DEAD";
152 break;
153 case Select:
154 szFile = ":/sound/SELECT";
155 break;
156 default:
157 return 0;
158 }
159#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
160 static QSoundEffect effect;
161 effect.setSource(QUrl::fromLocalFile(szFile));
162 //effect.setLoopCount(1);
163 //effect.setVolume(1);
164 if(effect.isPlaying())
165 effect.stop();
166 effect.play();
167#else
168 QSound::play(szFile);
169#endif
170 return 0;
171}
172
173int CFrmChineseChess::onPromptMessage(CGoRule::ENUM_ReturnValue val)
174{
175 QMessageBox msg(this);
176 switch (val)
177 {
179 msg.setText(tr("This step cannot be taken, otherwise you will lose"));
180 msg.setWindowTitle(tr("checked"));
181 break;
183 msg.setText(tr("This step cannot be taken, otherwise you will lose"));
184 msg.setWindowTitle(tr("Opposite"));
185 break;
186 default:
187 return 0;
188 }
189 msg.exec();
190 return 0;
191}
192
194{
195 Q_UNUSED(i)
196 Q_UNUSED(j)
197 int nRet = 0;
198 this->update();
199 return nRet;
200}
201
203{
204 Q_UNUSED(i)
205 Q_UNUSED(j)
206 int nRet = 0;
207 this->update();
208 return nRet;
209}
210
212{
213 emit sigGoChess(i, j, chess);
214 return 0;
215}
216
217void CFrmChineseChess::AboutBox()
218{
219 CDlgAbout* pAbout = new CDlgAbout(this);
220 pAbout->m_AppIcon = QImage(":/image/Chess");
221 pAbout->m_szAppName = tr("Chinese chess control");
222 pAbout->m_szHomePage = "https://github.com/KangLin/ChineseChessControl";
223 pAbout->m_szCopyrightTime = "1994 - " + QString::number(QDate::currentDate().year());
224#ifdef ChineseChessQt_VERSION
225 pAbout->m_szVersion = ChineseChessQt_VERSION;
226#endif
227#ifdef ChineseChessQt_REVISION
228 pAbout->m_szVersionRevision = ChineseChessQt_REVISION;
229#endif
230 RC_SHOW_WINDOW(pAbout);
231}
232
234{
235 time_t t = CChineseChess::GetStartTime();
236 QDateTime time;
237 time.setMSecsSinceEpoch(t);
238 return time;
239}
240
241int CFrmChineseChess::SetStartTime(const QDateTime &t)
242{
243 return CChineseChess::SetStartTime(t.toMSecsSinceEpoch());
244}
245
246QDateTime CFrmChineseChess::GetEndTime()
247{
248 QDateTime t;
249 t.setMSecsSinceEpoch(CChineseChess::GetEndTime());
250 return t;
251}
252
253int CFrmChineseChess::SetEndTime(const QDateTime &t)
254{
255 return CChineseChess::SetEndTime(t.toMSecsSinceEpoch());
256}
257
258QString CFrmChineseChess::GetRedName()
259{
260 return CChineseChess::GetRedName().c_str();
261}
262
263int CFrmChineseChess::SetRedName(const QString &name)
264{
265 return CChineseChess::SetRedName(name.toStdString().c_str());
266}
267
268QString CFrmChineseChess::GetBlackName()
269{
270 return CChineseChess::GetBlackName().c_str();
271}
272
273int CFrmChineseChess::SetBlackName(const QString &name)
274{
275 return CChineseChess::SetBlackName(name.toStdString().c_str());
276}
277
289bool CFrmChineseChess::ConvertCoordinate(long *x, long *y, int *i, int *j, ENUM_ConvertCoordinate eCC)
290{
291 switch (eCC)
292 {
293 case XYToIJ:
296 break;
297 case IJToXY:
300 break;
301 }
302 return true;
303}
304
311bool CFrmChineseChess::SetQiPang(int width, int height)
312{
313 if (width > height)
314 {
315 m_QiPangDistance = height / 11;
316 m_QiPangStartX = (width - m_QiPangDistance * 10) / 2 + m_QiPangDistance;
318 }
319 else
320 {
321 m_QiPangDistance = width / 10;
323 m_QiPangStartY = (height - m_QiPangDistance * 11) / 2 + m_QiPangDistance;
324 }
325 return true;
326}
327
333void CFrmChineseChess::DrawQiPang(QPainter *pPainter, QRect rect)
334{
335 if(nullptr == pPainter)
336 return;
337
338 pPainter->save();
339
340 DrawImage(pPainter, rect, m_QiPangPicture);
341
342 int i, j;
343 for (i = 0; i < 9; i++) //纵格
344 {
345 if (i == 0 || i == 8)
346 {
347 QPen pen;
348 pen.setColor(m_QiPangColor);
349 pen.setWidth(2);
350 pPainter->setPen(pen);
351 pPainter->drawLine(m_QiPangStartX + i * m_QiPangDistance,
355 }
356 else
357 {
358 QPen pen(QBrush(m_QiPangColor), 1);
359 pPainter->setPen(pen);
360 pPainter->drawLine(m_QiPangStartX + i * m_QiPangDistance,
364 pPainter->drawLine(m_QiPangStartX + i * m_QiPangDistance,
368 }
369 }
370
371 for (i = 0; i < 10; i++) //横格
372 {
373 QPen pen;
374 pen.setColor(m_QiPangColor);
375 if (i == 0 || i == 9)
376 {
377 pen.setWidth(2);
378 }
379 else
380 {
381 pen.setWidth(1);
382 }
383
384 pPainter->setPen(pen);
385
386 pPainter->drawLine(m_QiPangStartX,
390
391 }
392
393 //九宫
394 QPen pen;
395 pen.setColor(m_QiPangColor);
396 pen.setWidth(1);
397 pPainter->setPen(pen);
398 pPainter->drawLine(m_QiPangStartX + 3 * m_QiPangDistance,
402
403 pPainter->drawLine(m_QiPangStartX + 5 * m_QiPangDistance,
407
408 pPainter->drawLine(m_QiPangStartX + 3 * m_QiPangDistance,
412
413 pPainter->drawLine(m_QiPangStartX + 5 * m_QiPangDistance,
417
418
419 //星位
420 DrawXinWei(pPainter, 1, 2);
421 DrawXinWei(pPainter, 7, 2);
422 DrawXinWei(pPainter, 1, 7);
423 DrawXinWei(pPainter, 7, 7);
424 DrawXinWei(pPainter, 0, 3, Right_XinWei);
425 DrawXinWei(pPainter, 2, 3);
426 DrawXinWei(pPainter, 4, 3);
427 DrawXinWei(pPainter, 6, 3);
428 DrawXinWei(pPainter, 8, 3, Left_XinWei);
429 DrawXinWei(pPainter, 0, 6, Right_XinWei);
430 DrawXinWei(pPainter, 2, 6);
431 DrawXinWei(pPainter, 4, 6);
432 DrawXinWei(pPainter, 6, 6);
433 DrawXinWei(pPainter, 8, 6, Left_XinWei);
434
435 //楚河汉界
436 //楚
437 DrawPicture(pPainter, 7, 4, m_Chu, true);
438 //河
439 DrawPicture(pPainter, 6, 4, m_He, true);
440 //汉
441 DrawPicture(pPainter, 1, 4, m_Han, true);
442 //界
443 DrawPicture(pPainter, 2, 4, m_Jie, true);
444 //KL
445 DrawPicture(pPainter, 4, 4, m_KL, true);
446
447 //画棋子
448 for (i = 0; i < 9; i++)
449 for (j = 0; j < 10; j++)
450 {
451 DrawQiZi(pPainter, i, j, m_ChessBoard[i][j]);
452 }
453
454 //显示提示框
455 if (IsValidPosition(m_PreviouPositionX, m_PreviouPositionY))
456 DrawTiShiBox(pPainter, m_PreviouPositionX, m_PreviouPositionY);
457 if (IsValidPosition(m_CurrentPositionX, m_CurrentPositionY))
458 DrawTiShiBox(pPainter, m_CurrentPositionX, m_CurrentPositionY);
459
460 pPainter->restore();
461}
462
473void CFrmChineseChess::DrawXinWei(QPainter *pPainter, int i, int j, ENUM_XINWEI xinwei)
474{
475 int d, ds;
476 long x, y;
477
478 d = m_QiPangDistance * 4 / 10;
479 ds = m_QiPangDistance * 2 / 10;
480
481 ConvertCoordinate(&x, &y, &i, &j, IJToXY);
482
483 QPen pen;
484 pen.setColor(m_QiPangColor);
485 pen.setWidth(1);
486 pPainter->setPen(pen);
487
488 if (xinwei != Left_XinWei)
489 {
490 pPainter->drawLine(x + ds, y + ds, x + d, y + ds);
491 pPainter->drawLine(x + ds, y - ds, x + d, y - ds);
492
493 pPainter->drawLine(x + ds, y + ds, x + ds, y + d);
494
495 pPainter->drawLine(x + ds, y - ds, x + ds, y - d);
496 }
497
498 if (xinwei != Right_XinWei)
499 {
500 pPainter->drawLine(x - ds, y - ds, x - ds, y - d);
501
502 pPainter->drawLine(x - ds, y + ds, x - ds, y + d);
503
504 pPainter->drawLine(x - ds, y + ds, x - d, y + ds);
505
506 pPainter->drawLine(x - ds, y - ds, x - d, y - ds);
507 }
508}
509
517bool CFrmChineseChess::DrawTiShiBox(QPainter *pPainter, int i, int j)
518{
519 // CClientDC dc(this);
520
521 long m_X, m_Y, m_L = m_QiPangDistance / 2;
522
523 QPen pen;
524 pen.setColor(m_TiShiBoxColor);
525 pen.setWidth(1);
526 pPainter->setPen(pen);
527
528 ConvertCoordinate(&m_X, &m_Y, &i, &j, IJToXY);
529 pPainter->drawLine(m_X - m_L, m_Y - m_L, m_X - m_L, m_Y - m_L / 2);
530
531 pPainter->drawLine(m_X - m_L, m_Y - m_L, m_X - m_L / 2, m_Y - m_L);
532
533 pPainter->drawLine(m_X + m_L, m_Y + m_L, m_X + m_L, m_Y + m_L / 2);
534
535 pPainter->drawLine(m_X + m_L, m_Y + m_L, m_X + m_L / 2, m_Y + m_L);
536
537 pPainter->drawLine(m_X - m_L, m_Y + m_L, m_X - m_L, m_Y + m_L / 2);
538
539 pPainter->drawLine(m_X - m_L, m_Y + m_L, m_X - m_L / 2, m_Y + m_L);
540
541 pPainter->drawLine(m_X + m_L, m_Y - m_L, m_X + m_L, m_Y - m_L / 2);
542
543 pPainter->drawLine(m_X + m_L, m_Y - m_L, m_X + m_L / 2, m_Y - m_L);
544
545 return true;
546}
547
556int CFrmChineseChess::DrawQiZi(QPainter *pPainter, int i, int j, CPiece::ENUM_QiZi eQiZi)
557{
558
559 QImage qz;
560#pragma warning( disable : 4806 )
561
562 switch (eQiZi)
563 {
564 case CPiece::NoQiZi:
565 return false;
566 case CPiece::RShuai:
567 qz = m_RedShuai;
568 break;
569 case CPiece::RShi:
570 qz = m_RedShi;
571 break;
572 case CPiece::RXiang:
573 qz = m_RedXiang;
574 break;
575 case CPiece::RMa:
576 qz = m_RedMa;
577 break;
578 case CPiece::RChe:
579 qz = m_RedChe;
580 break;
581 case CPiece::RPao:
582 qz = m_RedPao;
583 break;
584 case CPiece::RBing:
585 qz = m_RedBing;
586 break;
587 case CPiece::BShuai:
588 qz = m_BlackShuai;
589 break;
590 case CPiece::BShi:
591 qz = m_BlackShi;
592 break;
593 case CPiece::BXiang:
594 qz = m_BlackXiang;
595 break;
596 case CPiece::BMa:
597 qz = m_BlackMa;
598 break;
599 case CPiece::BChe:
600 qz = m_BlackChe;
601 break;
602 case CPiece::BPao:
603 qz = m_BlackPao;
604 break;
605 case CPiece::BBing:
606 qz = m_BlackBing;
607 break;
608 }
609
610#pragma warning( default : 4806 )
611
612 if (!qz.isNull())
613 return DrawPicture(pPainter, i, j, qz);
614
615 return -1;
616}
617
627int CFrmChineseChess::DrawPicture(QPainter *pPainter, int i, int j, QImage image, bool CHHJKL)
628{
629 long m_X, m_Y;
630
631 ConvertCoordinate(&m_X, &m_Y, &i, &j, IJToXY);
632 if (CHHJKL) //画楚河汉界
633 {
634 m_X -= m_QiPangDistance / 2;
635 }
636 else
637 {
638 m_X -= m_QiPangDistance / 2;
639 m_Y -= m_QiPangDistance / 2;
640 }
641
642 QRect r(m_X, m_Y, m_QiPangDistance, m_QiPangDistance);
643 return DrawImage(pPainter, r, image);
644}
645
653int CFrmChineseChess::DrawImage(QPainter *pPainter, QRect rect, QImage image)
654{
655 pPainter->drawImage(rect, image);
656
658 //QImage bmp = image.scaled(rect.size(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
659 //pPainter->drawImage(rect, bmp, bmp.rect());
660
661 //QPixmap p = QPixmap::fromImage(image);
662 //p = p.scaled(r.size(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
663 //pPainter->drawPixmap(r, p, p.rect());
664 return 0;
665}
666
673int CFrmChineseChess::SetTransparentImage(QImage &image, const QColor &col)
674{
675 //设置位图透明
676 QImage mask = image.createMaskFromColor(col.rgb(), Qt::MaskOutColor);
677 image.setAlphaChannel(mask);
678 return 0;
679}
680
687int CFrmChineseChess::SetTransparentPixmap(QPixmap &pixmap, const QColor &col)
688{
689 QBitmap bmp = pixmap.createMaskFromColor(col, Qt::MaskOutColor);
690 pixmap.setMask(bmp);
691 return 0;
692}
中国象棋类
CPiece::ENUM_QiZi m_ChessBoard[9][10]
棋盘描述
bool GoChess(int i, int j, bool bNext=false)
走棋
中国象棋窗体,完成中国象棋的界面
QImage m_BlackXiang
黑相
QImage m_BlackShuai
黑帅
QImage m_BlackBing
黑兵
QImage m_KL
版本图片
QImage m_RedShuai
红帅
int m_QiPangStartX
棋盘的开始横坐标
int SetTransparentImage(QImage &image, const QColor &col=QColor(255, 255, 255))
设置 QImage 透明
virtual int onDrawPrompt(int i, int j) override
画提示框
ENUM_XINWEI
棋盘星位
virtual int onGoChess(int i, int j, CPiece::ENUM_QiZi chess) override
走棋事件
QImage m_RedMa
红马
QColor m_TiShiBoxColor
提示框的颜色
bool ConvertCoordinate(long *x, long *y, int *i, int *j, ENUM_ConvertCoordinate eCC=XYToIJ)
坐标转换
virtual int onPromptMessage(CGoRule::ENUM_ReturnValue val) override
提示错误消息
QImage m_BlackPao
黑炮
int SetTransparentPixmap(QPixmap &pixmap, const QColor &col=QColor(255, 255, 255))
设置 Pixmap 透明
QImage m_BlackChe
黑车
int DrawQiZi(QPainter *pPainter, int i, int j, CPiece::ENUM_QiZi eQiZi)
画棋子
bool DrawTiShiBox(QPainter *pPainter, int i, int j)
画提示框
QImage m_BlackMa
黑马
QImage m_RedShi
红仕
QImage m_RedXiang
红相
void DrawQiPang(QPainter *pPainter, QRect rect)
画棋盘
QImage m_RedChe
红车
int DrawPicture(QPainter *pPainter, int i, int j, QImage image, bool CHHJKL=false)
画图片
QImage m_RedPao
红炮
static int CleanResource()
清理资源,仅在程序结束时调用一次
QImage m_RedBing
红兵
QColor m_QiPangColor
棋盘格的颜色
bool SetQiPang(int width, int height)
设置棋盘位置
virtual int onCleanPrompt(int i, int j) override
清除提示框
QImage m_BlackShi
黑仕
int m_QiPangDistance
棋盘格的距离
ENUM_ConvertCoordinate
坐标转换
QDateTime GetStartTime()
得到开始时间
QImage m_QiPangPicture
棋盘背景图片
void DrawXinWei(QPainter *pPainter, int i, int j, ENUM_XINWEI xinwei=XinWei)
画星位
int DrawImage(QPainter *pPainter, QRect rect, QImage image)
在指定位置绘图
int m_QiPangStartY
棋盘的开始横坐标
static int InitResource(const QString szLanguage)
初始化资源,仅在程序开始时调用一次
@ BEIJIANGJUN
错误,不能走
Definition GoRule.h:31
@ JIANGDUIMIAN
被将军
Definition GoRule.h:32
enum CPiece::_ENUM_QiZi ENUM_QiZi
棋子枚举值 四个位表示棋子,最左1位表示颜色