📄 go.asm
字号:
; dd 8 ,0 ,16 ,0 ,24 ,0 ,24-ZN ,RPN4 ,24-ZN*2 ,RPN5 ,0,0 ;右三上
; dd 8 ,0 ,16 ,0 ,24 ,0 ,32 ,0 ,32-ZN ,RPN5 ,0,0 ;右四上
;
; dd 8 ,0 ,8+ZN ,RPN2 ,8+ZN*2 ,RPN3 ,8+ZN*3 ,RPN4 ,8+ZN*4 ,RPN5 ,0,0 ;右一下
; dd 8 ,0 ,16 ,0 ,16+ZN ,RPN3 ,16+ZN*2 ,RPN4 ,16+ZN*3 ,RPN5 ,0,0 ;右二下
; dd 8 ,0 ,16 ,0 ,24 ,0 ,24+ZN ,RPN4 ,24+ZN*2 ,RPN5 ,0,0 ;右三下
; dd 8 ,0 ,16 ,0 ,24 ,0 ,32 ,0 ,32+ZN ,RPN5 ,0,0 ;右四下
;
; dd FN ,0 ,FN-8 ,RPN2 ,FN-16 ,RPN3 ,FN-24 ,RPN4 ,FN-32 ,RPN5 ,0,0 ;上一右
; dd FN ,0 ,FN*2 ,0 ,FN*2-8 ,RPN3 ,FN*2-16 ,RPN4 ,FN*2-24 ,RPN5 ,0,0 ;上二右
; dd FN ,0 ,FN*2 ,0 ,FN*3 ,0 ,FN*3-8 ,RPN4 ,FN*3-16 ,RPN5 ,0,0 ;上三右
; dd FN ,0 ,FN*2 ,0 ,FN*3 ,0 ,FN*4 ,0 ,FN*4-8 ,RPN5 ,0,0 ;上四右
;
; dd FN ,0 ,FN+8 ,RPN2 ,FN+16 ,RPN3 ,FN+24 ,RPN4 ,FN+32 ,RPN5 ,0,0 ;上一左
; dd FN ,0 ,FN*2 ,0 ,FN*2+8 ,RPN3 ,FN*2+16 ,RPN4 ,FN*2+24 ,RPN5 ,0,0 ;上二左
; dd FN ,0 ,FN*2 ,0 ,FN*3 ,0 ,FN*3+8 ,RPN4 ,FN*3+16 ,RPN5 ,0,0 ;上三左
; dd FN ,0 ,FN*2 ,0 ,FN*3 ,0 ,FN*4 ,0 ,FN*4+8 ,RPN5 ,0,0 ;上四左
;
; dd -8 ,0 ,FN-8 ,RPN2 ,FN*2-8 ,RPN3 ,FN*3-8 ,RPN4 ,FN*4-8 ,RPN5 ,0,0 ;左一上
; dd -8 ,0 ,-16 ,0 ,FN-16 ,RPN3 ,FN*2-16 ,RPN4 ,FN*3-16 ,RPN5 ,0,0 ;左二上
; dd -8 ,0 ,-16 ,0 ,-24 ,0 ,FN-24 ,RPN4 ,FN*2-24 ,RPN5 ,0,0 ;左三上
; dd -8 ,0 ,-16 ,0 ,-24 ,0 ,-32 ,0 ,FN-32 ,RPN5 ,0,0 ;左四上
;
; dd -8 ,0 ,ZN-8 ,RPN2 ,ZN*2-8 ,RPN3 ,ZN*3-8 ,RPN4 ,ZN*4-8 ,RPN5 ,0,0 ;左一下
; dd -8 ,0 ,-16 ,0 ,ZN-16 ,RPN3 ,ZN*2-16 ,RPN4 ,ZN*3-16 ,RPN5 ,0,0 ;左二下
; dd -8 ,0 ,-16 ,0 ,-24 ,0 ,ZN-24 ,RPN4 ,ZN*2-24 ,RPN5 ,0,0 ;左三下
; dd -8 ,0 ,-16 ,0 ,-24 ,0 ,-32 ,0 ,ZN-32 ,RPN5 ,0,0 ;左四下
;
; dd ZN ,0 ,ZN-8 ,RPN2 ,ZN-16 ,RPN3 ,ZN-24 ,RPN4 ,ZN-32 ,RPN5 ,0,0 ;下一左
; dd ZN ,0 ,ZN*2 ,0 ,ZN*2-8 ,RPN3 ,ZN*2-16 ,RPN4 ,ZN*2-24 ,RPN5 ,0,0 ;下二左
; dd ZN ,0 ,ZN*2 ,0 ,ZN*3 ,0 ,ZN*3-8 ,RPN4 ,ZN*3-16 ,RPN5 ,0,0 ;下三左
; dd ZN ,0 ,ZN*2 ,0 ,ZN*3 ,0 ,ZN*4 ,0 ,ZN*4-8 ,RPN5 ,0,0 ;下四左
;
; dd ZN ,0 ,ZN+8 ,RPN2 ,ZN+16 ,RPN3 ,ZN+24 ,RPN4 ,ZN+32 ,RPN5 ,0,0 ;下一右
; dd ZN ,0 ,ZN*2 ,0 ,ZN*2+8 ,RPN3 ,ZN*2+16 ,RPN4 ,ZN*2+24 ,RPN5 ,0,0 ;下二右
; dd ZN ,0 ,ZN*2 ,0 ,ZN*3 ,0 ,ZN*3+8 ,RPN4 ,ZN*3+16 ,RPN5 ,0,0 ;下三右
; dd ZN ,0 ,ZN*2 ,0 ,ZN*3 ,0 ,ZN*4 ,0 ,ZN*4+8 ,RPN5 ,0,0 ;下四右
; dd 0 ,0 ,0 ,0
szABCkdfmn byte '为什么非要加这个啊!!!嘿嘿,有点明白了。',0
;以上数据OK
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.code
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_MRMCompuIt proc _Esi, _Color
;棋盘数据结构为word,1色2空3黑4白,计8个字节;21*21
;计算_Esi处下一颜色为_Color子所形成的辐射值;
;在此之前应进行规则计算
;如果有提子,则将所提子处的棋子色辐射值设为一个较大的负数
local @Edi ;指向RadioPath的当前位置;在本子程中不断向前;
local @Esi ;指向内存棋盘上当前“原位棋子”;在本子程中不变
local @TempEsi ;遇到棋子处的棋子位置
local @TempColor : word ;临时子颜色;
local @WhiteValue :word ;白子增量
local @BlackValue :word ;黑子增量
local @TempEdi
xor eax, eax
mov @WhiteValue, ax
mov @BlackValue, ax
;; ;这里要进行规则运算 ;
;; ;如果有提子,则将所提子处的棋子色辐射值设为一个较大的负数 ;
;; ;如果选取点不合规则,?直接退出? ;
; invoke _MRMDoTheRule, _Esi, _Color ;
; .if eax == 0 ;
; jmp @MRMCIExit ;
; .endif ;
mov esi, _Esi
;mov ax, [esi] ;这里计算当前点的增量;
.if dword ptr _Color == BlackStone
mov word ptr [esi] + 4, StoneValue
mov word ptr [esi] + 6, 0
;sub @BlackValue, ax ;不用计算增量了
.elseif dword ptr _Color == WhiteStone
mov word ptr [esi] + 6, StoneValue
mov word ptr [esi] + 4, 0
;sub @WhiteValue, ax
.endif
;xor eax, eax
;mov [esi]+4, eax ;清空“原位”的原有辐射值。现在不用了。
mov @Esi, esi ;指向内存棋盘上当前“原位棋子”;
mov edi, offset RadioPath
mov @Edi, edi ;指向RadioPath的当前位置;
@MRMCompuItA:
mov eax, [edi]+4 ;取加权值;
mov esi, [edi] ;要处理点处的偏移值
add esi, @Esi ;加上原位位置,得到正处理点的位置;
mov dx, [esi] ;正处理点的棋子颜色
;-------------
.if dx == 0 ;如为空点
.if eax != 0 ;如果加权值不为零;(为零则直接返回)
.if _Color == BlackStone ;加上相应的加权值
add [esi]+4, ax
add @BlackValue, ax
.elseif _Color == WhiteStone
add [esi]+6, ax
add @WhiteValue, ax
.endif
.endif
;-------------
.elseif dx == 0003h ;如为边界;(边界为二个00000003h)
;当遇到边界时,应返过头来,折回再加;
;直到遇到“原位棋子”或行结束;
;这时esi指向边界点,edi指向RadioPath的当前偏移
;mov ebx, esi
;push esi
mov ecx, 8
mov esi, @Esi
;这时esi指向原点
@@:
neg ecx
mov ebx, [edi+ecx] ;取偏移值
mov ax, [ebx+esi] ;取棋盘棋子颜色
.if ax != 0 ;如果是棋子,则下一RadioPath行
mov ecx, 8
@HeHeHe:
add edi, ecx
mov eax, [edi]
.if eax != 0
jmp @HeHeHe
.else
sub edi, 8
jmp @LineEnd
.endif
.endif
.if ebx == 0
;如果到了RadioPath行末,则设edi指向行最后一个数据
;
add edi, ecx
sub edi, 8
jmp @LineEnd
.endif
neg ecx
mov edx, [edi+ecx]-4 ;取加权值
mov ax, [ebx + esi]
.if ax == 0
.if _Color == BlackStone ;加上相应的加权值
add [ebx + esi] + 4, dx
add @BlackValue, dx
.elseif _Color == WhiteStone
add [ebx + esi] + 6, dx
add @WhiteValue, dx
.endif
add ecx, 8
jmp @B
.elseif
;
add edi, ecx
sub edi, 8
jmp @LineEnd
.endif
;-------------
.elseif ;如不为空也不为边界,则说明原来此处有子
;当遇到棋子时,应返头跳过“原位棋子”,
;去除所遇子原来的加权值;直到遇到另一棋子
;此时ESI为正在处理的点,不是“原位”@Esi
mov @TempEsi, esi
push ecx
mov cx, [esi]
mov @TempColor, cx ;遇到棋盘上原有棋子的颜色;
pop ecx
@ColorNext:
add edi, 8 ;下一RadioPath值
mov @Edi, edi ;存起来
mov eax, [edi]+4 ;取加权值
mov esi, [edi] ;取偏移值
.if esi != 0 ;如果不是RadioPath行结束
neg esi ;得偏移值的负数
add esi, @TempEsi ;得返向过原位棋子的一点
mov dx, [esi] ;正处理点的棋子颜色
.if dx == 0 ;如果为空点
.if eax != 0 ;如果加权值不为零;(为零则直接返回)
.if @TempColor == WhiteStone ;加上相应的加权值
sub [esi]+6, ax
sub @WhiteValue, ax
.elseif @TempColor == BlackStone
sub [esi]+4, ax
sub @BlackValue, ax
.endif
.endif
jmp @ColorNext
.elseif
;当遇到一棋子时,应结束此RadioPath行;
@@:
add edi, 8
mov @Edi, edi
mov eax, [edi]
.if eax != 0
jmp @B
.endif
;sub edi, 8
;mov @Edi, edi
;.elseif dx == 0003h
; ;当遇到边界时(可能吗?),
.endif
.endif
sub edi, 8
jmp @LineEnd
.endif
;-------------
@LineEnd: ;这里不应叫LineEnd,而应叫NextLine
add edi, 8 ;指向下一处(RadioPath的)
mov @Edi, edi ;存
mov eax, [edi] ;取值
.if eax != 0 ;如不是行尾
jmp @MRMCompuItA ;
.else ;
add edi, 8 ;如是行尾
mov @Edi, edi
mov eax, [edi]
.if eax != 0 ;不是RadioPath尾
jmp @MRMCompuItA
.else
jmp @MRMCompuItEnd
.endif
.endif
@MRMCompuItEnd:
;
movzx eax, @BlackValue
movzx ebx, @WhiteValue
xor ecx, ecx
;mov esi, eax
;MessageHex esi
;mov ecx, 0
;neg ecx
;MessageHex ebx
@MRMCIExit:
;这里要进行规则运算 ;
;如果有提子,则将所提子处的棋子色辐射值设为一个较大的负数 ;
;如果选取点不合规则,?直接退出? ;
invoke _MRMDoTheRule, _Esi, _Color ;
;
; movzx eax, @BlackValue
; movzx ebx, @WhiteValue
; xor ecx, ecx
ret
_MRMCompuIt endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_MRMPutOneStone proc _X, _Y, _Color
local @Edx
local @Edx2
local @Eax
local @Eax2
;在棋盘上放下一子,计算黑子和白子的累计值;
;
mov eax, _Y
mov ecx, 21 * 8
mul cl
mov ebx, _X
shl ebx, 3
add ebx, eax
mov esi, MMradio.mem
add esi, ebx
mov ebx, _Color
mov [esi], bl
;pusha
;rdtsc
;mov @Edx, edx
;mov @Eax, eax
;popa
invoke _MRMCompuIt, esi, ebx
;pusha
;rdtsc
;mov @Edx2, edx
;mov @Eax2, eax
;MessageHex @Edx
;MessageHex @Edx2
;MessageHex @Eax
;MessageHex @Eax2
;popa
ret
_MRMPutOneStone endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_MRMTryOneStone proc _Esi, _Color
;在棋盘上放下一子,计算黑子和白子的累计值;
;
;mov eax, _Y
;mov ecx, 21 * 8
;mul cl
;mov ebx, _X
;shl ebx, 3
;add ebx, eax
;mov esi, MMradio.mem
;add esi, ebx
;add esi, MemQiPanStep
mov esi, _Esi
mov ebx, _Color
mov al, [esi]
.if al == 0
mov [esi], bl
invoke _MRMCompuIt, esi, ebx
.else
mov ecx, 0FFFFFFh
.endif
ret
_MRMTryOneStone endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_MRMCompA proc _EdiP
;计算实地与影响点的多少;
;实地放在eax,ebx中,影响点放在ecx,edx中
;高位为黑,低位为白
;这一段可改进
local @Bdi, @Wdi ;黑白棋的实地数
local @Bying, @Wying ;黑白棋的影响点
local @BdiV, @WdiV ;黑白棋的实地和值(为某方实地才求和
local @ByingV, @WyingV;黑白棋的影响和值
local @ok
mov esi, _EdiP
mov dword ptr @Bdi, 0
mov dword ptr @Wdi, 0
mov dword ptr @Bying, 0
mov dword ptr @Wying, 0
mov dword ptr @BdiV, 0
mov dword ptr @WdiV, 0
mov dword ptr @ByingV, 0
mov dword ptr @WyingV, 0
add esi, 22 * 8
mov ecx, 19 * 21
@@:
mov ax, [esi]+4 ;ax中为黑子的影响值
mov bx, [esi]+6 ;bx中为白子的影响值
.if ax > bx ;编绎器这里用的是jbe,不行。改成下面的:
;push $
;pop @ok
;MessageHex @ok
;call [death]
movzx edx, ax
add dword ptr @Bying, 1
add dword ptr @ByingV, edx
sub ax, bx
.if ax > SHIDI
add dword ptr @Bdi, 1
add dword ptr @BdiV, edx
.endif
.elseif ax < bx
movzx edx, bx
add dword ptr @Wying, 1
add dword ptr @WyingV, edx
sub bx, ax
.if bx > SHIDI
add dword ptr @Wdi, 1
add dword ptr @WdiV, edx
.endif
.endif
;
; cmp ax, bx
; jl @CmpNext
; movzx edx, ax
; add dword ptr @Bying, 1
; add dword ptr @ByingV, edx
; sub ax, bx
; cmp ax, SHIDI
; jnge @CmpEnd
; add dword ptr @Bdi, 1
; add dword ptr @BdiV, edx
; jmp @CmpEnd
;@CmpNext:
; cmp ax, bx
; jg @CmpEnd
; movzx edx, bx
; add dword ptr @Wying, 1
; add dword ptr @WyingV, edx
; sub bx, ax
; cmp bx, SHIDI
; jnge @CmpEnd
; add dword ptr @Wdi, 1
; add dword ptr @WdiV, edx
;@CmpEnd:
;---以上是新改的---
add esi, 8
dec ecx
jnz @B
;
;mov esi, @Wdi
mov eax, @Bdi
sub eax, @Wdi
mov ebx, @Bying
sub ebx, @Wying
mov ecx, @BdiV
sub ecx, @WdiV
mov edx, @ByingV
sub edx, @WyingV
;
ret
_MRMCompA endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.data
dwSearchDeep dd ? ;搜索深度;暂未用
dwMoveNum dd ? ;
;全局变量
;lpCanPutList dd ? ;指向所有可着点之列表;其后有数据说明;
;dwCPLCount dd ? ;;当前所有合法着点的数量(基本没用);
.code
_MakeOneRadioMove proc _Color
;因为如果单子辐射最大值为128,则某点的最大值为128*4
;则361个点最大和为512*361=184832=02D200h
;因双方棋子大致相同,则可除二
;又因棋子要占据一定的点,棋子又可隔断,所以
;最大和不会超过16位值。
;可用32位同时计算黑白和。
local @MaxValue, @MaxMoveNum
local @EdiP
local @MaxDi ;最大点实地差值
local @MaxYing ;最大点影响差值
local @MaxDiV
local @MaxYingV
local @di, @ying, @diV, @yingV
mov dword ptr @MaxMoveNum, 0
mov dword ptr @MaxValue, 0
mov dword ptr @MaxDi, 0f0000000h
mov dword ptr @MaxYing, 0
mov edi, MMradio.mem ;如果要多层搜索,可修改此及相关处
add edi, MemQiPanStep
mov @EdiP, edi ;@EdiP为基值
;回复第二棋盘
cld
mov esi, MMradio.mem
mov edi, esi
add edi, MemQiPanStep
mov ecx, MemQiPanStep/4
rep movsd
mov dword ptr dwMoveNum, 0 ;如果要多层搜索,可修改此及相关处
mov esi, lpCanPutList
mov ecx, dwMoveNum ;以lpCanPutList与dwMoveNum得到偏移值
shl ecx, 2
add esi, ecx
@@:
mov edi, [esi]
;mov eax, [edi]
.if edi == 0FFFFFFFFh ;如果此点无效
add esi, 4
inc dword ptr dwMoveNum
.if dword ptr dwMoveNum <= 361
jmp @B
.else
jmp @EndThisFunc
.endif
.else
;
add edi, @EdiP
push esi
invoke _MRMTryOneStone, edi, _Color
;返回:eax为实地数黑减白,ebx为影响点黑减白
;ecx为某方实地值黑减白之和差,edx为黑的绝对影响值减白之和差
;
;也可在这里比较实地多少、控制点数、影响值及三者的加权来选择
invoke _MRMCompA, @EdiP
;
mov @di, eax
mov @ying, ebx
mov @diV, ecx
mov @yingV, edx
;此段相当于老算法
mov ecx, ebx
mov ebx, eax
;sub eax, ebx ;黑减白
;mov ebx, eax
sal eax, 1 ;*2
add eax, ebx ;*3
;sub ecx, edx
add eax, ecx ;计算出黑棋对白棋地势加权的差值
;新算法
.if dword ptr _Color == WhiteStone ;dothis
neg eax
.endif
cmp eax, @MaxDi
jng @NotGreater
mov @MaxDi, eax
push dwMoveNum
pop @MaxMoveNum
@NotGreater:
;回复第二棋盘
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -