From a62e48246c5cb191f6f9d0e62e107a24edf726aa Mon Sep 17 00:00:00 2001
From: Oskar Marquardt <oskar.marquardt@student.uni-halle.de>
Date: Sun, 16 Jun 2024 17:39:25 +0200
Subject: [PATCH] Added cost for adding dots - Created batch file for compiling
 - Added creation points 	- Includes freebie points 	- Includes
 sphere points - Added Entropy sphere

---
 public/main.js     | 141 +++++++++++++++++++++++++++++++++++++++------
 src/BoundedInt.elm |  10 +++-
 src/Character.elm  |  63 +++++++++++++++++++-
 src/Main.elm       |   4 +-
 src/Sphere.elm     |  23 ++++++--
 zzz_elm_make.bat   |   1 +
 6 files changed, 214 insertions(+), 28 deletions(-)
 create mode 100644 zzz_elm_make.bat

diff --git a/public/main.js b/public/main.js
index 45ef21f..037adbf 100644
--- a/public/main.js
+++ b/public/main.js
@@ -5167,6 +5167,7 @@ var $author$project$Sphere$dots = function (value) {
 	return A3($author$project$BoundedInt$new, value, 0, 5);
 };
 var $author$project$Character$new = {
+	creationPoints: {freebie: 15, spheres: 6},
 	name: 'Default Name',
 	spheres: _List_fromArray(
 		[
@@ -5174,6 +5175,11 @@ var $author$project$Character$new = {
 			affinity: false,
 			dots: $author$project$Sphere$dots(0),
 			name: 'Correspondence'
+		},
+			{
+			affinity: false,
+			dots: $author$project$Sphere$dots(0),
+			name: 'Entropy'
 		}
 		])
 };
@@ -5195,13 +5201,23 @@ var $author$project$Character$changeName = F2(
 			character,
 			{name: newName});
 	});
