`

告诉你什么是优雅的代码(5)------ 百度之星也是普通人(答案)

    博客分类:
  • Java
阅读更多

最近在写优雅代码系列的时候,由于程序偏向算法性,代码写得比较PO。于是今天打算用OO来写火柴游戏。谁知道,一旦打开我那OO思想的闸门,就让我意识到什么是厚积薄发,各种设计模式便如一个个性感的美女一样浮现在我脑海中,令我欲罢不能。于是一个个的类便如雪片一般飘散开来。写到兴起,竟抛弃了火柴游戏的实现,写成了一个“多位数运算控制台显示系统”的怪胎。首先来看下这个系统的使用方法:

public static void main(String[] args) {

        MultiDigit num1 = new MultiDigit(42723);

        MultiDigit num2 = new MultiDigit(2577);

        Operation op = OperFactory.getOper('+');

        Expression exp = new Expression(num1,num2,op);

        exp.draw();

       

    }
 



执行后,运行结果如下:

 M  M MMMM MMMM MMMM MMMM        MMMM MMMM MMMM MMMM        M  M MMMM MMMM MMMM MMMM
 M  M    M    M    M    M   |       M M       M    M  ---   M  M M       M M  M M  M
 MMMM MMMM    M MMMM MMMM  -+-   MMMM MMMM    M    M        MMMM MMMM MMMM M  M M  M
    M M       M M       M   |    M       M    M    M  ---      M    M    M M  M M  M
    M MMMM    M MMMM MMMM        MMMM MMMM    M    M           M MMMM MMMM MMMM MMMM

 

 


且不论这里显示效果不是太好,来说一下这个系统的设计。整个系统大概用到了“单例模式”,“模板模式”,“享元模式”,“工厂模式”,大概20个类,有极佳的可扩展性。不是太难,就不拿出来了。



好了,有了以上这个超强的显示系统。再来分析一下火柴游戏的算法。首先来看一下这张表:


数字   加一   减一   自移动

0       8                     6,9

1

2                              3

3       9                     2

.

.

.

9       8       5,3        6,0


这张是反映火柴可能变化的表,加一表示增加一根火柴,我们将每个数字的变化存到集合dic[],当检验某个表达式时,遍历一下三个数的dic[],如果符合移动规则并且等式成立,则找到了可行解。合理的移动规则有三种:1.没有产生过移动 2.一加一减 3.自移动一次,如何表示和计算这种规则是个难点。我的方法如下,为每个数字附加一个值,见下表:


数字 (0) 加一 (1) 减一 (3) 自移动 (4)


对应三条规则,对于任意三个数字,附加值的计算结果分别为:

0+0+0 = 0

0+1+3 = 4

0+0+4 = 4

可见,sum(3个数) == 0 或4 ,则是符合移动规则的。

于是,一个优雅的方案浮出水面:

 

import java.util.ArrayList;
import java.util.List;

import app.matchgame.digit.Expression;
import app.matchgame.digit.MultiDigit;
import app.matchgame.digit.OperFactory;
import app.matchgame.digit.Operation;


class Node{
	int digit;
	int flag;
	public Node(int digit,int flag){
		this.digit = digit;
		this.flag = flag;
	}
}
class Digit{
	
	List<Node> dic = new ArrayList<Node>();
	
	int p = 0;
	public void addNode(Node node){
		dic.add(node);
	}
	public boolean hasNext(){
		return p < dic.size();
	}
	public Node next(){
		return dic.get(p++);
	}
	public void clear(){
		p = 0;
	}
	public Digit clone(){
		Digit clone = new Digit();
		clone.dic = this.dic;
		clone.p = 0;
		return clone;
	}
}
public class MatchGame {
	private Digit[] digTable;
	public void init(){
		digTable = new Digit[10];
		for (int i = 0; i < digTable.length; i++) {
			digTable[i] = new Digit();
			digTable[i].addNode(new Node(i,0));
			
		}
		digTable[0].addNode(new Node(8,1));
		digTable[0].addNode(new Node(6,4));
		digTable[0].addNode(new Node(9,4));
		
		digTable[2].addNode(new Node(3,4));
		
		digTable[3].addNode(new Node(9,1));
		digTable[3].addNode(new Node(2,4));
		
		digTable[5].addNode(new Node(6,1));
		digTable[5].addNode(new Node(9,1));
		digTable[5].addNode(new Node(3,4));
		
		digTable[6].addNode(new Node(8,1));
		digTable[6].addNode(new Node(5,3));
		digTable[6].addNode(new Node(0,4));
		digTable[6].addNode(new Node(9,4));
		
		digTable[7].addNode(new Node(1,3));
		digTable[8].addNode(new Node(6,3));
		digTable[8].addNode(new Node(9,3));
		
		digTable[9].addNode(new Node(8,1));
		digTable[9].addNode(new Node(5,3));
		digTable[9].addNode(new Node(3,3));
		digTable[9].addNode(new Node(0,4));
		digTable[9].addNode(new Node(6,4));
	}
	
	public void calc(int a,int b,int c, Operation op){
		Digit dig1 = digTable[a].clone();
		Digit dig2 = digTable[b].clone();
		Digit dig3 = digTable[c].clone();
		while(dig1.hasNext()){
			Node d1 = dig1.next();
			dig2.clear();
			while(dig2.hasNext()){
				Node d2 = dig2.next();
				dig3.clear();
				while(dig3.hasNext()){
					Node d3 = dig3.next();
					int tmp = d1.flag + d2.flag + d3.flag;
					if((tmp == 0 || tmp == 4)&&
							op.oper(d1.digit,d2.digit) == d3.digit){
						
						MultiDigit num1 = new MultiDigit(d1.digit);
						MultiDigit num2 = new MultiDigit(d2.digit);
						Expression exp = new Expression(num1,num2,op);
						exp.draw();
						System.out.println();
					}
					
				}
			}
		}
	}
	
	public static void main(String[] args) {
		MatchGame demo = new MatchGame();
		demo.init();
		//此处可根据输入获取相应运算
		Operation op = OperFactory.getOper('+');		
		demo.calc(3, 6, 9,op);
	}

}

 

运行结果如下:

 

 

 HHHH        HHHH        HHHH
    H   |    H     ---   H  H
 HHHH  -+-   HHHH        HHHH
    H   |    H  H  ---      H
 HHHH        HHHH        HHHH

 HHHH        HHHH        HHHH
    H   |    H     ---   H  H
 HHHH  -+-   HHHH        HHHH
    H   |       H  ---   H  H
 HHHH        HHHH        HHHH
 

 

0
0
分享到:
评论
2 楼 Shengli_fu 2015-06-24  
1 楼 mengsina 2011-10-26  
高手啊,膜拜了。

相关推荐

    国嵌必修实验代码5-5-2

    国嵌必修实验代码5-5-2国嵌必修实验代码5-5-2国嵌必修实验代码5-5-2国嵌必修实验代码5-5-2国嵌必修实验代码5-5-2国嵌必修实验代码5-5-2国嵌必修实验代码5-5-2国嵌必修实验代码5-5-2国嵌必修实验代码5-5-2国嵌必修...

    国嵌必修实验代码5-4-2

    国嵌必修实验代码5-4-2国嵌必修实验代码5-4-2国嵌必修实验代码5-4-2国嵌必修实验代码5-4-2国嵌必修实验代码5-4-2国嵌必修实验代码5-4-2国嵌必修实验代码5-4-2国嵌必修实验代码5-4-2国嵌必修实验代码5-4-2国嵌必修...

    Spring5 框架 ---- Spring5的新功能 ---- 代码

    Spring5 框架 ---- Spring5的新功能 ---- 代码 Spring5 框架 ---- Spring5的新功能 ---- 代码 Spring5 框架 ---- Spring5的新功能 ---- 代码 Spring5 框架 ---- Spring5的新功能 ---- 代码 Spring5 框架 ---- Spring...

    国嵌必修实验代码3-1-3

    国嵌必修实验代码3-1-3国嵌必修实验代码3-1-3国嵌必修实验代码3-1-3国嵌必修实验代码3-1-3国嵌必修实验代码3-1-3国嵌必修实验代码3-1-3国嵌必修实验代码3-1-3国嵌必修实验代码3-1-3国嵌必修实验代码3-1-3国嵌必修...

    国嵌必修实验代码4-2-2

    国嵌必修实验代码4-2-2国嵌必修实验代码4-2-2国嵌必修实验代码4-2-2国嵌必修实验代码4-2-2国嵌必修实验代码4-2-2国嵌必修实验代码4-2-2国嵌必修实验代码4-2-2国嵌必修实验代码4-2-2国嵌必修实验代码4-2-2国嵌必修...

    Qt5.6.3源代码 qt-everywhere-opensource-src-5.6.3

    qt-everywhere-opensource-src-5.6.3 用于手工编绎用的。

    Qt5-嵌入百度地图demo

    在本文中,我们将深入探讨如何使用Qt5框架与WebEngineView组件来嵌入百度地图,以便在您的应用程序中集成地理定位功能。这个示例项目,"Qt5-嵌入百度地图demo",演示了如何利用Qt5.5的特性与百度地图API进行交互,...

    策略为王股市软件源代码-----网盘下载地址

    策略为王股市软件源代码-----网盘下载地址

    STM32电机控制软件开发工具包 完整源代码 X-Cube-MCSDK-FUL v5.4.3

    这些通常是为工作台生成的项目添加额外代码的示例。 修复了STM32G431CB器件的HSE时钟设置错误。在工作台中选择8 MHz作为振荡器频率实际上会导致HSE设置为24 MHz。这会影响B-G431B-ESC1板。 解决了固件示例对STM32...

    百度分布式id 代码uid-generator

    uid-generator中的workId是由uid-generator自动生成的,并且考虑到了应用部署在docker上的情况,在uid-generator中用户可以自己去定义workId的生成策略,默认提供的策略是:应用启动时由数据库分配。...

    家政服务-家政服务平台-家政服务平台源码-家政服务平台java代码-基于springboot的家政服务平台-家政服务平台java

    家政服务-家政服务平台-家政服务平台源码-家政服务平台java代码-家政服务平台设计与实现-基于springboot的家政服务平台-基于Web的家政服务平台设计与实现-家政服务网站-家政服务网站源码-家政服务网站java代码-家政...

    C语言程序设计实验指导-上交大-课前练习-改错-完善程序-课后练习参考答案.pdf

    C语言程序设计实验指导_上交大_课前练习-改错-完善程序-课后练习参考答案

    百度地图API(Android)的开发包、示例代码、技术文档

    **百度地图API(Android)开发详解** 在Android应用开发中,集成地图功能是非常常见的需求,而百度地图API提供了强大的地图服务,让开发者能够轻松地在应用中实现定位、导航、路线规划等多种功能。以下是对百度地图...

    天狼星_霖锋_51单片机到ARM征服嵌入式源码大全

    文档"天狼星51&AVR单片机程序代码.doc"可能包含了51单片机的实例代码和讲解,这对于初学者理解并模仿编写程序非常有帮助。"10天学会51与C配套仿真开发板.DSN"可能是某个开发板的工程文件,用于配合硬件进行实践操作...

    ucos-ii全部源代码

    ucos-ii全部源代码 ucos-ii全部源代码 ucos-ii全部源代码ucos-ii全部源代码ucos-ii全部源代码ucos-ii全部源代码 ucos-ii全部源代码ucos-ii全部源代码ucos-ii全部源代码ucos-ii全部源代码

    cmake-3.27.5-windows-x86-64 cmake 64位安装包

    它通过提供一种高级的、独立于具体构建工具的语言(CMakeLists.txt),使得开发者能够描述项目中的源代码组织方式、编译步骤以及如何组装可执行文件或库。CMake并不直接进行编译和链接,而是生成特定构建系统的构建...

    严蔚敏数据结构C语言版本-可运行源码-完全C语言代码实现.zip

    严蔚敏数据结构C语言版本_可运行源码_完全C语言代码实现 ----- 毕业设计,课程设计,项目源码均经过助教老师测试,运行无误,欢迎下载交流 ----- 下载后请首先打开README.md文件(如有),某些链接可能需要魔法打开...

    D-S证据理论 MATLAB完整代码

    压缩包中的"D-S Fusion"可能包含了实现以上步骤的MATLAB代码文件,包括定义BPA、Dempster's组合规则、计算信念和似然函数,以及进行决策的脚本或函数。通过阅读和理解这些代码,可以深入学习D-S证据理论的实际应用,...

    2023年CSP-J复赛真题及答案解析

    CSP-J第二轮认证真题及答案代码! 2023年CSP-J复赛第二轮认证真题,附带参考答案代码!附带参考代码! CSP-J/S复赛第二轮认证复习专用! CSP-J/S复赛第二轮认证得分技巧! CSP-J/S复赛第二轮认证真题参考! CSP-J/S...

Global site tag (gtag.js) - Google Analytics