module BoardOperater ( getTurnStone ,opTurn ,opStone ,dEndGame ,existPuttableCell ,dPuttableCell ,dEmptyCell ,bCellsList ,eightList ,putStone ,numberStone ) where import Graphics.Rendering.OpenGL import Graphics.UI.GLUT import States import VectorMaps import Control.Applicative import qualified Data.Map as Map import EventFlags (eventMState) import EventCheck (eventResetCheck) import ResionMap import SetValue (resetMState) import System.Random import General (listRandomSelect) -----ターンに対応する石の取得 getTurnStone :: MState -> GameTurn -> GStone getTurnStone mst gturn = case gturn of Turn1P -> playerStone mst Turn2P -> opStone (playerStone mst) -----ターンの交換 opTurn :: GameTurn -> GameTurn opTurn gturn = case gturn of Turn1P -> Turn2P Turn2P -> Turn1P -----反対の色の石 opStone :: GStone -> GStone opStone gs = case gs of SWhite -> SBlack SBlack -> SWhite ------ゲーム終了の判定 dEndGame :: MState -> GBoardCells -> Bool dEndGame mst gbcs = not ((existPuttableCell mst SWhite gbcs) && (existPuttableCell mst SBlack gbcs)) -----プット可能セルが存在するか existPuttableCell :: MState -> GStone -> GBoardCells -> Bool existPuttableCell mst s gbcs = foldl (||) False (map (dPuttableCell s gbcs) (bCellsList mst)) -----プット可能セルであるか dPuttableCell :: GStone -> GBoardCells -> (Vector2 GLint) -> Bool dPuttableCell s gbcs cPos = (dReversi s gbcs cPos) && (dEmptyCell gbcs cPos) -----空セルであるか dEmptyCell :: GBoardCells -> (Vector2 GLint) -> Bool dEmptyCell gbcs cPos = not (Map.member cPos gbcs) -----方向ベクトルへの返す石のチェックするためのリストを返す (再帰) dReversiDList :: GStone -> GBoardCells -> (Vector2 GLint) -> (Vector2 GLint) -> [GStone] dReversiDList s gbcs v cPos = let newPos = (+) <$> v <*> cPos in case Map.lookup newPos gbcs of Just x -> if x == s then [s] else (opStone s) : (dReversiDList s gbcs v newPos) _ -> [] -----方向ベクトルへの返す石のチェックする dReversiD :: GStone -> GBoardCells -> (Vector2 GLint) -> (Vector2 GLint) -> Bool dReversiD s gbcs v cPos = let checkListD = dReversiDList s gbcs v cPos in if (length checkListD) < 2 then False else if (last checkListD) == s then True else False -----ボード全体のセル bCellsList :: MState -> [(Vector2 GLint)] bCellsList mst = let w = divBoardNumX mst h = divBoardNumY mst in [(Vector2 i j) | i <- [0..(w - 1)] , j <- [0..(h - 1)]] -----8方向のベクトル eightList :: [(Vector2 GLint)] eightList = [(Vector2 i j) | i <- [(-1) .. 1] , j <- [(-1) .. 1] , (i , j) /= (0 , 0)] -----8方向のベクトルへの返す石のチェックする dReversi :: GStone -> GBoardCells -> (Vector2 GLint) -> Bool dReversi s gbcs cPos = let allCheckList = map ((flip (dReversiD s gbcs)) cPos) eightList in foldl (||) False allCheckList ------方向ベクトルへ石を返す(再帰) reverseStoneD :: GStone -> GBoardCells -> (Vector2 GLint) -> (Vector2 GLint) -> GBoardCells reverseStoneD s gbcs v cPos = if dReversiD s gbcs v cPos then let newPos = (+) <$> v <*> cPos in case Map.lookup newPos gbcs of Just x -> if x == s then gbcs else reverseStoneD s (Map.insert newPos s gbcs) v newPos _ -> gbcs else gbcs ------石を返す reverseStone :: GStone -> GBoardCells -> (Vector2 GLint) -> GBoardCells reverseStone s gbcs cPos = reverseStone' s gbcs cPos eightList ------石を返す (再帰) reverseStone' :: GStone -> GBoardCells -> (Vector2 GLint) -> [(Vector2 GLint)] -> GBoardCells reverseStone' _ gbcs _ [] = gbcs reverseStone' s gbcs cPos (a : as) = reverseStone' s (reverseStoneD s gbcs a cPos) cPos as ------石を置く処理 putStone :: GStone -> GBoardCells -> (Vector2 GLint) -> GBoardCells putStone s gbcs cPos = (Map.insert cPos s (reverseStone s gbcs cPos)) ------石の個数を数える numberStone :: GStone -> GBoardCells -> GLint numberStone s gbcs = let filteredgbcs = Map.filter (== s) gbcs in fromIntegral (Map.size filteredgbcs)