【发布时间】:2017-08-13 08:15:51
【问题描述】:
试图弄清楚如何存储一些对棋类游戏编程有用的数据。
我决定将棋子发出的光线存储在 Raycaster 中;这个问题是关于这个结构的实现的。
TL;DR(仅限国际象棋玩家...)
首先,我已经确定了三种射线:
- Ray.NORMAL 或 Ray.FULL:它们由所有棋子发出,但不是棋子,以迭代方式(车、象、后)或不(骑士和国王)发出
- Ray.CAPTURE:仅由 pawn、左前和/或右前捕获发射
- Ray.OFFSET:在前进时由棋子发出,而在王位/白车上则用于易位
因此,射线定义如下:
class Ray {
constructor (owner, kind) {
this.owner = owner // chessman which emits ray
this.kind = kind
this.ref = null
this.sequence = []
}
// is computed afetr construction
expand (ref, sequence) {
this.ref = ref // starting ref (origin of the ray)
this.sequence = sequence // array of refs
}
// is called when ray is inserted into raycaster
interact (otherRay) {
// to be implemented
}
}
射线还有两个特殊的复合属性:
- 阴影{ ray: null, idx: -1 }
- 穿越 { ray: null, idx: -1 }
表示该射线实例可能被另一个棋子遮蔽的位置,以及另一条射线穿过它的位置,以检测可通过性和干扰(用于castling)
问题:
如何在 RayCaster 中高效存储光线?
以优化操作的方式,例如:
- 添加新计算的射线,计算与以前存储的射线的交互,成本最低?
- 根据给定的起始参考确定所有目标图块/参考?
- 轻松确定哪些光线以给定参考为目标,以计算此图块上的压力平衡?
建议的解决方案/替代方案
- 单个光线阵列:最坏的情况是 64 * 63 个元素,寻找光线和计算交互的成本很高
- 数组映射:Map.set(startingRef, [list_of_emtted_rays_from_startingRef])
- 数组映射:Map.set(endingRef, [list_of_targetinhg_rays_to_endingRef])
也许是个不错的人选:
维护 2 个数组映射,一个用于发射,一个用于定位
class RayCaster {
constructor() {
this.startings = new Map()
this.endings = new Map()
}
cast(board) { ...iterate through board and casts individual rays }
add(ray) { ... }
getRefsAttackedBy(ref) { ... }
getRefsAttacking(ref) { ... }
}
那么您对这种数据结构(RayCaster)有何感受?
【问题讨论】:
-
按方向和列/行/对角线存储光线。
标签: javascript dictionary chess