D言語へ移植

アバター
大白定義
記事: 14
登録日時: 14年前
住所: 三重県

D言語へ移植

投稿記事 by 大白定義 » 12年前

前回Javaで作ったルート探索のプログラムをD言語に移植してみた。
これをクラス化するなりすれば、前のクォータービューに乗せられるはず。

CODE:

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("]");
	}
}
D言語の動的配列の宣言方法はJavaのに比べると面倒だなあと思った(KONAMI感)

コメントはまだありません。