#12 Add zone move constraints
This commit is contained in:
		
							parent
							
								
									5be2419163
								
							
						
					
					
						commit
						d0b708db62
					
				
					 1 changed files with 48 additions and 3 deletions
				
			
		|  | @ -3,6 +3,9 @@ module PatienceBoard | ||||||
| , Board (..) | , Board (..) | ||||||
| , amountOfGameStacks | , amountOfGameStacks | ||||||
| , amountOfEndingStacks | , amountOfEndingStacks | ||||||
|  | , gameStacksCoord | ||||||
|  | , endingStacksCoord | ||||||
|  | , pileCoord | ||||||
| 
 | 
 | ||||||
| , handleInputs | , handleInputs | ||||||
| , initGame | , initGame | ||||||
|  | @ -39,6 +42,20 @@ amountOfGameStacks = 7 | ||||||
| amountOfEndingStacks :: Int | amountOfEndingStacks :: Int | ||||||
| amountOfEndingStacks = 4 | amountOfEndingStacks = 4 | ||||||
| 
 | 
 | ||||||
|  | -- Coordinate of the GameStacks | ||||||
|  | gameStacksCoord :: Coordinate | ||||||
|  | gameStacksCoord = (0, 0) | ||||||
|  | 
 | ||||||
|  | -- Coordinate of the EndingStacks | ||||||
|  | endingStacksCoord :: Coordinate | ||||||
|  | endingStacksCoord = (x, 1) | ||||||
|  |     where x = amountOfGameStacks - amountOfEndingStacks | ||||||
|  | 
 | ||||||
|  | -- Coordinate of the Pile | ||||||
|  | pileCoord :: Coordinate | ||||||
|  | pileCoord = (0, 1) | ||||||
|  | 
 | ||||||
|  | -- Step size to rotate the pile of the game | ||||||
| rotateStep :: Int | rotateStep :: Int | ||||||
| rotateStep = 3 | rotateStep = 3 | ||||||
| 
 | 
 | ||||||
|  | @ -86,7 +103,7 @@ canPlayOn :: Card -> Stack -> Bool | ||||||
| canPlayOn (_,King,_) []             = True | canPlayOn (_,King,_) []             = True | ||||||
| canPlayOn (t1,v1,_)  ((t2,v2,_):cs) = differentColor && predValue | canPlayOn (t1,v1,_)  ((t2,v2,_):cs) = differentColor && predValue | ||||||
|     where differentColor = t1 /= t2 && fromEnum t1 + fromEnum t2 `elem` [1,2,4,5] |     where differentColor = t1 /= t2 && fromEnum t1 + fromEnum t2 `elem` [1,2,4,5] | ||||||
|           predValue      = fromEnum v1 + 1 == fromEnum v2 |           predValue      = succ v1 == v2 | ||||||
| canPlayOn _          _   = False | canPlayOn _          _   = False | ||||||
| 
 | 
 | ||||||
| -- Check if a card can be played ontop of an EndingStack. | -- Check if a card can be played ontop of an EndingStack. | ||||||
|  | @ -94,7 +111,7 @@ canFinishOn :: Card -> Stack -> Bool | ||||||
| canFinishOn (_,Ace,_) []             = True | canFinishOn (_,Ace,_) []             = True | ||||||
| canFinishOn (t1,v1,_) ((t2,v2,_):cs) = sameType && succValue | canFinishOn (t1,v1,_) ((t2,v2,_):cs) = sameType && succValue | ||||||
|     where sameType  = t1 == t2 |     where sameType  = t1 == t2 | ||||||
|           succValue = fromEnum v1 == fromEnum v2 + 1 |           succValue = v1 == succ v2 | ||||||
| canFinishOn _         _              = False | canFinishOn _         _              = False | ||||||
| 
 | 
 | ||||||
| -- Move a card to a GameStack. Move all the cards below the given card | -- Move a card to a GameStack. Move all the cards below the given card | ||||||
|  | @ -116,9 +133,37 @@ moveToES from to | ||||||
| 
 | 
 | ||||||
| ------------------------------ Input --------------------------------- | ------------------------------ Input --------------------------------- | ||||||
| 
 | 
 | ||||||
|  | -- Check if a coordinate is in the pile. | ||||||
|  | isInPile :: Coordinate -> Bool | ||||||
|  | isInPile = (pileCoord == ) | ||||||
|  | 
 | ||||||
|  | -- Check if a coordinate is in an endingStack. | ||||||
|  | isInEnding :: Coordinate -> Bool | ||||||
|  | isInEnding (x, y) = leftBound && rightBound && yCheck | ||||||
|  |     where leftBound  = fst endingStacksCoord <= x | ||||||
|  |           rightBound = x < amountOfGameStacks | ||||||
|  |           yCheck     = y == snd endingStacksCoord | ||||||
|  | 
 | ||||||
|  | -- Check if a coordinate is in a GameStack. | ||||||
|  | isInGame :: Coordinate -> Game -> Bool | ||||||
|  | isInGame (x, y) g = horizontalCheck && verticalCheck | ||||||
|  |     where horizontalCheck = leftBound && rightBound | ||||||
|  |           verticalCheck   = upBound && downBound | ||||||
|  |           leftBound       = fst gameStacksCoord <= x | ||||||
|  |           rightBound      = x < amountOfGameStacks | ||||||
|  |           upBound         = y <= snd gameStacksCoord | ||||||
|  |           downBound       = negate y < length (gameStacks (board g) !! x) | ||||||
|  | 
 | ||||||
|  | -- Check if moving in a direction is legal. | ||||||
|  | isLegalMove :: Direction -> Game -> Bool | ||||||
|  | isLegalMove dir g = isInPile coord || isInEnding coord || isInGame coord g | ||||||
|  |     where coord   = position $ move dir $ selector g | ||||||
|  | 
 | ||||||
| -- Move the selector of the game. (Wrapper) | -- Move the selector of the game. (Wrapper) | ||||||
| moveSelector :: Direction -> Game -> Game | moveSelector :: Direction -> Game -> Game | ||||||
| moveSelector dir g@Game{ selector = s } = g{ selector = move dir s } | moveSelector dir g@Game{ selector = s } | ||||||
|  |     | isLegalMove dir g = g{ selector = move dir s } | ||||||
|  |     | otherwise         = g | ||||||
| 
 | 
 | ||||||
| -- Toggle selector. (Wrapper) | -- Toggle selector. (Wrapper) | ||||||
| toggleSelector :: Game -> Game | toggleSelector :: Game -> Game | ||||||
|  |  | ||||||
		Reference in a new issue