Bye Bye Moore

PoCソルジャーな零細事業主が作業メモを残すブログ

戦術SLGでよく見る移動範囲表示をJavascriptで実装してみる その2:障害物がある場合

前回に引き続き、移動範囲表示です。
今度は地形による移動コストが加味されたバージョンです。

実際のところ

前回のものをベースに、以下のケースを考えます。

  • ユニット移動力:3
  • 草原地帯:必要移動力2
  • 山岳地帯:通行不能

再帰風の表現を使っているせいか、地形情報を参照しに行くデータを別途やらないとスタックオーバーフローで撃沈します。
また、今回は固定データで突っ込みましたがJSONデータから地図を生成する処理を追加してもいいでしょう。

math   = require('mathjs')
var MAX_Y = 9
var MAX_X = 16

var P_Y   = 4
var P_X   = 5

const MOUNTAIN = -9
const GRASS    = -2

const GRASSLIST    = [[3,6],[4,6],[5,6],[5,5],[6,6]]
const MOUNTAINLIST = [[4,4],[5,4],[6,4]]

//マップ情報。
var a  = math.matrix().resize([MAX_Y,MAX_X],-1)
var b  = math.matrix().resize([MAX_Y,MAX_X],-1)

GRASSLIST.forEach(function(item, index, array) {
  b.subset(math.index(item[0],item[1]), GRASS)
})

MOUNTAINLIST.forEach(function(item, index, array) {
  b.subset(math.index(item[0],item[1]), MOUNTAIN)
})

function bar(y,x,move) {
  if (move < 0 || y < 0 || x < 0 
      || y > MAX_Y-1 || x > MAX_X-1
      || (move-1) < a.get([y,x])
  ) { return }
  a.set([y,x], move)
  move = move + b.get([y,x]) //移動コストを反映。マイナスで表記されるので加算式。
  bar(y-1, x,   move)
  bar(y+1, x,   move)
  bar(y,   x-1, move)
  bar(y,   x+1, move)
}

bar(P_Y,P_X,3)

a.set([P_Y,P_X],'G')

結果

まず地形情報。
"g"が草原地帯、"m"が山岳地帯です。

________________
________________
________________
______g_________
____m_g_________
____mgg_________
____m_g_________
________________
________________

移動範囲を"+"、ユニット位置を"G"とすると、以下のように地形効果を受けている事がわかります。

________________
_____+__________
____+++_________
___++++_________
____+G++________
____+++_________
_____+__________
________________
________________