This commit is contained in:
mtgmonkey 2025-06-11 17:55:32 -04:00
commit f15932fc62
10 changed files with 303 additions and 0 deletions

26
flake.lock generated Normal file
View file

@ -0,0 +1,26 @@
{
"nodes": {
"nixpkgs": {
"locked": {
"lastModified": 1748889542,
"narHash": "sha256-Hb4iMhIbjX45GcrgOp3b8xnyli+ysRPqAgZ/LZgyT5k=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "10d7f8d34e5eb9c0f9a0485186c1ca691d2c5922",
"type": "github"
},
"original": {
"id": "nixpkgs",
"ref": "nixos-25.05",
"type": "indirect"
}
},
"root": {
"inputs": {
"nixpkgs": "nixpkgs"
}
}
},
"root": "root",
"version": 7
}

12
flake.nix Executable file
View file

@ -0,0 +1,12 @@
{
inputs = {
nixpkgs.url = "nixpkgs/nixos-25.05";
};
outputs = {nixpkgs, ...}: let
system = "x86_64-linux";
pkgs = nixpkgs.legacyPackages.${system};
in {
packages.${system}.default = pkgs.callPackage ./package.nix {};
nixosModules.${system}.default = ./module.nix;
};
}

22
module.nix Normal file
View file

@ -0,0 +1,22 @@
{
pkgs,
lib,
config,
...
}: {
options = {
services.math-project = {
enable = lib.mkEnableOption "math project";
package = lib.mkOption {
description = "math project package";
default = pkgs.callPackage ./package.nix {};
type = lib.types.package;
};
};
};
config = lib.mkIf config.services.math-project.enable {
environment.systemPackages = [
config.services.math-project.package
];
};
}

51
package.nix Normal file
View file

@ -0,0 +1,51 @@
{
esbuild,
elmPackages,
stdenv,
http-server,
...
}: let
elmConfig = elmPackages.fetchElmDeps {
elmPackages = import ./src/elm2nix/elm-srcs.nix;
elmVersion = "0.19.1";
registryDat = ./src/elm2nix/registry.dat;
};
in
stdenv.mkDerivation {
name = "math-project";
src = ./src;
nativeBuildInputs = [
esbuild
elmPackages.elm
];
buildInputs = [
http-server
];
configurePhase = ''
${elmConfig}
'';
buildPhase = ''
elm make ./Main.elm --optimize --output=tmp.js
esbuild ./tmp.js --minify --target=es5 --outfile=main.js
echo "<!DOCTYPE html><html><head><script type = 'text/javascript' src = './main.js'></script></head><body><script type = 'text/javascript' src = './init.js'></script></body></html>" > index.html
'';
installPhase = ''
mkdir $out/bin -p
mkdir $out/src -p
echo "#!/usr/bin/env bash" > math-project
echo "cd $(echo $out)/src/" >> math-project
echo "${http-server}/bin/http-server" >> math-project
chmod a+x math-project
cp math-project $out/bin/math-project
cp index.html $out/src/index.html
cp main.js $out/src/main.js
cp init.js $out/src/init.js
'';
meta = {
mainProgram = "math-project";
description = "math project";
homepage = "https://math.mtgmonkey.net";
};
}

118
src/Main.elm Normal file
View file

