Repository files navigation

Coxygen Global Haskell Plutus

Marathon

BouncingBall Game

Marathon—as opposed to what I call a Hackathon—is a small app created in order to apply skills learned in a chapter. It must be a little working mock app for real world applications.

It must be working, have tests, and tutorials so that others can use it as a learning tool, and so the Marathon developer can use it for interviews or job applications. It must be extendable to MVP and eventually can be deployed in production for commercial purposes.

Why Marathons? I have been invited to Hackathons on Haskell Plutus but did not have the background to compete with other developers who had done Haskell for years, and I lost. It alienated me. A Marathon, like common athletics marathons, is a team/group coding exercise as opposed to uneven or unfair competition. All Coxygen Haskell Marathon participants must be rewarded, and this helps prepare them for Hackathons.

Authors

A fun and extensible bouncing ball and shooter game written in Haskell, using the Gloss library for graphics and animation.


Features

  • Multiple bouncing balls with random motion and wall collisions
  • Keyboard-controlled shooter that can move, rotate, and fire bullets
  • Customizable environment: window size, ball count, ball speed, etc.
  • Optional trajectory logging

Directory Structure

BouncingBall/
│
├── src/
│ ├── Animation/
│ │ ├── Animation_Draw.md # Docs for Draw.hs
│ │ ├── Animation_Environment.md # Docs for Environment.hs
│ │ ├── Animation_Game.md # Docs for Game.hs
│ │ ├── Animation_Init.md # Docs for Init.hs
│ │ ├── Animation_Input.md # Docs for Input.hs
│ │ ├── Animation_State.md # Docs for State.hs
│ │ ├── Draw.hs
│ │ ├── Environment.hs
│ │ ├── Game.hs
│ │ ├── Init.hs
│ │ ├── Input.hs
│ │ └── State.hs
│ ├── Main.hs
│ └── Main.md # Docs for Main.hs
│
├── test/
│ ├── AllTests.hs # Main test runner (entry point)
│ ├── TestDraw.hs
│ ├── TestDraw.md
│ ├── TestEnvironment.hs
│ ├── TestEnvironment.md
│ ├── TestGame.hs
│ ├── TestGame.md
│ ├── TestInit.hs
│ ├── TestInit.md
│ ├── TestInput.hs
│ ├── TestInput.md
│ ├── TestState.hs
│ └── TestState.md
│
├── ball_log.txt # Gameplay logs
├── board and balls.png # Game assets/screenshot
├── BouncingBall.cabal # Cabal build config
├── BouncingBall.zip # (Optional) compressed archive
├── cabal.project.local # Local cabal project settings
├── CHANGELOG.md # Project changelog
├── log.txt # Log file
├── README.md # Project documentation (this file)

Prerequisites


Installation

  1. Clone the repository:

    git clone <your-repo-url>cd BouncingBall
  2. Install dependencies:

    cabal update
    cabal install --only-dependencies
  3. Build the project:

    cabal build

Running the Game

  • From Cabal:

    cabal run
  • Or directly with GHC:

    cd src
    ghc -isrc Main.hs -o bouncingball
    ./bouncingball
  • Customize your session: At startup, the game will prompt you to set window size, ball size, speed, count, and other parameters.


Running the Tests

To run all tests:

cabal test# Or manually:cdtest
ghc -itest -isrc AllTests.hs -o runtests
./runtests

Controls

  • Arrow keys (, ): Move/rotate the shooter
  • Space: Shoot a bullet
  • Q or window close: Exit the game

Extending

All major logic is organized in modules within src/Animation/. See the tutorials for each module to understand or extend each component!


I am inviting Haskell Students to use this to add these features:

  • sounds: bullets fired, exploding balls hit by bullets, stage and levels changing
  • dashboard with counters and scores
  • enemies and hurdles
  • props changes
  • distributed peer to peer game
  • add hydra technologies
  • ada incentives and betting
  • blockchain Cardano features
  • etc… move from learning to earning ADA!


About

This is Coxygen Global Haskell Plutus Example Marathon

Resources

Stars

