OpenHarmony 军棋开发带你了解如何选择数据结构 原创 精华

陈浩南xxx
发布于 2022-12-13 13:50
浏览
4收藏

OpenHarmony 军棋开发带你了解如何选择数据结构

一,引言

数据结构不只是用于组织数据,它还极大地影响着代码的运行速度。因为数据结构不同,程序的运行速度可能相差多个数量级。如果你写的程序要处理大量的数据,或者要让数千人同时使用,那么你采用何种数据结构,将决定它是能够运行,还是会因为不堪重负而崩溃。

很多应用的基本不考虑数据结构;也涉及不到选择的场景,遇到复杂的,也是不断的遍历得出结果;即耗时又耗内存;

二,需求分析

OpenHarmony 军棋开发带你了解如何选择数据结构-鸿蒙开发者社区

大体要求

1,记录整个棋的状态

2 ,快速查到任意棋的状态

3,棋子的定位问题

4,移动时如何记录路径

5,初始化随机布局

三,数据结构选择

HashMap

可用来存储具有关联关系的 key-value 键值对集合,存储元素中 key 是唯一的,每个 key 会对应一个 value 值。

HashMap 依据泛型定义,集合中通过 key 的 hash 值确定其存储位置,从而快速找到键值对。

1,通过HashMap的特性,很好的处理问题1和 2

我们给每个棋一个编号key来代替实体been,这样每次获取某个棋的状态只要直接通过key取就好了

// key 规则: weight+":"+编号 比如: 1:0

 static weightUI(weight: number): string{
      //  Logger.d("WeightUtil", `weightUI  ${JSON.stringify(weight)} `)
        let abs = Math.abs(weight)
        switch (abs) {
            case 1:
                return '工兵'
            case 2:
                return '排长'
            case 3:
                return '连长'
            case 4:
                return '营长'
            case 5:
                return '团长'
            case 6:
                return '旅长'
            case 7:
                return '师长'
            case 8:
                return '军长'
            case 9:
                return '司令'
            case 10:
                return '炸弹'
            case 11:
                return '地雷'
            case 12:
                return '军旗'
        }
    }

初始化的时候把所有棋存入map中。这样整个棋盘状态就存储了;比数组和list更方便

chessMap = new HashMap<string, Chess>()

for (var i = 1; i <= 12; i++) {
    let num = 2
    if (i < 4) {
        num = 3
    }
    if (i === 11) {
        num = 3
    }
    if (i === 12 || i === 8 || i === 9) {
        num = 1
    }
    for (var f = 0; f < num; f++) {
        let key1 = i + ":" + f
        let key2 = -i + ":" + f
        let chess1 = new Chess(i)
        let chess2 = new Chess(-i)
        this.chessMap.set(key1, chess1); // 添加元素
        this.chessMap.set(key2, chess2); // 添加元素
    }
}

二维数组

整个棋盘的行列来保存期的位置;存放他们的key,阵容的棋子去掉该key即可

OpenHarmony 军棋开发带你了解如何选择数据结构-鸿蒙开发者社区

js的二维数组初始化方法

this.layoutData = new Array(ROW);
for (var i = 0; i < ROW; i++) {
    this.layoutData[i] = new Array(COLUMN);
    for (var j = 0; j < COLUMN; j++) {
        this.layoutData[i][j] = chessList[index]
    }
}

链式数据结构

每次 把prev给记录下来。这下就可以追溯到整个完整的探测路线

OpenHarmony 军棋开发带你了解如何选择数据结构-鸿蒙开发者社区

export class RouteNode extends Point {
    prev: RouteNode ; //前一个节点
    next: RouteNode  ; //下一个节点
    step: number

    constructor(x: number, y: number, step: number) {
        super(x, y)
        this.step = step
    }
}

ArrayList

它有个特点,是有序的排列,我们利用这个可以随机布局之后定位

开始时,把map里的所有数据存入list中,这个时候他是位置不是随机的

let chessList = new ArrayList<string>()

this.chessMap.forEach(((value, key: string) => {
    chessList.add(key)
}));

利用随机数交换里面的任意位置,同时保证每个位置都得到交换

private shuffleCell(chessList) {
    let length = chessList.length
    for (var i = 0; i < length; i++) {
        let index = Math.floor(Math.random() * length); // Math.floor(Math.random() * 10) 可均衡获取 0 到 9 的随机整数。
        this.swap(chessList, i, index)
    }
}

private swap(chessList, i, j) {
    let tmp = chessList[i]
    chessList[i] = chessList[j]
    chessList[j] = tmp
}

军旗开始很多碉堡是不能有棋的;也利用list特性,在指定位置插入空白

chessList.insert("", 11)

二维素组是可以用一维组表示的

        this.layoutData = new Array(ROW);
        for (var i = 0; i < ROW; i++) {
            this.layoutData[i] = new Array(COLUMN);
            for (var j = 0; j < COLUMN; j++) {
                let index = i * COLUMN + j
                Logger.d(TAG, `randomLayout...index:${index}`)
                this.layoutData[i][j] = chessList[index]
            }
        }

三,总结

本文通过实际场景来体现一下数据结构如何运用和选择;

©著作权归作者所有,如需转载,请注明出处,否则将追究法律责任
已于2022-12-20 10:07:49修改
5
收藏 4
回复
举报
4条回复
按时间正序
/
按时间倒序
红叶亦知秋
红叶亦知秋

时间复杂度,空间复杂度是衡量代码的重要指标

回复
2022-12-13 14:31:06
香菜太难吃了
香菜太难吃了

学习优化存储的思路

回复
2022-12-14 18:17:45
青舟321
青舟321

很高效的存储思路,不过军旗这个体量的游戏应该不用考虑这么多吧

回复
2022-12-16 10:56:25
陈浩南xxx
陈浩南xxx 回复了 青舟321
很高效的存储思路,不过军旗这个体量的游戏应该不用考虑这么多吧

由简单的游戏引入这种思维;

1
回复
2022-12-16 14:04:18
回复
    相关推荐