エスカレータシミュレーション
https://gyazo.com/760d6ac078a0c67ed78998cef5ace9af.gif http://www.pitecan.com/Puzzle/escalator/
ランダムに客が来るとか
code:escalator.js
STRATEGY1 = 0; // 左優先
STRATEGY2 = 1; // 右優先
lspeedfactor = 1.0;
lgapfactor = 2.0;
rspeedfactor = 2.0;
rgapfactor = 3.0;
strategy = STRATEGY2;
var pair = location.search.substring(1).split('&');
for(var i=0; pairi; i++){ var kv = pairi.split('='); if(kv0 == 'ls') lspeedfactor = kv1; if(kv0 == 'lg') lgapfactor = kv1; if(kv0 == 'rs') rspeedfactor = kv1; if(kv0 == 'rg') rgapfactor = kv1; }
MOVING_LOWER = 0;
WAITING_LOWER = 1;
ASCENDING = 2;
UPPER = 3;
LEFT = 0;
RIGHT = 1;
llane = 220.0;
rlane = 250.0;
escheight = 460.0;
WINWIDTH = 500;
WINHEIGHT = 500;
NPERSONS = 50;
NSTAIRS = 15;
STAIRHEIGHT = 60;
STEPUNIT = 1;
steppos = 0;
waiting_l = 0;
waiting_r = 0;
done = false;
xspeed = 1.0;
persons = [];;
loops = 0;
var Person = function(){
this.x = 0.0;
this.y = 0.0;
this.status = MOVING_LOWER;
this.lr = LEFT;
};
function setup(){
createCanvas(WINWIDTH,WINHEIGHT);
frameRate(60);
for(var i=0;i<NPERSONS;i++){
}
}
function can_ascend_l(n){
var result = true;
for(var i=0;i<n;i++){
if(personsi.status == ASCENDING && personsi.y - personsn.y < STAIRHEIGHT * lgapfactor){ return false;
}
}
return true;
}
function can_ascend_r(n){
for(var i=0;i<n;i++){
if(personsi.status == ASCENDING && personsi.y - personsn.y < STAIRHEIGHT * rgapfactor){ return false;
}
}
return true;
}
function can_forward_lower(n){
for(var i=0;i<n;i++){
if(personsi.status == MOVING_LOWER && personsi.x - personsn.y < 30.0){ return false;
}
}
return true;
}
function can_forward_upper(n){
for(var i=0;i<NPERSONS;i++){
if(personsi.status == UPPER && personsi.x - personsn.x > 0.0 && personsi.x - personsn.x < 30.0){ return false;
}
}
return true;
}
function all_upper(){
for(var i=0;i<NPERSONS;i++){
if(personsi.status != UPPER) return false; }
return true;
}
function draw(){
if(done) return;
background(213,200,255);
for(var i=0;i<NSTAIRS;i++){
y = i * STAIRHEIGHT + steppos;
//line(llane-10+10,WINHEIGHT-y,rlane+10+20+10,WINHEIGHT-y);
fill(200,200,200);
strokeWeight(0);
rect(llane-10+10,WINHEIGHT-y,rlane-llane+40,STAIRHEIGHT/2);
}
steppos += STEPUNIT;
if(steppos >= STAIRHEIGHT){
steppos = 0;
}
for(var i=0;i<NPERSONS;i++){ // 駒をひとつずつ進める。
case MOVING_LOWER: // 下で移動中
if(personsi.x >= llane && // 左レーンまでたどりついたとき if(strategy == STRATEGY1){
if(waiting_l == 0 || waiting_l < waiting_r){
personsi.status = WAITING_LOWER; waiting_l++;
}
else {
personsi.lr = RIGHT; // 右で待つことにする }
}
else if(strategy == STRATEGY2){
if(waiting_l < waiting_r){
personsi.status = WAITING_LOWER; waiting_l++;
}
else {
personsi.lr = RIGHT; // 右で待つことにする }
}
}
else if(personsi.x >= rlane && // 右レーンまでたどりついたとき personsi.status = WAITING_LOWER; waiting_r++;
}
if(can_forward_lower(i)){ // 前に進める場合は一歩前に移動する
}
break;
case UPPER: // エスカレータからおりていて
if(can_forward_upper(i)){ // 前に進める場合は一歩前に移動する
}
break;
case WAITING_LOWER: // エスカレータ待ち状態で、
if(personsi.lr == LEFT && // 左で待っていて can_ascend_l(i) // 上に余地がある
){
personsi.status = ASCENDING; waiting_l--;
}
else if(personsi.lr == RIGHT && // 右で待っていて can_ascend_r(i) // 上に余地がある
){
personsi.status = ASCENDING; waiting_r--;
}
break;
case ASCENDING: //エスカレータに乗っていたら
if(personsi.y >= escheight){ // エスカレータで上まで到達していればおりる }
else {
personsi.y += STEPUNIT * lspeedfactor; // 1段上に移動する }
else {
personsi.y += STEPUNIT * rspeedfactor; // 1段上に移動する }
}
break;
}
}
strokeWeight(1);
for(var i=NPERSONS-1;i>=0;i--){
fill(255,255,0);
rect(personsi.x+10,WINHEIGHT-30-personsi.y,20,20); fill(0,0,0);
text(i+1,personsi.x+10+3,WINHEIGHT-30-personsi.y+14); }
if(! all_upper()){
loops++;
}
else {
done = true;
}
fill(0,0,0);
// text(millis(),20,20);
text(loops,20,20);
}