3 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Repository files navigation

Coxygen Global Haskell Plutus

Marathon

BouncingBall Game

Marathon—as opposed to what I call a Hackathon—is a small app created in order to apply skills learned in a chapter. It must be a little working mock app for real world applications.

It must be working, have tests, and tutorials so that others can use it as a learning tool, and so the Marathon developer can use it for interviews or job applications. It must be extendable to MVP and eventually can be deployed in production for commercial purposes.

Why Marathons? I have been invited to Hackathons on Haskell Plutus but did not have the background to compete with other developers who had done Haskell for years, and I lost. It alienated me. A Marathon, like common athletics marathons, is a team/group coding exercise as opposed to uneven or unfair competition. All Coxygen Haskell Marathon participants must be rewarded, and this helps prepare them for Hackathons.

Authors

A fun and extensible bouncing ball and shooter game written in Haskell, using the Gloss library for graphics and animation.


Features

  • Multiple bouncing balls with random motion and wall collisions
  • Keyboard-controlled shooter that can move, rotate, and fire bullets
  • Customizable environment: window size, ball count, ball speed, etc.
  • Optional trajectory logging

Directory Structure

BouncingBall/
│
├── src/
│ ├── Animation/
│ │ ├── Animation_Draw.md # Docs for Draw.hs
│ │ ├── Animation_Environment.md # Docs for Environment.hs
│ │ ├── Animation_Game.md # Docs for Game.hs
│ │ ├── Animation_Init.md # Docs for Init.hs
│ │ ├── Animation_Input.md # Docs for Input.hs
│ │ ├── Animation_State.md # Docs for State.hs
│ │ ├── Draw.hs
│ │ ├── Environment.hs
│ │ ├── Game.hs
│ │ ├── Init.hs
│ │ ├── Input.hs
│ │ └── State.hs
│ ├── Main.hs
│ └── Main.md # Docs for Main.hs
│
├── test/
│ ├── AllTests.hs # Main test runner (entry point)
│ ├── TestDraw.hs
│ ├── TestDraw.md
│ ├── TestEnvironment.hs
│ ├── TestEnvironment.md
│ ├── TestGame.hs
│ ├── TestGame.md
│ ├── TestInit.hs
│ ├── TestInit.md
│ ├── TestInput.hs
│ ├── TestInput.md
│ ├── TestState.hs
│ └── TestState.md
│
├── ball_log.txt # Gameplay logs
├── board and balls.png # Game assets/screenshot
├── BouncingBall.cabal # Cabal build config
├── BouncingBall.zip # (Optional) compressed archive
├── cabal.project.local # Local cabal project settings
├── CHANGELOG.md # Project changelog
├── log.txt # Log file
├── README.md # Project documentation (this file)

Prerequisites


Installation

  1. Clone the repository:

    git clone <your-repo-url>cd BouncingBall
  2. Install dependencies:

    cabal update
    cabal install --only-dependencies
  3. Build the project:

    cabal build

Running the Game

  • From Cabal:

    cabal run
  • Or directly with GHC:

    cd src
    ghc -isrc Main.hs -o bouncingball
    ./bouncingball
  • Customize your session: At startup, the game will prompt you to set window size, ball size, speed, count, and other parameters.


Running the Tests

To run all tests:

cabal test# Or manually:cdtest
ghc -itest -isrc AllTests.hs -o runtests
./runtests

Controls

  • Arrow keys (, ): Move/rotate the shooter
  • Space: Shoot a bullet
  • Q or window close: Exit the game

Extending

All major logic is organized in modules within src/Animation/. See the tutorials for each module to understand or extend each component!


I am inviting Haskell Students to use this to add these features:

  • sounds: bullets fired, exploding balls hit by bullets, stage and levels changing
  • dashboard with counters and scores
  • enemies and hurdles
  • props changes
  • distributed peer to peer game
  • add hydra technologies
  • ada incentives and betting
  • blockchain Cardano features
  • etc… move from learning to earning ADA!


About

This is Coxygen Global Haskell Plutus Example Marathon

Resources

