Bye Bye Moore

猫マンション建築の野望を胸に零細事業主として資本主義の荒波に漕ぎ出したアラサー男の技術メモ

戦術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++________
____+++_________
_____+__________
________________
________________