Skip to content

A place for suffering and the COM2108 assignment

License

Notifications You must be signed in to change notification settings

TheLostLambda/dominos

Repository files navigation

Dominos

Coming Here From My CV?

Thanks for checking things out! Here are a couple of things that you might be particularly interested in:

Want to play against my AI?

An interactive game can be started by via stack exec dominos

Miscellaneous Notes

Should I replace pure with return?

Danger, No Danger 6 & 5; -2 : (5130,4870) 6 & 5; -1 : (5106,4894) 6 & 5; 20 : (47958,52042) 6 & 5; -1 : (50383,49617) 6 & 5; -2 : (50588,49412) 6 & 5; -3 : (50588,49412) 6 & 5; -4 : (50387,49613) 6 & 5; -5 : (50371,49629) 6 ; -2 : (50234,49766) 6,5,4; -2 : (50422,49578)

*Main AI DomsMatch Game Control.Parallel.Strategies> foldr1 (\(a,b) (x,y) -> (a+x, b+y)) $ parMap rdeepseq (domsMatch playerHFE playerHFEBM 6250) [1..16]
(48173,51827)
*Main AI DomsMatch Game Control.Parallel.Strategies> foldr1 (\(a,b) (x,y) -> (a+x, b+y)) $ parMap rdeepseq (domsMatch playerHFEBM playerHFE 6250) [1..16]
(51683,48317)

*Main AI DomsMatch Game Control.Parallel.Strategies> foldr1 (\(a,b) (x,y) -> (a+x, b+y)) $ parMap rdeepseq (domsMatch playerHFEB playerHFE 6250) [1..16]
(50588,49412)
*Main AI DomsMatch Game Control.Parallel.Strategies> foldr1 (\(a,b) (x,y) -> (a+x, b+y)) $ parMap rdeepseq (domsMatch playerHFE playerHFEB 6250) [1..16]
(49340,50660)

*Main AI DomsMatch Game Control.Parallel.Strategies> foldr1 (\(a,b) (x,y) -> (a+x, b+y)) $ parMap rdeepseq (domsMatch playerHFEBM playerHFEB 6250) [1..16]
(51059,48941)
*Main AI DomsMatch Game Control.Parallel.Strategies> foldr1 (\(a,b) (x,y) -> (a+x, b+y)) $ parMap rdeepseq (domsMatch playerHFEB playerHFEBM 6250) [1..16]
(48839,51161)
flowchart TB
    playerX(playerX :: DomsPlayer\n\n Defined by a list of Tactics)
    playerX-- "[Tactic]" -->strategy
    strategy-. DomsPlayer .-> playerX
    strategy(strategy\n\n Composes individual tactics into\nan overall strategy, returning an\n intelligent `DomsPlayer`)
    mergePlays(mergePlays\n\n Merges two play lists, summing\n the points of duplicate plays)
    strategy-- "[(Play, Points)]\n[(Play, Points)]" --> mergePlays
    mergePlays-. "[(Play, Points)]" .->strategy
    allPlays(allPlays\n\n Return all possible plays)
    strategy-- "DominoBoard\nHand" -->allPlays
    allPlays-. "[Play]" .->strategy
    strategy -->H
    H-.->strategy
    H(highScoring :: Tactic\n\n Zip each play with the\n points it would score)
    scorePlay(scorePlay\n\n Simulate a play and\n calculate its score)
    H-- "Play\nDominoBoard" -->scorePlay
    scorePlay-. Points .->H
    strategy -->F
    F-.->strategy
    F("firstDrop :: Tactic\n\n Encourage dropping (5,4)\n on the first play")
    strategy -->E
    E-.->strategy
    E("endGame :: Tactic\n\n Check if it's possible to either\nwin the game or get to 59")
    scoreN(scoreN)
    E -- "DominoBoard\nPoints" --> scoreN
    scoreN -. "[Play]" .->E
    strategy -->B
    B-.->strategy
    B("blindDanger :: Tactic\n\n Discourage dropping dangerous\n dominos if they can't be knocked off")
    strategy -->M
    M-.->strategy
    M("mostPips :: Tactic\n\n Encourage plays that expose\n pips the player controls")
    countPips(countPips\n\n Convert a list of dominos\n into a count of their pips)
    M-- "[Domino]" -->countPips
    countPips-. "[(Int, Pip)]" .->M
    newEnds(newEnds\n\n Simulate a play and return\n the new ends of the board)
    M-- "DominoBoard\nPlay" -->newEnds
    newEnds-. "[Pip]" .->M
    strategy -->S
    S-.->strategy
    S("smartDanger :: Tactic\n\n Given what the opponent\n could be holding, calculate\n the average risk of each play")
    S-->allPlays
    allPlays-.->S
    allPlays-- "Hand\nBoard" -->possPlays(possPlays)
    possPlays-. "([Domino], [Domino])" .->allPlays
    S--GameState-->otherHand
    otherHand-."Hand".-> S
    otherHand(otherHand\n\n A list of dominos that could\n be in the opponent's hand)
    knockingPips(knockingPips\n\n Builds a list of pips that\n the opponent has knocked on)
    otherHand--History\nPlayer-->knockingPips
    knockingPips-."[Pip]".-> otherHand
    S--GameState-->otherHandSize
    otherHandSize-."Int".-> S
    otherHandSize(otherHandSize\n\n Calculate the number of dominos\n the opponent is holding)
flowchart TB
    documentPlayer("documentPlayer :: DomsPlayer -> DomsPlayer\n\n A 'wrapper' player that takes an existing AI\n player and prints some information about\n its plays to the screen (so the human knows\n which moves have been played)")
    
    human("human :: DomsPlayer\n\n A `DomsPlayer` controlled by a human\n user. It prints information about the state\n of the game, then interactively asks for\n a move to play")
    showGameState("showGameState\n\n Prints the score of the current player as\n well as the score of their opponent, and\n represents the Domino board in a\n user-friendly way")
    human-- "DominoBoard\nPlayer\nScores" --> showGameState
    showGameState-. "IO ()" .-> human

    getPlay("getPlay\n\n Prints the player's current hand, with each\n domino given an index. It then reads two lines\n of input: the index of the domino to play,\n and the end (L or R) to play it on. The two\n inputs are returned as a tuple of `String`s")
    human-- "Hand\nDominoBoard" --> getPlay
    getPlay-. "IO (String, String)" .-> human

    validateChoice("validateChoice\n\n Performs a number of sanity-checks on the\n provided user-input. Checks that the index\n is an `Int`, the end is a proper `End` (L or R),\n that the index isn't too small or too big, and\n that the requested play is actually legal. Returns\n either the fully validated play or an error message")
    human-- "(String, String)\nHand\nDominoBoard" --> validateChoice
    validateChoice-. "Either String (Domino, End)" .-> human

About

A place for suffering and the COM2108 assignment

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published