棋盘棋谱+识别脚本等图片打包下载:

 

识别象棋盘.ahk

#NoEnv
SetBatchLines -1
#SingleInstance, force
SetWorkingDir %A_ScriptDir% ; Ensures a consistent starting directory.
#Include 
#Include 

Gui, -DPIScale

ini := A_ScriptDir "\config.ini"
IniRead, winTitle, %ini% , config, winTitle ,
IniRead, winID, %ini% , config, winID ,
IniRead, QPxywh, %ini% , config, QPxywh , 未框选...

global TargetWindow ,QP  ,QP_L , QP_R , viewQP , QPDate

QP_L:=9 , QP_R:=10 ;棋盘的列 行数

WinGetPos, winX, winy, winW, winH,% winTitle
TargetWindow:={title:winTitle , ID:winID , winX:winx , winY:winY , winW: winW ,winH:winH , QParea:QPxywh} ; 目标窗口信息

Gui,font,s10 ,微软雅黑
Gui,add,button,xm ym g指定窗口 vBT_getTargetWin,选择目标窗口
winTitleInfo:=(winID="" or winID="error") ? "未选择..." : winTitle " - " winID
Gui,add,edit ,x+5 w300 vT_TargetWindow Disabled,% winTitleInfo
Gui,add,button ,xm y+10 g框选棋盘范围,框选棋盘范围
Gui,add,edit ,x+5 w300 vT_QPsize Disabled,% QPxywh
; gui,add,button,xm y+20 g绘制棋盘窗口 ,绘制棋盘窗口
Gui,add,button,xm y+10 g识别棋盘 ,识别棋盘
Gui,add,text,x+5 y+-22 vT_tip w200 r1,

;---预览棋盘的 大小设定
getD:=getKJxywh(1,"T_QPsize")
preViewQP_w:=getD.x + getD.w
preViewQP_h:=(preViewQP_w /9) * 10
aGird:= preViewQP_w / QP_L ; 棋盘内框到外框的范围,预留空间给棋子, 棋盘的格子应该比整个pic显示区域要小一些,不然棋子超出范围的部分就看不到
girdW := (preViewQP_w - aGird) / (QP_L -1) ;格子的宽度
viewQP:={outWidth: preViewQP_w , outHeight: preViewQP_h , inWidth: preViewQP_w - aGird , inHeight: preViewQP_H - aGird , girdWidth: girdW , girdHeight: girdW , margin: aGird/2 } ; 棋盘大小信息

gui Add, Progress, xm y+5 h6 w%preViewQP_w% cGreen vPG_tipCHeck ,0 ; 识别进度条
Gui Add, Picture, xm y+5 w%preViewQP_w% h%preViewQP_h% 0xE vGidpPic ; 必须有个图片控件,因为gdip引用该图片的指针来修改内容
getGidpPic:=getKJxywh(1,"GidpPic")

Gui +Resize
Gui show

gui,+LastFound
hwnd1 := WinExist()

GoSub, Gdip绘制棋盘

return



getFind(Text){  
  ; 全屏范围 , 范围越小速度越快
  ; get:=FindText(X, Y, 667-150000, 806-150000, 667+150000, 806+150000, 00, 0, Text)  
  
  ; 目标窗口的范围
  ; x1:=TargetWindow.winX , y1:=TargetWindow.winY , x2:=x1 + TargetWindow.winW  , y2:=y1 + TargetWindow.winH

  ; 目标窗口的棋盘范围 + 一个格子的范围
  x1:=TargetWindow.winX + QP.x - QP.GirdWidth
  y1:=TargetWindow.winY + QP.y - QP.GirdWidth
  x2:=TargetWindow.winX + QP.x + QP.Width + QP.GirdWidth
  y2:=TargetWindow.winY + QP.y + QP.height + QP.GirdWidth

  X:=Y:=""
  get:=FindText(X, Y, x1, y1, x2, y2, 0, 0, Text)
  return get
}