+var $author$project$BoundedInt$changeTo = F2(
+	function (boundedInt, value) {
+		return ((_Utils_cmp(value, boundedInt.min) < 0) || (_Utils_cmp(value, boundedInt.max) > 0)) ? boundedInt : _Utils_update(
+			boundedInt,
+			{value: value});
+	});
+var $author$project$BoundedInt$changeBy = F2(
+	function (boundedInt, value) {
+		return A2($author$project$BoundedInt$changeTo, boundedInt, boundedInt.value + value);
+	});
 var $author$project$Sphere$isSphere = F2(
-	function (a, b) {
-		return _Utils_eq(a.name, b.name);
+	function (name, sphere) {
+		return _Utils_eq(sphere.name, name);
 	});
 var $author$project$Sphere$changeSphere = F2(
 	function (newSphere, sphere) {
-		return A2($author$project$Sphere$isSphere, sphere, newSphere) ? newSphere : sphere;
+		return A2($author$project$Sphere$isSphere, newSphere.name, sphere) ? newSphere : sphere;
 	});
 var $author$project$Sphere$changeSphereInList = F2(
 	function (spheres, sphere) {
@@ -5210,13 +5226,90 @@ var $author$project$Sphere$changeSphereInList = F2(
 			$author$project$Sphere$changeSphere(sphere),
 			spheres);
 	});
+var $author$project$Sphere$freebieCost = 7;
+var $elm$core$Basics$ge = _Utils_ge;
+var $elm$core$List$filter = F2(
+	function (isGood, list) {
+		return A3(
+			$elm$core$List$foldr,
+			F2(
+				function (x, xs) {
+					return isGood(x) ? A2($elm$core$List$cons, x, xs) : xs;
+				}),
+			_List_Nil,
+			list);
+	});
+var $elm$core$List$head = function (list) {
+	if (list.b) {
+		var x = list.a;
+		var xs = list.b;
+		return $elm$core$Maybe$Just(x);
+	} else {
+		return $elm$core$Maybe$Nothing;
+	}
+};
+var $author$project$Sphere$getDotsOfSphereInList = F2(
+	function (spheres, name) {
+		var maybeSphere = $elm$core$List$head(
+			A2(
+				$elm$core$List$filter,
+				$author$project$Sphere$isSphere(name),
+				spheres));
+		if (maybeSphere.$ === 'Nothing') {
+			return $elm$core$Maybe$Nothing;
+		} else {
+			var sphere = maybeSphere.a;
+			return $elm$core$Maybe$Just(sphere.dots);
+		}
+	});
+var $elm$core$Basics$min = F2(
+	function (x, y) {
+		return (_Utils_cmp(x, y) < 0) ? x : y;
+	});
+var $elm$core$Basics$negate = function (n) {
+	return -n;
+};
 var $author$project$Character$changeSphere = F2(
 	function (character, sphere) {
-		return _Utils_update(
-			character,
-			{
-				spheres: A2($author$project$Sphere$changeSphereInList, character.spheres, sphere)
-			});
+		var maybeOldDots = A2($author$project$Sphere$getDotsOfSphereInList, character.spheres, sphere.name);
+		var difference = function () {
+			if (maybeOldDots.$ === 'Nothing') {
+				return 0;
+			} else {
+				var oldDots = maybeOldDots.a;
+				return sphere.dots.value - oldDots.value;
+			}
+		}();
+		if (maybeOldDots.$ === 'Nothing') {
+			return character;
+		} else {
+			var oldDots = maybeOldDots.a;
+			if (difference >= 0) {
+				var sA = (character.creationPoints.spheres > 0) ? A2($elm$core$Basics$min, difference, character.creationPoints.spheres) : 0;
+				var fA = A2($elm$core$Basics$min, difference - sA, (character.creationPoints.freebie / $author$project$Sphere$freebieCost) | 0);
+				return _Utils_update(
+					character,
+					{
+						creationPoints: {freebie: character.creationPoints.freebie - (fA * $author$project$Sphere$freebieCost), spheres: (character.creationPoints.spheres - sA) - fA},
+						spheres: A2(
+							$author$project$Sphere$changeSphereInList,
+							character.spheres,
+							_Utils_update(
+								sphere,
+								{
+									dots: A2($author$project$BoundedInt$changeBy, oldDots, fA + sA)
+								}))
+					});
+			} else {
+				var fA = (character.creationPoints.spheres < 0) ? (-A2($elm$core$Basics$max, difference, character.creationPoints.spheres)) : 0;
+				return _Utils_update(
+					character,
+					{
+						creationPoints: {freebie: character.creationPoints.freebie + (fA * $author$project$Sphere$freebieCost), spheres: character.creationPoints.spheres - difference},
+						spheres: A2($author$project$Sphere$changeSphereInList, character.spheres, sphere)
+					});
+			}
+		}
 	});
 var $author$project$Main$modalValue = F2(
 	function (modalType, character) {
@@ -5270,6 +5363,9 @@ var $author$project$Main$update = F2(
 		}
 	});
 var $author$project$Main$Name = {$: 'Name'};
+var $elm$html$Html$div = _VirtualDom_node('div');
+var $elm$virtual_dom$VirtualDom$text = _VirtualDom_text;
+var $elm$html$Html$text = $elm$virtual_dom$VirtualDom$text;
 var $author$project$Main$OpenModal = function (a) {
 	return {$: 'OpenModal', a: a};
 };
@@ -5282,7 +5378,6 @@ var $elm$html$Html$Attributes$stringProperty = F2(
 			$elm$json$Json$Encode$string(string));
 	});
 var $elm$html$Html$Attributes$class = $elm$html$Html$Attributes$stringProperty('className');
-var $elm$html$Html$div = _VirtualDom_node('div');
 var $elm$html$Html$i = _VirtualDom_node('i');
 var $elm$virtual_dom$VirtualDom$Normal = function (a) {
 	return {$: 'Normal', a: a};
@@ -5302,8 +5397,6 @@ var $elm$html$Html$Events$onClick = function (msg) {
 		$elm$json$Json$Decode$succeed(msg));
 };
 var $elm$html$Html$span = _VirtualDom_node('span');
