📄 go.asm
字号:
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;开始日期: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 + -