【C++编程题】斯诺克台球

【问题描述】

斯诺克台球是一项古老而又时尚的运动,使用长方形球桌,台面四角以及两长边中心位置各有一个球袋,使用的球分为1个白球,15个红球和6个彩球共22个球。

其中母球(白球)1只,目标球21只。目标球中:红球15只各1分、黄球1只2分、绿球1只3分、咖啡球1只4分、蓝球1只5分、粉球1只6分、黑球1只7分。

djh.jpg

选手需要使用球杆撞击母球去击打目标球来完成得分,每局开始时总是先从红球开始。击球顺序为先打进红球(每次击打允许多个红球同时落袋),然后必须任意指定一个目标彩球击打,如果该彩球被打进(打进后需要再摆回),然后接着击打红球,直到红球全部落袋,然后以黄、绿、咖啡、蓝、粉红、黑的顺序逐个击球(不再摆回),最后以得分高者为胜。任何时候红球落袋都不再摆回,任何时候因犯规导致彩球落袋,彩球必须摆回。

斯诺克比赛由双方轮流击打,必须击打合规的目标球,打进则本方得到相应的分数并继续击打,未打进或犯规轮换为对方击打,未打进不得分,犯规将进行罚分处理。

犯规规则如下:

1.     当击打目标球时,如果先击打到或同时击打到一个或多个其他颜色的球,或者有其他颜色的球落袋,或者打空(未击打到任何球),则视为犯规。此时需要比较目标球的分值和与本犯规相关的其他颜色的球的分值,取其中最高的分值,如果该分值小于4,则对方加4分,否则对方加该分值。

2.     当击打红球落袋后,继续击打任意彩球时打空,即未打击到任何球,对方加4分。

相比正式的斯诺克比赛,本问题对规则进行了简化,任何时候都可以结束比赛并计算比赛结果,不考虑白球落袋的情况。

信息化时代的智能台球桌能自动记录实际比赛时的击打记录,并传送到后台,但该记录仅仅是流水记录,并且无参赛选手的任何信息,需要你编程计算每场比赛的比分,同时需要计算单杆100分及以上的情况(单杆得分是指选手一次连续击打所得分数之和)。

【输入形式】

输入第一行为正整数t (t≤100),表示有t组测试数据,每组数据代表一局比赛。

在输入中,球的颜色表示为:

               r-红色球 y-黄色球 g-绿色球 c-咖啡色球 b-蓝色球 p-粉红球 B-黑色球

接下来的每组数据包括若干行,每一行为一次击打的结果,为智能球桌记录下来的流水记录,每组数据最后一行为-1,表示每组数据的结束。

流水记录包含用空格分隔的2个部分:

首先撞到的球 落袋球及数量

第一部分“首先撞到的球”为一个字符串,可以是“rygcbpB”中1个或多个字符组合(可能有多个字符“r”),或为字符串“NULL”。为“NULL”时,第二部分必为空,表示该次击打未撞击到任何球也没有任何球落袋。当红球落袋后继续击打任意彩球时,该部分为“ygcbpB”中的任意单个字符时都认为是合规的目标球。

第二部分“落袋球及数量”为一个字符串,例如“r2gb”,代表本次击打有两个红球落袋,以及绿球和篮球落袋,红色球r后面有数字(大于0小于16),表示红球的落袋数,其他彩球后无数字。该部分可以为空,表示本次击打无球落袋。

比赛在A与B之间进行,每局比赛总是由A先开球。

【输出形式】

输出为t+1行,前t行每行输出用冒号分隔的两个整数,表示每局比赛A与B之间的比分;最后一行输出用冒号分隔的两个整数,表示t局比赛之后A与B之间获得的单杆100分及以上的次数之比(单杆得分是指选手一次连续击打所得分数之和)。

【样例输入】

3
r r1
B
r r2
c c
r r1
b g
-1
rp r1
r br2B
NULL
r r12
y y
g p
-1
rr r3
NULL
r r1
yg y
-1

【样例输出】

6:7
13:24
7:5
0:0

