1076:Bowl

本文描述了一个关于如何开发一款半自动保龄球计分系统的项目,需根据投球者每局的击倒瓶数自动计分,并遵循特定的得分规则,如好球、备用和奖励球。
摘要由CSDN通过智能技术生成
描述

Technology hasn't come quickly to Joe's Bowl-a-rama. Minimum wage teens, and not those fancy machines, still reset the pins, and the grizzled veteran bowlers still mark up their own score sheets. Unfortunately for Joe Junior, who now runs the Bowl-a-rama, people his age are a little shaky on the scoring, especially after the second beer, and are staying away in droves, bowling instead at the new CyberBowl 2000 down the street, which scores automatically. Joe Junior figures that if he puts a cheap PC next to every lane, he can get a cheap, semi-automatic scoring system going. His plan is for the PC's to run software that only requires a bowler to enter the number of pins that remain standing after every throw -- and the software will keep score and tell the bowler when his game is over. Joe Junior would like to hire you to write the software.
Of course, since you may not know how to score a game of bowling either, Joe Junior has provided a description of the rules. The basic game consists of ten frames. In a frame, you get two chances to throw a ball down the alley and knock over as many pins as you can. There are ten pins standing at the beginning of a frame, and none are replaced after getting knocked over on the first ball, so the most pins you can knock over in a frame is ten. You get one point for each pin knocked over. In addition, there are two bonuses you can earn. If you knock over all ten pins on your first ball of the frame, you have scored a ``strike''; besides the ten points for the pins, your score in this frame is increased by the total number of pins knocked down with your next two balls. Those next two balls are usually part of another frame (or two) and score points in that frame (or those frames) as well.

If you knock over all ten pins in a frame, but it takes you two balls to do it, you have scored a ``spare''; in addition to your ten points for pins knocked down, your score for the frame is increased by the number of pins you knock down on your next ball. Of course, those pins also count as part of the next frame. If you score a spare (or strike) in the final (tenth) frame, you are entitled to one (or two) extra balls to determine your tenth frame bonus. A perfect game scores 300 points, because each frame scores 30, 10 for knocking down 10 pins, and 20 for knocking down 20 pins with the next two balls combined.

Now, are you ready to sign on to write the software?

技术还没有快速地发展到乔的保龄球大赛。最低工资的青少年,而不是那些花哨的机器,仍然重置瓶子,头发花白的老投球手仍然标记自己的得分表。不幸的是,对于乔 · 朱尼尔(Joe Junior)来说,他现在经营着一个保龄球赛(Bowl-a-rama) ,他这个年纪的人在得分方面有点不稳定,尤其是在喝了第二杯啤酒之后,他们成群结队地远离比赛,转而在街上新举办的赛博保龄球2000(CyberBowl 2000)上打保龄球,该比赛会自动得分。乔认为,如果他把一个廉价的个人电脑旁边的每一条球道,他可以得到一个廉价的,半自动计分系统去。他的计划是让个人电脑运行一个软件,只需要投球手输入每次投球后仍然站立的球瓶数,软件就会计分并告诉投球手比赛结束。Joe Junior 想要雇佣你来编写这个软件。当然,由于你可能也不知道如何在保龄球比赛中得分,Joe Junior 已经提供了一个规则的描述。基本的游戏包括十帧。在一个相框里,你有两次机会把球扔进球道,尽可能多地击倒瓶子。在一个框架的开始有10个瓶子,没有一个在第一个球被撞倒后被替换,所以在一个框架中你能撞倒的最多的瓶子是10个。每打翻一个销子就得一分。此外,你还可以获得两个奖金。如果你用第一个球击倒了所有10个瓶子,你就得到了一个“好球”; 除了瓶子的10分之外,你在这个框架中的得分会随着接下来两个球击倒的瓶子的总数而增加。接下来的两个球通常是另一个框架(或两个)的一部分,并且在那个框架(或那些框架)中得分。如果你击倒了一个框架中的所有10个瓶子,但需要两个球才能做到,那么你就得到了一个“备用”; 除了你击倒的10个瓶子之外,你在框架中的得分会随着你击倒下一个球的瓶子数量而增加。当然,这些图钉也算作下一帧的一部分。如果你在最后(第十)帧得到一个备用(或罢工) ,你有权一个(或两个)额外的球,以确定你的第十帧奖金。一个完美的游戏得分300分,因为每一帧得分30分,击倒10个瓶子得分10分,击倒20个瓶子得分20分,下面两个球加起来。