Stars

3 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

Coxygen Global Haskell Plutus

Marathon

BouncingBall Game

Marathon—as opposed to what I call a Hackathon—is a small app created in order to apply skills learned in a chapter. It must be a little working mock app for real world applications.

It must be working, have tests, and tutorials so that others can use it as a learning tool, and so the Marathon developer can use it for interviews or job applications. It must be extendable to MVP and eventually can be deployed in production for commercial purposes.

Why Marathons? I have been invited to Hackathons on Haskell Plutus but did not have the background to compete with other developers who had done Haskell for years, and I lost. It alienated me. A Marathon, like common athletics marathons, is a team/group coding exercise as opposed to uneven or unfair competition. All Coxygen Haskell Marathon participants must be rewarded, and this helps prepare them for Hackathons.

Authors

A fun and extensible bouncing ball and shooter game written in Haskell, using the Gloss library for graphics and animation.


Features

  • Multiple bouncing balls with random motion and wall collisions
  • Keyboard-controlled shooter that can move, rotate, and fire bullets
  • Customizable environment: window size, ball count, ball speed, etc.
  • Optional trajectory logging

Directory Structure

BouncingBall/
│
├── src/
│ ├── Animation/
│ │ ├── Animation_Draw.md # Docs for Draw.hs
│ │ ├── Animation_Environment.md # Docs for Environment.hs
│ │ ├── Animation_Game.md # Docs for Game.hs
│ │ ├── Animation_Init.md # Docs for Init.hs
│ │ ├── Animation_Input.md # Docs for Input.hs
│ │ ├── Animation_State.md # Docs for State.hs
│ │ ├── Draw.hs
│ │ ├── Environment.hs
│ │ ├── Game.hs
│ │ ├── Init.hs
│ │ ├── Input.hs
│ │ └── State.hs
│ ├── Main.hs
│ └── Main.md # Docs for Main.hs
│
├── test/
│ ├── AllTests.hs # Main test runner (entry point)
│ ├── TestDraw.hs
│ ├── TestDraw.md
│ ├── TestEnvironment.hs
│ ├── TestEnvironment.md
│ ├── TestGame.hs
│ ├── TestGame.md
│ ├── TestInit.hs
│ ├── TestInit.md
│ ├── TestInput.hs
│ ├── TestInput.md
│ ├── TestState.hs
│ └── TestState.md
│
├── ball_log.txt # Gameplay logs
├── board and balls.png # Game assets/screenshot
├── BouncingBall.cabal # Cabal build config
├── BouncingBall.zip # (Optional) compressed archive
├── cabal.project.local # Local cabal project settings
├── CHANGELOG.md # Project changelog
├── log.txt # Log file
├── README.md # Project documentation (this file)

Prerequisites


Installation

  1. Clone the repository:

    git clone <your-repo-url>cd BouncingBall
  2. Install dependencies:

    cabal update
    cabal install --only-dependencies
  3. Build the project:

    cabal build

Running the Game

  • From Cabal:

    cabal run
  • Or directly with GHC:

    cd src
    ghc -isrc Main.hs -o bouncingball
    ./bouncingball
  • Customize your session: At startup, the game will prompt you to set window size, ball size, speed, count, and other parameters.


Running the Tests

To run all tests:

cabal test# Or manually:cdtest
ghc -itest -isrc AllTests.hs -o runtests
./runtests

Controls

  • Arrow keys (, ): Move/rotate the shooter
  • Space: Shoot a bullet
  • Q or window close: Exit the game

Extending

All major logic is organized in modules within src/Animation/. See the tutorials for each module to understand or extend each component!


I am inviting Haskell Students to use this to add these features:

  • sounds: bullets fired, exploding balls hit by bullets, stage and levels changing
  • dashboard with counters and scores
  • enemies and hurdles
  • props changes
  • distributed peer to peer game
  • add hydra technologies
  • ada incentives and betting
  • blockchain Cardano features
  • etc… move from learning to earning ADA!


About

This is Coxygen Global Haskell Plutus Example Marathon

Resources

Stars

