*RVS_Define
gosub *BRD_Define
gosub *SUB_Define

; 他
numalias RVS_DRAWGAME,0
numalias RVS_PLAYER_WIN,1
numalias RVS_PLAYER_LOSE,-1

numalias RVS_VARNUM_EXTERNAL,200
numalias RVS_Turn,RVS_VARNUM_EXTERNAL+1
numalias RVS_Color,RVS_VARNUM_EXTERNAL+2
numalias RVS_Return,RVS_VARNUM_EXTERNAL+3
numalias RVS_PtX,RVS_VARNUM_EXTERNAL*4
numalias RVS_PtY,RVS_VARNUM_EXTERNAL+5
numalias RVS_Count,RVS_VARNUM_EXTERNAL+6
numalias RVS_Cell,RVS_VARNUM_EXTERNAL+7

numalias RVS_VARNUM_INTERNAL,210
numalias RVS_Arg1,RVS_VARNUM_INTERNAL
numalias RVS_Arg2,RVS_VARNUM_INTERNAL+1
numalias RVS_Arg3,RVS_VARNUM_INTERNAL+2
numalias RVS_Tmp,RVS_VARNUM_INTERNAL+9

;// 配列
; プレイ情報 プレイヤ、CPU 色、石数
numalias RVS_Info,2
; プレイヤ、CPU
numalias RVS_PLAYER,0
numalias RVS_CPU,1
; 色、石数
numalias RVS_INFO_COLOR,0
numalias RVS_INFO_STONES,1
dim ?RVS_Info[1][1]
; ヒット可能なセル セルインデックス X座標、Y座標
numalias RVS_ValidCells,12
dim ?RVS_ValidCells[63][1]

defsub RvsInit
defsub RvsSetFormer
defsub RvsIsPlayerTurn
defsub RvsPtInBoard
defsub RvsIsValidHit
defsub RvsHitStone
defsub RvsHitStoneByPos
defsub RvsCheckFinished
defsub RvsChangeTurn
defsub RvsUpdateBoard
defsub RvsCheckWinner
defsub RvsCalcTotalValidCell
defsub RvsGetValidCellPos
defsub rvsIsHittableCell
defsub rvsCheckValidCell
defsub rvsClearValidCell
defsub rvsPushValidCell
defsub rvsGetValidCellCount

return

*RvsInit
BrdInit
SubInit
return

*RvsSetFormer
getparam %RVS_Turn,%RVS_Color
mov ?RVS_Info[%RVS_Turn][RVS_INFO_COLOR],%RVS_Color
BrdGetReverseColor %RVS_Tmp,%RVS_Color
if %RVS_Turn=RVS_PLAYER mov ?RVS_Info[RVS_CPU][RVS_INFO_COLOR],%RVS_Tmp:return
mov ?RVS_Info[RVS_PLAYER][RVS_INFO_COLOR],%RVS_Tmp
return

*RvsIsPlayerTurn
getparam i%RVS_Return
if %RVS_Turn=RVS_PLAYER mov %%RVS_Return,1:return
mov %%RVS_Return,0
return

*RvsPtInBoard
getparam i%RVS_Return,%RVS_PtX,%RVS_PtY
BrdPtInRect %%RVS_Return,%RVS_PtX,%RVS_PtY
return

*RvsIsValidHit
getparam i%RVS_Return,%RVS_PtX,%RVS_PtY
LogOutput "RvsIsValidHit"
BrdCoordToCellPos %RVS_PtX,%RVS_PtY
rvsIsHittableCell %%RVS_Return,%RVS_PtX,%RVS_PtY
return

; クリック座標で石を打つ。プレイヤー用
*RvsHitStone
getparam %RVS_PtX,%RVS_PtY
LogOutput "RvsHitStone"
BrdCoordToCellPos %RVS_PtX,%RVS_PtY
BrdSetStone ?RVS_Info[%RVS_Turn][RVS_INFO_COLOR],%RVS_PtX,%RVS_PtY
SubReverseStone ?RVS_Info[%RVS_Turn][RVS_INFO_COLOR],%RVS_PtX,%RVS_PtY
return

; セル座標で石を打つ。CPU用
*RvsHitStoneByPos
getparam %RVS_PtX,%RVS_PtY
LogOutput "RvsHitStone2"
BrdSetStone ?RVS_Info[%RVS_Turn][RVS_INFO_COLOR],%RVS_PtX,%RVS_PtY
SubReverseStone ?RVS_Info[%RVS_Turn][RVS_INFO_COLOR],%RVS_PtX,%RVS_PtY
return

*RvsCheckFinished
getparam i%RVS_Return
LogOutput "RvsCheckFinished"
BrdGetStoneCount %RVS_Count
if %RVS_Count>=64 mov %%RVS_Return,1:return
mov %%RVS_Return,0
return

*RvsChangeTurn
if %RVS_Turn=RVS_PLAYER mov %RVS_Turn,RVS_CPU:return
mov %RVS_Turn,RVS_PLAYER
return

