; RVSのサブモジュール ; BRDの集計や判定などを行う *SUB_Define numalias SUB_TOWARD_ENUMSTART,0 numalias SUB_TOWARD_UP,0 numalias SUB_TOWARD_RIGHTUP,1 numalias SUB_TOWARD_RIGHT,2 numalias SUB_TOWARD_RIGHTDOWN,3 numalias SUB_TOWARD_DOWN,4 numalias SUB_TOWARD_LEFTDOWN,5 numalias SUB_TOWARD_LEFT,6 numalias SUB_TOWARD_LEFTUP,7 numalias SUB_TOWARD_ENUMEND,7 numalias SUB_NOTREVERSIBLE,0 numalias SUB_REVERSIBLE,1 defsub SubInit defsub SubIsExistStone defsub SubIsExistNeighber defsub SubIsExistReversibles defsub SubIsExistReversibleCell defsub SubReverseStone defsub subCheckReversibleAllWards numalias SUB_VARNUM_EXTERNAL,400 numalias SUB_Loop,SUB_VARNUM_EXTERNAL numalias SUB_Return,SUB_VARNUM_EXTERNAL+1 numalias SUB_PosX,SUB_VARNUM_EXTERNAL+2 numalias SUB_PosY,SUB_VARNUM_EXTERNAL+3 numalias SUB_Color,SUB_VARNUM_EXTERNAL+4 numalias SUB_ReverseColor,SUB_VARNUM_EXTERNAL+5 numalias SUB_PosX2,SUB_VARNUM_EXTERNAL+6 numalias SUB_PosY2,SUB_VARNUM_EXTERNAL+7 numalias SUB_Count,SUB_VARNUM_EXTERNAL+8 numalias SUB_VARNUM_INTERNAL,410 numalias SUB_Arg1,SUB_VARNUM_INTERNAL numalias SUB_Arg2,SUB_VARNUM_INTERNAL+1 numalias SUB_Arg3,SUB_VARNUM_INTERNAL+2 numalias SUB_Arg4,SUB_VARNUM_INTERNAL+3 numalias SUB_Arg5,SUB_VARNUM_INTERNAL+4 numalias SUB_Arg6,SUB_VARNUM_INTERNAL+5 numalias SUB_Arg7,SUB_VARNUM_INTERNAL+6 numalias SUB_Arg8,SUB_VARNUM_INTERNAL+7 numalias SUB_Arg9,SUB_VARNUM_INTERNAL+8 numalias SUB_Tmp,SUB_VARNUM_INTERNAL+9 ; 方向の状態 方向 X差分、Y差分、X終端、Y終端、反転可否 numalias SUB_Towards,4 dim ?SUB_Towards[SUB_TOWARD_ENUMEND][4] return *SubInit movl ?SUB_Towards[SUB_TOWARD_UP],0,-1,0,0,SUB_NOTREVERSIBLE movl ?SUB_Towards[SUB_TOWARD_RIGHTUP],1,-1,7,0,SUB_NOTREVERSIBLE movl ?SUB_Towards[SUB_TOWARD_RIGHT],1,0,7,0,SUB_NOTREVERSIBLE movl ?SUB_Towards[SUB_TOWARD_RIGHTDOWN],1,1,7,7,SUB_NOTREVERSIBLE movl ?SUB_Towards[SUB_TOWARD_DOWN],0,1,0,7,SUB_NOTREVERSIBLE movl ?SUB_Towards[SUB_TOWARD_LEFTDOWN],-1,1,0,7,SUB_NOTREVERSIBLE movl ?SUB_Towards[SUB_TOWARD_LEFT],-1,0,0,0,SUB_NOTREVERSIBLE movl ?SUB_Towards[SUB_TOWARD_LEFTUP],-1,-1,0,0,SUB_NOTREVERSIBLE return ; Xが返ってきたらアボート *SubIsExistStone getparam i%SUB_Return,%SUB_PosX,%SUB_PosY BrdIsExistStone %%SUB_Return,%SUB_PosX,%SUB_PosY return *SubIsExistNeighber getparam i%SUB_Return,%SUB_PosX,%SUB_PosY mov %%SUB_Return,0 for %SUB_Loop=SUB_TOWARD_ENUMSTART to SUB_TOWARD_ENUMEND BrdIsExistStone %SUB_Tmp,%SUB_PosX+?SUB_Towards[%SUB_Loop][0],%SUB_PosY+?SUB_Towards[%SUB_Loop][1] if %SUB_Tmp=1 mov %%SUB_Return,1:break next return ; 反転可能な方向が一つでもあればOK ; 時計回りにチェックしているが、特に意味は無い *SubIsExistReversibles getparam i%SUB_Return,%SUB_Color,%SUB_PosX,%SUB_PosY subCheckReversibleAllWards %%SUB_Return,%SUB_Color,%SUB_PosX,%SUB_PosY return *sub_PushCheckCellProc xyloopct %SUB_PosX2,%SUB_PosY2 BrdGetStone %SUB_Tmp,%SUB_PosX2,%SUB_PosY2 if %SUB_Tmp=X xyloopbreak:return if %SUB_Tmp=N xyloopbreak:return BrdPushCheckCell %SUB_Tmp return ; 反転可能な空きセルがあるかどうか ; ヒットセルが反転不可能な場合のみ呼ばれる *SubIsExistReversibleCell getparam i%SUB_Return,%SUB_Color mov %%SUB_Return,0 ; 全セルを調べる for %SUB_PosY=0 to 7 for %SUB_PosX=0 to 7 ; 空きセルでなければ調べる意味なし BrdIsExistStone %SUB_Tmp,%SUB_PosX,%SUB_PosY if %SUB_Tmp=0 subCheckReversibleAllWards %%SUB_Return,%SUB_Color,%SUB_PosX,%SUB_PosY if %%SUB_Return=1:break next if %%SUB_Return=1:break next return ; ひっくり返す *SubReverseStone getparam %SUB_Color,%SUB_PosX,%SUB_PosY BrdGetReverseColor %SUB_ReverseColor,%SUB_Color ; 各方向で反転可能かどうかを調べる for %SUB_Loop=SUB_TOWARD_ENUMSTART to SUB_TOWARD_ENUMEND BrdClearCheckCell ; 各方向のセル内容を列として登録する xyloop *sub_PushCheckCellProc,%SUB_PosX+?SUB_Towards[%SUB_Loop][0],%SUB_PosY+?SUB_Towards[%SUB_Loop][1],?SUB_Towards[%SUB_Loop][2],?SUB_Towards[%SUB_Loop][3],?SUB_Towards[%SUB_Loop][0],?SUB_Towards[%SUB_Loop][1] ; 反転数が1以上なら反転可能を登録する BrdCheckReverse %SUB_Count,%SUB_Color,%SUB_ReverseColor if %SUB_Count>0 mov ?SUB_Towards[%SUB_Loop][4],SUB_REVERSIBLE:skip 2 mov ?SUB_Towards[%SUB_Loop][4],SUB_NOTREVERSIBLE next ; 反転する for %SUB_Loop=SUB_TOWARD_ENUMSTART to SUB_TOWARD_ENUMEND if ?SUB_Towards[%SUB_Loop][4]=SUB_REVERSIBLE xyloop *sub_ReverseProc,%SUB_PosX+?SUB_Towards[%SUB_Loop][0],%SUB_PosY+?SUB_Towards[%SUB_Loop][1],?SUB_Towards[%SUB_Loop][2],?SUB_Towards[%SUB_Loop][3],?SUB_Towards[%SUB_Loop][0],?SUB_Towards[%SUB_Loop][1] next return *sub_ReverseProc xyloopct %SUB_PosX2,%SUB_PosY2 BrdGetStone %SUB_Tmp,%SUB_PosX2,%SUB_PosY2 if %SUB_Tmp=%SUB_ReverseColor BrdReverseStone %SUB_Color,%SUB_PosX2,%SUB_PosY2:return ; 反対色以外はブレーク xyloopbreak return ; どこか一つでも存在した場合は1を返す *subCheckReversibleAllWards getparam i%SUB_Arg1,%SUB_Arg2,%SUB_Arg3,%SUB_Arg4 mov %%SUB_Arg1,0 BrdGetReverseColor %SUB_Arg5,%SUB_Arg2 ; 各方向で反転可能かどうかを調べる ; Arg1 - Arg5 は不変なので注意 for %SUB_Loop=SUB_TOWARD_ENUMSTART to SUB_TOWARD_ENUMEND ; 各方向のセル内容を列として探索する mov %SUB_Count,0:mov %SUB_Arg9,0 xyloop *sub_CheckReversibleAWProc,%SUB_Arg3+?SUB_Towards[%SUB_Loop][0],%SUB_Arg4+?SUB_Towards[%SUB_Loop][1],?SUB_Towards[%SUB_Loop][2],?SUB_Towards[%SUB_Loop][3],?SUB_Towards[%SUB_Loop][0],?SUB_Towards[%SUB_Loop][1] ; 反転数が1以上なら反転可能を返す if %SUB_Count>0 mov %%SUB_Arg1,1:break next return *sub_CheckReversibleAWProc xyloopct %SUB_Arg6,%SUB_Arg7 BrdGetStone %SUB_Arg8,%SUB_Arg6,%SUB_Arg7 ;if %SUB_Arg3=7 & %SUB_Arg4=5 tracexy %SUB_Arg6,%SUB_Arg7 ; 連続する反対色の数をチェック if %SUB_Arg8=%SUB_Arg5 inc %SUB_Arg9:return ; 同色かつ反対色の連続があればOK if %SUB_Arg8=%SUB_Arg2 & %SUB_Arg9>0 mov %SUB_Count,%SUB_Arg9:xyloopbreak:return ; それ以外はNGでブレーク mov %SUB_Arg9,0 xyloopbreak return