3 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

Coxygen Global Haskell Plutus

Marathon

BouncingBall Game

Marathon—as opposed to what I call a Hackathon—is a small app created in order to apply skills learned in a chapter. It must be a little working mock app for real world applications.

It must be working, have tests, and tutorials so that others can use it as a learning tool, and so the Marathon developer can use it for interviews or job applications. It must be extendable to MVP and eventually can be deployed in production for commercial purposes.

Why Marathons? I have been invited to Hackathons on Haskell Plutus but did not have the background to compete with other developers who had done Haskell for years, and I lost. It alienated me. A Marathon, like common athletics marathons, is a team/group coding exercise as opposed to uneven or unfair competition. All Coxygen Haskell Marathon participants must be rewarded, and this helps prepare them for Hackathons.

Authors

A fun and extensible bouncing ball and shooter game written in Haskell, using the Gloss library for graphics and animation.


Features

  • Multiple bouncing balls with random motion and wall collisions
  • Keyboard-controlled shooter that can move, rotate, and fire bullets
  • Customizable environment: window size, ball count, ball speed, etc.
  • Optional trajectory logging

Directory Structure

BouncingBall/
│
├── src/
│ ├── Animation/
│ │ ├── Animation_Draw.md # Docs for Draw.hs
│ │ ├── Animation_Environment.md # Docs for Environment.hs
│ │ ├── Animation_Game.md # Docs for Game.hs
│ │ ├── Animation_Init.md # Docs for Init.hs
│ │ ├── Animation_Input.md # Docs for Input.hs
│ │ ├── Animation_State.md # Docs for State.hs
│ │ ├── Draw.hs
│ │ ├── Environment.hs
│ │ ├── Game.hs
│ │ ├── Init.hs
│ │ ├── Input.hs
│ │ └── State.hs
│ ├── Main.hs
│ └── Main.md # Docs for Main.hs
│
├── test/
│ ├── AllTests.hs # Main test runner (entry point)
│ ├── TestDraw.hs
│ ├── TestDraw.md
│ ├── TestEnvironment.hs
│ ├── TestEnvironment.md
│ ├── TestGame.hs
│ ├── TestGame.md
│ ├── TestInit.hs
│ ├── TestInit.md
│ ├── TestInput.hs
│ ├── TestInput.md
│ ├── TestState.hs
│ └── TestState.md
│
├── ball_log.txt # Gameplay logs
├── board and balls.png # Game assets/screenshot
├── BouncingBall.cabal # Cabal build config
├── BouncingBall.zip # (Optional) compressed archive
├── cabal.project.local # Local cabal project settings
├── CHANGELOG.md # Project changelog
├── log.txt # Log file
├── README.md # Project documentation (this file)

Prerequisites


Installation

  1. Clone the repository:

    git clone <your-repo-url>cd BouncingBall
  2. Install dependencies:

    cabal update
    cabal install --only-dependencies
  3. Build the project:

    cabal build

Running the Game

  • From Cabal:

    cabal run
  • Or directly with GHC:

    cd src
    ghc -isrc Main.hs -o bouncingball
    ./bouncingball
  • Customize your session: At startup, the game will prompt you to set window size, ball size, speed, count, and other parameters.


Running the Tests

To run all tests:

cabal test# Or manually:cdtest
ghc -itest -isrc AllTests.hs -o runtests
./runtests

Controls

  • Arrow keys (, ): Move/rotate the shooter
  • Space: Shoot a bullet
  • Q or window close: Exit the game

Extending

All major logic is organized in modules within src/Animation/. See the tutorials for each module to understand or extend each component!


I am inviting Haskell Students to use this to add these features:

  • sounds: bullets fired, exploding balls hit by bullets, stage and levels changing
  • dashboard with counters and scores
  • enemies and hurdles
  • props changes
  • distributed peer to peer game
  • add hydra technologies
  • ada incentives and betting
  • blockchain Cardano features
  • etc… move from learning to earning ADA!


About

This is Coxygen Global Haskell Plutus Example Marathon

Resources

Stars

