首页 > 其他分享 >黑白棋盘工具

黑白棋盘工具

时间:2022-12-12 19:22:56浏览次数:61  
标签:sel return pt SelectObject pic 黑白 pos 工具 棋盘

 

按C键复制图片到剪贴板。按Z键悔棋。默认是左图圆棋子。很容易改成方形棋子。

https://files.cnblogs.com/files/blogs/714801/BrdTool.zip 19KB 含源码和.exe

有效的代码130行左右:

enum { W = 354, H = 392, S = 39 }; // 棋盘与棋子大小

struct CBmpInDC : public CDC { // 本想继承CDC和CBitmap,但CDC和CBitmap没有virtual public CGdiObject
  CBitmap m_bmp; HGDIOBJ m_oldbmp;
  CBmpInDC() : m_oldbmp(0) {}
  ~CBmpInDC() { if (m_hDC && m_oldbmp) SelectObject(m_oldbmp); }
  void Create() { CreateCompatibleDC(ScreenDC()); }
  void CreateBmp(int w, int h) { m_bmp.CreateCompatibleBitmap(ScreenDC(), w, h); m_oldbmp = SelectObject(m_bmp); }
  void AttachBmp(PVOID hbmp) { m_bmp.Attach(hbmp); m_oldbmp = SelectObject(m_bmp); }
  PVOID DetachBmp() { return m_bmp.Detach(); } // 之后别忘了CreateBmp或AttachBmp
  static CDC* ScreenDC() { return CDC::FromHandle(GetDC(0)); }
};

CBmpInDC  bkgnd, pic;
CFont fnt;
char  pos_stack[256][10][9]; // position(局面)们
int   nPos;
#define pos pos_stack[nPos]
CPoint  sel(-1, 0); // 选中棋子的位置

int fen_atoi(int c) {
  switch (toupper(c)) {
  case 'K': return 0; case 'A': return 1; case 'B': return 2; case 'N': return 3;
  case 'R': return 4; case 'C': return 5; case 'P': return 6; default: abort();
  }
}

BOOL CBrdToolDlg::OnInitDialog()
{
  CDialog::OnInitDialog();
  m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
  SetIcon(m_hIcon, TRUE); SetIcon(m_hIcon, FALSE);
  CBitmap bmp; bmp.LoadBitmap(IDB_BRD);
  bkgnd.Create(); bkgnd.AttachBmp(bmp.Detach());
  pic.Create(); pic.CreateBmp(W, H);
  fnt.CreatePointFont(168, "黑体");
  const char* s = "rnbakabnr/9/1c5c1/p1p1p1p1p/9/9/P1P1P1P1P/1C5C1/9/RNBAKABNR";
  for (int y = 0, x = 0; *s && *s != ' '; ++s) {
    const char c = *s;
    if (c == '/') (x = 0, ++y);
    else if (c >= '1' && c <= '9') x += c - '0';
    else pos[y][x++] = char((c >= 'a' ? 8 : 1) + fen_atoi(c));
  }
  return TRUE;  // return TRUE unless you set the focus to a control
}

void CBrdToolDlg::SetCaption() { char s[80]; sprintf(s, "黑白棋盘 c=复制图片 z=悔棋 %d", nPos); SetWindowText(s); }

void CBrdToolDlg::OnLButtonDown(UINT nFlags, CPoint pt) 
{
  pt.x /= S; if (pt.x < 0 || pt.x >= 9) pt.x = -1;
  pt.y /= S; if (pt.y < 0 || pt.y >= 10) pt.y = pt.x = -1; 
  if (sel.x < 0)
  {
    if (pos[pt.y][pt.x]) sel = pt; // 第一次选择棋子,空白处不能选
  }
  else
  {
    if (pt.x < 0) sel = pt; // 点空步处取消选择
    else if (sel != pt) // 不能吃自己
    {
      memcpy(pos_stack[nPos + 1], pos_stack[nPos], sizeof(pos_stack[0])); ++nPos;
      pos[pt.y][pt.x] = pos[sel.y][sel.x]; pos[sel.y][sel.x] = 0;
      SetCaption();
    }
    sel = CPoint(-1, 0); // 回到没有棋子被选中
  }
  InvalidateRect(NULL, FALSE); UpdateWindow();
}

void CBrdToolDlg::OnPaint() 
{
  BitBlt(pic, 0, 0, W, H, bkgnd, 0, 0, SRCCOPY);
  CPen  pen(PS_INSIDEFRAME, 1, RGB(192, 192, 192));
  PVOID oldbrush = 0, oldpen = pic.SelectObject(pen), oldfnt = pic.SelectObject(fnt);
  pic.SetBkMode(TRANSPARENT);
  for (int y = 0; y < 10; y++) for (int x = 0; x < 9; x++)
  {
    int zi = pos[y][x];
    if (!zi) continue;
    if (zi < 8) { // 红棋
      oldbrush = pic.SelectObject(GetStockObject(WHITE_BRUSH));
      pic.SetTextColor(RGB(0, 0, 0));
    }
    else {
      oldbrush = pic.SelectObject(GetStockObject(BLACK_BRUSH));
      pic.SetTextColor(RGB(255, 255, 255));
    }
    if (x == sel.x && y == sel.y) pic.SetTextColor(RGB(0, 168, 0));
    static const char* Z = "\0\0\0帅\0仕\0相\0马\0车\0炮\0兵\0將\0士\0象\0馬\0車\0砲\0卒";
    CRect rc(CPoint(1 + x * S, 1 + y * S), CSize(S, S)); rc.InflateRect(-3, -3);
    pic.Ellipse(rc); // pic.Rectangle(rc);
    pic.DrawText(&Z[zi * 3], rc, DT_SINGLELINE | DT_VCENTER | DT_CENTER);
  }
  pic.SelectObject(oldbrush); pic.SelectObject(oldfnt); pic.SelectObject(oldpen);
  CPaintDC  dc(this);
  BitBlt(dc, 0, 0, W, H, pic, 0, 0, SRCCOPY);
}

BOOL CBrdToolDlg::PreTranslateMessage(MSG* pMsg) 
{
  if (pMsg->message == WM_CHAR && pMsg->wParam == 'c')
  {
    OpenClipboard(); EmptyClipboard();
    SetClipboardData(CF_BITMAP, pic.DetachBmp()); CloseClipboard();
    pic.CreateBmp(W, H);
  }
  else if (pMsg->message == WM_CHAR && pMsg->wParam == 'z' && nPos)
  {
    --nPos; InvalidateRect(NULL, FALSE); UpdateWindow(); SetCaption();
  }
  return CDialog::PreTranslateMessage(pMsg);
}

BOOL CBrdToolDlg::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
{ 
  static HCURSOR hand = LoadCursor(NULL, MAKEINTRESOURCE(32649)); // IDC_HAND
  SetCursor(hand);
  return TRUE;
}

 

标签:sel,return,pt,SelectObject,pic,黑白,pos,工具,棋盘
From: https://www.cnblogs.com/funwithwords/p/16976902.html

相关文章

  • zstd压缩工具
    zstd压缩工具https://github.com/facebook/zstd压缩文件:zstdxxx.file压缩文件夹:tar-cvfxxx.tarxxx/;zstdxxx.tar;解压:zstd-dxxx.zst......
  • Vue3.0文档学习心得--响应式工具
    1.isRef:检查某个值是否为ref。返回值是true或者falseletfoo:unknown//返回值是一个类型判定 (typepredicate),这意味着 isRef 可以被用作类型守卫。if(isRe......
  • 【辅助工具】Maven使用
    Maven使用导包错误找到对应的路径,丛正常导入的同事直接复制过来。Maven启动项目......
  • 更严格的代码格式化工具 gofumpt
    gofmt是golang自带的代码自动格式化工具,是保证Go代码风格一致的大杀器。我们这次要推荐的gofumpt在gofmt的基础上添加了一系列更加严格的格式化规则,并保证了对go......
  • 空间音频技术与生态发展高峰论坛成功举办,业界首个Audio Vivid创作工具花瓣三维声亮相
    11月26日至27日,UWA世界超高清视频产业联盟(以下简称“UWA联盟”)、上海交通大学-南加州大学文化创意产业学院、华为联合举办了“互联智慧,共赢未来”超高清音视频技术与生态发......
  • 数据分析必备工具书:Python官方中文文档
    本文推荐数据分析的必备工具书:Python官方文档,注意,这是一份中文文档!(作者孙强)一、前言今天推荐一下Python官方文档,注意,这是一份中文文档!主题:可以说非常详细了,Python3.7全新变......
  • postgresql/lightdb主要的extension及客户端工具清单(持续更新)
    如果说mysql因为其多引擎架构被人称赞,那么在postgresql中,extension开放性则完全可以说是完胜,而且其生态相比mysql而言,明显不在一个级别。本文维护了postgresql重要的三......
  • (翻译)60分钟入门深度学习工具-PyTorch
    60分钟入门深度学习工具-PyTorch作者:SoumithChintala原文翻译自:​​https://pytorch.org/tutorials/beginner/deep_learning_60min_blitz.html​​中文翻译、注释制作:黄海......
  • TheFuck—Python写的超实用命令纠正工具
    哈喽兄弟们,我们在学习Python的过程中,有这么一款工具,可以轻松纠正我们写错的命令,简直太好用了~TheFuck是一款功能强大的、Python编写的应用程序,可用于纠正控制台命令......
  • [MDX Editor] 微信排版工具新选择
    一个好用的排版编辑器前言哈喽,大家好,我是小马,去年年底,我开通了微信公众号“JS酷”,也开始陆陆续续开始写文章,发到微信公众号,作为一名程序员,我酷爱Markdown,相信很多朋友跟......