【样例说明】

第一局比赛:

A击打红球,打进1个红球,得1分,比分为 1:0

A继续击打任意彩球,打到黑球,未打进,不得分,比分为1:0

轮换为B击打红球,打进两个红球,得2分,比分为1:2

B继续击打任意彩球,打到咖啡球,打进咖啡球,咖啡球摆回,得4分,比分为1:6

B继续击打红球,打进一个红球,得1分,比分为1:7

B继续击打任意彩球,打到蓝球,打进绿球,犯规,取分值最大者蓝球,绿球摆回,对方加5分,比分为6:7

-1比赛结束

第二局比赛:

A击打红球,首先打到红球和粉球,犯规,打进1个红球和咖啡球,犯规,咖啡球摆回,取分值最大的粉球,对方加6分,比分为0:6

B击打红球,首先打到红球,打进蓝球、2个红球和黑球,犯规,蓝球和黑球摆回,取分值最大的黑球,对方加7分,比分为7:6

A击打红球,未打到任何球,犯规,对方加4分,比分为7:10

B击打红球,打到红球,打进12个红球,加12分,比分为7:22

B击打任意彩球,打到黄球,打进黄球,黄球摆回,得2分,比分为7:24

B击打黄球,打到绿球,打进粉球,犯规,粉球摆回,对方加6分,比分为13:24

-1比赛结束

第三局比赛:

A击打红球,打到2个红球,打进3个红球,加3分,比分为3:0

A击打任意彩球,打空,未打到任何球,对方加4分,比分为3:4

B击打红球,打到1个红球,打进1个红球,加1分,比分为3:5

B击打任意彩球,打到黄球和绿球,打进黄球,犯规,黄球摆回,取分值最高的绿球,绿球分值小于4,对方加4分,比分为7:5 

-1比赛结束

3局比赛中无人单杆得分过100,最后一行输出0:0




【思路】 

这道题写了好久,主要还是一开始没有能完全弄清题目的意思!

有几个值得注意的点:

1.只要击球或者落球犯规,都是从所有球(包括击打球,落球,目标球)中找分值最大的

2.红球落袋必定计数(任何情况都要)

3.单杆得分是一次连续击打,不是一局总分【因为这个点儿没搞清,弄了老久~

