new object $climate_frob: $frob;
var $root created_on = 837904716;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root inited = 1;
var $root managed = [$climate_frob];
var $root manager = $climate_frob;
public method ._distances() {
arg self, from, season;
var i, j, attr, w, refattr;
w = self[3];
refattr = (w[from])[1];
return map i in (w.keys()) to ([i, ((map j in [1 .. (attr = (w[i])[1]).length()] to (abs((attr[j]) - (refattr[j]))).sum()) * 100) / (((w[i])[2])[season])]);
};
public method .add_weather() {
arg self, name, attrs, probs, message, ch_messages;
return (<this(), [self[1], self[2], (self[3]).add(name, [attrs, probs, message, ch_messages])]>);
};
public method .advance() {
arg self, current, season, fuzz;
var dists, i, w, s;
w = self[3];
dists = ._distances(self, current, season);
dists = dists.sort(dists.slice(2));
i = 1;
while ((i < (dists.length())) && (random(20 + ((dists[i])[2])) < fuzz))
i++;
return (dists[i])[1];
};
public method .del_weather() {
arg self, weather;
return (<this(), [self[1], self[2], (self[3]).del(weather)]>);
};
public method .new_with() {
arg attributes, seasons;
return (<this(), [attributes, seasons, #[]]>);
};
public method .read_new() {
arg user;
var attrs, seasons, i;
attrs = user.prompt("Weather attribute names (default:visibility severity):");
if (attrs == "@abort")
throw(~abort, "User aborted.");
if (type(attrs) == 'symbol)
throw(~engaged, "Already reading.");
attrs = attrs || "visibility severity";
attrs = (attrs.explode()).mmap('to_symbol);
seasons = user.prompt("Season list (default:winter spring summer fall):");
if (seasons == "@abort")
throw(~abort, "User @aborted.");
if (type(seasons) == 'symbol)
throw(~engaged, "Already reading.");
seasons = seasons || "winter spring summer fall";
seasons = (seasons.explode()).mmap('to_symbol);
return .new_with(attrs, seasons);
};
public method .read_weather() {
arg self, user, weather;
var attrs, probs, message, ch_messages, i;
attrs = user.prompt("Attributes:");
if ((type(attrs) == 'symbol) || (attrs == "@abort"))
throw(~stop, "");
if (((self[1]).length()) != ((attrs = attrs.explode_quoted()).length()))
throw(~parse, "Wrong number of attributes");
attrs = map i in (attrs) to ((tostr(toint(i)) == i) ? toint(i) : i);
probs = user.prompt("Seasonal probabilities [0-99]:");
if ((type(probs) == 'symbol) || (probs == "@abort"))
throw(~stop, "");
if (((self[2]).length()) != ((probs = probs.explode()).length()))
throw(~parse, "Wrong number of attributes");
probs = map i in (probs) to (toint(i));
message = user.prompt("Weather description:");
if ((type(message) == 'symbol) || (message == "@abort"))
throw(~stop, "");
(> (message = $compiler.compile_cml(message)) <);
ch_messages = user.read("Enter messages to be displayed during the change ('.' to finish)");
if (type(ch_messages) == 'symbol)
throw(~stop, "");
(> (ch_messages = map i in (ch_messages) to ($compiler.compile_cml(i))) <);
return .add_weather(self, weather, attrs, probs, message, ch_messages);
};
public method .show() {
arg self;
var out, seasons, attrs, weathers, x, i;
attrs = self[1];
seasons = self[2];
weathers = self[3];
out = [("Attributes: " + (attrs.to_english())) + ".", ("Seasons: " + (seasons.to_english())) + "."];
for x in (weathers) {
out += [((((" * " + (x[1])) + "> (probs) ") + (map i in [1 .. seasons.length()] to ((tostr(seasons[i]) + ":") + (((x[2])[2])[i])).join(", "))) + " (attrs) ") + (map i in [1 .. attrs.length()] to ((tostr(attrs[i]) + ":") + (((x[2])[1])[i])).join(", "))];
out += [" Description = " + ((((x[2])[3]).uncompile()).join())];
if ((x[2])[4]) {
out += [" Change messages:"];
for i in ((x[2])[4])
out += [" " + ((i.uncompile()).join())];
}
}
return out;
};