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

闲来无事,看到论坛中一个帖子谈到
《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的分数。


保龄球计分的面向对象实现_第1张图片

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());
	}
}

你可能感兴趣的:(OO)