Javascript:优化国际象棋游戏的数据结构
试图找出如何为国际象棋游戏编程存储一些有用的数据。
我决定将由机载西洋棋棋子发出的光线存储在雷克斯特(Raycaster)中; 这个问题是关于这个结构的实现。
TL; DR(仅限国际象棋游戏玩家...)
首先,我已经确定了三种射线:
因此,光线是这样定义的:
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
}
}
光线还有两个特殊的化合物属性:
它表示这个光线实例可能被另一个棋子遮挡,并且另一条光线穿过它,检测通过性和干涉(对于castling)
问题:
如何在RayCaster中有效存储光线?
以一种优化操作的方式,例如:
建议的解决方案/替代方案
也许是一个很好的候选人:
维护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)有什么感受?
最后,由于地图是时间不变的访问,所以我考虑了一个双映射实现:
constructor() {
this.startings = new Map()
this.endings = new Map()
this.counters = { rays: 0, interactions: 0 }
}
每张地图都由电路板参考键,从“a1”到“h8”
casts(board) {
this.counters = {
rays: this.raysFrom(board),
interactions: this.computeInteractions()
}
}
添加光线很直接:
raysFrom(board) {
let counter = 0;
board.traverse((ref, chessman) => {
let rays = chessman.cast(ref)
for(let ray of rays) {
this.add(ray)
}
counter += rays.length
})
return counter
}
简单的射线:
add (ray) {
let skey = ray.ref
let sRays = this.startings.get(sKey)
if(sRays.indexOf(ray) === -1) {
sRays.push(ray)
}
ray.traverse((seqIdx, seqRef) => {
let seqKey = seqRef.key
let eRays = this.endings.get(seqKey)
if (eRays.indexOf(ray) === -1) {
eRays.push(ray)
}
})
}
计算光线交互(交叉和阴影)更复杂:
computeInteractions() {
let counter = 0
// consider all starting rays
for (let {sRef, sRays} of this.startings) {
for (let sRay of sRays) {
sRay.traverse((seqIdx, seqRef) => {
// consider all possible intersections
// into the endings map
let eRays = this.endings.get(seqRef.ref)
for(let eRay of eRays) {
// ensure that rays are different
if (sRay !== eRay) {
sRay.interact(eRay)
eRay.interact(sRay)
}
}
})
}
}
return counter
}
其余的工作是在射线课程中确定两条射线如何相互作用(交叉或阴影)
感谢您的建议,最好的问候!
链接地址: http://www.djcxy.com/p/84633.html