3 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Repository files navigation

Coxygen Global Haskell Plutus

Marathon

BouncingBall Game

Marathon—as opposed to what I call a Hackathon—is a small app created in order to apply skills learned in a chapter. It must be a little working mock app for real world applications.

It must be working, have tests, and tutorials so that others can use it as a learning tool, and so the Marathon developer can use it for interviews or job applications. It must be extendable to MVP and eventually can be deployed in production for commercial purposes.

Why Marathons? I have been invited to Hackathons on Haskell Plutus but did not have the background to compete with other developers who had done Haskell for years, and I lost. It alienated me. A Marathon, like common athletics marathons, is a team/group coding exercise as opposed to uneven or unfair competition. All Coxygen Haskell Marathon participants must be rewarded, and this helps prepare them for Hackathons.

Authors

A fun and extensible bouncing ball and shooter game written in Haskell, using the Gloss library for graphics and animation.


Features

  • Multiple bouncing balls with random motion and wall collisions
  • Keyboard-controlled shooter that can move, rotate, and fire bullets
  • Customizable environment: window size, ball count, ball speed, etc.
  • Optional trajectory logging

Directory Structure

BouncingBall/
│
├── src/
│ ├── Animation/
│ │ ├── Animation_Draw.md # Docs for Draw.hs
│ │ ├── Animation_Environment.md # Docs for Environment.hs
│ │ ├── Animation_Game.md # Docs for Game.hs
│ │ ├── Animation_Init.md # Docs for Init.hs
│ │ ├── Animation_Input.md # Docs for Input.hs
│ │ ├── Animation_State.md # Docs for State.hs
│ │ ├── Draw.hs
│ │ ├── Environment.hs
│ │ ├── Game.hs
│ │ ├── Init.hs
│ │ ├── Input.hs
│ │ └── State.hs
│ ├── Main.hs
│ └── Main.md # Docs for Main.hs
│
├── test/
│ ├── AllTests.hs # Main test runner (entry point)
│ ├── TestDraw.hs
│ ├── TestDraw.md
│ ├── TestEnvironment.hs
│ ├── TestEnvironment.md
│ ├── TestGame.hs
│ ├── TestGame.md
│ ├── TestInit.hs
│ ├── TestInit.md
│ ├── TestInput.hs
│ ├── TestInput.md
│ ├── TestState.hs
│ └── TestState.md
│
├── ball_log.txt # Gameplay logs
├── board and balls.png # Game assets/screenshot
├── BouncingBall.cabal # Cabal build config
├── BouncingBall.zip # (Optional) compressed archive
├── cabal.project.local # Local cabal project settings
├── CHANGELOG.md # Project changelog
├── log.txt # Log file
├── README.md # Project documentation (this file)

Prerequisites


Installation

  1. Clone the repository:

    git clone <your-repo-url>cd BouncingBall
  2. Install dependencies:

    cabal update
    cabal install --only-dependencies
  3. Build the project:

    cabal build

Running the Game

  • From Cabal:

    cabal run
  • Or directly with GHC:

    cd src
    ghc -isrc Main.hs -o bouncingball
    ./bouncingball
  • Customize your session: At startup, the game will prompt you to set window size, ball size, speed, count, and other parameters.


Running the Tests

To run all tests:

cabal test# Or manually:cdtest
ghc -itest -isrc AllTests.hs -o runtests
./runtests

Controls

  • Arrow keys (, ): Move/rotate the shooter
  • Space: Shoot a bullet
  • Q or window close: Exit the game

Extending

All major logic is organized in modules within src/Animation/. See the tutorials for each module to understand or extend each component!


I am inviting Haskell Students to use this to add these features:

  • sounds: bullets fired, exploding balls hit by bullets, stage and levels changing
  • dashboard with counters and scores
  • enemies and hurdles
  • props changes
  • distributed peer to peer game
  • add hydra technologies
  • ada incentives and betting
  • blockchain Cardano features
  • etc… move from learning to earning ADA!


About

This is Coxygen Global Haskell Plutus Example Marathon

Resources

Stars

