diff --git a/Hangman.cabal b/Hangman.cabal
--- a/Hangman.cabal
+++ b/Hangman.cabal
@@ -2,9 +2,10 @@
 -- documentation, see http://haskell.org/cabal/users-guide/
 
 name:                Hangman
-version:             0.1.0.0
+version:             0.1.0.1
 synopsis:            The classic game of Hangman.
--- description:         
+description:         With a number of guesses you must figure out the hidden word!
+homepage:            https://github.com/lf94/Hangman
 license:             GPL-3
 license-file:        LICENSE
 author:              Lee Fallat
@@ -12,9 +13,8 @@
 -- copyright:           
 category:            Game
 build-type:          Simple
--- extra-source-files:  
+extra-source-files:  Hangman.hs Words.hs Tests.hs README.md
 cabal-version:       >=1.10
-extra-source-files:  Tests.hs README.md
 
 executable Hangman
   main-is:             Main.hs
diff --git a/Hangman.hs b/Hangman.hs
new file mode 100644
--- /dev/null
+++ b/Hangman.hs
@@ -0,0 +1,80 @@
+module Hangman where
+
+import Control.Monad.Trans.State.Lazy
+import Control.Monad.IO.Class
+
+-- | Represents if a character is discovered.
+data Letter = Hidden Char | Guessed Char
+
+-- | Represents a word made up of letters.
+type Word = [Letter]
+
+-- | The state of the Hangman game. 
+data HangmanState = HangmanState Word (Int,Int) [Char]
+
+-- | The start of the game.
+hangman :: String -> Int -> IO ()
+hangman word guesses = do
+  let word' = fmap (\x -> Hidden x) word
+  (hs, s) <- evalStateT looper (HangmanState word' (0, guesses) [])
+  showState hs
+  case s of
+   True -> putStrLn "You've won!"
+   False -> putStrLn "You've lost!"
+
+-- | An iteration of the game.
+looper ::  StateT HangmanState IO (HangmanState, Bool)
+looper = do
+  hs@(HangmanState word (guess,guesses) guessed) <- get
+  liftIO $ showState hs
+  userChar <- liftIO getChar
+  let word' = fmap (checkGuess userChar) word
+  let hs' = (HangmanState word' (guess+1,guesses) (userChar:guessed))
+  case complete word' of
+   True -> return (hs', True)
+   False -> case guess == guesses of
+     True -> return (hs', False)
+     False -> do
+       put hs'
+       looper
+
+-- | Print the state of the game.
+showState :: HangmanState -> IO()
+showState (HangmanState word (guess, guesses) guessed) = do
+  putStrLn $
+    wordToString word ++
+    " " ++
+    (show guess) ++ "/" ++ (show guesses)
+  putStrLn $
+    "Guessed:" ++ (show guessed)
+
+wordToString :: Word -> String
+wordToString = (fmap letterToChar)
+
+letterToChar :: Letter -> Char
+letterToChar l = case l of
+  Hidden x -> '_'
+  Guessed x -> x
+
+-- | Transform a Hidden character into a Guessed character.
+checkGuess :: Char -> Letter -> Letter
+checkGuess c (Hidden x)
+  | x == c = Guessed x
+checkGuess c x = x
+
+-- | Determine if we've reached the end of the game.
+endGame :: Word -> (Int,Int) -> Bool
+endGame word (guess,guesses)
+  | complete word = True
+  | guess == guesses = True
+  | otherwise = False
+
+
+-- | Determine if the word is completely guessed.
+complete :: Word -> Bool
+complete = all isGuessed
+
+isGuessed :: Letter -> Bool
+isGuessed l = case l of
+                 Hidden x -> False
+                 Guessed x -> True
diff --git a/Words.hs b/Words.hs
new file mode 100644
--- /dev/null
+++ b/Words.hs
@@ -0,0 +1,6 @@
+{-
+A giant word list ready to rock and roll.
+-}
+module Words (list) where
+
+list = [ "" ]
