游戏地图中一道数字排列题

游戏的地图由625个区组成,一个中心区和624个普通区,原本的排列方式如下:
1,2,3,......24,25
26,27, ......49,50
...
...
     ...0...  
...
...     ....   624

      实际的每个区由25格组成,每格占5的坐标点,实际的坐标范围是-62~62数据库中也按实际的
坐标存储,中心区的坐标为,(2,2) ~(-2,-2),中心区中点为(0,0)。
     后来,我们的boss觉得这样按顺序排列不好,给玩家感觉到相邻的区有太远的感觉,也不知道他从哪儿看来的,还是自己想出来的,他希望区的排列方式如下:

               ......
53 , 54 , 55 , 56 , 57 , 58 , 59 , 60 , 61 , 97
52 , 28 , 29 , 30 , 31 , 32 , 33 , 34 , 62 , 98
51 , 27 , 11 , 12 , 13 , 14 , 15 , 35 , 63 , 99
50 , 26 , 10 , 2  , 3  , 4  , 16 , 36 , 64 , 100
49 , 25 , 9  , 1  , 0  , 5  , 17 , 37 , 65 , 101
80 , 48 , 24 , 8  , 7  , 6  , 18 , 38 , 66 , 102
79 , 47 , 23 , 22 , 21 , 20 , 19 , 39 , 67 , 103
78 , 46 , 45 , 44 , 43 , 42 , 41 , 40 , 68 , 104
77 , 76 , 75 , 74 , 73 , 72 , 71 , 70 , 69 , 105
                .....

        也就是说,区的排列方式 是从 中心向 周围散开的,是一圈一圈的...因为前期的数据已经生成,实际的坐标点不会再改也不容易改,于是想到在后台还是不变,但是在页面显示的时候将区的排列调整成这种方式就可以了,于是如何生成这样的数据就是首要的问题(不会是去手写的,少量还可以,625也是不小的数)
      这个排列貌似还是有规律的,一开始是想分成四个象限逐个生成,后来发现很困难,相邻的象限数据联系不容易保存,后来用了一个比较笨的思路搞定了
   
     基本思路是这样,中间的一行前半部分 0,1,9,25..自然奇数的平方,我是这样想的,每一圈数都由起点到下个奇数-1 例如 最里面的一圈 是1~(9-1), 这8个数可以按5的步骤生成,依次是 1-2,2-4,4-6,6-8,8-1, 尤其要注意的是生成 1-2,8-1的时候与其他是不一样的,而且每一圈都有差别,生成2-4,4-6,6-8,次数是相同的,每一步只需知道生成的起始数字和药生成的个数,然后再保存生成的尾数即可,具体代码如下(没有写成通用的,如果有变动,只需稍作改变即可)

      如果有好的算法,欢迎大家提出来

package com.farmerwar.map.util;

import java.util.HashMap;
import java.util.Map;

/**
 * @author Nov 18 2009 zjq
 *
 */
public class ChangeDistrictId {
    public static int[][] n = new int[26][26];

    // 产生第中心行(13行)前12列数
    public int[] createMiddleNum() {
        int[] middle = new int[13];
        for (int i = 1, j = 1; i < 25; i += 2, j++) {
            middle[j] = i * i;
        }
        return middle;
    }

    // 得到该数所在的列
    public int getcol(int middleNum) {
        int[] middle = this.createMiddleNum();
        Map map = new HashMap();
        for (int i = 1, j = 12; i < middle.length; i++, j--) {
            map.put(middle[i], j);
        }
        return (Integer) map.get(middleNum);
    }

    // 得到该数循环的高度
    public int getheight(int middleNum) {
        int[] middle = this.createMiddleNum();
        Map map = new HashMap();
        for (int i = 1, j = 2; i < middle.length; i++, j++) {
            map.put(middle[i], j);
        }
        return (Integer) map.get(middleNum);
    }

    // 得到从左下到中心点(add5)的循环次数
    public int getlastcount(int middleNum) {
        int[] middle = this.createMiddleNum();
        Map map = new HashMap();
        for (int i = 1, j = 0; i < middle.length; i++, j++) {
            map.put(middle[i], j);
        }
        return (Integer) map.get(middleNum);
    }