3 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

Coxygen Global Haskell Plutus

Marathon

BouncingBall Game

Marathon—as opposed to what I call a Hackathon—is a small app created in order to apply skills learned in a chapter. It must be a little working mock app for real world applications.

It must be working, have tests, and tutorials so that others can use it as a learning tool, and so the Marathon developer can use it for interviews or job applications. It must be extendable to MVP and eventually can be deployed in production for commercial purposes.

Why Marathons? I have been invited to Hackathons on Haskell Plutus but did not have the background to compete with other developers who had done Haskell for years, and I lost. It alienated me. A Marathon, like common athletics marathons, is a team/group coding exercise as opposed to uneven or unfair competition. All Coxygen Haskell Marathon participants must be rewarded, and this helps prepare them for Hackathons.

Authors

A fun and extensible bouncing ball and shooter game written in Haskell, using the Gloss library for graphics and animation.


Features

  • Multiple bouncing balls with random motion and wall collisions
  • Keyboard-controlled shooter that can move, rotate, and fire bullets
  • Customizable environment: window size, ball count, ball speed, etc.
  • Optional trajectory logging

Directory Structure

BouncingBall/
│
├── src/
│ ├── Animation/
│ │ ├── Animation_Draw.md # Docs for Draw.hs
│ │ ├── Animation_Environment.md # Docs for Environment.hs
│ │ ├── Animation_Game.md # Docs for Game.hs
│ │ ├── Animation_Init.md # Docs for Init.hs
│ │ ├── Animation_Input.md # Docs for Input.hs
│ │ ├── Animation_State.md # Docs for State.hs
│ │ ├── Draw.hs
│ │ ├── Environment.hs
│ │ ├── Game.hs
│ │ ├── Init.hs
│ │ ├── Input.hs
│ │ └── State.hs
│ ├── Main.hs
│ └── Main.md # Docs for Main.hs
│
├── test/
│ ├── AllTests.hs # Main test runner (entry point)
│ ├── TestDraw.hs
│ ├── TestDraw.md
│ ├── TestEnvironment.hs
│ ├── TestEnvironment.md
│ ├── TestGame.hs
│ ├── TestGame.md
│ ├── TestInit.hs
│ ├── TestInit.md
│ ├── TestInput.hs
│ ├── TestInput.md
│ ├── TestState.hs
│ └── TestState.md
│
├── ball_log.txt # Gameplay logs
├── board and balls.png # Game assets/screenshot
├── BouncingBall.cabal # Cabal build config
├── BouncingBall.zip # (Optional) compressed archive
├── cabal.project.local # Local cabal project settings
├── CHANGELOG.md # Project changelog
├── log.txt # Log file
├── README.md # Project documentation (this file)

Prerequisites


Installation

  1. Clone the repository:

    git clone <your-repo-url>cd BouncingBall
  2. Install dependencies:

    cabal update
    cabal install --only-dependencies
  3. Build the project:

    cabal build

Running the Game

  • From Cabal:

    cabal run
  • Or directly with GHC:

    cd src
    ghc -isrc Main.hs -o bouncingball
    ./bouncingball
  • Customize your session: At startup, the game will prompt you to set window size, ball size, speed, count, and other parameters.


Running the Tests

To run all tests:

cabal test# Or manually:cdtest
ghc -itest -isrc AllTests.hs -o runtests
./runtests

Controls

  • Arrow keys (, ): Move/rotate the shooter
  • Space: Shoot a bullet
  • Q or window close: Exit the game

Extending

All major logic is organized in modules within src/Animation/. See the tutorials for each module to understand or extend each component!


I am inviting Haskell Students to use this to add these features:

  • sounds: bullets fired, exploding balls hit by bullets, stage and levels changing
  • dashboard with counters and scores
  • enemies and hurdles
  • props changes
  • distributed peer to peer game
  • add hydra technologies
  • ada incentives and betting
  • blockchain Cardano features
  • etc… move from learning to earning ADA!


About

This is Coxygen Global Haskell Plutus Example Marathon

Resources

Stars

3 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

