java保龄球计分_TDD练习:保龄球计分

本文介绍了一个使用TDD(测试驱动开发)方法实现的Java保龄球计分系统。通过详细解读规则并编写代码,展示了如何根据保龄球比赛的计分规则计算每轮得分和总分。文章提供了测试用例和关键代码片段,并讨论了领域规则抽象的挑战。
摘要由CSDN通过智能技术生成

前言

培训遗留作业,计划放在国庆空闲时间做,所以这算是走计划节奏。另外,真的是不喜欢做这些题,虽然实现以后发现很简单。但是没实现之前,多少还是觉得有些困难,可能是自己做题太少(不知道别人做题时候啥感觉)。。另外,做这些题我是感觉完全搭不上算法的边,可能是我自己没专门学过的原因吧,基本上纯粹是按照题的说明需求,然后自己思考,整理思路,然后实现...过程就是这样。

保龄球计分

(题目摘自网络,反正都一个规则)

打保龄球是用一个滚球去撞击10个站立的瓶,将瓶击倒。一局分10轮,每轮可滚球1 次或多次,以击到的瓶数为依据计分,一局得分为10轮得分之和,而每轮的得分不仅与本轮的滚球情况有关,还可能与后一轮或两轮的滚球情况有关,即:某轮某次滚球击倒的瓶数不仅要计入本轮得分,还可能会计入前一轮或两轮得分。

计分规则具体如下:

① 若某一轮的第一次滚球就击倒全部10个瓶,则本轮不再滚球(若是第10轮还需加2次滚球),该轮得分为本次击倒瓶数10与以后2次滚球所击倒瓶数之和。

② 若某一轮的第一次滚球未击倒全部10个球,则对剩下未击倒的瓶再滚球一次,如果这2次滚球击倒全部10个瓶,则本轮不再滚球(若是第10轮还需加1次滚球),该轮得分为这2次击倒瓶数10与以后1次滚球所击倒瓶数之和。

③ 若某一轮2次滚球未击倒全部10个瓶,则本轮不在滚球,该轮得分为这2次滚球所击倒瓶数之和。

编写一个程序,统计各轮得分和累积总分。

Input:

输入数据是文本格式,共1行(字符串),有最多22个[0,10]之间的整数,表示每轮滚球第一次或第二次记到的秋熟,输入数据保证合法,两个整数间仅有一个空格。

Output:

自定义。对外接口为Calcscore(const char *s);

实现思路

计算每轮单独得分,十轮累加得总分。每轮单独得分,按规则可以大致总结出,如果议论中首次全中或者两次补中,则相当于第一次滚球后连续加后面两次;否则,只加后面一次。直接看代码吧,按照TDD方式,先写测例,再快速实现,最后的抽象实在不知道怎么抽象,估计是仅仅实现了功能,代码质量还相当欠缺,后续看下别人实现,再来做修改。

/* test.cpp */

#include

extern int Calcscore(const char *s);

void main()

{

assert(Calcscore("10 10 10 10 10 10 10 10 10 10 10 10") == 300);

assert(Calcscore("10 10 10 7 2 9 1 8 1 8 2 10 9 1 10 8 2") == 192);

assert(Calcscore("1 4 4 5 6 4 5 5 10 0 1 7 3 6 4 10 2 8 6") == 133);

}

/* bowling.cpp */

#include

#include

typedef struct _context

{

const char *s;

int pos;

}Context;

int Record[10];

bool Is_STRIKE(int score)

{

return score == 10;

}

int Parsescore(Context &ctx,int offset)

{

int temp_score = 0;

if (ctx.s[ctx.pos] == ' ')

{

ctx.pos++;

}

return atoi(ctx.s + ctx.pos + offset);

}

int CalcscorePerRound(Context &ctx)

{

int offset = 0;

int curr_score = 0;

int next_score = 0;

int round_score = 0;

curr_score = Parsescore(ctx,0); // 0表示解析分数的起始偏移

if (Is_STRIKE(curr_score))

{

offset = 2;

next_score = Parsescore(ctx,offset);

ctx.pos += 2; // 本轮STRIKE,下一轮击球开始解析的位置

}

else

{

offset = 0;

ctx.pos++;

next_score = Parsescore(ctx,offset);

ctx.pos++; // 本轮SPARE,下一轮击球开始解析的位置

}

// 本轮计分

if (10 > (curr_score + next_score)) // 本轮两次击球未全中

{

round_score = curr_score + next_score;

}

else // 本轮STRIKE或两次补中

{

int third_score = Parsescore(ctx,offset);

round_score = curr_score + next_score + third_score;

}

return round_score;

}

int Calcscore(const char *s)

{

Context ctx = {s,0};

int total_score = 0;

printf("每轮得分:\n");

for (int i = 0; i < 10; i++)

{

Record[i] = CalcscorePerRound(ctx);

printf("%-2d ",Record[i]);

total_score += Record[i];

}

printf("\n累计总分:%d",total_score);

printf("\n+++++++++++++++++++++++++++++++++\n");

return total_score;

}

总结

领域规则抽象,思考了N久,真心就是(臣妾做不到啊...)。如果仅仅就为实现功能而写的代码,再进行重构抽象,现在感觉好难。只能是多看高质量代码,多积累,多练习了!

相关文章

总结

以上是编程之家为你收集整理的TDD练习:保龄球计分全部内容,希望文章能够帮你解决TDD练习:保龄球计分所遇到的程序开发问题。

如果觉得编程之家网站内容还不错,欢迎将编程之家网站推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。

如您喜欢交流学习经验,点击链接加入交流1群:1065694478(已满)交流2群:163560250

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值