RPG attributes generator: Difference between revisions

→‎Functional JS: Updated in translation of the Python version
m (→‎Python: Functional composition: (Edited type comments))
(→‎Functional JS: Updated in translation of the Python version)
Line 459:
 
===Functional===
{{Trans|Python}} (Functional composition version)
{{Trans|Haskell}}
<lang javascript>(() => {
'use strict';
 
// main :: IO ()
const main = () =>
// 10 random heroes drawn from
console.log(
// a non-finite series.
unlines(
unlines(map(
() xs => {show(sum(xs)) +
const' xs-> =[' character+ show(xs); + ']',
return showJSON([sum(xs), xs]);
},
enumFromTo(1, 10)
)
)
);
 
take(10, heroes(
// character :: ([Int] -> Bool) -> [Int]
seventyFivePlusWithTwo15s
const character = () =>
discardUntil( ))
));
xs => 75 <= sum(xs) && 2 <= length(filter(x => 15 <= x, xs))
)(
() => map(
() => composeList([sum, tail, sort])(
map(x => randomRInt(1, 6), enumFromTo(1, 4))
),
enumFromTo(1, 6)
)
);
 
// discardUntilseventyFivePlusWithTwo15s :: ([Int] -> Bool) -> (() -> [Int]) -> [Int]
const seventyFivePlusWithTwo15s = xs =>
const discardUntil = p => f => {
const go = () =>// {Total score over 75,
// with two or more qualities scoring 15.
const xs = f();
return p 75 < sum(xs) ?&& xs1 :< golength(filter();
x => 15 === x, xs
));
 
 
function* heroes(p) {
// Non-finite list of heroes matching
// the requirements of predicate p.
while (true) {
yield hero(p)
}
}
return go();
};
 
// hero :: (Int -> Bool) -> IO (Int, Int, Int, Int, Int, Int)
const hero = p =>
// A random character matching the
// requirements of predicate p.
until(p, character, []);
 
// character :: () -> [Int]
const character = () =>
// A random character with six
// integral attributes.
map(() => sum(tail(sort(map(
randomRInt(1, 6),
enumFromTo(1, 4)
)))),
enumFromTo(1, 6)
);
 
 
// GENERIC FUNCTIONS ----------------------------------
 
// enumFromTo :: (Int, Int) -> [Int]
const enumFromTo = (m, n) =>
Array.from({
length: 1 + n - m
}, (_, i) => m + i);
 
// filter :: (a -> Bool) -> [a] -> [a]
// GENERIC FUNCTIONS ------------------------------------
const filter = (f, xs) => xs.filter(f);
 
// Returns Infinity over objects without finite length.
// composeList :: [(a -> a)] -> (a -> a)
// This enables zip and zipWith to choose the shorter
const composeList = fs =>
// argument when one is non-finite, like cycle, repeat etc
x => fs.reduceRight((a, f) => f(a), x, fs);
 
// enumFromTolength :: Int[a] -> Int -> [Int]
const enumFromTolength = (m, n)xs =>
(Array.isArray(xs) || 'string' === typeof xs) ? (
Array.from({
length: 1 + n - m xs.length
}, (_, i) => m) +: i)Infinity;
 
// filtermap :: (a -> Boolb) -> [a] -> [ab]
const filtermap = (f, xs) => xs.filter(f);
(Array.isArray(xs) ? (
xs
) : xs.split('')).map(f);
 
// e.g. map(randomRInt(1, 10), enumFromTo(1, 20))
// Returns Infinity over objects without finite length
// this enables zip and zipWith to choose the shorter
// argument when one is non-finite, like cycle, repeat etc
 
// lengthrandomRInt :: [a]Int -> Int -> IO () -> Int
const lengthrandomRInt = xs(low, high) => xs.length() || Infinity;=>
low + Math.floor(
(Math.random() * ((high - low) + 1))
);
 
// mapshow :: (a -> b) -> [a] -> [b]String
const mapshow = (f, xs)x => xsx.maptoString(f);
 
// randomRIntsort :: IntOrd -a => Int[a] -> Int[a]
const randomRIntsort = (low, high)xs => xs.slice()
.sort((a, b) => a < b ? -1 : (a > b ? 1 : 0));
low + Math.floor(
(Math.random() * ((high - low) + 1))
);
 
// showJSONsum :: a[Num] -> StringNum
const showJSONsum = xxs => JSONxs.stringifyreduce((a, x) => a + x, 0);
 
// sorttail :: Ord a => [a] -> [a]
const sorttail = xs => 0 < xs.length ? xs.slice(1) : [];
.sort((a, b) => a < b ? -1 : (a > b ? 1 : 0));
 
// sumtake :: Int -> [Numa] -> Num[a]
// take :: Int -> String -> String
const sum = xs => xs.reduce((a, x) => a + x, 0);
const take = (n, xs) =>
'GeneratorFunction' !== xs.constructor.constructor.name ? (
xs.slice(0, n)
) : [].concat.apply([], Array.from({
length: n
}, () => {
const x = xs.next();
return x.done ? [] : [x.value];
}));
 
// tailunlines :: [aString] -> [a]String
const tailunlines = xs => 0 < xs.length ? xs.slicejoin(1'\n') : [];
 
// unlinesuntil :: [String](a -> Bool) -> (a -> a) -> a -> Stringa
const unlinesuntil = xs(p, f, x) => xs.join('\n');{
let v = x;
while (!p(v)) v = f(v);
return v;
};
 
// MAIN ---
return main();
})();</lang>
{{Out}}
A sample of 10 character attribute sets:
<pre>79 -> [8312,[915,1312,1615,1713,12,16]]
92 -> [79,[1317,16,1215,1015,1617,12]]
82 -> [7812,[1514,1113,13,1415,15,10]]
84 -> [7615,[16,1318,1110,15,10,11]]
83 -> [8215,[1312,717,16,1514,1610,15]]
[79,83 -> [14,1415,1410,15,14,13,10]15]
[77, -> [912,913,15,1611,1615,12]11]
81 -> [8515,8,[16,15,16,1115,12,15]]
79 -> [7715,[15,1211,17,12,9,14,15]]
76 -> [8314,[1712,9,15,14,1415,11,12]]</pre>
 
=={{header|Julia}}==
9,655

edits