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

📄 go.asm

📁 一个汇编写的Win32围棋程序.测试版本.
💻 ASM
📖 第 1 页 / 共 5 页
字号:
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;开始日期:2006-08-21 最后修改日期:2006-10-30
;版本号:0.03.11.061030
;较上次之改动见目录下之《任务、目标及过程.txt》
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; Go.asm
;点线围棋汇编版
;蕃薯
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 使用 VC中的nmake 或下列命令进行编译和链接:
; ml /c /coff Go.asm
; rc Menu.rc
; Link /subsystem:windows Go.obj Go.res
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
		.586
		.model flat, stdcall
		option casemap :none
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; Include 文件定义
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
include		windows.inc
include		user32.inc
includelib	user32.lib
include		kernel32.inc
includelib	kernel32.lib

include		gdi32.inc
includelib	gdi32.lib

include		zxh.asm

MAKEMOVE	struct			;用于每个着子生成模块;是模块与外部对话的通道;
	lpFunc	DWORD		?	;有必要吗?
	thread	DWORD		?	;如果是一线程,则为线程句柄;否则为空;
	event	DWORD		?	;如果使用了事件对象,则为事件句柄;
	mem	DWORD		?	;如申请了内存,则为内存句柄;
	point	DWORD		?	;扩展指针;
	status	DWORD		?	;模块状态:未初始化?暂停?正常运行中?
	cmd	DWORD		?	;总程序给本模块的命令,如无为0
	result	DWORD		?	;结果描述(对于命令?)
	x	DWORD		?	;返回或给出的X点
	y	DWORD		?	;返回或给出的Y点
	color	DWORD		?	;返回或给出的棋子颜色;
MAKEMOVE	ends

QIPAN	struct				;好象暂未使用
	color	WORD		?
	count	WORD		?
	bhash	WORD		?	
	whash	WORD		?
QIPAN	ends

_TransXY	proto	:dword, :dword
_CheckRule	proto	:dword, :dword, :dword
_ShowLable	proto	:dword, :dword, :dword, :dword, :dword

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; Equ 等值定义
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
ICO_MAIN	equ		1000h	;图标
IDM_MAIN	equ		2000h	;菜单
IDA_MAIN	equ		2000h	;加速键
IDM_OPEN	equ		4101h
IDM_OPTION	equ		4102h
IDM_EXIT	equ		4103h
IDM_SETFONT	equ		4201h
IDM_SETCOLOR	equ		4202h
IDM_INACT	equ		4203h
IDM_GRAY	equ		4204h
IDM_BIG		equ		4205h
IDM_SMALL	equ		4206h
IDM_LIST	equ		4207h
IDM_DETAIL	equ		4208h
IDM_TOOLBAR	equ		4209h
IDM_TOOLBARTEXT	equ		4210h
IDM_INPUTBAR	equ		4211h
IDM_STATUSBAR	equ		4212h
IDM_HELP	equ		4F01h
IDM_ABOUT	equ		4F02h

IDM_MODE_BEGIN	equ		4400h
IDM_MAN2MAN	equ		4401h
IDM_MAN2PC	equ		4402h
IDM_PC2MAN	equ		4403h
IDM_MODE_END	equ		440Fh

IDM_MAKEDS1	equ		4501h
IDM_MAKEDS2	equ		4502h
IDM_VIEWDS 	equ		4503h

IDM_DEBUG1	equ		4901h 
IDM_DEBUG2	equ		4902h 

IDB_28BLACK	equ		1102h
IDB_28WHITE	equ		1103h
IDB_28MASK	equ		1104h
IDB_BOARD_1	equ		1201h

MODE_BEGIN	equ		10
MODE_MAN2MAN	equ		11
MODE_MAN2PC	equ		12
MODE_PC2MAN	equ		13
MODE_END	equ		20



;定义一系列消息标识符
WM_DLG_BEGIN	equ		WM_USER + 400h
WM_HP_WHITE	equ		WM_DLG_BEGIN + 1	;人类棋手下了白子
WM_HP_BLACK	equ		WM_DLG_BEGIN + 2	;人类棋手下了黑子
WM_PP_WHITE	equ		WM_DLG_BEGIN + 3	;电脑棋手下了白子
WM_PP_BLACK	equ		WM_DLG_BEGIN + 4	;电脑棋手下了黑子

iTableLastLine	equ		5120		;
iTableStep	equ		256		;

BlackStone	equ		1		;黑子(空点为零)
WhiteStone	equ		2		;白子
BianJie		equ		3		;边界

iQipanBX	equ		40		;棋盘开始的X点(?)
iQipanBY	equ		40		;Y点
iQipanEX	equ		544		;终止的X
iQipanEY	equ		544		;终止的Y

iQiziStep	equ		28

Asc		equ		1		;_ShowLable用标记类型:表示是ASCII类
Number		equ		2		;标记数字
Lable		equ		3		;标记形状
LableColor	equ		Red		;标记的颜色

NormalMark	equ		1		;标记:落子时的普通标记,右下三角
CircleMark	equ		2		;圆形标记
TriangleMark	equ		3		;三角标记	
CrossMark	equ		4		;叉形标记
RectangleMark	equ		5		;正方标记

MMS_PAUSE	equ		2		;MAKEMOVE结构的.status中表示暂停
MMS_RUNNING	equ		1		;同上;表示正常使用中;0则表示未初始化;
MMS_HOLD	equ		3		;同上;表示模块被hold住;
MMS_WAITING	equ		4		;同上;表示模块在等待;
						;以上具体含义待详述。

;MAKEMOVE结构中cmd的可能取值及含义:
MMC_GETONEMOVE	equ		1		;将x,y处放入颜色为color的子并计算应有的值;将改变棋盘1的数据;
MMC_MAKEONEMOVE	equ		2		;在xy处返回颜色为color的一个着点;不改变棋盘1的数据;
MMC_GETANDMAKE	equ		3		;取xycolor值,改变棋盘1;生成一点,在xycolor中返回;
MMC_GETMOVES	equ		4		;将makemove.point指向的xycolor序列放入棋盘计算;将改变棋盘1的数据;
MMC_GAMEOVER	equ		5		;着子生成结束;

bTuoXian	equ		250		;表示脱先;字节型;局部计算才用;
wTuoXian	equ		500h		;表示脱先;字型
dwTuoXian	equ		wTuoXian	;表示脱先;双字型
TuoXian		equ		wTuoXian	;表示脱先;一般情况下使用;
RanZi		equ		TuoXian + 1	;表示在程序开始时让子;或可表示飞刀;

MemQiPanStep	equ		3800		;计算时内存棋盘的大小
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 数据段
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
		.data
iTable		word		0,256,512,768,1024,1280,1536,1792,2048,2304,2560,2816,3072,3328,3584,3840,4096,4352,4608,4864,iTableLastLine,5376
;这里有点浪费空间哈

lpFile		dword		2000		;生成一随机数文件,可删除。
lpWriten	dword		0		;生成一随机数文件,可删除。

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 数据段
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
		.data?
hInstance	dd		?	;
hWinMain	dd		?	;
hMenu		dd		?	;
hSubMenu	dd		?	;

hMemDC		dd		?	;
hMaskDC		dd		?	;
hBlackDC	dd		?	;
hWhiteDC	dd		?	;
hQipanDC	dd		?	;这是是内存中的棋盘屏幕,含棋子;
hOrgQipanDC	dd		?	;这里是棋盘,仅仅是棋盘


hWhiteBmp	dd		?	;
hBlackBmp	dd		?	;
hMaskBmp	dd		?	;
hQipanBmp	dd		?	;
hOrgQipanBmp	dd		?	;
iMode		dd		?	;当前模式(11为人人对弈,人机为12,机人为13)
iModeGoing	dd		?	;当前模式是否已在使用?(0未使用,1已使用)
iWillPutColor	dd		?	;将下一子之颜色
iWMTemp		dd		?	;暂放系统消息
iPlayedByPc	dd		?	;人机对弈时,表示已下完的一子是谁下的,1为True为是PC下的,0为FALSE为人下的;
					;指完全处理完的一子,不是刚产生的一步;准备地说是上一子;
iWhatColorPcPlay	dd		?	;电脑执黑还是执白?可能黑白都是它哟(现在不可能)

;iBlackIsWho	dd		?	;黑棋是谁?1表示为电脑,0为电脑旁坐的人
;iWhiteIsWho	dd		?	;白棋是谁?1表示为电脑,0为电脑旁坐的人



iX		dd		?	;客户区的X坐标值
iY		dd		?	;客户区的Y坐标值
iQiziX		dd		?	;棋子在棋盘上的X坐标(数字值1-19,从左到右)
iQiziY		dd		?	;棋子在棋盘上的Y坐标(数字值1-19,从上到下)

dHandsCount	dd		?	;已下棋子手数

dPrevX		dd		?	;上一手的X坐标
dPrevY		dd		?	;上一手的Y坐标
dPrevColor	dd		?	;上一手的棋子颜色


iShuqiCount	dd		?	;数气时所用的区别值
iTiziI		dd		?

hMoveEvent	dd		?	;_MakeOneMove控制用的事件句柄
hMoveThread	dd		?	;线程句柄
;hOldThread	dd		?	;要退出的线程句柄;
lpMoveThreadId	dd		?	;_MakeOneMove的线程ID
iMoveThreadExit	dd		?	;如果想要线程退出,就将此处的值设为100h
dwThreadIsRunning	dd	?	;如果线程在运行,则设为1;否则为0
lpExitCode	dd		?	;线程退出码

PcPlay		dd		?	;
HumanPlay	dd		?	;

lpCanPutList	dd		?	;指向所有可着点之列表;其后有数据说明;
dwCPLCount	dd		?	;当前所有合法着点的数量(基本没用);

MMmakeOneMove	MAKEMOVE	<?>	;
MMrnd		MAKEMOVE	<?>	;
MMradio		MAKEMOVE	<?>	;

		align		4
memQipan	equ		this word 
abcmemQipan	word		2700 dup (?)
iShuqi		dd		400 dup(?)
iTizi		dd		400 dup (?)

lpRSPoint	dd		?			;指向iRecordStone;
iShouShu	dd		?			;已下棋子的个数(手数);
iRecordStone	dd		2000 dup (?)		;记录棋子着点;word;X, Y,COLOR,NUMBER;

OrgDSKBuf	db		7400 dup(?)		;生成数据库用,原始文件
;NewDSKBuf	db		740000 dup(?)		;新文件


;在生成一随机数文件_CreateRndFile中使用,可删除。
hFile		dd		?		;生成一随机数文件,可删除。
;;;;					##################################################
fileoff		dd		?	;想生成随机数文件就注释掉此行,并解除下一行的注释。
;fileoff		word		4000 dup (?)	;生成一随机数文件,可删除。

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 数据段
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
		.const
szClassName	db	'点线围棋',0
szCaptionMain	db	'点线围棋汇编版',0
szMenuHelp	db	'帮助主题(&H)',0
szMenuAbout	db	'关于本程序(&A)...',0
szCaption	db	'菜单选择',0
szFormat	db	'您选择了菜单命令:%08x',0

szAskCancelC	db	'终止对局', 0
szAskCancel	db	'是否终止当前对局?', 0
szAskReplayC	db	'开始对局', 0
szAskReplay	db	'是否开始新的对局?', 0

szFileName	db	'hash.rnd',0	;生成一随机数文件,可删除。
szOrgDSK	db	'..\定式大全org.sgf', 0		;原始定式库文件名,放在程序文件的上级目录
szNewDSK	db	'..\定式大全.dlg',0			;要生成的新的定式库的文件名;


;在_ShowAscBJ中使用
lpStringABC	db	'ABCDEFGHIJKLMNOPQRST',0
lpString123	db	' 1 2 3 4 5 6 7 8 910111213141516171819',0
death		dword	0ffffffffh

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 代码段
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
		.code

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_WhatColor	proc	_wcX, _wcY
		;在eax中返回X,Y处的棋子颜色,0为空
		local	@wcX, @wcY

		;以下使esi指向当前点(_iMemX, _iMemY)的内存棋盘位置
		mov	eax, _wcX
		mov	@wcX, eax
		mov	eax, _wcY
		mov	@wcY, eax

		mov	ebx, @wcY
		sal	ebx, 1
		mov	edi, offset iTable
		add	edi, ebx
		mov	bx, [edi]
		movzx	ebx, bx
		mov	esi,offset memQipan
		add	esi, ebx

		;mov	ecx,3
		mov	ebx,@wcX
		sal	ebx,3
		add	esi,ebx
		;-------------------------

		mov	ax, [esi]
		movzx	eax, ax

		ret
_WhatColor	endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_MakeRndMove	proc
		;生成一个随机数,从而形成一个着法
		;在这段程序中,没有打劫、禁入点等判断,
		;不过,由于这只是一个测试模块,
		;所以也不会进一步地改进。
		pushad
@redoit:
		rdtsc
		mov	esi, eax

		mov	edi, eax
		and	eax, 00011110000b
		shr	eax, 4

		and	edi, 01100000000b
		shr	edi, 8
		add	edi, eax
	
		inc	edi
		.if	edi >19

			jmp	@redoit
		.endif
		mov	iQiziX, edi
		mov	MMrnd.x, edi
		
		shr	esi, 10
		mov	eax, esi

		movzx	eax, ax
		mov	bx, ax
		and	ax, 0001111b
		and	bx, 0110000b
		shr	bx, 4
		add	bx, ax
		movzx	ebx, bx
		inc	ebx
		.if	ebx > 19
			jmp	@redoit
		.endif
		mov	iQiziY, ebx
		mov	MMrnd.y, ebx
		
		;还是在这里基本搞定合法性先。
		invoke	_WhatColor, iQiziX, iQiziY
		.if	eax != 0
			;
			;invoke	

			jmp	@redoit
		.endif

		;该提子时就提子;这里因为还是知道是否合法,
		;所以提子贸然提子还是值得商榷。不过算了,
		;没必要在这里花时间精力了。
		invoke	_CheckRule, iQiziX, iQiziY,dword ptr iWillPutColor
		.if	eax == 0FFFFFFFFh
			jmp	@redoit
		.endif

		popad

		ret
_MakeRndMove	endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;*需要一个回调函数,
;当人按鼠标或用程序生成一个走子时,用此回调函数通知走子
;或者
;*每一个着点生成函数应先有个声明,在其中提供一个结构,
;用于传递数据
;
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;_MakeRadioMove
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
FirstDot	equ	21*8 + 8
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_ShowMem	proc	_Mem
		;测试用
		local	@Mem
		
		pushad
		mov	eax, _Mem
		mov	@Mem, eax
		mov	edi, eax
		mov	ecx, 0ffffh
		;
@@:
		mov	ebx, [edi]
		MessageHexOC	ebx
		.if	eax == IDOK
			add	edi, 4
			sub	ecx, 1
			jnz	@B
		.elseif
			popad
			ret
		.endif

		popad
		ret
_ShowMem	endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

_ReadMem		proc
		;测试用
		;
		;invoke	_ShowMem, 014f310h	;天元处
		invoke	_ShowMem, 014ec80h	;天元处
		ret
_ReadMem		endp

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_MRM_CopyQipan	proc	_First, _Second
		;将前一级棋盘的数据拷到下一级棋盘;
		;
		pushad
		cld
		mov	esi, _First
		mov	edi, _Second
		mov	ecx, MemQiPanStep/4
		rep	movsd
		popad
		ret
_MRM_CopyQipan	endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_UnloadMakeRadioMove	proc
		;
		;
		invoke	GlobalFree, MMradio.mem
		ret

_UnloadMakeRadioMove	endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_InitMakeRadioMove	proc
		;
		local	@FirstQipan
		local	@SecondQipan
		local	@Edi

		;要申请内存等
		invoke	GlobalAlloc, GPTR, MemQiPanStep * 2		
		;(8*21*21)*2=3528*2->MemQiPanStep*2 + 800*2
		;->7056 +800*2
		;即二个棋盘加上

		.if	eax == NULL
			Message	'“辐射法”模块申请内存失败!'
			ret
		.endif
		mov	MMradio.mem, eax
		mov	@FirstQipan, eax

		mov	eax, offset _MakeRadioMove
		mov	MMradio.lpFunc, eax

		;画内存棋盘
		cld
		mov	edi, @FirstQipan
		mov	ecx, 21*2
		mov	eax, 00000003h
		rep	stosd

		mov	edi, @FirstQipan
		add	edi, 3360		;到棋盘下边界头
		mov	ecx, 21*2
		mov	eax, 00000003h
		rep	stosd
		
		mov	eax, 00000003h		;两边边界
		mov	edi, @FirstQipan
		add	edi, 20 * 8
		mov	ecx, 20
@@:		
		stosd
		stosd
		stosd
		stosd
		add	edi, 19*4*2
		sub	ecx, 1
		cmp	ecx, 0
		jnz	@B
		stosd
		stosd
		
;		;要将三线内设成一个正值
;		;即棋盘不平坦
;		mov	edi, MMradio.mem
;		add	edi, 22*8
;		mov	eax, BuPinTan
;		mov	ecx, 19
;@XX1:
;		add	edi, 4
;		stosd
;		dec	ecx
;		jnz	@XX1
;
;		mov	edi, MMradio.mem
;		add	edi, 21*8*17
;		add	edi, 8
;		;mov	eax, BuPinTan
;		mov	ecx, 19
;@XX2:		
;		add	edi, 4
;		stosd

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -