⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 go.asm

📁 一个汇编写的Win32围棋程序.测试版本.
💻 ASM
📖 第 1 页 / 共 5 页
字号:
;		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 + -