*BRD_Define
; ボード位置
numalias BRD_RECT_X,120
numalias BRD_RECT_Y,20
numalias BRD_RECT_WIDTH,400
numalias BRD_RECT_HEIGHT,400

; コマ
numalias W,1
numalias B,2
numalias N,-1
numalias X,0
numalias BRD_STONE_WIDTH,50
numalias BRD_STONE_HEIGHT,50

stralias BRD_FILE_BG,"bg/BoardDefault.bmp"
stralias BRD_FILE_PIECE,":l/2,0,3;parts/stone.bmp"
stralias BRD_FILE_CELLFOCUS,"parts/cellfocus.bmp"

defsub BrdInit
defsub BrdDraw
defsub BrdCoordToCellPos
defsub BrdPtInRect
defsub BrdSetStone
defsub BrdGetStone
defsub BrdReverseStone
defsub BrdGetStoneCount
defsub BrdClearCheckCell
defsub BrdPushCheckCell
defsub BrdCheckReverse
defsub BrdGetReverseColor
defsub BrdCalcCells
defsub BrdIsExistNeighberLines
defsub BrdDrawFocus
defsub BrdHideFocus
defsub brdIsExistNeighberLineX
defsub brdIsExistNeighberLineY
defsub BrdIsExistStone
defsub brdInitDefault
defsub brdLoad
defsub brdGetStoneFromCell
defsub brdSetStoneToCell
defsub brdIncrementLineX
defsub brdIncrementLineY
defsub brdIncrementCount

numalias BRD_VARNUM_EXTERNAL,300
numalias BRD_PtX,BRD_VARNUM_EXTERNAL
numalias BRD_PtY,BRD_VARNUM_EXTERNAL+1
numalias BRD_Return,BRD_VARNUM_EXTERNAL+2
numalias BRD_Color,BRD_VARNUM_EXTERNAL+3
numalias BRD_PosX,BRD_VARNUM_EXTERNAL+4
numalias BRD_PosY,BRD_VARNUM_EXTERNAL+5
numalias BRD_Loop,BRD_VARNUM_EXTERNAL+6

numalias BRD_VARNUM_INTERNAL,310
numalias BRD_Arg1,BRD_VARNUM_INTERNAL
numalias BRD_Arg2,BRD_VARNUM_INTERNAL+1
numalias BRD_Arg3,BRD_VARNUM_INTERNAL+2
numalias BRD_Tmp,BRD_VARNUM_INTERNAL+3

numalias BRD_Info,3
numalias BRD_STARTPOS,0
numalias BRD_ENDPOS,7
numalias BRD_COUNTPOS,10
dim ?BRD_Info[10][10]
numalias BRD_CheckCells,13
dim ?BRD_CheckCells[8]

return

*BrdInit
brdInitDefault
brdLoad
return

*BrdDraw
for %BRD_PtY=0 to 7
	for %BRD_PtX=0 to 7
		mov %BRD_Tmp,%BRD_PtY*8+%BRD_PtX
		brdGetStoneFromCell %BRD_Color,%BRD_PtX,%BRD_PtY
		if %BRD_Color=N vsp %BRD_Tmp,0:skip 3
		if %BRD_Color=B vsp %BRD_Tmp,1:cell %BRD_Tmp,1:skip 2
		vsp %BRD_Tmp,1:cell %BRD_Tmp,0
	next
next
return

*BrdCoordToCellPos
getparam i%BRD_PtX,i%BRD_PtY
mov %%BRD_PtX,(%%BRD_PtX-BRD_RECT_X)/BRD_STONE_WIDTH
mov %%BRD_PtY,(%%BRD_PtY-BRD_RECT_Y)/BRD_STONE_HEIGHT
if %%BRD_PtX<0 die "BrdCoordToCellPos - Invalid Coord (Under X)"
if %%BRD_PtY<0 die "BrdCoordToCellPos - Invalid Coord (Under Y)"
if %%BRD_PtX>7 die "BrdCoordToCellPos - Invalid Coord (Over X)"
if %%BRD_PtY>7 die "BrdCoordToCellPos - Invalid Coord (Over Y)"
return

*BrdPtInRect
getparam i%BRD_Return,%BRD_PtX,%BRD_PtY
if %BRD_PtX>=BRD_RECT_X & %BRD_PtX<=BRD_RECT_X+BRD_RECT_WIDTH & %BRD_PtY>=BRD_RECT_Y & %BRD_PtY<=BRD_RECT_Y+BRD_RECT_HEIGHT mov %%BRD_Return,1:return
mov %%BRD_Return,0
return

*BrdSetStone
getparam %BRD_Color,%BRD_PosX,%BRD_PosY
brdSetStoneToCell %BRD_Color,%BRD_PosX,%BRD_PosY
brdIncrementLineX %BRD_PosX
brdIncrementLineY %BRD_PosY
brdIncrementCount
return