指定窗口:
  while ! GetKeyState("lbutton","P")
  {
    MouseGetPos, cx, cy, winID, kj
    WinGetTitle, winTitle, ahk_id %winID%
    ToolTip ,% "xy:" cx "," cy "`n标题:" winTitle "`nID:" winID "`n点击鼠标左键确定坐标"
  }
  ToolTip
  GuiControl,, T_TargetWindow , % winTitle " - " winID ""
  TargetWindow["Title"]:=winTitle
  TargetWindow["ID"]:=winID

  IniWrite, %winTitle%, %ini% , config, winTitle
  IniWrite, %winID%, %ini% , config, winID
  
  棋盘左上边缘 := "|<>0xD8C4A5@0.92$11.000000zlzXz7yDwTszs"
  棋盘右下边缘 := "|<>0x513F22@0.96$15.010080100801008010080100801008zz00000000U"

  FindText().BindWindow(winID,1)  ; 后台绑定模式目前有0-4
  
  WinGetPos, pX, pY, pW, pH, ahk_id %winID%
  if ( FindText(棋盘X, 棋盘Y, pX, pY, pX+pW, pY+pH, 0, 0, 棋盘左上边缘, ,0) and FindText(棋盘X2, 棋盘Y2, pX, pY, pX+pW, pY+pH, 0, 0, 棋盘右下边缘, ,0) ) {
    棋盘X:=棋盘X -pX , 棋盘Y:=棋盘Y-pY
    QPxywh:= 棋盘X+36 "," 棋盘Y+39 "," 棋盘X2-棋盘X-145 "," 棋盘Y2-棋盘Y-242
    ToolTip % 棋盘X2-棋盘X """" 棋盘Y2-棋盘Y
    ; Gosub 自动识别棋盘边缘
  }
Return

框选棋盘范围:
  CoordMode, Mouse
  CoordMode, ToolTip
  SysGet, allWin_w, 78
  SysGet, allWin_h, 79

  Gui,9: Destroy
  Gui,9: +LastFound +AlwaysOnTop
  Gui,9: Color, black
  WinSet, Transparent, 50
  Gui,9: -Caption +ToolWindow +E0x08000000
  Gui,9: Show, NA x0 y0 w%allWin_w% h%allWin_h% ;gui9为了避免框选时候响应文件夹或者桌面(用冻结显示后,次窗口的作用仅作为做个白底提示当前正在截图)

  ;-----------------------------
  Gui,8: Destroy
  Gui,8: +LastFound +AlwaysOnTop
  WinSet, Transparent, 100
  Gui,8: -Caption +ToolWindow +E0x08000000
  Gui,8: Color, red
  ; ------

  WinGetPos, winX, winy, winW, winH,% TargetWindow.Title

  down=0
  Loop {
    Sleep, 50
    MouseGetPos, x, y
    if (down=0)
    {
      ToolTip, %x%,%y%`n按住鼠标左键选择范围!`n取消请按【esc】键
      mx1:=x , my1:=y
      if GetKeyState("LButton","P")
        down:=1, x1:=x, y1:=y
      if GetKeyState("esc","P")
        Break
    }
    else
    {
      mx2:=x , my2:=y
      w:=Abs(x-x1), h:=Abs(y-y1)
      x:=x1 1000 ? 
  GuiControl, , T_tip , % "用时:" timeLen / 1000 " 秒"
  GuiControl,, PG_tipCHeck, 0 ; 识别进度条

  Gosub, Gdip绘制棋盘
Return


/* 使用GUI progress 绘制棋盘(弃用)
  绘制棋盘窗口:

    gui,Submit,NoHide

    WinGetPos, winX, winy, winW, winH,% TargetWindow.title
    TargetWindow["winX"]:=winx
    TargetWindow["winY"]:=winY
    TargetWindow["winW"]:=winW
    TargetWindow["winH"]:=winH

    arr:=StrSplit(T_QPsize, ",")
    QP:={x:arr[1] , y: arr[2] , width: arr[3] , height: arr[4] }
    Gird:={width: QP.width / (QP_L-1) , height: QP.height / (QP_R-1)} ; 单个格子长宽

    gui,2: Destroy
    gui,2:font,s10 ,微软雅黑

    loop % QP_R
      gui,2:add,Progress, % "x" QP.x " y" (a_index-1) * Gird.height + QP.y " h3 w" QP.width " c888888", 100

    loop % QP_L
    {
      lineH:=(a_index>1 and a_index< QP_L) ? Gird.height * 4 : QP.height
      gui,2:add,Progress, % "y" QP.y " x" (a_index-1) * Gird.width + QP.x " w3 h" lineH " c888888", 100

      if(a_index>1 and a_index< QP_L)
        gui,2:add,Progress, % "y" Gird.height * 5 + QP.y " x" (a_index-1) * Gird.width + QP.x " w3 h" lineH " c888888", 100
    }

    gui,2: +Resize
    gui,2:show,% "w" TargetWindow.winW " h" TargetWindow.winH
  Return
*/

getKJxywh(win,kjName){
  ; win gui窗口编号,例如 gui:11
  ; kjName 控件的变量名
  gui,Submit,NoHide
  GuiControlGet,%kjName%,%win%:pos
  x:=%kjName%x , y:=%kjName%y , w:=%kjName%w , h:=%kjName%h
  ; arr:=[x,y,w,h]
  Return {x:x,y:y,w:w,h:h}
}

Gdip绘制棋盘:

  ;-----------------------------画图表
  Gdip_Startup()
  GuiControlGet, hwnd, hwnd, GidpPic
  ; 绘图范围 , 从图片控件绘制图片 , 绘制边缘的平滑度
  pBitmap := Gdip_CreateBitmap(preViewQP_w, preViewQP_h)
  G := Gdip_GraphicsFromImage(pBitmap)
  Gdip_SetSmoothingMode(G, 4)

  ; --画外框线
  cMargin:=viewQP.margin*0.8
  pPen := Gdip_CreatePen( "0xFF000000" , 2 )
  ; 棋盘四个角的点位,1:左上角 2:右上角 3:右下角 4:左下角
  Point:=[]
  point[1]:={x:0+cMargin , y:0+cMargin}
  point[2]:={x:viewQP.outWidth-cMargin , y:0+cMargin}
  point[3]:={x:viewQP.outWidth-cMargin , y:viewQP.outHeight-cMargin}
  point[4]:={x:0+cMargin , y:viewQP.outHeight-cMargin}
  
  pBrush := Gdip_BrushCreateSolid("0xffffe8c7" )
  Gdip_FillRectangle(G, pBrush, point[1].x, point[1].y, point[2].x-point[1].x, point[4].y - point[1].y) ;棋盘背景色
  
  Gdip_DrawLine(G, pPen, point[1].x, point[1].y, point[2].x, point[2].y)
  Gdip_DrawLine(G, pPen, point[1].x, point[1].y, point[4].x, point[4].y)
  Gdip_DrawLine(G, pPen, point[3].x, point[3].y, point[2].x, point[2].y)
  Gdip_DrawLine(G, pPen, point[3].x, point[3].y, point[4].x, point[4].y)



  ; --画内格子线
  pPen := Gdip_CreatePen( "0xFF31240f" , 1 )
  loop % QP_R
  {
    getA:=girdToViewQPpos( "1_" A_Index )
    getB:=girdToViewQPpos( "9_" A_Index )
    Gdip_DrawLine(G, pPen, getA.x, getA.y, getB.x, getB.y)
  }

  loop % QP_L
  {
    if(a_index>1 and a_index< QP_L)
    {
      getA:=girdToViewQPpos(A_Index "_1")
      getB:=girdToViewQPpos(A_Index "_5")
      Gdip_DrawLine(G, pPen, getA.x, getA.y, getB.x, getB.y)

      getA:=girdToViewQPpos(A_Index "_6")
      getB:=girdToViewQPpos(A_Index "_10")
      Gdip_DrawLine(G, pPen, getA.x, getA.y, getB.x, getB.y)
    }
    Else
    {
      getA:=girdToViewQPpos(A_Index "_1")
      getB:=girdToViewQPpos(A_Index "_10")
      Gdip_DrawLine(G, pPen, getA.x, getA.y, getB.x, getB.y)
    }
  }

  ; --画米字
  getA:=girdToViewQPpos("4_1") , getB:=girdToViewQPpos("6_3")
  Gdip_DrawLine(G, pPen, getA.x, getA.y, getB.x, getB.y)

  getA:=girdToViewQPpos("4_3") , getB:=girdToViewQPpos("6_1")
  Gdip_DrawLine(G, pPen, getA.x, getA.y, getB.x, getB.y)

  getA:=girdToViewQPpos("4_8") , getB:=girdToViewQPpos("6_10")
  Gdip_DrawLine(G, pPen, getA.x, getA.y, getB.x, getB.y)

  getA:=girdToViewQPpos("4_10") , getB:=girdToViewQPpos("6_8")
  Gdip_DrawLine(G, pPen, getA.x, getA.y, getB.x, getB.y)
  


  ; --画炮、兵点位线
  pPen := Gdip_CreatePen( "0xFF000000" , 2 )
  curArr:=[ "2_3","8_3","2_8","8_8" , "1_4","3_4","5_4","7_4","9_4","1_7","3_7","5_7","9_7" ]
  loop % curArr.Length()
  {
    get := girdToViewQPpos(curArr[A_Index])
    margin:=3 , len:=viewQP.girdWidth * 0.18
    cc:=[[-1,-1] ,[1,-1] ,[-1,1] , [1,1] ] ;[ 上左,上右,下左,下右]
    cLie:= SubStr(curArr[A_Index], 1 , 1)
    loop 4 {

      if( (cLie = 1 && a_index=1) or (cLie = 1 && a_index=3) or (cLie = QP_L && a_index=2) or (cLie = QP_L && a_index=4) )
        Continue

      x1:=get.x + cc[A_Index][1] * margin
      y1:=get.y + cc[A_Index][2] * margin
      index:=a_index
      loop % 2{
        x2:=(a_index=1) ? x1 : x1 + cc[index][1] * len ;先画竖线
        y2:=(a_index=1) ? y1 + cc[index][2] * len : y1
        Gdip_DrawLine(G, pPen, x1, y1, x2, y2)
      }
    }

  }

  ; --画棋子
  Qz_width:= girdW * 0.8

  ; --棋子配色
  QZ_color:=[]
  QZ_color["红方"]:={fontColor: "ac2000" , BackgroundColor: "efae7f" , BackgroundColor2: "642b09" }
  QZ_color["黑方"]:={fontColor: "1a1a1a" , BackgroundColor: "ffc974" , BackgroundColor2: "703f00" }

  for LR , i in QPdate
  {
    cQz:=QPdate[LR]

    if(cQz.qzName="")
      Continue

    get:=girdToViewQPpos(LR)
    cx:=get.x - Qz_width/2 , cy:=get.y - Qz_width/2

    ; pBrush := Gdip_BrushCreateHatch("0xffdb6c64" , "0xffFFFFFF", a_index) ; backColor , forcCOlor, bursh样式  ;

    pBrush := Gdip_BrushCreateSolid("0xff" QZ_color[cQz.qzGroup].BackgroundColor2)
    Gdip_FillEllipse(G, pBrush, cx, cy, Qz_width + 4, Qz_width + 4) ;棋子底层

    pBrush := Gdip_BrushCreateSolid("0xff" QZ_color[cQz.qzGroup].BackgroundColor)
    Gdip_FillEllipse(G, pBrush, cx, cy, Qz_width, Qz_width) ;棋子表层

    Gdip_TextToGraphics(G, cQz.qzName ,"x" cx+2 "y" cy+5 "c" "FF" QZ_color[cQz.qzGroup].fontColor " s26 Center Bold ", "微软雅黑", Qz_width, Qz_width) ;文字
  }

  hBitmap := Gdip_CreateHBITMAPFromBitmap(pBitmap)
  SetImage(hwnd, hBitmap)	;应用图片内容
  Gdip_DeleteBrush(pBrush) , Gdip_DeletePen(pPen) ;删除不再需要的画笔释放内存
  Gdip_DeleteGraphics(G), Gdip_DisposeImage(pBitmap), DeleteObject(hBitmap)
  Gdip_Shutdown(pToken)

Return

girdToViewQPpos(str:="1_1"){

  arr:=StrSplit(str, "_" )
  cx:= viewQP.girdWidth * (arr[1]-1) + viewQP.margin
  cy:= viewQP.girdheight * (arr[2]-1) + viewQP.margin
  ; MsgBox, % viewQP.girdWidth "`n" viewQP.girdheight "`n " viewQP.margin
  return {x:cx , y:cy}
}

GuiClose:
  ExitApp

 

声明:站内资源为整理优化好的代码上传分享与学习研究,如果是开源代码基本都会标明出处,方便大家扩展学习路径。请不要恶意搬运,破坏站长辛苦整理维护的劳动成果。本站为爱好者分享站点,所有内容不作为商业行为。如若本站上传内容侵犯了原著者的合法权益,请联系我们进行删除下架。