// Copyright: (c) 2011 Wybo Wiersma <mail@wybowiersma.net>
//
// Available under the Affero GPL v3, http://www.gnu.org/licenses/agpl.html

ABF = {};

// Includes
$.include('actor.js');
$.include('helpers.js');
$.include('config.js');
$.include('post.js');
$.include('forum_thread.js');
$.include('forum.js');

// Important parts (excerpts)

/// Settings //ABF.DIRECTIONS = {oldnew: 0, newold: 1}; //ABF.MODES = {random: 0, threaded: 1, subthreaded: 2, ordered: 3}; //ABF.PLOTS = {unique_posters: 0, users: 1, arrivals_leavers: 2, posts: 3, threads: 4, topics: 5}; // //ABF.DEFAULT_OPTIONS = {}; // //// Initialization ////ABF.DEFAULT_OPTIONS.initial_actors = 3; //ABF.DEFAULT_OPTIONS.initial_actors = 100; // Disabled in threshold mode ////ABF.DEFAULT_OPTIONS.initial_threads = 20; // Seed threads //ABF.DEFAULT_OPTIONS.initial_threads = 20; // Seed threads //ABF.DEFAULT_OPTIONS.max_threads = 20; // threads dropped after this //ABF.DEFAULT_OPTIONS.mode = ABF.MODES.ordered; // //// Chances //ABF.DEFAULT_OPTIONS.reply_chance = 25; // out of a thousand, per tick, 1 / 40.0 space * 1000 //ABF.DEFAULT_OPTIONS.new_thread_chance = 1.25; // out of a thousand, per tick, 1 / 20.0 / 40.0 * 1000 //// ABF.DEFAULT_OPTIONS.next_thread_chance = calculated on the fly; // out of a thousand, per tick, 1 / 100.0 * 1000 //ABF.DEFAULT_OPTIONS.daily_arrivals_fraction = 0.09; // 0.05 // Fraction of current arriving every day //ABF.DEFAULT_OPTIONS.desire_for_online_divider = 4.0; // > roll, current_desire divided by this, 15 / (1 / 240.0 * 1000) = 3.6 //// 240 ticks is a day, so slightly less often than once a day with avg starting desire // //// Costs and rewards //// current desire //ABF.DEFAULT_OPTIONS.c_d_max_starting = 25; // 30; // Actors receive this + c_d_leave_cutoff //// also is max carry over of current (not counting next desire (see below)) //ABF.DEFAULT_OPTIONS.c_d_leave_cutoff = 5; //ABF.DEFAULT_OPTIONS.c_d_read = -1; //ABF.DEFAULT_OPTIONS.c_d_create = -3; // If costlier, 5, can make ordered better than indented //ABF.DEFAULT_OPTIONS.c_d_page_load = -0.2; //ABF.DEFAULT_OPTIONS.c_d_received_reply = 20; // Also see r_d_received_reply //ABF.DEFAULT_OPTIONS.c_d_nothing_left_fraction = 3.0 / 4; // Substracted from any remaining that is carried over //// next //ABF.DEFAULT_OPTIONS.n_d_on_topic = 1.8; // 1.8 // 2.3 //ABF.DEFAULT_OPTIONS.n_d_off_topic = 0.5; // 0.5; // -0.5 //// reply //ABF.DEFAULT_OPTIONS.r_d_received_reply = 60; //ABF.DEFAULT_OPTIONS.r_d_drop_off = -1 * ABF.DEFAULT_OPTIONS.r_d_received_reply / 10.0; // //// Switches //ABF.DEFAULT_OPTIONS.with_thresholds = false; //ABF.DEFAULT_OPTIONS.threshold_average = 25; //ABF.DEFAULT_OPTIONS.threshold_standard_deviation = 15; //ABF.DEFAULT_OPTIONS.daily_arrivals = 10; //ABF.DEFAULT_OPTIONS.disable_reply_bonus = false; //ABF.DEFAULT_OPTIONS.disable_reciprocity = false; // true if disable_reply_bonus is set to true // //if (ABF.DEFAULT_OPTIONS.with_thresholds) { // No initial actors in thresholds mode // ABF.DEFAULT_OPTIONS.initial_actors = 0; // ABF.DEFAULT_OPTIONS.daily_arrivals_fraction = 0; //} //if (ABF.DEFAULT_OPTIONS.disable_reply_bonus) { // No reciprocity without reply-bonus // ABF.DEFAULT_OPTIONS.disable_reciprocity = true; //} // //// Normally not changed //ABF.DEFAULT_OPTIONS.direction = ABF.DIRECTIONS.newold; // new threads shown first //ABF.DEFAULT_OPTIONS.topics = 4; // Number of topics //ABF.DEFAULT_OPTIONS.topic_power = 2; // x ** i, for each power // //// Layout //ABF.SELECTED_PLOT = ABF.PLOTS.users; //ABF.SPACING = 70; //ABF.NO_BARS = true; //ABF.SCL = 1; // Scale, 1 is normal //ABF.TOPIC_CHOICE = ABF.topic_choice(ABF.DEFAULT_OPTIONS.topics); //ABF.TOPIC_COLORS = ABF.topic_colors(ABF.DEFAULT_OPTIONS.topics); //ABF.DEBUG = true; // True if debugging /// Agent attributes // if (this.forum.options.with_thresholds) { // this.threshold = this.forum.options.threshold_average + // normal_rand()[0] * this.forum.options.threshold_standard_deviation; // } // // Will be removed if true // this.left_forum = false; // // The position, false if offline // this.position = (options.position ? options.position : false); // this.next_desire = 0; // this.current_desire = this.forum.options.c_d_leave_cutoff + // Math.floor(Math.random() * (this.forum.options.c_d_max_starting)); // this.reply_desire = 0; // this.topic = ABF.choose_random_action(ABF.TOPIC_CHOICE); // actions = []; // if (this.forum.options.mode != ABF.MODES.random) { // actions.push({ // chance: this.forum.options.reply_chance, // action: this.to_reply // }, { // chance: this.forum.options.new_thread_chance, // action: this.to_new_thread // }, { // chance: this.forum.options.next_thread_chance, // action: this.to_next_thread // }, { // total: 1000, // action: this.to_next_post // }); // } else { // actions.push({ // chance: this.forum.options.reply_chance + this.forum.options.new_thread_chance, // action: this.to_new_thread // }, { // total: 1000, // action: this.to_next_thread // }); // } // this.choice = ABF.prepare_choice(actions, {bind: this}); // this.reading = true; // this.seen_thread_in_session = {}; // this.seen_reply_from_queue = []; // this.seen_reply_from = {}; // this.seen_uninteresting_in_thread = 0; // this.forum.users_count++; // if (!this.forum.users_per_topic_count[this.topic]) { // this.forum.users_per_topic_count[this.topic] = 0; // } // this.forum.users_per_topic_count[this.topic]++; // return this; /// Agent rate and objective functions // construct.prototype.run = function() { // var reply_chance; // if (this.position === false) { // is offline, rate function // if (this.current_desire < this.forum.options.c_d_leave_cutoff) { // this.leave_forum(); // } else { // var roll = Math.floor(Math.random()*1001); // if (this.current_desire / this.forum.options.desire_for_online_divider > roll) { // if desire greater than roll // this.go_online(); // this.read_current_post(); // } // } // } else { // is visiting forum, objective function // // this.own_post_bonus() could be added; // if (this.current_desire < 0) { // no desire left, leave // this.go_offline(); // } else { // last_post = this.post(); // reply_chance = 1.0 * this.forum.options.reply_chance + this.reply_desire; // if (this.seen_reply_from[last_post.author_id]) { // undefined author_id is impossible, as checked on set // reply_chance = reply_chance * 3; // } // if (this.forum.options.mode != ABF.MODES.random) { // this.choice.actions[0].chance = reply_chance; // this.choice.actions[2].chance = this.seen_uninteresting_in_thread * 4; // } else { // this.choice.actions[0].chance = reply_chance + this.forum.options.new_thread_chance; // } // this.choice = ABF.calculate_choice_cutoffs(this.choice); // //ABF.choose_random_action(this.choice, {boost: [0, this.current_desire + this.reply_desire]}); // ABF.choose_random_action(this.choice); // both reply_ and seen_uninteresting here for boost implementation reasons // if (this.position !== false) { // this.read_current_post(); // } // } // // reduce reply desire with time // if (this.reply_desire >= this.forum.options.r_d_drop_off) { // this.reply_desire += this.forum.options.r_d_drop_off; // } else { // this.reply_desire = 0; // } // } // };