现在,你准备好登录编写软件了吗?

输入
Input contains several complete or partial games. A game is described by a single line with a single name, not to exceed 12 characters, and sequence of numbers, one for each ball thrown indicating the number of pins still standing after that throw,ended with -1. According to the rules, there are from 11 to 21 throws in a game; no input line will show throws beyond the last throw of the game. The number of games described in a file is not predetermined, so you'll have to detect the end of the input file.

输入包含几个完整的或部分的游戏。一个游戏是由一个单一的名称,不超过12个字符,和数字序列,一个球表示每个球扔出后仍然站立的瓶数,以 -1结束。根据规则,一场比赛有11到21次投掷,没有输入线会显示超过最后一次投掷的投掷。文件中描述的游戏数量不是预先确定的,因此您必须检测输入文件的结尾。

输出
The standard output will contain, on successful completion of the program, two output lines for each input line. The first output line contains the name of the bowler and a record of the throws in each frame. This record shows, for each frame, the number of pins knocked down for each throw as a digit, with some exceptions. For a throw that knocks down no pins, a dash (\verb$-$) is used instead of a `0'. An 'X' indicates a throw that knocks down all 10 pins on the first try. A slash ('/') indicates a throw that finishes knocking down all the pins, after the previous throw left some standing. Otherwise, a throw is shown as a digit (`1' to `9'). The number of throws in a frame may be one (a strike in frames 1 to 9), or three (a strike or spare in frame 10, followed by bonus balls), but is usually two. Here are examples of throw markings for a variety of situations:

在程序成功完成后,标准输出将包含每个输入行的两个输出行。第一个输出行包含投球手的名字和每个框架中投球的记录。这个记录显示,对于每一个框架,每一次掷球被击倒的瓶子数作为一个数字,除了一些例外。对于不击倒瓶子的抛掷,使用破折号(动词 $- $)代替“0”。“ X”表示在第一次尝试中击倒所有10个瓶子。斜线(’/’)表示在前一次抛球留下一些站立位置后,完成击倒所有瓶子的一次抛球。否则,抛出显示为一个数字(“1”到“9”)。一个框架中的投掷次数可以是一次(在框架1到9中的一次打击) ,或者是三次(在框架10中的一次打击或者备用,然后是奖励球) ,但是通常是两次。下面是各种情况下的投掷标记示例:

The second output line shows cumulative scores. The cumulative score for the first frame is just the score for pins knocked down in frame, plus bonus points if they apply. The cumulative score for any other frame is the cumulative score for the previous frame plus the score for pins knocked down in that frame, plus the bonus pins that may have been earned for a strike or spare in this frame. It is possible to have markings on line one for a frame, but no score on line two, in the event that the frame is a strike or spare but the bonus points for the frame aren't yet known.

The format for this output requires that the bowler's name be left-justified. The fields for each frame are three characters wide, with a space separating each field. The fields begin in columns 14, 18, 22, and so on. The record of the throws in the first line is left justified in its field. The cumulative score is right justified in its field. There is a blank line that separates the scores of one bowler from the scores of another.

第二个输出行显示累积分数。第一帧的累计分数只是击倒在帧内的针的分数,如果适用的话还可以加分。任何其他帧的累积得分是前一帧的累积得分加上该帧中击倒的销钉的得分,再加上该帧中击倒或备用销钉可能获得的奖励。有可能在第一行标记一个框架,但没有得分在第二行,在事件中的框架是一个罢工或备用,但奖金点的框架尚不知道。