Coxygen Global Haskell Plutus

Marathon

BouncingBall Game

Marathon—as opposed to what I call a Hackathon—is a small app created in order to apply skills learned in a chapter. It must be a little working mock app for real world applications.

It must be working, have tests, and tutorials so that others can use it as a learning tool, and so the Marathon developer can use it for interviews or job applications. It must be extendable to MVP and eventually can be deployed in production for commercial purposes.

Why Marathons? I have been invited to Hackathons on Haskell Plutus but did not have the background to compete with other developers who had done Haskell for years, and I lost. It alienated me. A Marathon, like common athletics marathons, is a team/group coding exercise as opposed to uneven or unfair competition. All Coxygen Haskell Marathon participants must be rewarded, and this helps prepare them for Hackathons.

Authors

A fun and extensible bouncing ball and shooter game written in Haskell, using the Gloss library for graphics and animation.


Features

  • Multiple bouncing balls with random motion and wall collisions
  • Keyboard-controlled shooter that can move, rotate, and fire bullets
  • Customizable environment: window size, ball count, ball speed, etc.
  • Optional trajectory logging

Directory Structure

BouncingBall/
│
├── src/
│ ├── Animation/
│ │ ├── Animation_Draw.md # Docs for Draw.hs
│ │ ├── Animation_Environment.md # Docs for Environment.hs
│ │ ├── Animation_Game.md # Docs for Game.hs
│ │ ├── Animation_Init.md # Docs for Init.hs
│ │ ├── Animation_Input.md # Docs for Input.hs
│ │ ├── Animation_State.md # Docs for State.hs
│ │ ├── Draw.hs
│ │ ├── Environment.hs
│ │ ├── Game.hs
│ │ ├── Init.hs
│ │ ├── Input.hs
│ │ └── State.hs
│ ├── Main.hs
│ └── Main.md # Docs for Main.hs
│
├── test/
│ ├── AllTests.hs # Main test runner (entry point)
│ ├── TestDraw.hs
│ ├── TestDraw.md
│ ├── TestEnvironment.hs
│ ├── TestEnvironment.md
│ ├── TestGame.hs
│ ├── TestGame.md
│ ├── TestInit.hs
│ ├── TestInit.md
│ ├── TestInput.hs
│ ├── TestInput.md
│ ├── TestState.hs
│ └── TestState.md
│
├── ball_log.txt # Gameplay logs
├── board and balls.png # Game assets/screenshot
├── BouncingBall.cabal # Cabal build config
├── BouncingBall.zip # (Optional) compressed archive
├── cabal.project.local # Local cabal project settings
├── CHANGELOG.md # Project changelog
├── log.txt # Log file
├── README.md # Project documentation (this file)

Prerequisites


Installation

  1. Clone the repository:

    git clone <your-repo-url>cd BouncingBall
  2. Install dependencies:

    cabal update
    cabal install --only-dependencies
  3. Build the project:

    cabal build

Running the Game

  • From Cabal:

    cabal run
  • Or directly with GHC:

    cd src
    ghc -isrc Main.hs -o bouncingball
    ./bouncingball
  • Customize your session: At startup, the game will prompt you to set window size, ball size, speed, count, and other parameters.


Running the Tests

To run all tests:

cabal test# Or manually:cdtest
ghc -itest -isrc AllTests.hs -o runtests
./runtests

Controls

  • Arrow keys (, ): Move/rotate the shooter
  • Space: Shoot a bullet
  • Q or window close: Exit the game

Extending

All major logic is organized in modules within src/Animation/. See the tutorials for each module to understand or extend each component!


I am inviting Haskell Students to use this to add these features:

  • sounds: bullets fired, exploding balls hit by bullets, stage and levels changing
  • dashboard with counters and scores
  • enemies and hurdles
  • props changes
  • distributed peer to peer game
  • add hydra technologies
  • ada incentives and betting
  • blockchain Cardano features
  • etc… move from learning to earning ADA!


About

This is Coxygen Global Haskell Plutus Example Marathon

Resources

Stars

3 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Repository files navigation