*BrdGetStone
getparam i%BRD_Return,%BRD_PosX,%BRD_PosY
brdGetStoneFromCell %%BRD_Return,%BRD_PosX,%BRD_PosY
return

*BrdReverseStone
getparam %BRD_Color,%BRD_PosX,%BRD_PosY
;brdGetStoneFromCell %BRD_Color,%BRD_PosX,%BRD_PosY
;BrdGetReverseColor %BRD_Color,%BRD_Color
brdSetStoneToCell %BRD_Color,%BRD_PosX,%BRD_PosY
return

*BrdGetStoneCount
getparam i%BRD_Return
mov %%BRD_Return,?BRD_Info[10][10]
return

;// セル列化

; BでもWでもNでも無い数値で初期化
*BrdClearCheckCell
movl ?BRD_CheckCells,0,X,X,X,X,X,X,X,X
return

; 0番地を一時的なカウンタとして使う
*BrdPushCheckCell
getparam %BRD_Arg1
incary BRD_CheckCells,0
;traceint ?BRD_CheckCells[0]
mov ?BRD_CheckCells[?BRD_CheckCells[0]],%BRD_Arg1
return

; 反転条件:BW[W...]B or WB[B...]W
; 一応反転数を0番地に保持しておく
*BrdCheckReverse
getparam i%BRD_Arg1,%BRD_Arg2,%BRD_Arg3
;traceary BRD_CheckCells,7
; 配列が2つ未満なら反転不可
if ?BRD_CheckCells[0]<2 mov %%BRD_Arg1,0:return
; 反対色を探査
; 隣接セルが反対色の連続でなければ反転不可
mov %BRD_Tmp,0
for %BRD_Loop=1 to 7
	if ?BRD_CheckCells[%BRD_Loop]!=%BRD_Arg3 break
	inc %BRD_Tmp
next
; 反対色の連続の直後のセルが同色でなければ反転不可
if ?BRD_CheckCells[%BRD_Loop]!=%BRD_Arg2 mov %BRD_Tmp,0
mov %%BRD_Arg1,%BRD_Tmp
mov ?BRD_CheckCells[0],%BRD_Tmp
return

*BrdGetReverseColor
getparam i%BRD_Arg1,%BRD_Arg2
if %BRD_Arg2=B mov %%BRD_Arg1,W:return
mov %%BRD_Arg1,B
return

; 集計ルーチン
*BrdCalcCells
getparam i%BRD_Return,%BRD_Color
mov %%BRD_Return,0
for %BRD_PosY=BRD_STARTPOS to BRD_ENDPOS
	for %BRD_PosX=BRD_STARTPOS to BRD_ENDPOS
		brdGetStoneFromCell %BRD_Tmp,%BRD_PosX,%BRD_PosY
		if %BRD_Tmp=%BRD_Color inc %%BRD_Return
	next
next
return

*brdIsExistNeighberLineY
getparam i%BRD_Arg1,%BRD_Arg2
; 上の行
if %BRD_Arg2!=BRD_STARTPOS & ?BRD_Info[%BRD_Arg2-1][0]>0 mov %%BRD_Arg1,1:return
; 下の行
if %BRD_Arg2!=BRD_ENDPOS & ?BRD_Info[%BRD_Arg2+1][0]>0 mov %%BRD_Arg1,1:return
mov %%BRD_Arg1,0
return

*brdIsExistNeighberLineX
getparam i%BRD_Arg1,%BRD_Arg2
; 左の行
if %BRD_Arg2!=BRD_STARTPOS & ?BRD_Info[0][%BRD_Arg2-1]>0 mov %%BRD_Arg1,1:return
; 右の行
if %BRD_Arg2!=BRD_ENDPOS & ?BRD_Info[0][%BRD_Arg2+1]>0 mov %%BRD_Arg1,1:return
mov %%BRD_Arg1,0
return

*BrdIsExistNeighberLines
getparam i%BRD_Return,%BRD_PosX,%BRD_PosY
BrdIsExistNeighberLineX %BRD_PosX,%BRD_PosX
BrdIsExistNeighberLineY %BRD_PosY,%BRD_PosY
if %BRD_PosX=0 & %BRD_PosY=0 mov %%BRD_Return,0:return
mov %%BRD_Return,1
return

*BrdIsExistStone
getparam i%BRD_Return,%BRD_PosX,%BRD_PosY
brdGetStoneFromCell %BRD_Tmp,%BRD_PosX,%BRD_PosY
if %BRD_Tmp>0 mov %%BRD_Return,1:return
mov %%BRD_Return,0
return

; デバッグフォーカス用
*BrdDrawFocus
getparam %BRD_PosX,%BRD_PosY
amsp 64,BRD_RECT_X+%BRD_PosX*BRD_STONE_WIDTH,BRD_RECT_Y+%BRD_PosY*BRD_STONE_HEIGHT
vsp 64,1
return

