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