Coxygen Global Haskell Plutus

Marathon

BouncingBall Game

Marathon—as opposed to what I call a Hackathon—is a small app created in order to apply skills learned in a chapter. It must be a little working mock app for real world applications.

It must be working, have tests, and tutorials so that others can use it as a learning tool, and so the Marathon developer can use it for interviews or job applications. It must be extendable to MVP and eventually can be deployed in production for commercial purposes.

Why Marathons? I have been invited to Hackathons on Haskell Plutus but did not have the background to compete with other developers who had done Haskell for years, and I lost. It alienated me. A Marathon, like common athletics marathons, is a team/group coding exercise as opposed to uneven or unfair competition. All Coxygen Haskell Marathon participants must be rewarded, and this helps prepare them for Hackathons.

Authors

A fun and extensible bouncing ball and shooter game written in Haskell, using the Gloss library for graphics and animation.


Features

  • Multiple bouncing balls with random motion and wall collisions
  • Keyboard-controlled shooter that can move, rotate, and fire bullets
  • Customizable environment: window size, ball count, ball speed, etc.
  • Optional trajectory logging

Directory Structure

BouncingBall/
│
├── src/
│ ├── Animation/
│ │ ├── Animation_Draw.md # Docs for Draw.hs
│ │ ├── Animation_Environment.md # Docs for Environment.hs
│ │ ├── Animation_Game.md # Docs for Game.hs
│ │ ├── Animation_Init.md # Docs for Init.hs
│ │ ├── Animation_Input.md # Docs for Input.hs
│ │ ├── Animation_State.md # Docs for State.hs
│ │ ├── Draw.hs
│ │ ├── Environment.hs
│ │ ├── Game.hs
│ │ ├── Init.hs
│ │ ├── Input.hs
│ │ └── State.hs
│ ├── Main.hs
│ └── Main.md # Docs for Main.hs
│
├── test/
│ ├── AllTests.hs # Main test runner (entry point)
│ ├── TestDraw.hs
│ ├── TestDraw.md
│ ├── TestEnvironment.hs
│ ├── TestEnvironment.md
│ ├── TestGame.hs
│ ├── TestGame.md
│ ├── TestInit.hs
│ ├── TestInit.md
│ ├── TestInput.hs
│ ├── TestInput.md
│ ├── TestState.hs
│ └── TestState.md
│
├── ball_log.txt # Gameplay logs
├── board and balls.png # Game assets/screenshot
├── BouncingBall.cabal # Cabal build config
├── BouncingBall.zip # (Optional) compressed archive
├── cabal.project.local # Local cabal project settings
├── CHANGELOG.md # Project changelog
├── log.txt # Log file
├── README.md # Project documentation (this file)

Prerequisites


Installation

  1. Clone the repository:

    git clone <your-repo-url>cd BouncingBall
  2. Install dependencies:

    cabal update
    cabal install --only-dependencies
  3. Build the project:

    cabal build

Running the Game

  • From Cabal:

    cabal run
  • Or directly with GHC:

    cd src
    ghc -isrc Main.hs -o bouncingball
    ./bouncingball
  • Customize your session: At startup, the game will prompt you to set window size, ball size, speed, count, and other parameters.


Running the Tests

To run all tests:

cabal test# Or manually:cdtest
ghc -itest -isrc AllTests.hs -o runtests
./runtests

Controls

  • Arrow keys (, ): Move/rotate the shooter
  • Space: Shoot a bullet
  • Q or window close: Exit the game

Extending

All major logic is organized in modules within src/Animation/. See the tutorials for each module to understand or extend each component!


I am inviting Haskell Students to use this to add these features:

  • sounds: bullets fired, exploding balls hit by bullets, stage and levels changing
  • dashboard with counters and scores
  • enemies and hurdles
  • props changes
  • distributed peer to peer game
  • add hydra technologies
  • ada incentives and betting
  • blockchain Cardano features
  • etc… move from learning to earning ADA!


About

This is Coxygen Global Haskell Plutus Example Marathon

Resources

Stars

3 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages