欢迎光临散文网 会员登陆 & 注册

【按键精灵】中国象棋脚本详解

2021-12-29 19:51 作者:酷玩蚊仔  | 我要投稿

Dim LTX, LTY, mapLTX, mapLTY, mapRBX, mapRBY// 窗口左上角坐标;棋盘左上角、右下角坐标

Dim xPosArr, yPosArr// 各交点横纵坐标数组

Dim myColor, oppositeColor// 我方颜色、对方颜色,w:红,b:黑

Dim map// 二维数组(已根据红黑方排序)

Dim mapX, mapY// 数字对应的行,字母对应的列

Dim round// 走棋方,w:红,b:黑

Dim fen // FEN局面代码


Call 地图初始化


Sub 地图初始化

Hwnd = Plugin.Window.Find(0, "QQ新中国象棋")

sRect = Plugin.Window.GetClientRect(Hwnd)

LTX = split(sRect, "|")(0) // 默认448

LTY = split(sRect, "|")(1)// 默认165

mapLTX = LTX + 219

mapLTY = LTY + 35

mapRBX = LTX + 774

mapRBY = LTY + 652

L9 = Array("r", "n", "b", "a", "k", "a", "b", "n", "r")

L8 = Array("", "", "", "", "", "", "", "", "")

L7 = Array("", "c", "", "", "", "", "", "c", "")

L6 = Array("p", "", "p", "", "p", "", "p", "", "p")

L5 = Array("", "", "", "", "", "", "", "", "")

L4 = Array("", "", "", "", "", "", "", "", "")

L3 = Array("P", "", "P", "", "P", "", "P", "", "P")

L2 = Array("", "C", "", "", "", "", "", "C", "")

L1 = Array("", "", "", "", "", "", "", "", "")

L0 = Array("R", "N", "B", "A", "K", "A", "B", "N", "R")

xPosArr = Array(LTX + 269, LTX + 326, LTX + 383, LTX + 440, LTX + 497, LTX + 554, LTX + 611, LTX + 668, LTX + 725)

yPosArr = Array(LTY + 87, LTY + 144, LTY + 201, LTY + 258, LTY + 315, LTY + 372, LTY + 429, LTY + 486, LTY + 543, LTY + 600)

Call 判断先手

End Sub


Sub 判断先手

IfColor LTX + 501, LTY + 595, "0020AC", 0 Then

// 我方先手

myColor = "w"

oppositeColor = "b"

map = Array(L9, L8, L7, L6, L5, L4, L3, L2, L1, L0)

mapX = Array("a", "b", "c", "d", "e", "f", "g", "h", "i")

mapY = Array("9", "8", "7", "6", "5", "4", "3", "2", "1", "0")

Else

// 对方先手

myColor = "b"

oppositeColor = "w"

map = Array(L0, L1, L2, L3, L4, L5, L6, L7, L8, L9)

mapX = Array("i", "h", "g", "f", "e", "d", "c", "b", "a")

mapY = Array("0", "1", "2", "3", "4", "5", "6", "7", "8", "9")

End If

round = "w"

Call 生成FEN局面代码

End Sub


Sub 生成FEN局面代码

fen = ""

For i = 0 To 9

blankCount = 0 // 此行空白位置计数

For j = 0 To 8

If map(i)(j) = "" Then 

blankCount = blankCount + 1// 此位置无棋,计数+1

ElseIf blankCount > 0 Then// 此位置有有棋,前面无棋,插入数字后拼接棋码,并重新计数

fen = fen & blankCount & map(i)(j)

blankCount = 0

ElseIf blankCount = 0 Then // 此位置有有棋,前面也有棋,直接拼接棋码

fen = fen & map(i)(j)

End If

Next

If blankCount > 0 Then // 换行前拼接数字

fen = fen & blankCount

End If

If i < 9 Then 

fen = fen & "/" // 普通换行拼接斜杠

End If

Next

If myColor = "b" Then 

fen = StrReverse(fen)

End If

fen = fen & " " & round

TracePrint fen

If round = myColor Then 

Call 我方走棋

Else 

Call 等待对方走棋

End If

End Sub


Sub 我方走棋

Dim move // 走棋代码

Dim rowIndex_1, colIndex_1, rowIndex_2, colIndex_2 // 走棋点1、走棋点2在地图中的行列下标

Set querybest = CreateObject("Msxml2.ServerXMLHTTP.3.0")

querybest.Open "Get", "http://www.chessdb.cn/chessdb.php?action=querybest&board=" & fen, False

querybest.Send

If querybest.readyState=4 Then

   TracePrint querybest.responsetext

   If InStr(querybest.responsetext, "invalid board") > 0 Then // 非法局面代码

   EndScript

   ElseIf InStr(querybest.responsetext, "nobestmove") > 0 Then // 没有最佳着法,查询思考细节

   Set querypv = CreateObject("Msxml2.ServerXMLHTTP.3.0")

   querypv.Open "Get", "http://www.chessdb.cn/chessdb.php?action=querypv&board=" & fen, False

   querypv.Send 

   If querypv.readyState = 4 Then 

   TracePrint querypv.responsetext

   If InStr(querypv.responsetext, "unknown") > 0 Then 

   EndScript

   End If

   move = Right(split(querypv.responsetext, "|")(0), 4) // 不一定有|,但不影响运算结果

   End If

   querypv.abort

