これをクラス化するなりすれば、前のクォータービューに乗せられるはず。
import std.stdio, std.math;
enum State{
NONE = 0,
OPENED,
CLOSE
}
enum Direction{
UP = 0,
DOWN,
LEFT,
RIGHT
}
class Vector{
public{
int X = 0;
int Y = 0;
int Cost = -1;
}
this(int x, int y, int cost){
this.X = x;
this.Y = y;
this.Cost = cost;
}
override int opCmp(Object o){
Vector v = cast(Vector)o;
return this.Cost - v.Cost;
}
}
Vector[] explore(Vector start, Vector goal, State[][] mapState){
//探索する場所を何度も探索されないようにする
mapState[start.Y][start.X] = State.OPENED;
//各方向の移動距離の計算結果をここに入れる
Vector[] cost = new Vector[4];
//文字数短縮のために記述。処理の無駄は承知の上
int mx = mapState[0].length-1; int my = mapState.length-1;
//各方向のコストを計算
cost[Direction.UP] =
(start.Y != 0) ? new Vector(start.X, start.Y-1, getCost(new Vector(start.X, start.Y-1, -1), goal, mapState)) : null;
cost[Direction.DOWN] =
(start.Y != my) ? new Vector(start.X, start.Y+1, getCost(new Vector(start.X, start.Y+1, -1), goal, mapState)) : null;
cost[Direction.LEFT] =
(start.X != 0) ? new Vector(start.X-1, start.Y, getCost(new Vector(start.X-1, start.Y, -1), goal, mapState)) : null;
cost[Direction.RIGHT] =
(start.X != mx) ? new Vector(start.X+1, start.Y, getCost(new Vector(start.X+1, start.Y, -1), goal, mapState)) : null;
//計算結果を出力
writeln(start.toString());
if(!(cost[Direction.UP] is null)) writeln(cost[Direction.UP].Cost);
else writeln("UP:null");
if(!(cost[Direction.DOWN] is null)) writeln(cost[Direction.DOWN].Cost);
else writeln("DOWN:null");
if(!(cost[Direction.LEFT] is null)) writeln(cost[Direction.LEFT].Cost);
else writeln("LEFT:null");
if(!(cost[Direction.RIGHT] is null)) writeln(cost[Direction.RIGHT].Cost);
else writeln("RIGHT:null");
writeln("---");
//コストの値を元に結果をソート
Vector[] route;
cost.sort;
for(int i=0; i<cost.length; i++){
Vector v = cost[i];
if(v is null || v.Cost == -1) continue;
//ゴールに行けるなら、ルートにそれを追加
else if(v.X == goal.X && v.Y == goal.Y){
route = [v];
return route;
}
else{
//ゴールへの道を探す
if((route = explore(v, goal, mapState)) != null){
route = route ~ [v];
return route;
}
}
}
//見つからなかったらnullを返して別の方向へいけるようにする
return null;
}
int getCost(Vector start, Vector goal, State[][] mapState){
return (mapState[start.Y][start.X] == State.NONE) ? abs(goal.X - start.X) + abs(goal.Y - start.Y) : -1;
}
void main(){
int[][] mapData= [
[1,1,1,1,1],
[1,0,1,1,1],
[1,0,0,0,1],
[1,0,1,0,1],
[1,1,1,1,1]
];
//スタート地点
Vector start = new Vector(0,0,-1);
//ゴール地点
Vector goal = new Vector(2,3,-1);
//マップの探索可・不可、探索前・後のフラグをセット
uint x = mapData.length;
uint y = mapData[0].length;
State[][] mapState = new State[][y];
for(int i=0; i<mapState.length; i++){
mapState[i] = new State[x];
}
for(int i=0; i<y; i++){
for(int j=0; j<x; j++){
switch(mapData[i][j]){
case 0:
mapState[i][j] = State.CLOSE;
break;
case 1:
mapState[i][j] = State.NONE;
break;
default:
break;
}
}
}
//探索開始
Vector[] route = explore(start, goal, mapState);
//結果表示
writeln("******************************************");
for(int i=0; i<route.length; i++){
Vector v = route[i];
write("[");
write(v.X);
write(",");
write(v.Y);
write("]");
}
}