4.如果打红球的时候,没有犯规,并且打进最后一个红球,这时候要先来个【自由彩球】,才能到 顺序彩球(具体规则一定要仔细看样例

代码长,大概表述一下就是:

分出:【   A打红,A打彩;B打红,B打彩     】 四种情况,来回调用直至结束

        其中彩球又分为【自由彩球,顺序彩球】 两种,通过前一个击打的球确定

        每次要切换到对手打的时候,把自己单杆得分看一下,并且两边单杆得分都清零

一道麻烦的题目~耐心点才能拿下~




【AC代码】

 #include<string>
 #include<iostream>
 #include<sstream>
 #include<stack>
 #include<vector>
 using namespace std;
 
 int ball_score(char a){
 	 switch(a){
 	 	case 'r':{
 	 		return 1;
			break;
		  }
		case 'y':{
 	 		return 2;
			break;
		  }
		case 'g':{
 	 		return 3;
			break;
		  }
		case 'c':{
 	 		return 4;
			break;
		  }
		case 'b':{
 	 		return 5;
			break;
		  }
		case 'p':{
 	 		return 6;
			break;
		  }
		case 'B':{
 	 		return 7;
			break;
		  }	
		  default:{
		  	return 0;
			break;
		  }  
	  }
 } 
 
 int ball[8];
 int ball_num(char a){
 	return ball[ball_score(a)];
 }
	
 void init_ball_num(){
	ball[1]=15;
	for(int i=2;i<=7;i++) ball[i]=1;
 } 
 
 int A_100_times=0,B_100_times=0;//(单杆得分是指选手一次连续击打所得分数之和)!!! 【 不是一局的总分!!!】 
 int A_score,B_score; 
 
 void A_red();
 void B_red();
 void A_color(char fa);
 void B_color(char fa);
 
 int A_hit_score=0,B_hit_score=0; 
 
 
 void A_red(){
 	if(ball_num('r')==0) {
	 	A_color('r');     //红球没了,只能是按顺序击打彩球 
 		return; 
	 } 
 	
 	if(B_hit_score>=100){
 		//cout<<endl<<endl<<"B_MARK__100"<<endl<<endl;
 		B_100_times++; 
 		B_hit_score=0;
		//cout<<endl<<"@@@@@a_red: "<<A_hit_score<<"  "<<B_hit_score<<endl;
	 }
 	
 	 string condition;
	 getline(cin,condition); 
 	
 	if(condition=="-1")  {
 		
 		if(A_hit_score>=100) A_100_times++;   //在自己连续击打的时候结束 
 		A_hit_score=0;B_hit_score=0;//初始化双方连续击打分 
 		
	 	cout<<A_score<<":"<<B_score<<endl; 
		 return; //本局比赛结束;
	 } 
 	
 	if(condition=="NULL") {//打空了  犯规 
		B_score+=4; 
		B_hit_score=0;
		B_red(); 
		} else if(condition.find(' ')!=string::npos ){   //有打球,有落入 
			string hit,drop;
			hit=condition.substr(0,condition.find(' '));
			drop=condition.substr(condition.find(' ')+1,condition.size() - condition.find(' '));

			int flag1=1;
			int maxi1=4;
			for(int i=0;i<hit.size() ;i++){    //看击打有没有犯规  
				if(hit[i]!='r') flag1=0;
				if(maxi1<ball_score(hit[i])) maxi1=ball_score(hit[i]);
			}
			
			int flag2=1;
			int maxi2=4;         //看落球有没有犯规 
			for(int i=0;i<drop.size() ;i++){
				if(drop[i]!='r'){
					if(drop[i]<'0'||drop[i]>'9'){
						flag2=0;
					}
				}
				if(maxi2<ball_score(drop[i])) maxi2=ball_score(drop[i]);
			} 
			
			//不管犯不犯规  红球落入了就得减去 
			int r_num=0;
				if(drop.find('r')!=string::npos ){//有红球落入 
					int pos=drop.find('r');
					vector<int> v;
					for(int i=pos+1;i<drop.size() ;i++) {
						if(drop[i]>='0'&&drop[i]<='9') v.push_back(drop[i]-'0'); 
					}
					if(v.size()==1) {
						r_num+=v[0];
						ball[ball_score('r')]-=r_num; 
					}
					else {
						r_num+=v[0]*10 + v[1];
						ball[ball_score('r')]-=r_num; 
					}
				}   
	
			if(flag1==0 || flag2==0){   //两样都犯规了  比较出最大分数给对方加上  计算掉入的红球
				B_score+=max(maxi1,maxi2);
				B_hit_score=0;
				B_red();
			}else {        //没有犯规 
				A_hit_score+=r_num;
				A_score+=r_num;
				A_color('f'); //常规自由球 
			}
		}else {   //只打了球,没落入 
			int flag=1;
			for(int i=0;i<condition.size() ;i++){
				if(condition[i]!='r'){
					flag=0;
				} 
			}
			if(flag==1){  //打得全是红球  因为没落入 所以没分  红球也没有少 
				B_hit_score=0;
				B_red();
			}else{        //打到了其他球, 犯规 对方加分 
				int maxi3=4;
				for(int i=0;i<condition.size() ;i++){
					if(ball_score(condition[i])>maxi3) maxi3=ball_score(condition[i]);
				} 
				B_score+=maxi3; 
				B_hit_score=0;
				B_red(); 
			}
		}
 }
 
 void A_color(char fa){     //要判断当前打自由彩球还是顺序彩球   记录上一球 
 	
	 if(B_hit_score>=100){ 
	 	//cout<<endl<<endl<<"B_MARK__100"<<endl<<endl;
 		B_100_times++; 
 		B_hit_score=0;
		//cout<<endl<<"@@@@@a_color: "<<A_hit_score<<"  "<<B_hit_score<<endl;
	 }
	
 	string condition;
	getline(cin,condition); 
 	
 	if(condition=="-1" ){
 		
 		if(A_hit_score>=100) A_100_times++;   //在自己连续击打的时候结束 
 		 A_hit_score=0;B_hit_score=0;
 		
 		cout<<A_score<<":"<<B_score<<endl;
		 return; //本局比赛结束;
	 }
 	
 	if(fa=='f') {  //自由彩球 
	    if(condition=="NULL") {                          //打空了  犯规 
			B_score+=4; 
			B_hit_score=0;
			B_red(); 
		} else if(condition.find(' ')!=string::npos ){   //有打球,有落入			
			string hit,drop;
			hit=condition.substr(0,condition.find(' '));
			drop=condition.substr(condition.find(' ')+1,condition.size() - condition.find(' '));
			
			int r_num=0; //无论如何,只要有红球落入,就要计算 
				if(drop.find('r')!=string::npos ){//有红球落入 
					int pos=drop.find('r');
					vector<int> v;
					for(int i=pos+1;i<drop.size() ;i++) {
						if(drop[i]>='0'&&drop[i]<='9') v.push_back(drop[i]-'0'); 
					}
					if(v.size()==1) {
						r_num+=v[0];
						ball[ball_score('r')]-=r_num; 
					}
					else {
						r_num+=v[0]*10 + v[1];
						ball[ball_score('r')]-=r_num; 
					}	
				}
			
			int flag1=1;  //看击打有没有犯规 
			int maxi1=4;
			if(hit=="r"||hit.size()>1){
				flag1=0;
				for(int i=0;i<hit.size();i++){
					if(ball_score(hit[i])>maxi1) maxi1=ball_score(hit[i]);
				}	
			} 
			
			if(flag1==0){//击球犯规,在击球和落球里面找个最大的给对方加分 
				for(int i=0;i<drop.size();i++){
					if(ball_score(drop[i])>maxi1) maxi1=ball_score(drop[i]);
				} 
				B_score+=maxi1;
				B_hit_score=0;
				B_red();
				
			} else{       //击球没犯规,只打了一个彩球 
				if(drop==hit){      //落球也完全一样 ,加分继续打红球 
					A_hit_score+=ball_score(drop[0]);
					A_score+=ball_score(drop[0]); 
					A_red(); 
				}else{              //落球多了些东西,给对方加最大分 
					int maxi3=4; 
					for(int i=0;i<hit.size();i++){
						if(ball_score(hit[i])>maxi3) maxi3=ball_score(hit[i]);
					}
					for(int i=0;i<drop.size();i++){
						if(ball_score(drop[i])>maxi3) maxi3=ball_score(drop[i]);
					} 
					B_score+=maxi3;
					B_hit_score=0;
					B_red(); 
				} 
			}	
		} else{//只打了球,没落入 
			if(condition=="r"||condition.size() >1) {//打到了多个球或者打到了红球   没进 
				int maxi=4;
				for(int i=0;i<condition.size() ;i++){
					if(ball_score(condition[i])>maxi)  maxi=ball_score(condition[i]);
				} 
				B_score+=maxi;
				B_hit_score=0;
				B_red();
			} else{                                  //打到单个彩球 但没进 
				B_hit_score=0;
				B_red();
			} 
		} 
		
	} else {       //顺序彩球  
		string sub="rygcbpB";
		string goal=sub.substr(sub.find(fa)+1,1); 
		char c_goal=sub[sub.find(fa)+1 ]; 
		
		if(condition=="NULL") {                          //打空了,犯规,对方加分,按顺序打 
			B_score+=4; 
			B_hit_score=0;
			B_color(fa); 
		} else if(condition.find(' ')!=string::npos ){   //有打球,有落入		
		
			string hit,drop;
			hit=condition.substr(0,condition.find(' '));
			drop=condition.substr(condition.find(' ')+1,condition.size() - condition.find(' '));
			
			if( hit==goal && hit==drop )   { //目标, 击打,落入都一样  
				A_hit_score+=ball_score(c_goal);
				A_score+=ball_score(c_goal);//分数增加 
				ball[ball_score(c_goal)]--; //球数减少 
				A_color(c_goal);            //继续按照顺序击打 
			} else{//击球或者落球犯规,在所有球里面找最大的 (包括目标球) 
				int maxi3=max(4,ball_score(c_goal)); 
				for(int i=0;i<hit.size();i++){
					if(ball_score(hit[i])>maxi3) maxi3=ball_score(hit[i]);
				}
				for(int i=0;i<drop.size();i++){
					if(ball_score(drop[i])>maxi3) maxi3=ball_score(drop[i]);
				}
				B_score+=maxi3;
				B_hit_score=0;
				B_color(fa);
			}
		}else {                                           //有打球,没落入 
			string hit=condition;
			if(hit==goal){
				B_hit_score=0;
				B_color(fa);
			}else {
				int maxi=4;
				for(int i=0;i<hit.size();i++){
					if(ball_score(hit[i])>maxi) maxi=ball_score(hit[i]);
				}
				B_score+=maxi;
				B_hit_score=0;
				B_color(fa);
			}	
		}
	}
 	
 } 

 void B_red(){
 	if(ball_num('r')==0) {
	 	B_color('r');     //红球没了,只能是按顺序击打彩球 
 		return; 
	 } 

 	if(A_hit_score>=100){
 		//cout<<endl<<endl<<"A_MARK__100"<<endl<<endl;
 		A_100_times++; 
 		A_hit_score=0;
		//cout<<endl<<"@@@@@b_red: "<<A_hit_score<<"  "<<B_hit_score<<endl;
	 }
 	
 	 string condition;
	 getline(cin,condition); 
 	
 	if(condition=="-1")  {
 		
 		if(B_hit_score>=100) B_100_times++;   //在自己连续击打的时候结束 
 		 A_hit_score=0;B_hit_score=0;
 		
	 	cout<<A_score<<":"<<B_score<<endl; 
		 return; //本局比赛结束;
	 } 
 	
 	if(condition=="NULL") {//打空了  犯规 
		A_score+=4; 
		A_hit_score=0;
		A_red(); 
		} else if(condition.find(' ')!=string::npos ){   //有打球,有落入 
			string hit,drop;
			hit=condition.substr(0,condition.find(' '));
			drop=condition.substr(condition.find(' ')+1,condition.size() - condition.find(' '));
			//cout<<endl<<"@@@@"<<hit<<"@@"<<drop<<endl;
			int flag1=1;
			int maxi1=4;
			for(int i=0;i<hit.size() ;i++){    //看击打有没有犯规  
				if(hit[i]!='r') flag1=0;
				if(maxi1<ball_score(hit[i])) maxi1=ball_score(hit[i]);
			}
			
			int flag2=1;
			int maxi2=4;         //看落球有没有犯规 
			for(int i=0;i<drop.size() ;i++){
				if(drop[i]!='r'){
					if(drop[i]<'0'||drop[i]>'9'){
						flag2=0;
					}
				}
				if(maxi2<ball_score(drop[i])) maxi2=ball_score(drop[i]);
			} 
			
			//不管犯不犯规  红球落入了就得减去 
			int r_num=0;
				if(drop.find('r')!=string::npos ){//有红球落入 
					int pos=drop.find('r');
					vector<int> v;
					for(int i=pos+1;i<drop.size() ;i++) {
						if(drop[i]>='0'&&drop[i]<='9') v.push_back(drop[i]-'0'); 
					}
					if(v.size()==1) {
						r_num+=v[0];
						ball[ball_score('r')]-=r_num; 
					}
					else {
						r_num+=v[0]*10 + v[1];
						ball[ball_score('r')]-=r_num; 
					}
				}   
	
			if(flag1==0&&flag2==0){   //两样都犯规了  比较出最大分数给对方加上  计算掉入的红球
				A_score+=max(maxi1,maxi2);
				A_hit_score=0;
				A_red();
			}else if(flag1==0){     //击球犯规      @@@@@@@@@@@@@@存疑 
				A_score+=max(maxi1,maxi2);
				A_hit_score=0;
				A_red();
			}else if(flag2==0){     //落球犯规 
				A_score+=max(maxi1,maxi2);
				A_hit_score=0;
				A_red();
			}else {        //没有犯规 
				B_hit_score+=r_num;
				B_score+=r_num;
				B_color('f'); //常规自由球 
			}
		}else {   //只打了球,没落入 
			int flag=1;
			for(int i=0;i<condition.size() ;i++){
				if(condition[i]!='r'){
					flag=0;
				} 
			}
			
			if(flag==1){  //打得全是红球  因为没落入 所以没分  红球也没有少 
				A_hit_score=0;
				A_red();
			}else{        //打到了其他球, 犯规 对方加分 
				int maxi3=4;
				for(int i=0;i<condition.size() ;i++){
					if(ball_score(condition[i])>maxi3) maxi3=ball_score(condition[i]);
				} 
				A_score+=maxi3; 
				A_hit_score=0;
				A_red(); 
			}
		}
 }
 
 void B_color(char fa){
 	


	if(A_hit_score>=100){
		//cout<<endl<<endl<<"A_MARK__100"<<endl<<endl;
 		A_100_times++; 
 		A_hit_score=0;
		//cout<<endl<<"@@@@@b_color: "<<A_hit_score<<"  "<<B_hit_score<<endl; 
	 }
	
 	 string condition;
	 getline(cin,condition); 
 	
 	if(condition=="-1" ){
 		
 		if(B_hit_score>=100) B_100_times++;   //在自己连续击打的时候结束 
 		 A_hit_score=0;B_hit_score=0;
 		
 		cout<<A_score<<":"<<B_score<<endl;
		 return; //本局比赛结束;
	 }
 	
 	if(fa=='f') {  //自由彩球 
	    if(condition=="NULL") {                          //打空了  犯规 
			A_score+=4; 
			A_hit_score=0;
			A_red(); 
			
		} else if(condition.find(' ')!=string::npos ){   //有打球,有落入			
			string hit,drop;
			hit=condition.substr(0,condition.find(' '));
			drop=condition.substr(condition.find(' ')+1,condition.size() - condition.find(' '));
			
			int r_num=0; //无论如何,只要有红球落入,就要计算 
				if(drop.find('r')!=string::npos ){//有红球落入 
					int pos=drop.find('r');
					vector<int> v;
					for(int i=pos+1;i<drop.size() ;i++) {
						if(drop[i]>='0'&&drop[i]<='9') v.push_back(drop[i]-'0'); 
					}
					if(v.size()==1) {
						r_num+=v[0];
						ball[ball_score('r')]-=r_num; 
					}
					else {
						r_num+=v[0]*10 + v[1];
						ball[ball_score('r')]-=r_num; 
					}	
				}
			
			int flag1=1;  //看击打有没有犯规 
			int maxi1=4;
			if(hit=="r"||hit.size()>1){
				flag1=0;
				for(int i=0;i<hit.size();i++){
					if(ball_score(hit[i])>maxi1) maxi1=ball_score(hit[i]);
				}	
			} 
			
			if(flag1==0){ //击球犯规,在击球和落球里面找个最大的给对方加分    击球犯规,落球一定犯规 
				for(int i=0;i<drop.size();i++){
					if(ball_score(drop[i])>maxi1) maxi1=ball_score(drop[i]);
				} 
				A_score+=maxi1;
				A_hit_score=0;
				A_red();
				
			} else{       //击球没犯规,只打了一个彩球 
				if(drop==hit){      //落球也完全一样 ,加分继续打红球 
					B_hit_score+=ball_score(drop[0]);
					B_score+=ball_score(drop[0]); 
					B_red(); 
				}else{              //落球多了些东西犯规,给对方加最大分 (击打和落球中的最大分)
					int maxi3=4; 
					for(int i=0;i<hit.size();i++){
						if(ball_score(hit[i])>maxi3) maxi3=ball_score(hit[i]);
					}
					for(int i=0;i<drop.size();i++){
						if(ball_score(drop[i])>maxi3) maxi3=ball_score(drop[i]);
					} 
					A_score+=maxi3;
					A_hit_score=0;
					A_red(); 
				} 
			}	
		} else{//只打了球,没落入 
			if(condition=="r"||condition.size() >1) {//打到了多个球或者打到了红球   没进 
				int maxi=4;
				for(int i=0;i<condition.size() ;i++){
					if(ball_score(condition[i])>maxi)  maxi=ball_score(condition[i]);
				} 
				A_score+=maxi;
				A_hit_score=0;
				A_red();
			} else{                                  //打到单个彩球 但没进 
				A_hit_score=0;
				A_red();
			} 
		} 
		
	} else {       //顺序彩球  
		string sub="rygcbpB";
		string goal=sub.substr(sub.find(fa)+1,1); 
		char c_goal=sub[sub.find(fa)+1 ]; 
		
		if(condition=="NULL") {                          //打空了,犯规,对方加分,按顺序打 
			A_score+=4; 
			A_hit_score=0;
			A_color(fa); 
		} else if(condition.find(' ')!=string::npos ){   //有打球,有落入		
		
			string hit,drop;
			hit=condition.substr(0,condition.find(' '));
			drop=condition.substr(condition.find(' ')+1,condition.size() - condition.find(' '));
			
			if( hit==goal && hit==drop )   { //目标, 击打,落入都一样  
				B_hit_score+=ball_score(c_goal);
				B_score+=ball_score(c_goal);//分数增加 
				ball[ball_score(c_goal)]--; //球数减少 
				B_color(c_goal);            //继续按照顺序击打 
			} else  {  //击球犯规,在所有球里面找最大的
//			if(hit==goal && hit!=drop){
//				int maxi=4;
//				for(int i=0;i<drop.size();i++){
//					if(ball_score(drop[i])>maxi) maxi=ball_score(drop[i]);
//				}
//				A_score+=maxi;
//				A_color(fa);
//			}else if(hit!=goal){	 
				int maxi=max(4,ball_score(c_goal));
				for(int i=0;i<hit.size();i++){
					if(ball_score(hit[i])>maxi) maxi=ball_score(hit[i]);
				}
				for(int i=0;i<drop.size();i++){
					if(ball_score(drop[i])>maxi) maxi=ball_score(drop[i]);
				}
				A_score+=maxi;
				A_hit_score=0;
				A_color(fa);
			}
		}else {                                           //有打球,没落入 
			string hit=condition;
			if(hit==goal){
				A_hit_score=0;
				A_color(fa);
			}else {
				int maxi=4;
				for(int i=0;i<hit.size();i++){
					if(ball_score(hit[i])>maxi) maxi=ball_score(hit[i]);
				}
				A_score+=maxi;
				A_hit_score=0;
				A_color(fa);
			}	
		}
	}
 	
 } 
 
 int main(){
 	int t;
 	cin>>t;
 	cin.get();  //吸收回车 
 	while(t--){
 		A_score=0;B_score=0;  //每局开始,双方分数清零 
 		A_hit_score=0;B_hit_score=0; //击打得分清零 
 		init_ball_num(); //球数初始化 
		A_red();
	 }
	 cout<<A_100_times<<":"<<B_100_times;
 }
 

 
 

【写在后面】

觉得对你有帮助的话记得一键三连哦~(误

相关题目放在了【HNU CJ】专栏

如果有啥问题可以评论留言或者私我哦~

/****************************************************************** *软件名称: 三维斯诺克 * *开发者 : 赵亮 * *版本号 : 1.0 * *版权信息: 无。(有商业利益,不要忘了我^_^) * *日期 : 2002年11月29日 * * * * * * *********************************************************************/ ////////////////////////////////////////////////////////////////////// 1. 运行环境: 此软件可运行在windows98,windows2000,windows nt下,需要用户先安装 DirectX8.0或8.0以上的版本,CPU的主频需要在500Hz以上,最好配有3d图形 加速卡。为了使用户在使用的时候得心应手,最好配备有3d鼠标(通过中键的 滚动可以方便地调整观察者与物体的距离)。 ////////////////////////////////////////////////////////////////////// 2. 开发环境: 软件的开发平台为Microsoft Visual C++ 6.0,并且安装了DirectX8 SDK, 整个开发过程中用的是Windows API和DirectX API,没有使用MFC。 ////////////////////////////////////////////////////////////////////// 3. 功能说明: 此软件为一个桌面的游戏,可以在窗口模式和全屏模式(推荐使用)下运行。 游戏的内容为传统的斯诺克台球,游戏的场景为三维的。 (1)在应用第一人称视角瞄准时,鼠标的前后左右移动分别代表了玩家的抬 头和扭头,玩家击球的方向为视线的方向。 (2)在击球的时候,鼠标的前后移动代表了球杆的前后移动,当球杆接触到 球的时候球被击出,击球的力度与鼠标前进的速度成正比。 (3)在游戏的过程中玩家可以通过右键将视角切换为俯视。 (4)在游戏的过程中玩家可以通过对话框选择是否预先画出球的运动路径。 (5)玩家可以改变窗口大小(在没有开局时,用鼠标拖动)。 (6)玩家可以来回切换与窗口和全屏模式之间(Alt+Enter)。 /////////////////////////////////////////////////////////////////////// 4. 操作说明(操作简单,几乎全部使用鼠标): (1) 游戏选项-->;;;;;;;开局:开始游戏。 (2) 游戏开始后,鼠标拖动可以移动白球的位置,选择好位 置后,单击左键确定。 (3) 此时移动鼠标可以改变视角,视角影响击球的方向。 (4) 滚动滚轮可以拉近视距,再单击左键确定击球的方向。 (5) 前后移动鼠标,可看见球杆跟着鼠标一起前后移动,当 球杆接触到球,球即被击出。 (6) 击球的力度与鼠标向前移动的速度成正比。 (7) 在移动白球和改变视角的时候可以单击右键切换投影的 方式。 (8) 在改变视角时可以滚动中键改变视点离白球得距离。 (9) 在玩家姓名的对话框中,选中";;;;;;;使用画线器";;;;;;;可在未击球 的时候看到球的运动路线。 (10) Alt+Enter:全屏和窗口模式的转换。 (11) Esc:退出游戏。 ///////////////////////////////////////////////////////////////////////// 6. 版权说明: 此游戏从设计到写代码均由我一个人完成。除Windows API和DirectX API外,未 使用第三方控件。 //////////////////////////////////////////////////////////////////////// 7. 与同类软件比较: 在以前电视游戏机、现在的一些网络游戏中(如:联众、可乐吧)可以看到类似 的游戏。但是我的游戏与这些游戏有着本质的区别: (1)它们是二维的,我是三维的。 (2)光照、纹理、滚动、视距的改变,在视觉效果上有很大突破。 (3)它们都只能通过俯视观察场景,我可以从真实的击球者位置观察场景。 (4)它们都通过不同的画线方式来瞄准,而我是通过击球者的视线来瞄准。 (5)它们的台球与球台的尺寸比例与真实差距很大(原因:屏幕象素有限) 而在我的游戏中一次不需要让玩家看到整个场景,因而台球与球台的 尺寸比例是真实的,而且在瞄准时方向的选择更加细腻。 (6)我通过鼠标的前后移动来击球,既有强烈的真实感,又可以细腻地把 握出杆的力度。 (7)当玩家为一个初学者时,我的“画运动路径”可以帮助玩家100%精确 的瞄准,逐步培养他的球感。 综上所述:我的这个游戏的最大的优点是强烈的真实感,我是一个台球爱 好者,在设计时我从各个方面、最大程度的考虑了游戏的真实性。无论从感官还 是玩法上都与以前的游戏有着天差地别。我可以毫不夸张地说,玩家这个游戏玩 得好,他玩真实的台球的球感也一定好。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值