关于拉登游戏的开发本身并没有太大难度,主要还是要解决计算结果需要很长时间的问题。要在时间上缩短就有两种方式:算法效率足够好,计算机运算能力足够强。对于这个问题而言,算法的改进没有太大可能性,而且问题本身就是一个大量遍历的过程,只有通过遍历才能在其中找到更多的信息,更多的美妙的发现。
下面的图是设计的基本思路:
游戏本身的研究价值似乎倒不是太多,而其中的趣味性还是蛮高的。
程序的设计思路如下:
服务计算机端运行程序为服务程序;个人PC端运行的程序为计算程序;存储数据主要记录计算的结果,计算过程日志记录。
计算程序和服务程序的交互信息传递:
1.服务程序启动监听计算程序
2.计算程序发送计算请求
3.服务程序响应请求
4.服务程序划分,协调,分配计算任务
5.服务程序发送计算任务消息
6.计算程序接收计算任务信息
7.计算程序计算(最为耗时,耗计算机资源)
8.计算程序发送计算结果信息
9.服务程序接收计算结果信息
10.服务程序处理计算结果信息,存储记录
一个计算周期1-10完成,继续进行2-10操作。
下面是服务程序部分代码:
- public class ServerDisCompute {
- private Map<String, Task> serverMap;
- private ServerSocket serverSocket;
- private int clientId=0;
- /**
- *
- * 构造服务器程序
- */
- public ServerDisCompute() {
- try {
- serverSocket = new ServerSocket(5140, 1, InetAddress.getLocalHost());
- serverMap=new HashMap();
- } catch (UnknownHostException ex) {
- Logger.getLogger(ServerDisCompute.class.getName()).log(Level.SEVERE, null, ex);
- } catch (IOException ex) {
- Logger.getLogger(ServerDisCompute.class.getName()).log(Level.SEVERE, null, ex);
- }
- }
- public void serverStart() {
- try {
- System.out.println("服务器已经启动");
- while (true) {
- Socket socket = serverSocket.accept();
- ServerHandlerDisCompute runable = new ServerHandlerDisCompute(socket, this);
- Thread thread = new Thread(runable);
- thread.start();
- }
- } catch (IOException ex) {
- Logger.getLogger(ServerDisCompute.class.getName()).log(Level.SEVERE, null, ex);
- }
- }
服务程序以多线程来与每一个计算程序进行通信。对与使用C/S模式设计,这部分可以继续改进。在这里可以将通信的连接变为请求---应答---断开---请求---应答方式。
下面是服务程序部分代码:
- class ServerHandlerDisCompute implements Runnable {
- private Socket socket;
- private final ServerDisCompute outer;
- private byte[] clientMsg;
- private byte[] serverMsg;
- private Task task;
- public ServerHandlerDisCompute(Socket socket, final ServerDisCompute outer) {
- this.outer = outer;
- this.socket = socket;
- }
- @Override
- public void run() {
- try {
- //获取请求信息
- clientMsg = readRequestMsg();
- //发送任务信息
- //任务编号
- String taskSignStamp = initSignStamp(clientMsg);
- //分配任务
- sendTaskMsg(taskSignStamp);
- Map<String, String> resultMap = readResultMsg();
- //更新任务信息
- updateTaskMsg(resultMap);
- } catch (IOException ex) {
- Logger.getLogger(ServerHandlerDisCompute.class.getName()).log(Level.SEVERE, null, ex);
- }
- }
服务程序运行主要监听计算机程序发回的信息。
下面是计算程序部分代码:
- /**
- * 客户端计算程序启动方法
- */
- public void clientStart() {
- System.out.println("客户端已经启动......");
- try {
- //发送请求信息
- sendRequestMsg();
- } catch (IOException ex) {
- Logger.getLogger(ClientDisCompute.class.getName()).log(Level.SEVERE, null, ex);
- }
- try {
- //读取响应信息
- readResponseMsg();
- } catch (IOException ex) {
- Logger.getLogger(ClientDisCompute.class.getName()).log(Level.SEVERE, null, ex);
- }
- //执行计算
- executeCompute();
- try {
- //发送结果信息
- sendResultMsg();
- } catch (IOException ex) {
- Logger.getLogger(ClientDisCompute.class.getName()).log(Level.SEVERE, null, ex);
- }
- }
程序的计算部分代码在拉登游戏开发--在时间积累中寻找美丽的图案文章中。
有关分布式计算的整体设计基本完成,通过多个计算程序与服务程序同时运行,对同一个N元格子的进行计算寻求最终的计算结果值可以实现。
对于一个N的值,寻找所以可能的计算结果将不用考虑计算结果被其中一个计算程序获取到,服务程序需要向其他正在进行N元格子的计算程序发出中断消息。计算程序可以灵活的向服务程序发送计算能力的相关消息,服务程序可以协调性的分配任务。
下面是N=35,一共有1225中可能,在其中寻找最终的结果,目前运算的情况截图如下:
目前这个运算不存在分布式,一个计算程序在进行处理,出现上面VM摘要图,并且此时此刻计算程序还在运行当中。如果对于一个N仅仅找出一个符合的结果就结束本次N的计算,则对已经获取的数据结果进行分析是非常重要和有价值的。这对于服务程序分配任务有很大的参考价值。
本文出自 “野马红尘” 博客,谢绝转载!