这个输出的格式要求投球手的名字左对齐。每个框架的字段有三个字符宽,每个字段之间用一个空格分隔。字段以第14、18、22列开始,以此类推。第一行的掷球记录在其场地中左对齐。累积得分在它的领域是正确的。有一条空白线把一个投球手的分数和另一个投球手的分数分开。


样例输入
Chuck 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 -1
Solly 0 0 0 0 0 0 0 0 0 0 0 8 -1
Lothar 10 0 10 0 10 0 -1
Brutus 5 1 2 0 6 0 9 -1
McGillicuddy 0 0 1 0 -1
Homer 0 10 0 0 0 0 -1
Barney 0 0 0 0 0 0 0 0 0 0 1 0 -1
样例输出
The line of digits is intended to guide you in proper output alignment, and is not part of the output that your solution should produce. 

数字行是用来指导正确的输出对齐方式,而不是解决方案应该产生的输出的一部分。
  
1234567890123456789012345678901234567890123456789012 
Chuck        9/  9/  9/  9/  9/  9/  9/  9/  9/  9/9 
              19  38  57  76  95 114 133 152 171 190 

Solly        X   X   X   X   X   X   X   X   X   XX2 
              30  60  90 120 150 180 210 240 270 292 

Lothar       -/  -/  -/ 
              10  20 

Brutus       54  8/  4/  1 
               9  23  34 

McGillicuddy X   X   9/ 
              29  49 

Homer        X   -/  X   X   X 
              20  40  70 

Barney       X   X   X   X   X   X   X   X   X   X9/ 
              30  60  90 120 150 180 210 240 269 289 
来源
South Central USA 1998


分析

又是一道情境题,又极长,简单浓缩一下:

给出姓名,每掷一球后没倒的瓶数,-1表示结束

投掷表达方式:数字表示打倒的瓶数。X表示第一球全中。/表示补掷全中。-表示一个也没中。

成绩:全中得分是10加下两球倒瓶数。补全中是10加下一球倒瓶数。最后一轮投三个球,得分是倒球数。

现在看上去简单多了吧。


代码
#include <stdio.h>
 
int main(int argc, char *argv[]) 
{
	char name[25];	
	int number, r[25], score[20];	
	while(scanf("%s", name) > 0)
	{
		int k = 0, c = 0;
		while(scanf("%d", &number) && number != -1)
		{
			r[k++] = number;
		}
		printf("%-12s", name);
		for(int i = 0; i < k; ++i)
		{
			if(c++ < 10) printf(" ");
			score[c] = 0;
			
			if(r[i] == 0) 
			{
				if(i + 1 < k && c < 10) printf("X  ");
				else printf("X");
				if(i + 2 < k)
				{
					if(r[i + 1] == 0)
						score[c] = 10 + 10 + 10 - r[i + 2];
					else score[c] = 10 + 10 - r[i + 2];
				} 
				else score[c] = -1;
			}
			else 
			{
				if(r[i] == 10) printf("-");
				else printf("%d", 10 - r[i]);
				if(i + 1 < k){
					if(r[i + 1] == 0) {
						printf("/");
						if(i + 2 < k) score[c] = 10 + 10 - r[i + 2];
						else score[c] = -1;
					}
					else if(r[i] == r[i + 1]) 
					{
						score[c] = 10 - r[i];
						printf("-");
					}
					else {
						score[c] = 10 - r[i + 1];
						printf("%d", r[i] - r[i + 1]);
					}
				}
				else score[c] = -1;
				if(i + 2 < k && c < 10) printf(" ");
				++i;
			} 
		}
		printf("\n            ");
		int total = 0;
		for(int i = 1; i <= c; ++i) {
			if(score[i] == -1) break;
			total += score[i];
			printf(" %3d", total);
		}
		printf("\n\n");
	}
	return 0;
}

给个赞和关注吧

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值