@ -0,0 +1,118 @@
module Main exposing (main)
import Html exposing (..)
import Html.Attributes exposing (srcdoc)
import Playground as P exposing (..)
import Tuple exposing (first, second)
type alias Memory =
{ dx : Number
}
type alias Bounds =
{ ymin : Number
, ymax : Number
, xmin : Number
, xmax : Number
}
type alias Coords =
( Number, Number )
init : Memory
init =
{ dx = 100
}
main = game
game =
P.game view update init
view : Computer -> Memory -> List Shape
view computer memory =
let
bounds =
{ ymin = 0
, ymax = 511
, xmin = 0
, xmax = 511 * computer.screen.width / computer.screen.height
}
at =
placeAtCoords computer bounds
fx x =
(x - (bounds.xmax - bounds.xmin) / 2) ^ 2 / 1000
in
List.append
[ P.words purple "Welcome to my math project! Use arrow keys to adjust the width of each rectangle."
|> at ( (bounds.xmax - bounds.xmin) / 2, bounds.ymax - 10 )
, P.words purple "The current equation is y=0.25x^2."
|> at ( (bounds.xmax - bounds.xmin) / 2, bounds.ymax - 20 )
, P.words purple ("The current dx is " ++ (String.fromInt <| truncate memory.dx))
|> at ( (bounds.xmax - bounds.xmin) / 2, bounds.ymax - 30 )
, P.square purple 10
|> at ( 100, 100 )
]
<|
makeRectangles at fx bounds memory []
makeRectangles : (Coords -> Shape -> Shape) -> (Number -> Number) -> Bounds -> Memory -> List Shape -> List Shape
makeRectangles at fx bounds memory prev =
let
height =
fx <| toFloat (List.length prev + 1) * memory.dx
numOfRecs =
1 + (truncate <| toFloat (List.length prev) * memory.dx)
newRec =
rectangle red memory.dx height
|> at ( memory.dx / 4 + memory.dx * toFloat (List.length prev) / 2, height / 4 )
in
if toFloat (List.length prev) <= 1 + 2 * (bounds.xmax - bounds.xmin) / memory.dx then
makeRectangles at fx bounds memory <|
List.append prev [ newRec ]
else
prev
update : Computer -> Memory -> Memory
update computer memory =
{ memory
| dx = memory.dx + 0.2 * toX computer.keyboard
}
placeAtScreen : Computer -> Coords -> Shape -> Shape
placeAtScreen computer coords shape =
let
x =
first coords
y =
second coords
in
shape |> P.move (-computer.screen.width / 2 + x) (-computer.screen.height / 2 + y)
placeAtCoords : Computer -> Bounds -> Coords -> Shape -> Shape
placeAtCoords computer bounds coords shape =
let
x =
first coords
y =
second coords
in
placeAtScreen computer ( x / (bounds.xmax - bounds.xmin) * computer.screen.width, y / (bounds.ymax - bounds.ymin) * computer.screen.height ) shape

View file

26
src/elm.json Normal file
View file

@ -0,0 +1,26 @@
{
"type": "application",
"source-directories": [
"."
],
"elm-version": "0.19.1",
"dependencies": {
"direct": {
"elm/browser": "1.0.2",
"elm/core": "1.0.5",
"elm/html": "1.0.0",
"evancz/elm-playground": "1.0.3"
},
"indirect": {
"elm/json": "1.1.3",
"elm/svg": "1.0.1",
"elm/time": "1.0.0",
"elm/url": "1.0.0",
"elm/virtual-dom": "1.0.3"
}
},
"test-dependencies": {
"direct": {},
"indirect": {}
}
}

47
src/elm2nix/elm-srcs.nix Normal file
View file

@ -0,0 +1,47 @@
{
"elm/browser" = {
sha256 = "0nagb9ajacxbbg985r4k9h0jadqpp0gp84nm94kcgbr5sf8i9x13";
version = "1.0.2";
};
"elm/core" = {
sha256 = "19w0iisdd66ywjayyga4kv2p1v9rxzqjaxhckp8ni6n8i0fb2dvf";
version = "1.0.5";
};
"elm/html" = {
sha256 = "1n3gpzmpqqdsldys4ipgyl1zacn0kbpc3g4v3hdpiyfjlgh8bf3k";
version = "1.0.0";
};
"evancz/elm-playground" = {
sha256 = "197igis4swjppr0dly1sx6d0hxbn56vl4gs83pwahslxx6rnw45z";
version = "1.0.3";
};
"elm/json" = {
sha256 = "0kjwrz195z84kwywaxhhlnpl3p251qlbm5iz6byd6jky2crmyqyh";
version = "1.1.3";
};
"elm/svg" = {
sha256 = "1cwcj73p61q45wqwgqvrvz3aypjyy3fw732xyxdyj6s256hwkn0k";
version = "1.0.1";
};
"elm/time" = {
sha256 = "0vch7i86vn0x8b850w1p69vplll1bnbkp8s383z7pinyg94cm2z1";
version = "1.0.0";
};
"elm/url" = {
sha256 = "0av8x5syid40sgpl5vd7pry2rq0q4pga28b4yykn9gd9v12rs3l4";
version = "1.0.0";
};
"elm/virtual-dom" = {
sha256 = "1yvb8px2z62xd578ag2q0r5hd1vkz9y7dfkx05355iiy1d7jwq4v";
version = "1.0.3";
};
}

BIN
src/elm2nix/registry.dat Normal file

Binary file not shown.

1
src/init.js Executable file
View file

@ -0,0 +1 @@
app = Elm.Main.init();