-
Notifications
You must be signed in to change notification settings - Fork 10
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Haskell implementation. Cabalized, too.
- Loading branch information
1 parent
2a11839
commit b7a458a
Showing
3 changed files
with
114 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
import Distribution.Simple | ||
main = defaultMain |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
-- SimpleRL.cabal auto-generated by cabal init. For additional | ||
-- options, see | ||
-- http://www.haskell.org/cabal/release/cabal-latest/doc/users-guide/authors.html#pkg-descr. | ||
-- The name of the package. | ||
Name: SimpleRL | ||
|
||
-- The package version. See the Haskell package versioning policy | ||
-- (http://www.haskell.org/haskellwiki/Package_versioning_policy) for | ||
-- standards guiding when and how versions should be incremented. | ||
Version: 0.1 | ||
|
||
-- A short (one-line) description of the package. | ||
Synopsis: A simple roguelike | ||
|
||
-- A longer description of the package. | ||
-- Description: | ||
|
||
-- The package author(s). | ||
Author: Ari Rahikkala | ||
|
||
-- An email address to which users can send suggestions, bug reports, | ||
-- and patches. | ||
Maintainer: ari.rahikkala@gmail.com | ||
|
||
-- A copyright notice. | ||
-- Copyright: | ||
|
||
Category: Game | ||
|
||
Build-type: Simple | ||
|
||
-- Extra files to be distributed with the package, such as examples or | ||
-- a README. | ||
-- Extra-source-files: | ||
|
||
-- Constraint on the version of Cabal needed to build this package. | ||
Cabal-version: >=1.2 | ||
|
||
|
||
Executable SimpleRL | ||
-- .hs or .lhs file containing the Main module. | ||
Main-is: SimpleRL.hs | ||
|
||
-- Packages needed in order to build this package. | ||
Build-depends: base < 5, array == 0.*, hscurses == 1.* | ||
|
||
-- Modules not exported by this package. | ||
-- Other-modules: | ||
|
||
-- Extra tools (e.g. alex, hsc2hs, ...) needed to build the source. | ||
-- Build-tools: | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
module Main where | ||
|
||
import UI.HSCurses.Curses | ||
import Data.Array.IArray | ||
|
||
type Coord = (Int, Int) | ||
|
||
gameMap :: Array Coord Char | ||
gameMap = | ||
let xs = ["#### ####", | ||
"# #### #", | ||
"# #", | ||
"## ##", | ||
" # # ", | ||
" # # ", | ||
"## ##", | ||
"# #", | ||
"# #### #", | ||
"#### ####"] in | ||
listArray ((0, 0), (length (head xs) - 1, length xs - 1)) $ concat xs | ||
|
||
-- note: Curses uses (y, x) addressing, going against all good sense, and the | ||
-- first thing any self-respecting roguelike developer should do is write a | ||
-- translation layer that returns sanity | ||
-- also, Haskell's Char represent Unicode characters in an abstract manner; | ||
-- passing through Enum probably isn't the cleanest way to convert them into | ||
-- characters as understood by Curses, but it'll work within the 7-bit ASCII | ||
-- range | ||
renderAt :: Coord -> Char -> IO () | ||
renderAt (x, y) c = | ||
mvAddCh y x (toEnum $ fromEnum c) | ||
|
||
moveIfOk f c | ||
| gameMap ! f c /= ' ' = c | ||
| otherwise = f c | ||
|
||
-- gameLoop takes the player's position as its only argument. In a more complex | ||
-- roguelike, it would take a more complex /game state/ as its argument, or | ||
-- equivalently be a computation in a state monad containing the game state. | ||
gameLoop :: Coord -> IO () | ||
gameLoop playerPosition = do | ||
mapM_ (\c -> renderAt c $ if c == playerPosition then '@' else gameMap ! c) | ||
$ range $ bounds gameMap | ||
refresh | ||
key <- getCh | ||
case key of | ||
KeyLeft -> gameLoop $ moveIfOk (\(x, y) -> (x - 1, y)) playerPosition | ||
KeyRight -> gameLoop $ moveIfOk (\(x, y) -> (x + 1, y)) playerPosition | ||
KeyDown -> gameLoop $ moveIfOk (\(x, y) -> (x, y + 1)) playerPosition | ||
KeyUp -> gameLoop $ moveIfOk (\(x, y) -> (x, y - 1)) playerPosition | ||
KeyChar 'q' -> return () | ||
_ -> gameLoop playerPosition | ||
|
||
main = do | ||
scr <- initScr | ||
keypad scr True | ||
echo False | ||
cursSet CursorInvisible | ||
gameLoop (5, 5) | ||
endWin |