-var $elm$virtual_dom$VirtualDom$text = _VirtualDom_text;
-var $elm$html$Html$text = $elm$virtual_dom$VirtualDom$text;
 var $author$project$Main$viewEditableText = F2(
 	function (modalType, content) {
 		return A2(
@@ -5548,12 +5641,6 @@ var $author$project$Main$ChangeSphere = function (a) {
 var $author$project$Main$boolAsIntString = function (bool) {
 	return bool ? '1' : '0';
 };
-var $author$project$BoundedInt$change = F2(
-	function (boundedInt, value) {
-		return ((_Utils_cmp(value, boundedInt.min) < 0) || (_Utils_cmp(value, boundedInt.max) > 0)) ? boundedInt : _Utils_update(
-			boundedInt,
-			{value: value});
-	});
 var $elm$core$String$concat = function (strings) {
 	return A2($elm$core$String$join, '', strings);
 };
@@ -5665,7 +5752,7 @@ var $author$project$Main$viewDot = F6(
 							sphere,
 							{
 								dots: A2(
-									$author$project$BoundedInt$change,
+									$author$project$BoundedInt$changeTo,
 									sphere.dots,
 									A2($author$project$Main$valueOrReset, sphere.dots, id + 1))
 							})))
@@ -5738,7 +5825,23 @@ var $author$project$Main$view = function (model) {
 			[
 				A2($author$project$Main$viewEditableText, $author$project$Main$Name, model.character.name),
 				$author$project$Main$viewSpheres(model.character.spheres),
-				$author$project$Main$viewModal(model)
+				$author$project$Main$viewModal(model),
+				A2(
+				$elm$html$Html$div,
+				_List_Nil,
+				_List_fromArray(
+					[
+						$elm$html$Html$text(
+						'freebie: ' + $elm$core$String$fromInt(model.character.creationPoints.freebie))
+					])),
+				A2(
+				$elm$html$Html$div,
+				_List_Nil,
+				_List_fromArray(
+					[
+						$elm$html$Html$text(
+						'spheres: ' + $elm$core$String$fromInt(model.character.creationPoints.spheres))
+					]))
 			]),
 		title: 'Character Sheet'
 	};
diff --git a/src/BoundedInt.elm b/src/BoundedInt.elm
index fb040d6..274d705 100644
--- a/src/BoundedInt.elm
+++ b/src/BoundedInt.elm
@@ -22,11 +22,15 @@ new value min max =
         , max = max
         }
 
-change : BoundedInt -> Int -> BoundedInt
-change boundedInt value =
+changeTo : BoundedInt -> Int -> BoundedInt
+changeTo boundedInt value =
     if value < boundedInt.min
     || value > boundedInt.max
     then
         boundedInt
     else
-        { boundedInt | value = value }
\ No newline at end of file
+        { boundedInt | value = value }
+
+changeBy : BoundedInt -> Int -> BoundedInt
+changeBy boundedInt value =
+    changeTo boundedInt ( boundedInt.value + value )
\ No newline at end of file
diff --git a/src/Character.elm b/src/Character.elm
index 7f73d98..9ad4726 100644
--- a/src/Character.elm
+++ b/src/Character.elm
@@ -1,12 +1,22 @@
 module Character exposing (..)
 
 import Sphere exposing (Sphere)
+import Json.Decode exposing (int)
+import Sphere exposing (getDotsOfSphereInList)
+import BoundedInt
+import Html exposing (s)
 
 type alias Character =
     { name : String
+    , creationPoints : CreationPoints
     , spheres : List Sphere
     }
 
+type alias CreationPoints =
+    { freebie : Int
+    , spheres : Int
+    }
+
 changeName : Character -> String -> Character
 changeName character newName =
     if ( newName == "")
@@ -17,15 +27,66 @@ changeName character newName =
 
 changeSphere : Character -> Sphere -> Character
 changeSphere character sphere =
