জনপ্রিয় অনুরোধ অনুযায়ী আপডেট করা হয়েছে
সাধারণ আচরণ
প্রোগ্রামটি এখন কিছুটা ইন্টারেক্টিভ।
উত্স কোডটি সম্পূর্ণ প্যারামিট্রাইজড, যাতে আপনি আপনার প্রিয় পাঠ্য সম্পাদকের সাথে আরও কয়েকটি অভ্যন্তরীণ প্যারামিটারগুলি টুইচ করতে পারেন।
আপনি বনের আকার পরিবর্তন করতে পারেন।
নূন্যতম 2 টির জন্য 3 টি বিভিন্ন দাগে একটি গাছ, একটি কাঠের কাঁটা এবং ভালুক রাখার জন্য পর্যাপ্ত জায়গা থাকা দরকার এবং সর্বোচ্চটি নির্বিচারে 100 টি স্থির করা হয় (যা আপনার গড় কম্পিউটারকে ক্রল করবে)।
আপনি সিমুলেশন গতিও পরিবর্তন করতে পারেন।
প্রতি 20 এমএসে প্রদর্শন আপডেট করা হয়, সুতরাং একটি বৃহত্তর সময় ধাপে সূক্ষ্ম অ্যানিমেশন তৈরি হবে।
বোতামগুলি সিমুলেশনটি থামাতে / শুরু করতে, বা এক মাস বা এক বছরের জন্য চালানোর অনুমতি দেয়।
বনবাসীদের চলাচল এখন কিছুটা অ্যানিমেটেড। মলিং এবং গাছ কাটার ঘটনাগুলিও চিত্রিত হয়।
কিছু ইভেন্টের লগও প্রদর্শিত হয়। আপনি যদি ভার্বোসিটি স্তর পরিবর্তন করেন তবে আরও কিছু বার্তা পাওয়া যায়, তবে এটি আপনাকে "বব আরও একটি গাছ কাটবে" বিজ্ঞপ্তি দিয়ে বন্যা করে।
আমি যদি আপনি থাকতাম তবে আমি এটি করতাম না, তবে আমি তা করি না, তাই ...
খেলার মাঠের পাশেই, অটো-স্কেলেড গ্রাফিক্সের একটি সেট আঁকা:
- ভাল্লুক এবং লম্বারজ্যাকস জনসংখ্যা
- চারা, পরিপক্ক এবং বড় গাছগুলিতে বিভক্ত মোট গাছের সংখ্যা
কিংবদন্তি প্রতিটি আইটেমের বর্তমান পরিমাণ প্রদর্শন করে।
সিস্টেমের স্থিতিশীলতা
গ্রাফগুলি দেখায় যে প্রাথমিক শর্তগুলি কৃপণভাবে স্কেল করে না। যদি বনটি খুব বড় হয়, তবে অনেকগুলি ভালুক লম্বারজ্যাকের জনসংখ্যা হ্রাস করে যতক্ষণ না প্যানকেকপ্রেমীদের যথেষ্ট পরিমাণে কারাগারে আটকানো হয়। এটি বড় গাছগুলির প্রাথমিক বিস্ফোরণ ঘটায়, যার ফলে লম্বারজ্যাক জনগণ পুনরুদ্ধারে সহায়তা করে।
15 টি বনের বেঁচে থাকার জন্য সর্বনিম্ন আকার বলে মনে হচ্ছে। 10 মাপের একটি বন সাধারণত কয়েকশ বছর পরে ধ্বংসস্তূপে পরিণত হবে। ৩০ এর উপরে যে কোনও আকারের গাছগুলি পূর্ণ একটি মানচিত্র তৈরি করবে। 15 থেকে 30 এর মধ্যে আপনি গাছের জনসংখ্যা উল্লেখযোগ্যভাবে দোলায়মান দেখতে পাচ্ছেন।
কিছু বিতর্কযোগ্য নিয়ম পয়েন্ট
মূল পোস্টের মন্তব্যে, দেখে মনে হচ্ছে যে বিভিন্ন বিপিড একই স্থান দখল করার কথা নয়। এটি কোনওভাবেই রেডনেক প্যানকেক অপেশাদারের মধ্যে বিচরণ সম্পর্কে নিয়মের বিরোধিতা করে।
কোনও হারে, আমি সেই নির্দেশিকাটি অনুসরণ করি নি। যে কোনও বনকোষে যে কোনও সংখ্যক অনাবাদী (এবং ঠিক শূন্য বা একটি গাছ) ধারণ করতে পারে। লম্বারজ্যাকের দক্ষতায় এর কিছু পরিণতি হতে পারে: আমার সন্দেহ হয় যে এটি তাদের আরও বড় আকারের বড় গাছের গোছা খননের অনুমতি দেয়। ভালুক হিসাবে, আমি এটি অনেক পার্থক্য করা আশা করি না।
আমি বনে সর্বদা কমপক্ষে একটি কাঠের ঝাঁকুনির পথ বেছে নিয়েছি, এই বিন্দুটি সত্ত্বেও যে রেডনেক জনসংখ্যা শূন্যে পৌঁছতে পারে (ফসলটি যদি সত্যিই দরিদ্র না হত তবে মানচিত্রে শেষ কাঠের ঝাঁকুনি ছোঁড়া, যা বনভূমি না হলে কখনও ঘটবে না) বিলুপ্তির নিচে কাটা)।
tweaking
স্থিতিশীলতা অর্জনের জন্য, আমি দুটি টুইট পরামিতি যুক্ত করেছি:
1) লম্বারজ্যাকগুলি বৃদ্ধির হার
সূত্রটিতে প্রয়োগ করা একটি সহগ যা পর্যাপ্ত কাঠবাদাম রয়েছে তখন ভাড়া নেওয়া অতিরিক্ত লম্বারজ্যাকের সংখ্যা দেয়। মূল সংজ্ঞা ফিরে পেতে 1 এ সেট করুন, তবে আমি প্রায় 5 টির একটি বুনো (উদাহরণস্বরূপ বড় গাছগুলি) আরও উন্নত করার অনুমতি পেয়েছি found
2) ভালুক অপসারণের মানদণ্ড
একটি গুণাগুণ যা চিড়িয়াখানায় একটি ভালুক প্রেরণে মাউড লম্বারজ্যাকগুলির ন্যূনতম শতাংশ নির্ধারণ করে। মূল সংজ্ঞায় ফিরে যেতে 0 তে সেট করুন, তবে এই কঠোর ভালুক নির্মূলকরণ মূলত জনসংখ্যাকে 0-1 দোলনচক্রের মধ্যে সীমাবদ্ধ করবে। আমি এটি .15 তে সেট করে রেখেছি (অর্থাত্ এই বছর 15% বা আরও বেশি লম্বারজ্যাকগুলি ম্যুড করা থাকলে কেবল একটি ভালুক সরানো হবে)। এটি মধ্যম ভাল্লুক জনসংখ্যার জন্য অনুমতি দেয়, অঞ্চলটি পরিষ্কার করে দিয়ে লালচেগুলি রোধ করতে যথেষ্ট তবে তবুও বনের বেশিরভাগ অংশ কেটে ফেলার অনুমতি দেয়।
পার্শ্ব নোট হিসাবে, সিমুলেশন কখনও থামে না (এমনকি প্রয়োজনীয় 400 বছর পেরিয়ে যায়)। এটি সহজেই এটি করতে পারে, তবে তা হয় না।
কোড
কোডটি সম্পূর্ণ একক এইচটিএমএল পৃষ্ঠায় অন্তর্ভুক্ত থাকে। ভালুক এবং লম্বারজ্যাকের জন্য উপযুক্ত ইউনিকোড প্রতীকগুলি প্রদর্শন করতে
এটি অবশ্যই ইউটিএফ -8 এনকোড হওয়া উচিত ।
ইউনিকোড প্রতিবন্ধী সিস্টেমগুলির জন্য (যেমন উবুন্টু): নিম্নলিখিত লাইনগুলি সন্ধান করুন:
jack :{ pic: '🙎', color:'#bc0e11' },
bear :{ pic: '🐻', color:'#422f1e' }},
ও ডিসপ্লে করা আরো সহজ অক্ষরের জন্য pictograms পরিবর্তন ( #
, *
যাই হোক না কেন)
<!doctype html>
<meta charset=utf-8>
<title>Of jacks and bears</title>
<body onload='init();'>
<style>
#log p { margin-top: 0; margin-bottom: 0; }
</style>
<div id='main'>
</div>
<table>
<tr>
<td><canvas id='forest'></canvas></td>
<td>
<table>
<tr>
<td colspan=2>
<div>Forest size <input type='text' size=10 onchange='create_forest(this.value);'> </div>
<div>Simulation tick <input type='text' size= 5 onchange='set_tick(this.value);' > (ms)</div>
<div>
<input type='button' value='◾' onclick='stop();'>
<input type='button' value='▸' onclick='start();'>
<input type='button' value='1 month' onclick='start(1);'>
<input type='button' value='1 year' onclick='start(12);'>
</div>
</td>
</tr>
<tr>
<td id='log' colspan=2>
</td>
</tr>
<tr>
<td><canvas id='graphs'></canvas></td>
<td id='legend'></td>
</tr>
<tr>
<td align='center'>evolution over 60 years</td>
<td id='counters'></td>
</tr>
</table>
</td>
</tr>
</table>
<script>
// ==================================================================================================
// Global parameters
// ==================================================================================================
var Prm = {
// ------------------------------------
// as defined in the original challenge
// ------------------------------------
// forest size
forest_size: 45, // 2025 cells
// simulation duration
duration: 400*12, // 400 years
// initial populations
populate: { trees: .5, jacks:.1, bears:.02 },
// tree ages
age: { mature:12, elder:120 },
// tree spawning probabilities
spawn: { sapling:0, mature:.1, elder:.2 },
// tree lumber yields
lumber: { mature:1, elder:2 },
// walking distances
distance: { jack:3, bear:5 },
// ------------------------------------
// extra tweaks
// ------------------------------------
// lumberjacks growth rate
// (set to 1 in original contest parameters)
jacks_growth: 1, // .5,
// minimal fraction of lumberjacks mauled to send a bear to the zoo
// (set to 0 in original contest parameters)
mauling_threshold: .15, // 0,
// ------------------------------------
// internal helpers
// ------------------------------------
// offsets to neighbouring cells
neighbours: [
{x:-1, y:-1}, {x: 0, y:-1}, {x: 1, y:-1},
{x:-1, y: 0}, {x: 1, y: 0},
{x:-1, y: 1}, {x: 0, y: 1}, {x: 1, y: 1}],
// ------------------------------------
// goodies
// ------------------------------------
// bear and people names
names:
{ bear: ["Art", "Ursula", "Arthur", "Barney", "Bernard", "Bernie", "Bjorn", "Orson", "Osborn", "Torben", "Bernadette", "Nita", "Uschi"],
jack: ["Bob", "Tom", "Jack", "Fred", "Paul", "Abe", "Roy", "Chuck", "Rob", "Alf", "Tim", "Tex", "Mel", "Chris", "Dave", "Elmer", "Ian", "Kyle", "Leroy", "Matt", "Nick", "Olson", "Sam"] },
// months
month: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" ],
// ------------------------------------
// graphics
// ------------------------------------
// messages verbosity (set to 2 to be flooded, -1 to have no trace at all)
verbosity: 1,
// pixel sizes
icon_size: 100,
canvas_f_size: 600, // forest canvas size
canvas_g_width : 400, // graphs canvas size
canvas_g_height: 200,
// graphical representation
graph: {
soil: { color: '#82641e' },
sapling:{ radius:.1, color:'#52e311', next:'mature'},
mature :{ radius:.3, color:'#48b717', next:'elder' },
elder :{ radius:.5, color:'#8cb717', next:'elder' },
jack :{ pic: '🙎', color:'#2244ff' },
bear :{ pic: '🐻', color:'#422f1e' },
mauling:{ pic: '★', color:'#ff1111' },
cutting:{ pic: '●', color:'#441111' }},
// animation tick
tick:100 // ms
};
// ==================================================================================================
// Utilities
// ==================================================================================================
function int_rand (num)
{
return Math.floor (Math.random() * num);
}
function shuffle (arr)
{
for (
var j, x, i = arr.length;
i;
j = int_rand (i), x = arr[--i], arr[i] = arr[j], arr[j] = x);
}
function pick (arr)
{
return arr[int_rand(arr.length)];
}
function message (str, level)
{
level = level || 0;
if (level <= Prm.verbosity)
{
while (Gg.log.childNodes.length > 10) Gg.log.removeChild(Gg.log.childNodes[0]);
var line = document.createElement ('p');
line.innerHTML = Prm.month[Forest.date%12]+" "+Math.floor(Forest.date/12)+": "+str;
Gg.log.appendChild (line);
}
}
// ==================================================================================================
// Forest
// ==================================================================================================
// --------------------------------------------------------------------------------------------------
// a forest cell
// --------------------------------------------------------------------------------------------------
function cell()
{
this.contents = [];
}
cell.prototype = {
add: function (elt)
{
this.contents.push (elt);
},
remove: function (elt)
{
var i = this.contents.indexOf (elt);
this.contents.splice (i, 1);
},
contains: function (type)
{
for (var i = 0 ; i != this.contents.length ; i++)
{
if (this.contents[i].type == type)
{
return this.contents[i];
}
}
return null;
}
}
// --------------------------------------------------------------------------------------------------
// an entity (tree, jack, bear)
// --------------------------------------------------------------------------------------------------
function entity (x, y, type)
{
this.age = 0;
switch (type)
{
case "jack": this.name = pick (Prm.names.jack); break;
case "bear": this.name = pick (Prm.names.bear); break;
case "tree": this.name = "sapling"; Forest.t.low++; break;
}
this.x = this.old_x = x;
this.y = this.old_y = y;
this.type = type;
}
entity.prototype = {
move: function ()
{
Forest.remove (this);
var n = neighbours (this);
this.x = n[0].x;
this.y = n[0].y;
return Forest.add (this);
}
};
// --------------------------------------------------------------------------------------------------
// a list of entities (trees, jacks, bears)
// --------------------------------------------------------------------------------------------------
function elt_list (type)
{
this.type = type;
this.list = [];
}
elt_list.prototype = {
add: function (x, y)
{
if (x === undefined) x = int_rand (Forest.size);
if (y === undefined) y = int_rand (Forest.size);
var e = new entity (x, y, this.type);
Forest.add (e);
this.list.push (e);
return e;
},
remove: function (elt)
{
var i;
if (elt) // remove a specific element (e.g. a mauled lumberjack)
{
i = this.list.indexOf (elt);
}
else // pick a random element (e.g. a bear punished for the collective pancake rampage)
{
i = int_rand(this.list.length);
elt = this.list[i];
}
this.list.splice (i, 1);
Forest.remove (elt);
if (elt.name == "mature") Forest.t.mid--;
if (elt.name == "elder" ) Forest.t.old--;
return elt;
}
};
// --------------------------------------------------------------------------------------------------
// global forest handling
// --------------------------------------------------------------------------------------------------
function forest (size)
{
// initial parameters
this.size = size;
this.surface = size * size;
this.date = 0;
this.mauling = this.lumber = 0;
this.t = { low:0, mid:0, old:0 };
// initialize cells
this.cells = new Array (size);
for (var i = 0 ; i != size ; i++)
{
this.cells[i] = new Array(size);
for (var j = 0 ; j != size ; j++)
{
this.cells[i][j] = new cell;
}
}
// initialize entities lists
this.trees = new elt_list ("tree");
this.jacks = new elt_list ("jack");
this.bears = new elt_list ("bear");
this.events = [];
}
forest.prototype = {
populate: function ()
{
function fill (num, list)
{
for (var i = 0 ; i < num ; i++)
{
var coords = pick[i_pick++];
list.add (coords.x, coords.y);
}
}
// shuffle forest cells
var pick = new Array (this.surface);
for (var i = 0 ; i != this.surface ; i++)
{
pick[i] = { x:i%this.size, y:Math.floor(i/this.size)};
}
shuffle (pick);
var i_pick = 0;
// populate the lists
fill (Prm.populate.jacks * this.surface, this.jacks);
fill (Prm.populate.bears * this.surface, this.bears);
fill (Prm.populate.trees * this.surface, this.trees);
this.trees.list.forEach (function (elt) { elt.age = Prm.age.mature; });
},
add: function (elt)
{
var cell = this.cells[elt.x][elt.y];
cell.add (elt);
return cell;
},
remove: function (elt)
{
var cell = this.cells[elt.x][elt.y];
cell.remove (elt);
},
evt_mauling: function (jack, bear)
{
message (bear.name+" sniffs a delicious scent of pancake, unfortunately for "+jack.name, 1);
this.jacks.remove (jack);
this.mauling++;
Gg.counter.mauling.innerHTML = this.mauling;
this.register_event ("mauling", jack);
},
evt_cutting: function (jack, tree)
{
if (tree.name == 'sapling') return; // too young to be chopped down
message (jack.name+" cuts a "+tree.name+" tree: lumber "+this.lumber+" (+"+Prm.lumber[tree.name]+")", 2);
this.trees.remove (tree);
this.lumber += Prm.lumber[tree.name];
Gg.counter.cutting.innerHTML = this.lumber;
this.register_event ("cutting", jack);
},
register_event: function (type, position)
{
this.events.push ({ type:type, x:position.x, y:position.y});
},
tick: function()
{
this.date++;
this.events = [];
// monthly updates
this.trees.list.forEach (b_tree);
this.jacks.list.forEach (b_jack);
this.bears.list.forEach (b_bear);
// feed graphics
Gg.graphs.trees.add (this.trees.list.length);
Gg.graphs.jacks.add (this.jacks.list.length);
Gg.graphs.bears.add (this.bears.list.length);
Gg.graphs.sapling.add (this.t.low);
Gg.graphs.mature .add (this.t.mid);
Gg.graphs.elder .add (this.t.old);
// yearly updates
if (!(this.date % 12))
{
// update jacks
if (this.jacks.list.length == 0)
{
message ("An extra lumberjack is hired after a bear rampage");
this.jacks.add ();
}
if (this.lumber >= this.jacks.list.length)
{
var extra_jacks = Math.floor (this.lumber / this.jacks.list.length * Prm.jacks_growth);
message ("A good lumbering year. Lumberjacks +"+extra_jacks, 1);
for (var i = 0 ; i != extra_jacks ; i++) this.jacks.add ();
}
else if (this.jacks.list.length > 1)
{
var fired = this.jacks.remove();
message (fired.name+" has been chopped", 1);
}
// update bears
if (this.mauling > this.jacks.list.length * Prm.mauling_threshold)
{
var bear = this.bears.remove();
message (bear.name+" will now eat pancakes in a zoo", 1);
}
else
{
var bear = this.bears.add();
message (bear.name+" starts a quest for pancakes", 1);
}
// reset counters
this.mauling = this.lumber = 0;
}
}
}
function neighbours (elt)
{
var ofs,x,y;
var list = [];
for (ofs in Prm.neighbours)
{
var o = Prm.neighbours[ofs];
x = elt.x + o.x;
y = elt.y + o.y;
if ( x < 0 || x >= Forest.size
|| y < 0 || y >= Forest.size) continue;
list.push ({x:x, y:y});
}
shuffle (list);
return list;
}
// --------------------------------------------------------------------------------------------------
// entities behaviour
// --------------------------------------------------------------------------------------------------
function b_tree (tree)
{
// update tree age and category
if (tree.age == Prm.age.mature) { tree.name = "mature"; Forest.t.low--; Forest.t.mid++; }
else if (tree.age == Prm.age.elder ) { tree.name = "elder" ; Forest.t.mid--; Forest.t.old++; }
tree.age++;
// see if we can spawn something
if (Math.random() < Prm.spawn[tree.name])
{
var n = neighbours (tree);
for (var i = 0 ; i != n.length ; i++)
{
var coords = n[i];
var cell = Forest.cells[coords.x][coords.y];
if (cell.contains("tree")) continue;
Forest.trees.add (coords.x, coords.y);
break;
}
}
}
function b_jack (jack)
{
jack.old_x = jack.x;
jack.old_y = jack.y;
for (var i = 0 ; i != Prm.distance.jack ; i++)
{
// move
var cell = jack.move ();
// see if we stumbled upon a bear
var bear = cell.contains ("bear");
if (bear)
{
Forest.evt_mauling (jack, bear);
break;
}
// see if we reached an harvestable tree
var tree = cell.contains ("tree");
if (tree)
{
Forest.evt_cutting (jack, tree);
break;
}
}
}
function b_bear (bear)
{
bear.old_x = bear.x;
bear.old_y = bear.y;
for (var i = 0 ; i != Prm.distance.bear ; i++)
{
var cell = bear.move ();
var jack = cell.contains ("jack");
if (jack)
{
Forest.evt_mauling (jack, bear);
break; // one pancake hunt per month is enough
}
}
}
// --------------------------------------------------------------------------------------------------
// Graphics
// --------------------------------------------------------------------------------------------------
function init()
{
function create_counter (desc)
{
var counter = document.createElement ('span');
var item = document.createElement ('p');
item.innerHTML = desc.name+" ";
item.style.color = desc.color;
item.appendChild (counter);
return { item:item, counter:counter };
}
// initialize forest canvas
Gf = { period:20, tick:0 };
Gf.canvas = document.getElementById ('forest');
Gf.canvas.width =
Gf.canvas.height = Prm.canvas_f_size;
Gf.ctx = Gf.canvas.getContext ('2d');
Gf.ctx.textBaseline = 'Top';
// initialize graphs canvas
Gg = { counter:[] };
Gg.canvas = document.getElementById ('graphs');
Gg.canvas.width = Prm.canvas_g_width;
Gg.canvas.height = Prm.canvas_g_height;
Gg.ctx = Gg.canvas.getContext ('2d');
// initialize graphs
Gg.graphs = {
jacks: new graphic({ name:"lumberjacks" , color:Prm.graph.jack.color }),
bears: new graphic({ name:"bears" , color:Prm.graph.bear.color, ref:'jacks' }),
trees: new graphic({ name:"trees" , color:'#0F0' }),
sapling: new graphic({ name:"saplings" , color:Prm.graph.sapling.color, ref:'trees' }),
mature: new graphic({ name:"mature trees", color:Prm.graph.mature .color, ref:'trees' }),
elder: new graphic({ name:"elder trees" , color:Prm.graph.elder .color, ref:'trees' })
};
Gg.legend = document.getElementById ('legend');
for (g in Gg.graphs)
{
var gr = Gg.graphs[g];
var c = create_counter (gr);
gr.counter = c.counter;
Gg.legend.appendChild (c.item);
}
// initialize counters
var counters = document.getElementById ('counters');
var def = [ "mauling", "cutting" ];
var d; for (d in def)
{
var c = create_counter ({ name:def[d], color:Prm.graph[def[d]].color });
counters.appendChild (c.item);
Gg.counter[def[d]] = c.counter;
}
// initialize log
Gg.log = document.getElementById ('log');
// create our forest
create_forest(Prm.forest_size);
start();
}
function create_forest (size)
{
if (size < 2) size = 2;
if (size > 100) size = 100;
Forest = new forest (size);
Prm.icon_size = Prm.canvas_f_size / size;
Gf.ctx.font = 'Bold '+Prm.icon_size+'px Arial';
Forest.populate ();
draw_forest();
var g; for (g in Gg.graphs) Gg.graphs[g].reset();
draw_graphs();
}
function animate()
{
if (Gf.tick % Prm.tick == 0)
{
Forest.tick();
draw_graphs();
}
draw_forest();
Gf.tick+= Gf.period;
if (Gf.tick == Gf.stop_date) stop();
}
function draw_forest ()
{
function draw_dweller (dweller)
{
var type = Prm.graph[dweller.type];
Gf.ctx.fillStyle = type.color;
var x = dweller.x * time_fraction + dweller.old_x * (1 - time_fraction);
var y = dweller.y * time_fraction + dweller.old_y * (1 - time_fraction);
Gf.ctx.fillText (type.pic, x * Prm.icon_size, (y+1) * Prm.icon_size);
}
function draw_event (evt)
{
var gr = Prm.graph[evt.type];
Gf.ctx.fillStyle = gr.color;
Gf.ctx.fillText (gr.pic, evt.x * Prm.icon_size, (evt.y+1) * Prm.icon_size);
}
function draw_tree (tree)
{
// trees grow from one category to the next
var type = Prm.graph[tree.name];
var next = Prm.graph[type.next];
var radius = (type.radius + (next.radius - type.radius) / Prm.age[type.next] * tree.age) * Prm.icon_size;
Gf.ctx.fillStyle = Prm.graph[tree.name].color;
Gf.ctx.beginPath();
Gf.ctx.arc((tree.x+.5) * Prm.icon_size, (tree.y+.5) * Prm.icon_size, radius, 0, 2*Math.PI);
Gf.ctx.fill();
}
// background
Gf.ctx.fillStyle = Prm.graph.soil.color;
Gf.ctx.fillRect (0, 0, Gf.canvas.width, Gf.canvas.height);
// time fraction to animate displacements
var time_fraction = (Gf.tick % Prm.tick) / (Prm.tick-Gf.period);
// entities
Forest.trees.list.forEach (draw_tree);
Forest.jacks.list.forEach (draw_dweller);
Forest.bears.list.forEach (draw_dweller);
Forest.events.forEach (draw_event);
}
// --------------------------------------------------------------------------------------------------
// Graphs
// --------------------------------------------------------------------------------------------------
function graphic (prm)
{
this.name = prm.name || '?';
this.color = prm.color || '#FFF';
this.size = prm.size || 720;
this.ref = prm.ref;
this.values = [];
this.counter = document.getElement
}
graphic.prototype = {
draw: function ()
{
Gg.ctx.strokeStyle = this.color;
Gg.ctx.beginPath();
for (var i = 0 ; i != this.values.length ; i++)
{
var x = (i + this.size - this.values.length) / this.size * Gg.canvas.width;
var y = (1-(this.values[i] - this.min) / this.rng) * Gg.canvas.height;
if (i == 0) Gg.ctx.moveTo (x, y);
else Gg.ctx.lineTo (x, y);
}
Gg.ctx.stroke();
},
add: function (value)
{
// store value
this.values.push (value);
this.counter.innerHTML = value;
// cleanup history
while (this.values.length > this.size) this.values.splice (0,1);
// compute min and max
this.min = Math.min.apply(Math, this.values);
if (this.min > 0) this.min = 0;
this.max = this.ref
? Gg.graphs[this.ref].max
: Math.max.apply(Math, this.values);
this.rng = this.max - this.min;
if (this.rng == 0) this.rng = 1;
},
reset: function()
{
this.values = [];
}
}
function draw_graphs ()
{
function draw_graph (graph)
{
graph.draw();
}
// background
Gg.ctx.fillStyle = '#000';
Gg.ctx.fillRect (0, 0, Gg.canvas.width, Gg.canvas.height);
// graphs
var g; for (g in Gg.graphs)
{
var gr = Gg.graphs[g];
gr.draw();
}
}
// --------------------------------------------------------------------------------------------------
// User interface
// --------------------------------------------------------------------------------------------------
function set_tick(value)
{
value = Math.round (value / Gf.period);
if (value < 2) value = 2;
value *= Gf.period;
Prm.tick = value;
return value;
}
function start (duration)
{
if (Prm.timer) stop();
Gf.stop_date = duration ? Gf.tick + duration*Prm.tick : -1;
Prm.timer = setInterval (animate, Gf.period);
}
function stop ()
{
if (Prm.timer)
{
clearInterval (Prm.timer);
Prm.timer = null;
}
Gf.stop_date = -1;
}
</script>
</body>
এরপর কী?
আরও মন্তব্য এখনও স্বাগত।
এনবি: আমি সচেতন চারা / পরিপক্ক / বড় গাছের গণনা এখনও কিছুটা অগোছালো তবে এর সাথে নরকও বটে।
এছাড়াও, আমি ডকুমেন্ট.গেটমেন্টমেন্ট বাই দ্বারা আইডি $ এর চেয়ে বেশি পাঠযোগ্য, তাই jQueryism এর অভাব সম্পর্কে অভিযোগ করার দরকার নেই। এটি jQuery বিনামূল্যে। প্রত্যেকের নিজের, তাই না?
Note that you will never reduce your Lumberjack labor force below 0
লম্বারজ্যাক বিভাগের তালিকা আইটেমে ৩. আপনি ভালুক বিভাগে যা উল্লেখ করেছেন তার সাথে সামঞ্জস্য থাকতে সম্ভবত এটি 1 তে পরিবর্তন করুন?