/* Rahman ve Rahim olan Allah'in adiyla * * compilation command: * * g++ fork.cpp -o fork.o -lncurses -lpthread -O2 * **************************************************/ #include #include #include // move() is here #include // usleep() is here #include // abs() is here #include // strlen() is here #include // pthread stuffs // fork and share memory stuffs #include #include typedef long int LONG; typedef short int SHORT; void LimitScreen(); void ShowInfo(); void ShowLoser(); void FireThread(); void MainThread(); void BrainThread(); SHORT *global; bool direction = true; int shot_count; #define row 30 #define col 70 #define sleep_time 12000 #define fire_time 80000 #define shield_length 9 #define ball_count 8 // this should be even for working better #define aggressive_level 6 //********************************************************************************************** class FireBall { public: SHORT x; SHORT y; SHORT move_count; bool busy; void init() { this->x = -1; this->y = -1; busy = false; } }; FireBall *pFireball; //********************************************************************************************** class Player { public: int x; int y; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Player(){} //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ void Initialize(bool is_brain) { if(is_brain) { this->x = 0; this->y = 1; } else { this->x = row - 1; this->y = 1; } } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ void DrawShield() { move(this->x,this->y); int ceil = this->x + shield_length; for(SHORT i=this->x;iy < col - shield_length) { move(this->x,this->y); printw(" "); this->y++; } } else { if(this->y > 1) { move(this->x,this->y + shield_length - 1); printw(" "); this->y--; } } refresh(); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ void Fire(bool is_brain) { if(is_brain) { for(SHORT i=ball_count / 2;ix; pFireball[i].y = this->y + 4; pFireball[i].move_count = row + 1; pFireball[i].busy = true; break; } } } else { for(SHORT i=0;ix; pFireball[i].y = this->y + 4; pFireball[i].move_count = row + 1; pFireball[i].busy = true; break; } } } } }; Player *pPlayer; // player[0] = human, player[1] = brain //*********************************************************************************************************** //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //*********************************************************************************************************** void LimitScreen() { for(SHORT i=0;i~~~~~~~~~~~~~~~~~~~~~~~ if(shot_count == aggressive_level && (rand() % 2) == 1) { pPlayer[1].Fire(true); shot_count = 0; } if(direction) { pPlayer[1].Move(true); if(!(pPlayer[1].y < col - shield_length)) direction = false; } else { pPlayer[1].Move(false); if(!(pPlayer[1].y > 1)) direction = true; } if(shot_count++ == aggressive_level) shot_count = 0; usleep(fire_time); } //********************************************************************************************** void FireThread() { // brain fireballs for(SHORT i=ball_count / 2;i 0) { move(pFireball[i].x - 1,pFireball[i].y); printw(" "); move(pFireball[i].x,pFireball[i].y); } printw("X"); pFireball[i].x++; pFireball[i].move_count--; if(pFireball[i].move_count == 0) pFireball[i].busy = false; } } // human fireballs for(SHORT i=0;i 0) { move(pFireball[i].x + 1,pFireball[i].y); printw(" "); move(pFireball[i].x,pFireball[i].y); } printw("X"); pFireball[i].x--; pFireball[i].move_count--; if(pFireball[i].move_count == 0) pFireball[i].busy = false; } } // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // check lose conditions for(SHORT i=ball_count / 2;i= pPlayer[0].y && (pFireball[i].y < pPlayer[0].y + shield_length)) { global[2] = 0; global[1] = 0; break; } } for(SHORT i=0;i= pPlayer[1].y && (pFireball[i].y < pPlayer[1].y + shield_length)) { global[2] = 1; global[1] = 0; break; } } move(row,col); refresh(); usleep(fire_time); } //********************************************************************************************** void MainThread() { pPlayer[0].DrawShield(); pPlayer[1].DrawShield(); move(row,col); refresh(); // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ switch(getch()) { case 'd': case 'D': pPlayer[0].Move(true); break; case 'a': case 'A': pPlayer[0].Move(false); break; case 's': case 'S': pPlayer[0].Fire(false); break; case 'q': case 'Q': global[1] = 0; } usleep(fire_time); } //********************************************************************************************** int main(int hamintori_alaki, char *vase_kelas[]) { int process_num; int shmid_player,shmid_fireball,shmid_active; // shared memory IDs pid_t fire_pid,brain_pid; initscr(); clear(); LimitScreen(); ShowInfo(); refresh(); nodelay(stdscr,TRUE); noecho(); // create shared memory shmid_player = shmget(IPC_PRIVATE,sizeof(Player) * 2,IPC_CREAT|S_IRUSR|S_IWUSR|S_IXUSR); shmid_fireball = shmget(IPC_PRIVATE,sizeof(FireBall) * ball_count,IPC_CREAT|S_IRUSR|S_IWUSR|S_IXUSR); shmid_active = shmget(IPC_PRIVATE,sizeof(SHORT) * 3,IPC_CREAT|S_IRUSR|S_IWUSR|S_IXUSR); // attach shared memory to the process pPlayer = (Player*)shmat(shmid_player,NULL,0); pFireball = (FireBall*)shmat(shmid_fireball,NULL,0); global = (SHORT*)shmat(shmid_active,NULL,0); pPlayer[0].Initialize(false); // human pPlayer[1].Initialize(true); // brain for(int i=0;i while(quit)s global[2] = 0; // global loser fire_pid = fork(); if(fire_pid == -1) { printw("An error occured while creating another process!\n"); global[1] = 0; } else if(fire_pid == 0) // child process will execute this line process_num = 1; else // parent process will execute this section { brain_pid = fork(); if(brain_pid == 0) // second child will excute this line process_num = 2; } while(global[1]) { if(process_num == 0) // main process { /*int resume = global[0]; while(resume != 0) { resume = global[0]; usleep(1000); }*/ MainThread(); //global[0] = 1; //refresh(); } else if(process_num == 1) // fire process { /*int resume = global[0]; while(resume != 1) { resume = global[0]; usleep(1000); }*/ FireThread(); //global[0] = 2; //refresh(); } else if(process_num == 2) { /*int resume = global[0]; while(resume != 2) { resume = global[0]; usleep(1000); }*/ BrainThread(); //global[0] = 0; //refresh(); } } if(process_num == 0) // our main process should delete allocated memory { // kill the children!! char murderer[0x0D]; sprintf(murderer,"kill %d",fire_pid); system(murderer); sprintf(murderer,"kill %d",brain_pid); system(murderer); ShowLoser(); shmid_ds *p; // delete allocated memory -> fireball shmdt(pPlayer); shmctl(shmid_fireball,IPC_RMID,p); // delete allocated memory -> player shmdt(pFireball); shmctl(shmid_fireball,IPC_RMID,p); // delete allocated memory -> active shmdt(global); shmctl(shmid_active,IPC_RMID,p); } nodelay(stdscr,FALSE); while('q' != getch()); // wait till user press q endwin(); return 0; }