Set querypv = Nothing

   Else // 正常返回

   move = Right(querybest.responsetext, 5)

   End If

   // 遍历行

For i = 0 To 9

   If mapY(i) = Mid(move, 2, 1) Then 

   rowIndex_1 = i // 起始行下标

   moveY_1 = yPosArr(i) // 起始行纵坐标

   End If

   If mapY(i) = Mid(move, 4, 1) Then 

   rowIndex_2 = i // 目标行下标

   moveY_2 = yPosArr(i) // 目标行纵坐标

   End If

   Next

   // 遍历列

   For i = 0 To 8

   If mapX(i) = Mid(move, 1, 1) Then 

   colIndex_1 = i // 起始列下标

   moveX_1 = xPosArr(i) // 起始列横坐标

   End If

   If mapX(i) = Mid(move, 3, 1) Then 

   colIndex_2 = i // 目标列下标

   moveX_2 = xPosArr(i) // 目标列横坐标

   End If

   Next

End If

querybest.abort

Set querybest = Nothing

MoveTo moveX_1, moveY_1

Delay 100

LeftClick 1

MoveTo moveX_2, moveY_2

Delay 100

LeftClick 1

Call 刷新二维数组(rowIndex_1, colIndex_1, rowIndex_2, colIndex_2)

End Sub


Sub 等待对方走棋

Delay 2000

While True

IfColor LTX + 183, LTY + 471, "5A7A7A", 1 Then

Call 计算对方走棋点

End If

Wend

End Sub


Sub 计算对方走棋点

FindColor mapLTX, mapLTY, mapRBX, mapRBY, "0000FF", intX_1, intY_1

If intX_1 > 0 And intY_1 > 0 Then 

Dim rowIndex_1, colIndex_1, rowIndex_2, colIndex_2// 走棋点1、走棋点2在地图中的行列下标

// 确定走棋点1在地图中的行列下标

For i = 0 To 9

If yPosArr(i) > intY_1 Then 

rowIndex_1 = i

Exit For

End If

Next

For i = 0 To 8

If xPosArr(i) > intX_1 Then 

colIndex_1 = i

Exit For

End If

Next

// 确定走棋点2在地图中的行列下标

FindColor intX_1 + 52, intY_1, mapRBX, intY_1, "0000FF", intX_2, intY_2

If intX_2 > 0 And intY_2 > 0 Then // 在正右方找到走棋点2

rowIndex_2 = rowIndex_1

For i = colIndex_1 + 1 To 8

If xPosArr(i) > intX_2 Then 

colIndex_2 = i

Exit For

End If

Next

Else // 正右方没有,在下方找走棋点2

FindColor mapLTX, intY_1 + 52, mapRBX, mapRBY, "0000FF", intX_2, intY_2

If intX_2 > 0 And intY_2 > 0 Then

For i = rowIndex_1 + 1 To 9

If yPosArr(i) > intY_2 Then 

rowIndex_2 = i

Exit For

End If

Next

For i = 0 To 8

If xPosArr(i) > intX_2 Then 

colIndex_2 = i

Exit For

End If

Next

End If

End If

End If

Call 刷新二维数组(rowIndex_1, colIndex_1, rowIndex_2, colIndex_2)

End Sub


Sub 刷新二维数组(rowIndex_1, colIndex_1, rowIndex_2, colIndex_2)

TracePrint rowIndex_1 & colIndex_1 & rowIndex_2 & colIndex_2

If map(rowIndex_2)(colIndex_2) = "" Then // 走棋点2本身无子,从1走到2

map(rowIndex_2)(colIndex_2) = map(rowIndex_1)(colIndex_1)

map(rowIndex_1)(colIndex_1) = ""

ElseIf InStr("rnbakcp", map(rowIndex_1)(colIndex_1)) > 0 And map(rowIndex_1)(colIndex_1) <> "" And round = "b" Then// 黑色方走棋,且走棋点1本身是黑子,从1走到2(黑吃红)

map(rowIndex_2)(colIndex_2) = map(rowIndex_1)(colIndex_1)

map(rowIndex_1)(colIndex_1) = ""

ElseIf InStr("RNBAKCP", map(rowIndex_1)(colIndex_1)) > 0 And map(rowIndex_1)(colIndex_1) <> "" And round = "w" Then// 红色方走棋,且走棋点1本身是红子,从1走到2(红吃黑)

map(rowIndex_2)(colIndex_2) = map(rowIndex_1)(colIndex_1)

map(rowIndex_1)(colIndex_1) = ""

Else // 2走到1 

map(rowIndex_1)(colIndex_1) = map(rowIndex_2)(colIndex_2)

map(rowIndex_2)(colIndex_2) = ""

End If

// 交换回合

If round = myColor Then 

round = oppositeColor

Else 

round = myColor

End If

Call 生成FEN局面代码

End Sub

【按键精灵】中国象棋脚本详解的评论 (共 条)

分享到微博请遵守国家法律