Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- {-
- Written by Abai Edmund
- Version 1.0
- Last updated: 15/11/2017
- -}
- module Dom3 where
- import DomsMatch
- testBoard :: DomBoard
- testBoard = (Board (1,2) (3,4) [((2,2),P1, 1), ((2,3), P2, 2), ((3,4), P1, 3), ((1,2), P2, 4)])
- -- Helper functions to allow extracting elements from 3-tuple, history
- first (a,_,_) = a -- get the first element from a tuple
- second (_,b,_) = b -- get the second element from a tuple
- third (_,_,c) = c -- get the third element
- {-
- getDoms get all previous dominos that have been played
- -}
- getDoms :: DomBoard -> [Dom]
- getDoms (Board _ _ history) = previousDoms
- where previousDoms = map first history -- get every domino
- {-
- Guess opponents potential hand.
- - Look at previously played dominos, and discount them
- - Look at the ends, (e.g if the ends are 5 & 5 at some point and the opponent didnt play (5,5), they dont have it)
- - General rule if ends = x and the next dom played isn't (x,x) they dont have it
- -Filter all dominos that the opponent doesnt have from Domset
- -}
- --HELPER FUNCTIONS FOR GUESS OPPONENTS HAND
- {-
- LookAtEnds:
- If LeftEnd == RightEnd and the next dom played isn't (LeftEnd,RightEnd)
- return true
- True means they dont have a domino
- -}
- lookAtEnds :: DomBoard -> Bool
- lookAtEnds (Board (lEnd,_) (_,rEnd) [(dom,_,_)])
- | (lEnd == rEnd) && (dom /= (lEnd,lEnd)) = True
- | otherwise = False
- --for a domino, (a,b) if a < b then (a,b)=(b,a)
- flipDom :: Dom -> Dom
- flipDom (a,b)
- | a < b = (a,b)
- | otherwise = (b,a)
- --remove all played dominos from the predicted opponents hand
- removePlayedDoms :: DomBoard -> Hand
- removePlayedDoms b = hand
- where playedDoms = getDoms b
- hand = filter(\doms -> flipDom(doms) `notElem` playedDoms) domSet
- --remove all dominos that you have in your hand
- removeOwnDoms :: Hand->Hand-> Hand
- removeOwnDoms yourHand dominoSet = playerHand
- where playerHand = filter(\dominos -> dominos `elem` yourHand) dominoSet
- -- guess potential dominos opponent may have using lookAtEnds
- --guessDom :: DomBoard -> [Dom]
- --guessDom (Board L) = guessedDoms
- --where
- opponentsHand :: DomBoard -> Hand -> Hand
- opponentsHand b h = potentialHand
- where rmPlayedDoms = removePlayedDoms b
- potentialHand = removeOwnDoms h rmPlayedDoms
- --create tactics for smart player to use
- {-
- Check to see if player has domino 9
- -}
- {--
- First move tactic, if player has the domino (5,4) then play it
- if not then play the highest scoring domino
- --}
- --check to see if player has the domino (5,4)
- has54 :: DomBoard -> Hand -> Bool
- has54 _ [] = False
- has54 InitBoard (h:t)
- | h == (5,4) = True
- | otherwise = has54 InitBoard t
- firstMove :: DomBoard -> Hand -> (Dom,End)
- firstMove InitBoard hand
- | has54 InitBoard hand = ((5,4),L)
- | otherwise = (dom,end)
- where (dom,end,_) = hsd hand InitBoard
- {-
- playHighest
- play the highest scoring domino unless it risks the opponent scoring more
- check to see if the opponent could potentially play a high scoring dom after you play
- your hsd
- e.g if the ends are 6 and 0 and your hsd is 6,6. The opponent could play (0,3) resulting in a score of 8
- or (0,6) resulting in a score of 6 for them
- Use their potential hand to figure out if their hsd will result in them getting a higher score
- -}
- {-
- Stitch game: if you are behind your opponent and your hand is weak (low scoring)
- try and make both players knock so the game restarts
- -}
- --HELPER FUNCTIONS FOR STITCH GAME
- {-
- isPlayerKnocking - Look through a board state, the previous board state
- If two successive moves were made by the same player then one was knocking
- return true if theyre knocking
- -}
- isPlayerKnocking :: DomBoard -> Bool
- isPlayerKnocking (Board _ _ (h:t)) -- history = [(dom,player,movenum)]
- | second(h) == second(t!!0) = True
- | otherwise = False
- {-
- ReturnKPips , return all the times the opponent was knocking
- and check what will make you knock, then try to make both players knock
- -}
- returnKPips :: DomBoard -> [Int]
- returnKPips (Board (l1, r1) (l2,r2) history)
- | isPlayerKnocking (Board (l1, r1) (l2,r2) history) = [r1, l2]
- | otherwise = error "returnKPips: This shouldn't be reached"
- {-
- amILosing : if youre losing returns true
- -}
- amILosing :: Player -> Scores -> Bool
- amILosing player (score1,score2)
- | (player == P1) && (score1 < score2) = True
- | (player == P2) && (score1 > score2) = True
- | otherwise = False
- {-
- myScore: returns your score
- -}
- myScore :: Player -> Scores -> Int
- myScore player (s1,s2)
- | player == P1 = s1
- | player == P2 = s2
- {-
- scoreDiff : returns the difference between the two scores
- -}
- scoreDiff :: Scores -> Int
- scoreDiff (s1,s2)
- | s1 > s2 = s1-s2
- | otherwise = s2-s1
- {-
- isHandWeak: if you're losing and your highest scoring dom is 2 or less then
- return true. if you also dont have many dominos that score at all then return
- true
- -}
- isHandWeak :: DomBoard -> Hand -> Player -> Scores -> Bool
- isHandWeak board hand player scores
- | (highest < 3 ) && losing && myscore < 59 && scorediff > 4 = True
- | otherwise = False
- where (_,_,highest) = hsd hand board
- losing = amILosing player scores
- myscore = myScore player scores
- scorediff = scoreDiff scores
- {-
- makePlayerKnock, tries to play a domino that will make the other person knock
- -}
- makePlayerKnock :: DomBoard -> Hand -> (Dom,End)
- makePlayerKnock
- {-
- Stitch game , make both knock
- -}
- {-
- getTo59:
- if you are able to play a domino that gets 61 then play that domino,
- otherwise play a domino that can get you to 59, or as close to 59 as possiblePlays
- -}
- {-
- Evaluate risk: Function which takes the potential hand of the opponent, your hand
- the current board and checks the scores. If you can make a play that has a low risk high reward play it
- returns an integer 'risk factor'. if certain conditions are fufilled then the risk factor goes up
- if the risk is low enough, make a play. only use evaluate risk in the mid game
- For example, if the opponent has 2 dominos left and you want to play (6,6), what are the chances the opponent
- has (0,6) or (0,3). They have 2 dominos left so quite low, it might be worth the risk especially if playing (6,6)
- will put you in a better position
- -}
- --CREATE SMART PLAYER
- smartPlayer :: DomsPlayer
- smartPlayer h InitBoard p s = firstMove InitBoard h
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement