您好,欢迎访问三七文档
当前位置:首页 > 电子/通信 > 综合/其它 > 多线程乒乓球双打-服务计算概论作业
JIANGSUUNIVERSITY多线程模拟乒乓球双打学院名称:计算机专业班级:软件1401学生姓名:吴帅帅学生学号:3140608020指导教师姓名:陈锦富2017年6月7日一、题目1.有四个选手,A1和A2为一个队,B1和B2为另一个队.A1首先发球(启动球),然后B1,A2,B2将最后发球.每一轮每个选手发2个球.2.选手不改变他们的位置.3.比赛期间,双方选手必须轮流发球,并且在同一个队伍的两个选手可以竞争发球.4.当轮到某个选手时,他/她可以调用一个叫做shot(rate)的随机函数来模拟比赛,在给定概率rate以内,该函数返回“in”,否则返回”out”.例如rate=85%,则球在界内的概率为85%,出界的概率为15%.5.如果shot函数返回”in”,对方选手必须调用shot函数把球打回.6.如果shot函数返回”out”,对方选手赢得1分,随后重新发球.7.当每个选手发完2个球后比赛终止.分数多的一方赢得比赛.分数一样多,比赛为平局.8.每个选手作为一个线程实现.二、实现思路serve:是指发球的goroutine.serveMetux:发球锁。playerA:是指A队伍抢到球的goroutine.playerB:是指B队伍抢到球的goroutine.catch_chanel_A:给A队伍的球的通道。catch_chanel_B:给B队伍的球的通道。大致步骤:1.serve先加锁,后发球(将TableTennis放入通道中,如catch_chanel_A),然后重复上锁(serveMetux)阻塞自身。2.playerA如果catch_chanel_A没有球,阻塞自身。如果有球,则从通道中拿到球,shot(rate)后返回in,记录信息后,则将球放入给B的通道catch_chanel_B中。3.playerB如果catch_chanel_B没有球,阻塞自身。如果有球,则从通道中拿到球,shot(rate)后返回in,记录信息后,则将球放入给B的通道catch_chanel_A中。如果shot(rate)返回out,则解除锁(serveMetux),此时serve唤醒,开始下一次发球。三、实现代码packagemainimport(fmtsyncmath/randcontainer/ringstringstime)var(wgsync.WaitGroup//用于goroutine计数times=2//每个选手发球次数nums=4//多少个选手serveTotals=nums*times//总发球次数score_balls_A=make([]TableTennis,0,serveTotals)//A的得分球score_balls_B=make([]TableTennis,0,serveTotals)//B的得分球turn=ring.New(4)//发球顺序serveMetuxsync.Mutex//发球锁catch_chanel_B=make(chanTableTennis,0)//B队伍接球的通道catch_chanel_A=make(chanTableTennis,0)//A队伍接球的通道balls_ids=make(chanint,serveTotals)//球的id)//乒乓球typeTableTennisstruct{idinttrailstring//球的轨迹}funcserve(){deferwg.Done()//初始化发球顺序turn.Value=A1turn=turn.Next()turn.Value=B1turn=turn.Next()turn.Value=A2turn=turn.Next()turn.Value=B2//开始发球fori:=0;itimes;i++{forj:=0;jnums;j++{serveMetux.Lock()//解锁时发下一个球turn=turn.Next()name:=turn.Value.(string)t:=TableTennis{-balls_ids,name+-in}ifname[0]=='A'{catch_chanel_B-t}else{catch_chanel_A-t}}}time.Sleep(time.Second)//等待playergoroutine对catch_chanel的使用close(catch_chanel_A)close(catch_chanel_B)}//A队选手funcplayerA(namestring,rateint){deferwg.Done()//延迟递减计数fort:=rangecatch_chanel_A{//2.将球击打出去rest:=shot(rate)//3.记录球的轨迹t.trail+=-+name+-+rest//球出界ifstrings.Compare(out,rest)==0{//对方得分score_balls_B=append(score_balls_B,t)fmt.Println(t)serveMetux.Unlock()continue}//4.对面队伍准备接球catch_chanel_B-t}}//B队选手funcplayerB(namestring,rateint){deferwg.Done()//延迟递减计数fort:=rangecatch_chanel_B{//2.将球击打出去rest:=shot(rate)//3.记录球的轨迹t.trail+=-+name+-+rest//球出界ifstrings.Compare(out,rest)==0{//对方得分score_balls_A=append(score_balls_A,t)fmt.Println(t)serveMetux.Unlock()continue}//4.对面队伍准备接球catch_chanel_A-t}}//击球funcshot(rateint)string{ifrand.Intn(100)rate{returnin}else{returnout}}funcmain(){fmt.Println(比赛开始...)//初始化球的idfori:=0;iserveTotals;i++{balls_ids-i+1}//初始化发球顺序wg.Add(nums+1)//累加计数goserve()//time.Sleep(time.Second)goplayerA(A1,45)goplayerA(A2,60)goplayerB(B1,50)goplayerB(B2,90)wg.Wait()fmt.Println(比赛结束.)fmt.Printf(A:B=(%d,%d)\n,len(score_balls_A),len(score_balls_B))for_,t:=rangescore_balls_A{fmt.Println(t)}fmt.Println()for_,t:=rangescore_balls_B{fmt.Println(t)}}四、运行结果(从自己博客复制的图片,所以有水印)
本文标题:多线程乒乓球双打-服务计算概论作业
链接地址:https://www.777doc.com/doc-4912154 .html