📄 rpg.c
字号:
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <pthread.h>
#include <time.h>
pthread_mutex_t lock=PTHREAD_MUTEX_INITIALIZER;
int APmid,peomid,boutmid,def_mid;
int * pAP,*pp,*pn,i;
float *pd;
const int attack=100,develop=50;
void ACT_Attack(int country_num); //攻击线程
void ACT_Defend(int country_num); //防御线程
void ACT_Develop(int country_num); //发展线程
int init( ); //信号灯初始化程序
void p( int ); //信号灯实现的P操作
void v( int ); //信号灯实现的V操作
union semun {
int val; /* Value for SETVAL */
struct semid_ds *buf; /* Buffer for IPC_STAT, IPC_SET */
unsigned short *array; /* Array for GETALL, SETALL */
struct seminfo *__buf; /* Buffer for IPC_INFO
(Linux specific) */
};
int main() {
int attack=100,develop=50;
float defend=0.2;
int status;
pthread_t AttackThread,DefendThread,DevelopThread;
printf("\n模拟开始!\n\n");
printf("初始状态(三国相同):兵力300,攻击力100,防御力0.2(防御20%的伤害),发展能力50\n\n ");
//建立共享内存
APmid = shmget(0x911, 3*4, IPC_CREAT|0600 );
pAP = (int *)shmat( APmid, NULL, 0 ); //每回合的行动点数
peomid= shmget( 0x985, 3*4, IPC_CREAT|0600 );
pp=(int *)shmat( peomid, NULL, 0 ); //每个进程的兵力
boutmid=shmget( 0x995, 3*4, IPC_CREAT|0600 ); //回合数
pn=(int *)shmat( boutmid, NULL, 0 );
def_mid=shmget( 0x923, 3*sizeof(float), IPC_CREAT|0600 );
pd=(float *)shmat( def_mid, NULL, 0 ); //每个进程的防御力
for(i=0;i<3;i++) //共享内存初始化
{
*(pAP+i)=10,*(pp+i)=300;
*(pd+i)=0.2;
*(pn+i)=0;
}
int pid1,pid2; pid1=fork(); //生成子进程
if(pid1==0) pid2=fork(); //生成孙进程
int semid;
semid = init( ); //初始化信号灯
while((*pp)*(*(pp+1))+(*pp)*(*(pp+2))+(*(pp+1))*(*(pp+2))!=0) //当有2个国家以上兵力不为0时
{
for(i=0;i<3;i++) *(pAP+i)=10; //初始化每回合的行动点数
if(pid1!=0 )
{
p( semid );
while(*pAP>=1 && (*pp)!=0 )
{
pthread_create( &AttackThread, NULL,(void *)&ACT_Attack, (void *)0 );
if(*(pd)<0.5)pthread_create( &DefendThread, NULL,(void *)&ACT_Defend, (void *)0 );
pthread_create( &DevelopThread, NULL,(void *)&ACT_Develop, (void *)0 );
// 等待线程结束
pthread_join( AttackThread, NULL );
if(*(pd)<0.5)pthread_join( DefendThread, NULL );
pthread_join( DevelopThread, NULL );
}
if ((*pp)!=0) printf("**魏行动结束\n\n");
else printf("\n魏国已亡!\n\n");
(*pn)++;
// printf("pn=%d\n",*pn);
v( semid );
}
else if(pid2!=0 )
{
p( semid );
while(*(pAP+1)>=1 && (*(pp+1))!=0 )
{
pthread_create( &AttackThread, NULL,(void *)&ACT_Attack, (void *)1 );
if(*(pd+1)<0.5)pthread_create( &DefendThread, NULL,(void *)&ACT_Defend, (void *)1 );
pthread_create( &DevelopThread, NULL,(void *)&ACT_Develop, (void *)1 );
// 等待线程结束
pthread_join( AttackThread, NULL );
if(*(pd+1)<0.5)pthread_join( DefendThread, NULL );
pthread_join( DevelopThread, NULL );
}
if ((*(pp+1))!=0) printf("**蜀行动结束\n\n");
else printf("\n蜀国已亡!\n\n");
(*(pn+1))++;
// printf("pn+1=%d\n",*(pn+1));
v( semid );
}
else
{
p( semid );
while (*(pAP+2)>=1 && (*(pp+2))!=0)
{
pthread_create( &AttackThread, NULL,(void *)&ACT_Attack, (void *)2 );
if(*(pd+2)<0.5)pthread_create( &DefendThread, NULL,(void *)&ACT_Defend, (void *)2 );
pthread_create( &DevelopThread, NULL,(void *)&ACT_Develop, (void *)2 );
// 等待线程结束
pthread_join( AttackThread, NULL );
if(*(pd+2)<0.5)pthread_join( DefendThread, NULL );
pthread_join( DevelopThread, NULL );
}
if ((*(pp+2))!=0) printf("**吴国行动结束\n\n");
else printf("\n吴国已亡!\n\n");
(*(pn+2))++;
// printf("pn+2=%d\n",*(pn+2));
v( semid );
}
// printf("pn=%d,pn+1=%d,pn+2=%d\n",*pn,*(pn+1),*(pn+2));
if((*pp)*(*(pp+1))+(*pp)*(*(pp+2))+(*(pp+1))*(*(pp+2))!=0) //此if防止陷入死循环
{
while((*pn>*(pn+1) || *pn>*(pn+2)) && pid1!=0); //3个循环用来同步进程
while((*(pn+1)>*pn || *(pn+1)>*(pn+2)) && (pid1==0 && pid2!=0));
while((*(pn+2)>*pn || *(pn+2)>*(pn+1)) && (pid1==0 && pid2==0));
}
if(*pn==*(pn+1) && *pn==*(pn+2)){ //每回合结束
printf("第%d回合结束!\n",*pn);
printf("魏兵力:%d,蜀兵力:%d,吴兵力:%d\n",*pp,*(pp+1),*(pp+2));
printf("------------------------------------\n\n");
}
}
while( wait( &status ) != -1 ); //等待所有子进程结束
if(*pp>0 && pid1!=0) printf("*************魏国统一了三国!**********\n");
else if (*(pp+1)>0 && pid1!=0) printf("*************蜀国统一了三国!**********\n");
else if (*(pp+2)>0 && pid1!=0) printf("*************吴国统一了三国!**********\n");
// 释放共享内存
shmdt( pn );
shmctl( boutmid, IPC_RMID, 0 );
shmdt( pp );
shmctl( peomid, IPC_RMID, 0 );
shmdt( pd );
shmctl( def_mid, IPC_RMID, 0 );
shmdt( pAP );
shmctl( APmid, IPC_RMID, 0 );
//删除信号灯
semctl( semid, 0, IPC_RMID, 0 );
if(pid1!=0)printf("\n模拟结束!\n");
}
void ACT_Attack(int country_num)
{
if(*(pAP+country_num)<1)return;
if((*pp)*(*(pp+1))+(*pp)*(*(pp+2))+(*(pp+1))*(*(pp+2))==0) //此if防止死循环
{
pthread_mutex_lock( &lock ); //锁住互斥锁
*(pAP+country_num)-=1;
pthread_mutex_unlock( &lock ); //解锁互斥锁
return ;
}
pthread_mutex_lock( &lock ); //锁住互斥锁
int aim;
// srand((int)time(0)); //设置随机种子
do{ aim=rand()%3; }while(aim==country_num || *(pp+aim)==0); //随机攻击对像
switch(country_num)
{
case 0: printf("魏攻击"); break;
case 1: printf("蜀攻击"); break;
case 2: printf("吴攻击"); break;
}
switch(aim)
{
case 0: printf("魏。魏"); break;
case 1: printf("蜀。蜀"); break;
case 2: printf("吴。吴"); break;
}
int damage; //计算伤害值
damage= attack * (1-*(pd+aim));
*(pp+aim)-=damage;
if(*(pp+aim)<0) *(pp+aim)=0;
printf("伤亡%d万,其现在兵力为%d.\n",damage,*(pp+aim));
*(pAP+country_num)-=1;
pthread_mutex_unlock( &lock ); //解锁互斥锁
}
void ACT_Defend(int country_num)
{
if(*(pAP+country_num)<4)return;
pthread_mutex_lock( &lock ); //锁住互斥锁
switch(country_num)
{
case 0: printf("魏加固防御,"); break;
case 1: printf("蜀加固防御,"); break;
case 2: printf("吴加固防御,"); break;
}
*(pd+country_num)+=0.1;
printf("防御值为%2f.\n",*(pd+country_num));
if(*(pd+country_num)>=0.5)printf("防御值已经达上限(0.5)!\n");
*(pAP+country_num)-=4;
pthread_mutex_unlock( &lock ); //解锁互斥锁
}
void ACT_Develop(int country_num)
{
if(*(pAP+country_num)<2)return;
pthread_mutex_lock( &lock ); //锁住互斥锁
switch(country_num)
{
case 0: printf("魏发展生产,"); break;
case 1: printf("蜀发展生产,"); break;
case 2: printf("吴发展生产,"); break;
}
*(pp+country_num)+=develop;
printf("兵力达到%d.\n",*(pp+country_num));
*(pAP+country_num)-=2;
pthread_mutex_unlock( &lock ); //解锁互斥锁
}
void p( int semid )
{
struct sembuf buf;
buf.sem_num = 0;
buf.sem_op = -1;
buf.sem_flg = SEM_UNDO;
semop( semid, &buf, 1 );
}
void v( int semid )
{
struct sembuf buf;
buf.sem_num = 0;
buf.sem_op = 1;
buf.sem_flg = SEM_UNDO;
semop( semid, &buf, 1 );
}
int init()
{
int semid;
union semun s;
s.val=1;
if( (semid = semget( 0x555, 1, IPC_CREAT|IPC_EXCL|0666 )) == -1 )
{
semid = semget( 0x555, 1, 0 );
}
else
{
semctl( semid, 0, SETVAL, s ); //初始化
}
return( semid );
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -