`
sswh
  • 浏览: 163822 次
  • 性别: Icon_minigender_1
社区版块
存档分类
最新评论

保龄球计分的面向对象实现

OO 
阅读更多
闲来无事,看到论坛中一个帖子谈到
《OO 还是 procedural 小程序的设计》http://www.iteye.com/topic/1112383
尝试用OO的方式写了一下(真的是太闲了 ):

引用

保龄球基本规则: 每一盘可以有10 个frame ,从1-9 个 frame 是有两次击球机会,第10个 有可能有3次机会。
如果一个frame第一个球全中(strike) 那就 进入 下一个frame, 并把下两次击球的得分算为这次的bonus。
如果一个frame 没有全中,就打这个frame的第二个球, 如果补了个全中(Spare),那就把下一次击球的得分算为bonus。
如果一个frame既没有全中,也没有补全中,那就击倒几个瓶算积分。
第10个frame,如果是全中,或者补中 就有3次击球机会,并把三次击球总共打倒的瓶数算为这个frame的分数。




public interface IFrame {

	int BALLS = 10;

	/** 当前Frame以及之后的总分 */
	int totalScore();

	/** 当前Frame得分 */
	int frameScore();

	/** 当前Frame可贡献的Spare奖励 */
	int getSpareBonus();

	/** 当前Frame可贡献的Strike奖励 */
	int getStrikeBonus();

	IFrame nextFrame();

	void setNextFrame(IFrame frame);

}


public abstract class AbstractFrame implements IFrame {

	private IFrame nextFrame;

	@Override
	public int totalScore() {
		return frameScore() + nextFrame().totalScore();
	}

	@Override
	public IFrame nextFrame() {
		return nextFrame;
	}

	@Override
	public void setNextFrame(IFrame frame) {
		nextFrame = frame;
	}
}


public class StrikeFrame extends AbstractFrame implements IFrame {

	@Override
	public int frameScore() {
		return BALLS + nextFrame().getStrikeBonus();
	}

	@Override
	public int getSpareBonus() {
		return BALLS;
	}

	@Override
	public int getStrikeBonus() {
		return BALLS + nextFrame().getSpareBonus();
	}
}


public class SpareFrame extends AbstractFrame implements IFrame {

	protected int[] hits;

	public SpareFrame(int[] hits) {
		this.hits = hits;
	}

	@Override
	public int frameScore() {
		return BALLS + nextFrame().getSpareBonus();
	}

	@Override
	public int getSpareBonus() {
		return hits[0];
	}

	@Override
	public int getStrikeBonus() {
		return BALLS;
	}

}


public class NormalFrame extends AbstractFrame implements IFrame {

	protected int[] hits;

	public NormalFrame(int[] hits) {
		this.hits = hits;
	}

	@Override
	public int frameScore() {
		return hits[0] + hits[1];
	}

	@Override
	public int getSpareBonus() {
		return hits[0];
	}

	@Override
	public int getStrikeBonus() {
		return hits[0] + hits[1];
	}

	public void setHits(int[] hits) {
		this.hits = hits;
	}

}


public abstract class AbstractFinalFrame extends AbstractFrame implements IFrame {

	@Override
	public int totalScore() {
		return frameScore();
	}

	@Override
	public IFrame nextFrame() {
		throw new RuntimeException("不支持此方法!");
	}
}


public class FinalStrikeFrame extends AbstractFinalFrame implements IFrame {

	protected int[] hits;

	public FinalStrikeFrame(int[] hits) {
		this.hits = hits;
	}

	@Override
	public int frameScore() {
		return BALLS + hits[1] + hits[2];
	}

	@Override
	public int getSpareBonus() {
		return BALLS;
	}

	@Override
	public int getStrikeBonus() {
		return BALLS + hits[1];
	}

}


public class FinalSpareFrame extends AbstractFinalFrame implements IFrame {

	protected int[] hits;

	public FinalSpareFrame(int[] hits) {
		this.hits = hits;
	}

	@Override
	public int frameScore() {
		return BALLS + hits[2];
	}

	@Override
	public int getSpareBonus() {
		return hits[0];
	}

	@Override
	public int getStrikeBonus() {
		return BALLS;
	}

	public void setHits(int[] hits) {
		this.hits = hits;
	}

}


public class FinalNormalFrame extends AbstractFinalFrame implements IFrame {

	protected int[] hits;

	public FinalNormalFrame(int[] hits) {
		this.hits = hits;
	}

	@Override
	public int frameScore() {
		return hits[0] + hits[1];
	}

	@Override
	public int getSpareBonus() {
		return hits[0];
	}

	@Override
	public int getStrikeBonus() {
		return hits[0] + hits[1];
	}

	public void setHits(int[] hits) {
		this.hits = hits;
	}

}


public class FrameFactory {

	static IFrame buildFrame(int[] hits) {
		if (hits[0] == IFrame.BALLS) return new StrikeFrame();
		if (hits[0] + hits[1] == IFrame.BALLS) return new SpareFrame(hits);
		return new NormalFrame(hits);
	}

	static IFrame buildFinalFrame(int[] hits) {
		if (hits[0] == IFrame.BALLS) return new FinalStrikeFrame(hits);
		if (hits[0] + hits[1] == IFrame.BALLS) return new FinalSpareFrame(hits);
		return new FinalNormalFrame(hits);
	}

	public static IFrame buildFrames(int[][] hitCounts) {
		if (hitCounts == null || hitCounts.length == 0) throw new IllegalArgumentException("参数无效!");
		IFrame last = buildFinalFrame(hitCounts[hitCounts.length - 1]);
		for (int i = hitCounts.length - 2; i >= 0; i--) {
			IFrame frame = buildFrame(hitCounts[i]);
			frame.setNextFrame(last);
			last = frame;
		}
		return last;
	}
}


public class Main {
	public static void main(String[] args) {
		int[][] hitCounts = new int[][] { { 10, 0 }, { 7, 2 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 } };
		IFrame head = FrameFactory.buildFrames(hitCounts);
		System.out.println(head.totalScore());
	}
}
  • 大小: 13.9 KB
0
3
分享到:
评论
2 楼 sswh 2011-07-22  
1 楼 sswh 2011-07-21  
另一份 半OO 的代码:
public class Frame {

	public static final int BALLS = 10;

	protected Frame nextFrame;

	protected int[] hitCounts;

	public Frame(int[] hitCounts) {
		this.hitCounts = hitCounts;
	}

	/** 当前Frame以及之后的总分 */
	public int totalScore() {
		int total = 0;
		for (Frame f = this; f != null; f = f.nextFrame) {
			total += f.frameScore();
		}
		return total;
	}

	/** 一局得分 */
	public int frameScore() {
		int total = 0;
		for (int hit : hitCounts)
			total += hit;

		if (nextFrame != null) {
			if (isStrikeFrame()) total += nextFrame.getStrikeBonus();
			if (isSpareFrame()) total += nextFrame.getSpareBonus();
		}
		return total;
	}

	/** 当前Frame可贡献的Spare奖励 */
	public int getSpareBonus() {
		return hitCounts[0];
	}

	/** 当前Frame可贡献的Strike奖励 */
	public int getStrikeBonus() {
		return hitCounts[0] + (nextFrame != null && isStrikeFrame() ? nextFrame.hitCounts[0] : hitCounts[1]);
	}

	public boolean isSpareFrame() {
		return !isStrikeFrame() && hitCounts[0] + hitCounts[1] == BALLS;
	}

	public boolean isStrikeFrame() {
		return hitCounts[0] == BALLS;
	}

	public void setNextFrame(Frame frame) {
		nextFrame = frame;
	}

}

 class FrameFactory {

	public static Frame buildFrames(int[][] hitCounts) {

		Frame last = new Frame(hitCounts[hitCounts.length - 1]);
		for (int i = hitCounts.length - 2; i >= 0; i--) {
			Frame frame = new Frame(hitCounts[i]);
			frame.setNextFrame(last);
			last = frame;
		}
		return last;
	}
}

 class Main {

	public static void main(String[] args) {
		int[][] hitCounts = new int[][] { { 10, 0 }, { 7, 2 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 },
				{ 0, 0 }, { 0, 0 }, { 0, 0 } };
		Frame head = FrameFactory.buildFrames(hitCounts);
		System.out.println(head.totalScore());
	}
}

相关推荐

    保龄球计分程序 完整源代码

    总之,这个保龄球计分程序展示了C++在实现规则复杂的游戏逻辑时的能力,同时也体现了代码调试和优化的重要性。通过学习和理解这个程序,开发者不仅可以提升C++编程技能,还能对游戏编程的逻辑处理有更深的认识。对于...

    保龄球计分java代码

    通过扩展这个简单的保龄球计分程序,开发者可以深入了解Java的面向对象编程、数据结构(如列表或队列来存储回合得分)、控制流(如循环和条件语句)以及用户交互设计。这不仅是一个有趣的项目,也是一个学习和巩固...

    C#版保龄球记分代码

    保龄球记分系统是一个常见的编程练习,可以帮助开发者熟悉条件语句、循环、数组以及面向对象编程的概念。以下是对C#版保龄球记分代码的详细解析: 首先,我们需要了解保龄球的基本规则。一局保龄球由10个“帧”组成...

    保龄球计分程序模拟(C#)

    在本文中,我们将深入探讨如何使用C#编程语言模拟一个保龄球计分程序。保龄球计分系统是一个有趣且具有挑战性的项目,它涉及到循环、条件判断、数组等核心编程概念。让我们一起深入了解这个项目的实现细节。 首先,...

    VisualC++ MFC 保龄球计分系统

    保龄球计分系统通常需要有显示分数、记录投球情况、计算总分等功能,这可以通过设计多个窗口和控件来实现。MFC提供了丰富的控件类,如CButton,CEdit,CStatic等,可以方便地创建按钮、文本框和标签等元素。我们可以...

    保龄球管理系统C++ 期末课程设计

    2. **面向对象编程**:保龄球管理系统的核心是类的设计,如“保龄球游戏”类、“球员”类、“比赛”类等。这些类封装了相关的数据(如得分、球员信息)和操作(如投球、计算得分)。继承和多态性也是OOP的重要概念,...

    BBCBowlingGame:保龄球比赛记分牌

    通过阅读和分析这些代码,我们可以深入理解如何利用Java实现一个功能完备的保龄球计分系统。 总结,这个项目提供了一个实践Java编程、理解面向对象设计和算法实现的好机会。开发者可以通过它学习如何用代码模拟现实...

    jmosullivan-bowling:保龄球记分卡

    保龄球记分卡起源在接受BBC技术毕业生计划的面试过程中,我被要求开发一款软件,该软件可以计算10针保龄球比赛的得分。 确切的说法是建立“ 10针保龄球记分卡”。 误认为这意味着该软件应该对正在进行的游戏进行评分...

    CC_保龄球

    这个描述虽然简洁,但我们可以推测它可能是一个实现保龄球比赛计分系统的程序。保龄球游戏的计分系统相对复杂,包括每局10个框架(frames),每个框架两次投球机会,以及特殊情况如全中(strike)和补中(spare)等...

    bowling-scorecard:Makers Academy 第 5 周挑战 - 使用 JavaScript、JQuery、TDD、OOP 的 10 针保龄球记分卡

    保龄球记分卡概括我在 Makers Academy 的第 5 周挑战是用 JavaScript 创建一个 10 针保龄球记分卡。 这对于在 JavaScript 中学习面向对象编程是一个巨大的挑战。 虽然获得基本游戏逻辑相对简单,但我的代码最初看...

    BowlingGame:在保龄球比赛中跟踪分数的计算器

    首先,我们需要了解保龄球的计分规则。一局保龄球共分为10轮,每轮有两次投球机会。如果在一轮内击倒所有10个瓶,即称为"全中"(Strike),则在这一轮的得分是10分加上接下来两轮的投球得分。如果在第一次投球时击倒...

    bowling:保龄球游戏的简单计算器

    总之,这个保龄球游戏的Java实现是一个很好的练习,可以帮助开发者加深对面向对象编程、数据结构、控制流和异常处理的理解。通过研究这个项目,你可以提升自己的编程技巧,并对Java编程有更深入的认识。

    保龄球

    通过以上分析,我们可以看出,创建一个保龄球游戏项目涵盖了Python编程的多个核心概念,包括基础语法、面向对象编程、异常处理、文件操作以及游戏逻辑的实现。这样的项目对于学习和提高Python技能是很有价值的。

    java-bowling-kata:鲍勃叔叔的 Java 保龄球卡塔

    在实现过程中,你可能会涉及一些面向对象的设计原则,如单一职责原则(SRP)、开放封闭原则(OCP)、里氏替换原则(LSP)、接口隔离原则(ISP)和依赖倒置原则(DIP)。例如,你可以将计分逻辑与游戏记录分离,以...

    C++经典习题

    通过解决这个保龄球记分系统的编程问题,C++初学者可以深入理解面向对象编程的概念,如类和对象的设计,同时提升对控制流、数据处理和异常处理的理解。此外,还可以锻炼逻辑思维和问题解决能力,这些都是软件开发中...

    bowling-game

    在本项目"bowling-game"中,我们关注的是一个用Java编程语言实现的保龄球比赛计分系统。这个系统不仅能够计算单个玩家的得分,还具备展示比赛排名的功能,包括顶级球员和最佳球队的SQL查询。让我们深入探讨这个项目...

    TDDinC_Smidig2007 ATDD

    《TDD in C_Smidig2007 ATDD》是一本优秀的编程训练书籍,它通过一个具体的例子——保龄球计分游戏(Bowling Game Kata),向读者展示了如何在纯C语言环境中进行测试驱动开发(TDD)。本书作者Olve Maudal,通过他在...

    JAVA(spoto)内部培训ppt

    最后,“案例:保龄球记分程序.ppt”提供了一个实际的编程案例,让学员运用所学知识解决实际问题。通过分析和实现保龄球得分计算,学员可以更深入地理解类的设计、对象的交互以及控制流程等概念。 总的来说,这套...

    cl-bowling:Common Lisp中保龄球鞋的解决方案

    保龄球游戏是一个经典的编程练习,它涉及到一系列规则和计分逻辑,这对于熟悉新编程语言或者实践面向对象设计是很有帮助的。 首先,让我们了解一下保龄球游戏的基本规则。一局保龄球由十轮组成,每轮球员有两次投球...

Global site tag (gtag.js) - Google Analytics