*RvsUpdateBoard
BrdDraw
print 1
return

*RvsCheckWinner
getparam i%RVS_Return
LogOutput "RvsCheckWinner"
; プレイヤとCPUの色を集計して比較
BrdCalcCells %RVS_Tmp,?RVS_Info[RVS_PLAYER][RVS_INFO_COLOR]
mov ?RVS_Info[RVS_PLAYER][RVS_INFO_STONES],%RVS_Tmp
BrdCalcCells %RVS_Tmp,?RVS_Info[RVS_CPU][RVS_INFO_COLOR]
mov ?RVS_Info[RVS_CPU][RVS_INFO_STONES],%RVS_Tmp
if ?RVS_Info[RVS_PLAYER][RVS_INFO_STONES]=?RVS_Info[RVS_CPU][RVS_INFO_STONES] mov %%RVS_Return,RVS_DRAWGAME:return
if ?RVS_Info[RVS_PLAYER][RVS_INFO_STONES]>?RVS_Info[RVS_CPU][RVS_INFO_STONES] mov %%RVS_Return,RVS_PLAYER_WIN:return
mov %%RVS_Return,RVS_PLAYER_LOSE
return

*RvsCalcTotalValidCell
getparam i%RVS_Return
LogOutput "RvsCalcTotalValidCell"
rvsClearValidCell
for %RVS_PtY=0 to 7
	for %RVS_PtX=0 to 7
		rvsCheckValidCell %RVS_Cell,%RVS_PtX,%RVS_PtY
		if %RVS_Cell=1 rvsPushValidCell %RVS_PtX,%RVS_PtY
	next
next
rvsGetValidCellCount %%RVS_Return
return

*RvsGetValidCellPos
getparam i%RVS_PtX,i%RVS_PtY,%RVS_Cell
mov %%RVS_PtX,?RVS_ValidCells[%RVS_Cell][0]
mov %%RVS_PtY,?RVS_ValidCells[%RVS_Cell][1]
BrdDrawFocus %%RVS_PtX,%%RVS_PtY:print 1
tracexy %%RVS_PtX,%%RVS_PtY
BrdHideFocus:print 1
return

; 検証速度の速そうな順に並べる
*rvsIsHittableCell
getparam i%RVS_Arg1,%RVS_Arg2,%RVS_Arg3
LogOutput "rvsIsHittableCell"
; 石が既にある
SubIsExistStone %RVS_Tmp,%RVS_Arg2,%RVS_Arg3
if %RVS_Tmp=1 mov %%RVS_Arg1,0:return
; 隣接する石が無い
SubIsExistNeighber %RVS_Tmp,%RVS_Arg2,%RVS_Arg3
if %RVS_Tmp=0 mov %%RVS_Arg1,0:return
; 反転可能なら問題無し
SubIsExistReversibles %RVS_Tmp,?RVS_Info[%RVS_Turn][RVS_INFO_COLOR],%RVS_Arg2,%RVS_Arg3
if %RVS_Tmp=1 mov %%RVS_Arg1,1:return
traceint -9998
; 反転不可かつ反転可能な空きセルがある
SubIsExistReversibleCell %RVS_Tmp,?RVS_Info[%RVS_Turn][RVS_INFO_COLOR]
if %RVS_Tmp=1 mov %%RVS_Arg1,0:return
traceint -9999
; 反転不可かつ反転可能な空きセルが無い
mov %%RVS_Arg1,0 ; 無ければパスするため0を返す
return

*rvsCheckValidCell
getparam i%RVS_Arg1,%RVS_Arg2,%RVS_Arg3
LogOutput "rvsCheckValidCell"
; 石が既にある
SubIsExistStone %RVS_Tmp,%RVS_Arg2,%RVS_Arg3
if %RVS_Tmp=1 mov %%RVS_Arg1,0:return
; 隣接する石が無い
SubIsExistNeighber %RVS_Tmp,%RVS_Arg2,%RVS_Arg3
if %RVS_Tmp=0 mov %%RVS_Arg1,0:return
; 反転可能なら問題無し
SubIsExistReversibles %RVS_Tmp,?RVS_Info[%RVS_Turn][RVS_INFO_COLOR],%RVS_Arg2,%RVS_Arg3
if %RVS_Tmp=1 mov %%RVS_Arg1,1:return
mov %%RVS_Arg1,0
return

*rvsClearValidCell
mov %RVS_Count,0
return

*rvsPushValidCell
getparam %RVS_Arg1,%RVS_Arg2
BrdDrawFocus %RVS_Arg1,%RVS_Arg2:print 1:wait 100
;tracexy %RVS_Arg1,%RVS_Arg2
BrdHideFocus:print 1
movl ?RVS_ValidCells[%RVS_Count],%RVS_Arg1,%RVS_Arg2
inc %RVS_Count
return

*rvsGetValidCellCount
getparam i%RVS_Arg1
mov %%RVS_Arg1,%RVS_Count
return