- 締切済み
”Java”か”Javascrip”を使用して迷路探索・・・
JavaまたはJavascriptを使い迷路探査するようなソフトウェアロボット?(意味が違うかもしれません・・・)を作成したいのですが、JavaとJavascriptではどちらがこのようなプログラムを作るときに向いてますでしょうか?ちなみに自分はホームページ作成とC言語をほんの少し学んだ程度なので、いったいどうやったらよいのか・・・本当に困っています。 プログラム内容としては (1)画面上に(5×5)マスの迷路を作成 (2)ロボット?を画面上で動かすとして前後左右に動 き自ら判断して進んでいく (3)出口で停止する (4)迷路のパターンを変えても作動していく 上記の内容なのですがどなたかおわかりなりますでしょうか?
- みんなの回答 (5)
- 専門家の回答
みんなの回答
- BLUEPIXY
- ベストアンサー率50% (3003/5914)
書き直してみました。プログラムは、若干短くなりましたけど、かえってわかりにくくなった処もあるかもしれません。やっていることは、同じなので見比べてみるといいかも。 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <html> <head> <meta name="generator" content="WZ EDITOR 5.0"> <meta HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=shift_jis"> <title>迷路</title> <style> <!-- table.maze { border-spacing:0px; padding:0px; border:solid 1px black; } table.maze td { width:40px;height:40px; padding:0px; margin:0px; border:solid 1px black; text-align:center; } table.maze td.wall { background-color:black; } //--> </style> <script type="text/javascript"> <!-- var ID; //setInterval用 var mazeSize = 5; var maze = new Array( new Array(0,1,0,0,0), new Array(0,1,0,1,1), new Array(0,0,0,0,0), new Array(0,1,1,1,0), new Array(0,1,0,0,0) ); var robot = { x:0, y:0, dir:"→", Az:0, next:next, turnLeft:turnLeft, turnRight:turnRight, dx:dx, dy:dy, sideWallNone:sideWallNone }; var EXIT = { x:2, y:4 }; function init(){ var x,y; for(y=0;y<mazeSize;y++){ for(x=0;x<mazeSize;x++){ if(maze[y][x]) document.getElementById(xyToN(x,y)).className="wall"; } } document.getElementById(xyToN(EXIT.x,EXIT.y)).innerText="出口"; document.getElementById(xyToN(robot.x,robot.y)).innerText=robot.dir; } function xyToN(x,y){ return(y*mazeSize+x); } function canMove(x, y){ if(Math.max(x,y)>=mazeSize || Math.min(x,y)<0 || maze[y][x]==1) return(false); else return(true); } function turnRight(){ var dirList = "→↓←↑→"; robot.dir = dirList.substr(dirList.indexOf(robot.dir)+1,1); robot.Az -= 90; if(robot.Az<0) robot.Az+=360; } function turnLeft(){ var dirList = "→↓←↑→"; robot.dir = dirList.substr(dirList.lastIndexOf(robot.dir)-1,1); robot.Az += 90; if(robot.Az>=360) robot.Az-=360; } function dx(){ //進行方向の量 return(Math.round(Math.cos(robot.Az*Math.PI/180))); } function dy(){ //進行方向の量 return(-1*Math.round(Math.sin(robot.Az*Math.PI/180))); } function sideWallNone(){//左手に壁がない? var Az = robot.Az; var dx,dy; Az += 90 ;//進行方向左 if(Az>=360) Az-=360; dx=Math.round(Math.cos(Az*Math.PI/180)); dy=-1*Math.round(Math.sin(Az*Math.PI/180)); return (canMove(robot.x+dx,robot.y+dy)); } function next(){ if(canMove(robot.x+robot.dx(),robot.y+robot.dy())){//前進できる? document.getElementById(xyToN(robot.x,robot.y)).innerText=" "; robot.x+=robot.dx(); robot.y+=robot.dy();//進行方向に進む if(robot.sideWallNone()){ //左手に壁がない時 robot.turnLeft(); } } else { robot.turnRight(); } document.getElementById(xyToN(robot.x,robot.y)).innerText=robot.dir; if(EXIT.x==robot.x && EXIT.y==robot.y){ alert("出口につきました"); clearInterval(ID); } } //--> </script> </head> <body onload="init()"> <body onload="init()"> <table class="maze" cellspacing="0"> <tr><td id="0"> </td><td id="1"> </td><td id="2"> </td><td id="3"> </td><td id="4"> </td></tr> <tr><td id="5"> </td><td id="6"> </td><td id="7"> </td><td id="8"> </td><td id="9"> </td></tr> <tr><td id="10"> </td><td id="11"> </td><td id="12"> </td><td id="13"> </td><td id="14"> </td></tr> <tr><td id="15"> </td><td id="16"> </td><td id="17"> </td><td id="18"> </td><td id="19"> </td></tr> <tr><td id="20"> </td><td id="21"> </td><td id="22"> </td><td id="23"> </td><td id="24"> </td></tr> </table> <button onclick="javascript:ID=setInterval('robot.next()',500)">スタート</button> </body> </html>
- BLUEPIXY
- ベストアンサー率50% (3003/5914)
>スタートからゴールまでの動きを一連の動きとして、ボタンを押すとゴールまで自動的に進んでゆく。 黙って実行させてしまうと、あっという間に終わってしまうので、 robot.next() を、時間間隔を置いて実行させればいいと思います。 今のonclickで呼び出している部分を 「onclick="javascript:robot.next(document.FORM1.MES)"」 を onclick="setInterval('robot.next()',1000))" とかに変えれば、設定時間毎にロボットが次の行動に進みます。 >テキストボックスの表示をなくす 必要なければ、テキストボックスそのものを削除して、テキストボックスへのメッセージの設定部分の削除、next(f)への引数をなくせばいいだけですけど。 もう一回、そういう風に全体を書き直してもいいけど、setIntervalを知らないのはしょうがないとしても、テキストボックスの処理を省くくらいのことはできないと、このプログラムに限らず(私のプログラムにこだわる理由もないし)、どんなプログラムを教えて貰っても、しょうがないというか、道は遠いと言わざるを得ません。 >ちなみに上記の方法はどのようにすればいいのでしょうか?? 0,1が□,■に置き換わっただけですね。 2次の配列を1次の文字列の配列にして横の座標を文字列の抜き出しに変えて、canMoveの判定を変えます。
- BLUEPIXY
- ベストアンサー率50% (3003/5914)
>もっと簡単な素人にもできる記述の仕方はないでしょうか?? どういう意味でしょうか? 迷路の表現方法という意味ですか? 迷路の表現方法として 1と0の配列を使っていますけれども new Array(0,1,0,0,0), new Array(0,1,0,1,1), new Array(0,0,0,0,0), new Array(0,1,1,1,0), new Array(0,1,0,0,0) を "□■□□□", "□■□■■", "□□□□□", "□■■■□", "□■□□□" のような表現に変えることはそれほど難しくないと思います。 それとも、別の意味でしょうか?
- BLUEPIXY
- ベストアンサー率50% (3003/5914)
とりあえず、javascriptでサンプルを作ってみました。 IEで動作します。(NNで動くようにも注意すればできるとは思いますけど、ラクしたかっただけ) 通路を埋めたものを壁としていますが、 まあ、本来別に管理しても同じことです。 迷路のパターンを自動で変える部分や、 ロボットの初期位置を変える部分は作っていませんけど、変わっても動作するようにはなっていると思います。 ロボットの判断ルールは、いわゆる左手を壁に付けて迷路を抜けると言うヤツです。 まあ、やり方や実現の仕方は色々あるでしょうから 参考程度に <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <html> <head> <meta name="generator" content="WZ EDITOR 5.0"> <meta HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=shift_jis"> <title>迷路</title> <style> <!-- table.maze { border-spacing:0px; padding:0px; border:solid 1px black; } table.maze td { width:40px;height:40px; padding:0px; margin:0px; border:solid 1px black; text-align:center; } table.maze td.wall { background-color:black; } //--> </style> <script type="text/javascript"> <!-- var mazeSize = 5; var maze = new Array( new Array(0,1,0,0,0), new Array(0,1,0,1,1), new Array(0,0,0,0,0), new Array(0,1,1,1,0), new Array(0,1,0,0,0) ); var robot = { x:0, y:0, dir:"→", next:null }; robot.next = next; var EXIT = { x:2, y:4 }; function init(){ var x,y; for(y=0;y<mazeSize;y++){ for(x=0;x<mazeSize;x++){ if(maze[y][x]) document.getElementById(xyToN(x,y)).className="wall"; } } document.getElementById(xyToN(EXIT.x,EXIT.y)).innerText="出口"; document.getElementById(xyToN(robot.x,robot.y)).innerText=robot.dir; } function xyToN(x,y){ return(y*mazeSize+x); } function canMove(x, y){ if(Math.max(x,y)>=mazeSize || Math.min(x,y)<0 || maze[y][x]==1) return(false); else return(true); } function next(f){ switch(robot.dir){ case "→": if(canMove(robot.x+1,robot.y)){ document.getElementById(xyToN(robot.x,robot.y)).innerText=" "; robot.x+=1; document.getElementById(xyToN(robot.x,robot.y)).innerText=robot.dir; f.value="右に移動しました"; if(canMove(robot.x,robot.y-1)){ //左手に壁がない時 robot.dir="↑"; document.getElementById(xyToN(robot.x,robot.y)).innerText=robot.dir; f.value+="、左に90度方向変換しました"; } } else { robot.dir="↓"; document.getElementById(xyToN(robot.x,robot.y)).innerText=robot.dir; f.value="右に90度方向変換しました"; } break; case "←": if(canMove(robot.x-1,robot.y)){ document.getElementById(xyToN(robot.x,robot.y)).innerText=" "; robot.x-=1; document.getElementById(xyToN(robot.x,robot.y)).innerText=robot.dir; f.value="左に移動しました"; if(canMove(robot.x,robot.y+1)){ //左手に壁がない時 robot.dir="↓"; document.getElementById(xyToN(robot.x,robot.y)).innerText=robot.dir; f.value+="、左に90度方向変換しました"; } } else { robot.dir="↑"; document.getElementById(xyToN(robot.x,robot.y)).innerText=robot.dir; f.value="右に90度方向変換しました"; } break; case "↑": if(canMove(robot.x,robot.y-1)){ document.getElementById(xyToN(robot.x,robot.y)).innerText=" "; robot.y-=1; document.getElementById(xyToN(robot.x,robot.y)).innerText=robot.dir; f.value="上に移動しました"; if(canMove(robot.x-1,robot.y)){ //左手に壁がない時 robot.dir="←"; document.getElementById(xyToN(robot.x,robot.y)).innerText=robot.dir; f.value+="、左に90度方向変換しました"; } } else { robot.dir="→"; document.getElementById(xyToN(robot.x,robot.y)).innerText=robot.dir; f.value="右に90度方向変換しました"; } break; case "↓": if(canMove(robot.x,robot.y+1)){ document.getElementById(xyToN(robot.x,robot.y)).innerText=" "; robot.y+=1; document.getElementById(xyToN(robot.x,robot.y)).innerText=robot.dir; f.value="下に移動しました"; if(canMove(robot.x+1,robot.y)){ //左手に壁がない時 robot.dir="→"; document.getElementById(xyToN(robot.x,robot.y)).innerText=robot.dir; f.value+="、左に90度方向変換しました"; } } else { robot.dir="←"; document.getElementById(xyToN(robot.x,robot.y)).innerText=robot.dir; f.value="右に90度方向変換しました"; } break; } if(EXIT.x==robot.x && EXIT.y==robot.y) alert("出口につきました"); } //--> </script> </head> <body onload="init()"> <table class="maze" cellspacing="0"> <tr><td id="0"> </td><td id="1"> </td><td id="2"> </td><td id="3"> </td><td id="4"> </td></tr> <tr><td id="5"> </td><td id="6"> </td><td id="7"> </td><td id="8"> </td><td id="9"> </td></tr> <tr><td id="10"> </td><td id="11"> </td><td id="12"> </td><td id="13"> </td><td id="14"> </td></tr> <tr><td id="15"> </td><td id="16"> </td><td id="17"> </td><td id="18"> </td><td id="19"> </td></tr> <tr><td id="20"> </td><td id="21"> </td><td id="22"> </td><td id="23"> </td><td id="24"> </td></tr> </table> <form name="FORM1"> <input type="text" name="MES" value="" size="50"><br> <button onclick="javascript:robot.next(document.FORM1.MES)">次の行動</button> </form> </body> </html>
お礼
・・・今、このソース見てわかるのは多次元配列、条件分岐が使用されているな~程度でした。 BLUEPIXYさんが作成されたものを参考にさせて頂きます。まずはこのソースを分析してみるとこから始めてみようと思います。 参考となるプログラムありがとうございました。 (ロボットの制御が中々難しそうですね)
補足
もっと簡単な素人にもできる記述の仕方はないでしょうか??
JavaScriptはHTML内に記述するインタープリタ型の言語で、HTMLを動的にすることをもっぱらの目的としており、私の知る限りではブラウザ上でしか作動しないものです。従いまして、ブラウザ上で実現しようとお考えならば、JavaScriptで実現させてもよいし、JavaのAppletで実現させてもよいかと思います。 そうではなく、単体のプログラムを作成したいということでしたら、Javaで書かれるべきかと思います。 少しでも学習されたC言語でやれるのが一番よいとは思いますが、そうはいかないから困っていらっしゃるのですよね。JavaScriptはHTML用の言語と考えていただいてよいかと思います。それ以外にもっと広範囲に渡るプログラミングをやれるようになりたいなら、Javaを覚えた方がよいかと思います(もちろん両方習得するのが一番よい。)。
お礼
JavaScriptはホームページなどで動きを付けたいときによく使いますよね。今回はブラウザ上で使用したいため、JavaScriptになりそうです。本やネットで検索しながらなんとかやってみます。 JavaのAppletはJavaを学んだことがないので、JavaScriptでの作成後に挑戦してみようと思います。 (C言語・Javaで作成となると大変難しそうですね・・・) 丁寧で的確な回答をありがとうございました。
補足
すみません。説明不足でした。 ちなみに上記の方法はどのようにすればいいのでしょうか??単に(a1・a2・・・)みたいに記号化してみるということなのでしょうか? 簡単な記述とは具体的に言うとBLUEPIXYさんが作成されましたプログラムをもっとシンプルなものにしたいのです(折角作成して頂いたのに申し訳ありませんが自分の勉強不足ゆえに理解するのが難しいので・・・)。自分で色々試行錯誤してみましたが上手くいかないので質問させて頂きました。 ○スタートからゴールまでの動きを一連の動きとして、ボタンを押すとゴールまで自動的に進んでゆく。 ○テキストボックスの表示をなくす 上記のことをしてなるべく軽量化といいますか簡略化(簡単)にしたいのですが、これ以上に可能でしょうか??