*BrdHideFocus
vsp 64,0
return

;// 内部ルーチン //

*brdInitDefault
movl ?BRD_Info[0],X,X,X,X,X,X,X,X,X,X,0
movl ?BRD_Info[1],X,N,N,N,N,N,N,N,N,X,0
movl ?BRD_Info[2],X,N,N,N,N,N,N,N,N,X,0
movl ?BRD_Info[3],X,N,N,N,N,N,N,N,N,X,0
movl ?BRD_Info[4],X,N,N,N,W,B,N,N,N,X,2
movl ?BRD_Info[5],X,N,N,N,B,W,N,N,N,X,2
movl ?BRD_Info[6],X,N,N,N,N,N,N,N,N,X,0
movl ?BRD_Info[7],X,N,N,N,N,N,N,N,N,X,0
movl ?BRD_Info[8],X,N,N,N,N,N,N,N,N,X,0
movl ?BRD_Info[9],X,X,X,X,X,X,X,X,X,X,0
movl ?BRD_Info[10],0,0,0,0,2,2,0,0,0,0,4
return

;// デバッグ用
; 探査で連続反対色後のループ終了の考慮が漏れていたためバグを出していた。
; チェック用の変数を別途設けて対応 sub_CheckReversibleAWProc
movl ?BRD_Info[0],X,X,X,X,X,X,X,X,X,X,0
movl ?BRD_Info[1],X,N,N,N,N,N,N,N,N,X,0
movl ?BRD_Info[2],X,N,N,N,N,N,B,N,N,X,0
movl ?BRD_Info[3],X,N,N,B,N,N,B,B,N,X,0
movl ?BRD_Info[4],X,N,N,N,B,W,B,N,N,X,2
movl ?BRD_Info[5],X,N,N,W,B,B,B,B,N,X,2
movl ?BRD_Info[6],X,N,N,W,W,B,B,W,N,X,0
movl ?BRD_Info[7],X,N,N,N,B,W,W,B,W,X,0
movl ?BRD_Info[8],X,N,N,N,B,B,B,B,B,X,0
movl ?BRD_Info[9],X,X,X,X,X,X,X,X,X,X,0
movl ?BRD_Info[10],0,0,0,0,2,2,0,0,0,0,4
; 反転チェックで端のセルに対して返り値の設定がもれていたためバグを出していた
; 端のセルが反転しない場合も返り値を設定するよう修正 BrdCheckReverse
movl ?BRD_Info[0],X,X,X,X,X,X,X,X,X,X,0
movl ?BRD_Info[1],X,N,N,N,N,N,N,N,W,X,0
movl ?BRD_Info[2],X,N,N,N,N,N,N,N,N,X,0
movl ?BRD_Info[3],X,N,N,N,N,N,N,N,W,X,0
movl ?BRD_Info[4],X,N,N,N,W,B,N,W,B,X,2
movl ?BRD_Info[5],X,N,N,N,B,W,W,B,N,X,2
movl ?BRD_Info[6],X,N,N,N,N,N,N,N,N,X,0
movl ?BRD_Info[7],X,N,N,N,N,N,N,N,N,X,0
movl ?BRD_Info[8],X,N,N,N,N,N,N,N,N,X,0
movl ?BRD_Info[9],X,X,X,X,X,X,X,X,X,X,0
movl ?BRD_Info[10],0,0,0,0,2,2,0,0,0,0,4

*brdLoad
bg BRD_FILE_BG,1
for %BRD_PosY=BRD_STARTPOS to BRD_ENDPOS
	for %BRD_PosX=BRD_STARTPOS to BRD_ENDPOS
		lsph %BRD_PosY*8+%BRD_PosX,BRD_FILE_PIECE,BRD_RECT_X+%BRD_PosX*BRD_STONE_WIDTH,BRD_RECT_Y+%BRD_PosY*BRD_STONE_HEIGHT
	next
next
lsph 64,BRD_FILE_CELLFOCUS,0,0
return

; 0-7 を変換して返す
*brdGetStoneFromCell
getparam i%BRD_Arg1,%BRD_Arg2,%BRD_Arg3
mov %%BRD_Arg1,?BRD_Info[%BRD_Arg3+1][%BRD_Arg2+1]
return

; 0-7 を変換して設置
*brdSetStoneToCell
getparam %BRD_Arg1,%BRD_Arg2,%BRD_Arg3
mov ?BRD_Info[%BRD_Arg3+1][%BRD_Arg2+1],%BRD_Arg1
return

*brdIncrementLineX
getparam %BRD_Arg1
incary2 BRD_Info,%BRD_Arg1+1,BRD_COUNTPOS
return

*brdIncrementLineY
getparam %BRD_Arg1
incary2 BRD_Info,BRD_COUNTPOS,%BRD_Arg1+1
return

*brdIncrementCount
incary2 BRD_Info,BRD_COUNTPOS,BRD_COUNTPOS
return