#define NMAX 200
#define Qtime 4    // 量子時間
#define OverHead 1 // 1量子時間あたりのオーバヘッド
int enQue(int DT, int Que[], int nQue, int Qsize){
	if(nQue >= Qsize) return - nQue;// オーバしたとき負のポインタを返す
	Que[nQue]=DT;return (nQue + 1); // Queのポインタを返す。
}
int deQue(int Que[], int *nQue, int Qsize){
	if(*nQue == 0) return - 1;  // 空のとき-1を返す
	int DT=Que[0]; for(int i=0; i< *nQue;i++) Que[i]=Que[i+1]; 
	(*nQue)--;
	return DT;   
}
int main(void)
{   
	int nQ0=4, Q0[]={0,1,2,3}, nQ1=0, Q1[4], nQ2=0, Q2[4];
	int n=4; double burstTime[]={50,40,30,20};//バースト時間を入れる
	int notStart[]={true,true,true,true};
	int pE=0, execProc[NMAX];
	double T0=0, Tend, TendTotal=0;int notEnd=true;
	int count=0;
	while(nQ0!=0 || nQ1!=0 || nQ2!=0){
		count++;
		if((count % 4)==0){
		  if(nQ0==0)while(nQ1 !=0){
			  int DT=deQue(Q1,&nQ1,n);
			  printf("\n  --Move Que 1 to Que 0 Proc No. %d",DT+1);
			  nQ0 = enQue(DT,Q0,nQ0,n);
		  }
		  if(nQ1==0)while(nQ2 !=0){
			  int DT=deQue(Q2,&nQ2,n);
			  printf("\n  --Move Que 2 to Que 1 Proc No. %d",DT+1);
			  nQ1=enQue(DT,Q1,nQ1,n);
		  }
		}
		int i;
		int Qmax=Qtime  ; i=deQue(Q0,&nQ0,n);
		if(i<0){	Qmax=Qtime*2; i=deQue(Q1,&nQ1,n);		}
		if(i<0){ Qmax=9999   ; i=deQue(Q2,&nQ2,n);}
		if(i<0) break;
		double addTime=Qmax;
		if(burstTime[i]<Qmax) addTime=burstTime[i]; 
		Tend = T0 + OverHead + addTime; burstTime[i] -= addTime;   
		for(int j=0;j<(int)addTime ;j++)execProc[pE++]=i;// 実行プロセスの保管
		char str[20];						// Start,Endの文字列設定
		if     (notStart[i] && burstTime[i]<=0) strcpy(str,"Start and End");
		else if(notStart[i]                   ) strcpy(str,"Start");
		else if(               burstTime[i]<=0) strcpy(str,"End");
		else                                    strcpy(str,"");   
		if(notStart[i]) notStart[i]= false;	// プロセス開始とする
		if(burstTime[i]==0) TendTotal +=Tend;	// ターンアランド決定 
		printf("\n  time %7.2lf to  %7.2lf, Exec Time= %7.2lf: Process %d %s",
				T0,Tend, addTime,i+1, str);
		T0=Tend;
		if(burstTime[i]>0){
			if(Qmax==Qtime){
				nQ1 = enQue(i,Q1,nQ1,n); 
				if(nQ1<0){ printf("\n*** Que 1 Over Frow ***\n"); break;}
				printf("\n  **enQue 1 Process No.%d",i+1);
			}
			else{
				nQ2 = enQue(i,Q2,nQ2,n);
				if(nQ1<0){printf("\n*** Que 2 Over Frow ***\n"); break;}
				printf("\n  ** enQue 2 Process No.%d",i+1);
			}
		}
		getch();
	}
	printf("\n  *** Avarage of turnaround time =%7.3lf", TendTotal/(double)n);
	printf("\n\n                  ");           // ガントチャート式の表示
	for(int j=1;j<pE+1;j++)printf("%2d",j % 10);
	for(int i=0;i<n;i++){
		printf("\n Process No. %2d : ",i+1);
		int M;for(M=pE-1;M>=0 && execProc[M]!=i;M--);
		for(int j=0;j<=M;j++) if(execProc[j]==i)printf("=");else printf("…");
	}
	getch();
	return 0;
}