-    { character | spheres = Sphere.changeSphereInList character.spheres sphere }
+    let
+        maybeOldDots = getDotsOfSphereInList character.spheres sphere.name
+        difference = case maybeOldDots of
+            Nothing -> 0
+            Just oldDots ->
+                sphere.dots.value - oldDots.value
+    in
+        case maybeOldDots of
+            Nothing -> character
+            Just oldDots ->
+                if difference >= 0
+                then
+                    let
+                        sA = 
+                            if character.creationPoints.spheres > 0
+                                then min difference character.creationPoints.spheres
+                                else 0
+                        fA = min ( difference - sA ) ( character.creationPoints.freebie // Sphere.freebieCost )
+                    in
+                        { character
+                        | spheres = Sphere.changeSphereInList character.spheres 
+                            { sphere 
+                            | dots = BoundedInt.changeBy oldDots ( fA + sA )
+                            } 
+                        , creationPoints =
+                            { freebie = character.creationPoints.freebie - fA * Sphere.freebieCost
+                            , spheres = character.creationPoints.spheres - sA - fA
+                            }
+                        }
+                else
+                    let
+                        fA =
+                            if character.creationPoints.spheres < 0
+                            then negate ( max difference character.creationPoints.spheres )
+                            else 0
+                    in
+                        { character
+                        | spheres = Sphere.changeSphereInList character.spheres sphere
+                        , creationPoints =
+                            { freebie = character.creationPoints.freebie + fA * Sphere.freebieCost
+                            , spheres = character.creationPoints.spheres - difference
+                            }
+                        }
+        -- this currently works incorrectly
 
 new : Character
 new =
     { name = "Default Name" 
+    , creationPoints =
+        { freebie = 15
+        , spheres = 6
+        }
     , spheres = 
         [   { name = "Correspondence"
             , dots = Sphere.dots 0
             , affinity = False
             }
+        ,   { name = "Entropy"
+            , dots = Sphere.dots 0
+            , affinity = False
+            }
         ]
     }
\ No newline at end of file
diff --git a/src/Main.elm b/src/Main.elm
index c129fea..8f114ef 100644
--- a/src/Main.elm
+++ b/src/Main.elm
@@ -85,6 +85,8 @@ view model =
         [ viewEditableText Name model.character.name
         , viewSpheres model.character.spheres
         , viewModal model
+        , div [] [ text ( "freebie: " ++ String.fromInt model.character.creationPoints.freebie ) ]
+        , div [] [ text ( "spheres: " ++ String.fromInt model.character.creationPoints.spheres ) ]
         ]
     }
 
@@ -216,7 +218,7 @@ viewDot sphere size strokeWidth isFilled id position =
         , Svg.Attributes.fillOpacity ( boolAsIntString isFilled )
         , Svg.Attributes.stroke "var(--bulma-body-color)"
         , Svg.Attributes.strokeWidth ( String.fromFloat strokeWidth )
-        , onClick ( ChangeSphere { sphere | dots = BoundedInt.change sphere.dots ( valueOrReset sphere.dots ( id + 1 ) ) } )
+        , onClick ( ChangeSphere { sphere | dots = BoundedInt.changeTo sphere.dots ( valueOrReset sphere.dots ( id + 1 ) ) } )
         ] []
 
 tupleToString : ( Float, Float ) -> String
diff --git a/src/Sphere.elm b/src/Sphere.elm
index 708b4bb..1e551f0 100644
--- a/src/Sphere.elm
+++ b/src/Sphere.elm
@@ -8,21 +8,36 @@ type alias Sphere =
     , affinity : Bool
     }
 
+freebieCost : Int
+freebieCost = 7
+
 changeSphereInList : List Sphere -> Sphere -> List Sphere
 changeSphereInList spheres sphere =
     List.map ( changeSphere sphere ) spheres
 
 changeSphere : Sphere -> Sphere -> Sphere
 changeSphere newSphere sphere =
-    if isSphere sphere newSphere
+    if isSphere newSphere.name sphere
     then
         newSphere
     else
         sphere
 
-isSphere : Sphere -> Sphere -> Bool
-isSphere a b =
-    a.name == b.name
+isSphere : String -> Sphere -> Bool
+isSphere name sphere =
+    sphere.name == name
+
+getDotsOfSphereInList : List Sphere -> String -> Maybe BoundedInt
+getDotsOfSphereInList spheres name =
+    let
+        maybeSphere = spheres
+            |> List.filter ( isSphere name )
+            |> List.head
+    in
+        case maybeSphere of
+            Nothing -> Nothing
+            Just sphere ->
+                Just sphere.dots
 
 dots : Int -> BoundedInt
 dots value =
diff --git a/zzz_elm_make.bat b/zzz_elm_make.bat
new file mode 100644
index 0000000..bb74cf5
--- /dev/null
+++ b/zzz_elm_make.bat
@@ -0,0 +1 @@
+elm make src/Main.elm --output=public/main.js
\ No newline at end of file
-- 
GitLab