    public void createRound(int middleNum) {
        n[13][13] = 0;// 中心点是0
        int col = this.getcol(middleNum);
        int height = this.getheight(middleNum);
        int[] rc1 = this.add1(middleNum, col, height);
        int weighth = (int) Math.sqrt(middleNum) + 2;//循环的次数,除了首尾,

中间的次数是相同的
        int[] rc2 = this.add2(weighth, rc1);
        int[] rc3 = this.add3(weighth, rc2);
        int[] rc4 = this.add4(weighth, rc3);   
        this.add5(middleNum, rc4);
    }

    // 从中心向左上
    public int[] add1(int middleNum, int col, int height) {
        int[] rc1 = new int[3];
        // 从a[13]中心行开始
        int nrow = 13;
        for (int i = 1; i <= height; i++) {
            n[nrow][col] = middleNum;
            nrow--;
            middleNum++;
        }
        rc1[0] = nrow + 1;
        rc1[1] = col;
        rc1[2] = middleNum - 1;

        return rc1;
    }

    // 从左上向右上
    public int[] add2(int weighth, int[] rc1) {
        int[] rc2 = new int[3];
        int row = rc1[0];
        int col = rc1[1] + 1;
        int st = rc1[2];

        for (int i = 1; i < weighth; i++) {
            n[row][col] = st + 1;
            st++;
            col++;
        }
        rc2[0] = row;
        rc2[1] = col - 1;
        rc2[2] = st;
        return rc2;
    }

    // 从右上向右下
    public int[] add3(int weighth, int[] rc2) {
        int[] rc3 = new int[3];
        int row = rc2[0] + 1;
        int col = rc2[1];
        int st = rc2[2];
        for (int i = 1; i < weighth; i++) {
            n[row][col] = st + 1;
            st++;
            row++;
        }
        rc3[0] = row - 1;
        rc3[1] = col;
        rc3[2] = st;
        return rc3;
    }

    // 从右下向左下
    public int[] add4(int weighth, int[] rc3) {
        int[] rc4 = new int[3];
        int row = rc3[0];
        int col = rc3[1] - 1;
        int st = rc3[2];
        for (int i = 1; i < weighth; i++) {
            n[row][col] = st + 1;
            st++;
            col--;
        }
        rc4[0] = row;
        rc4[1] = col + 1;
        rc4[2] = st;
        return rc4;
    }

    // 从左下向中心
    public void add5(int middleNum, int[] rc4) {
        int row = rc4[0] - 1;
        int col = rc4[1];
        int st = rc4[2];
        int count = this.getlastcount(middleNum);
        for (int i = 1; i <= count; i++) {
            n[row][col] = st + 1;
            st++;
            row--;
        }
    }
    //返回n
    public  int [] returnDistrictId(){
       
        int[] m = this.createMiddleNum();
        for (int i = 1; i < m.length; i++) {
            this.createRound(m[i]);
        }
        int [] k = new int [625];
        int count =1;
        for (int i = 1; i < 26; i++) {
            for (int j = 1; j < 26; j++) {
                if (n[i][j]!=0) {
                    k[count] = n[i][j];
                    count++;
                }
               
            }
        }
        return k;
    }
   

public static void main(String[] args) {
        ChangeDistrictId tn2 = new ChangeDistrictId();

        int [] a = tn2.returnDistrictId();
       
        for (int i = 1; i <625; i++) {
            System.out.print(a[i]+",");
        }
       
//为了便于查看,调整数字的间隙
/*        int[] m = tn2.createMiddleNum();
        for (int i = 1; i < m.length; i++) {
            tn2.createRound(m[i]);
        }
        String[][] str = new String[26][26];
        for (int i = 1; i < 26; i++) {
            for (int j = 1; j < 26; j++) {
                String s = n[i][j] + "";
                if (s.length() == 1) {
                    s = s + "  ";
                } else if (s.length() == 2) {
                    s = s + " ";
                }
                str[i][j] = s;
            }
        }
        for (int i = 1; i < 26; i++) {
            for (int j = 1; j < 26; j++) {
                if (j == 25) {
                    System.out.print(str[i][j] + " ");
                } else {
                    System.out.print(str[i][j] + ", ");
                }
            }
            System.out.println("");
        }*/
       
    }
}

效果如图: http://hi.youkuaiyun.com/space.php?uid=2715526&do=album&picid=529686

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值