無限ループになってしまう

[新着] Webテンプレートを仮オープンしました



0   名前: うひょ : 2006/04/29(土) 11:07  ID:Y1L64jC2
始めまして。うひょと申します。
今、簡易カードゲームをJavaScriptで作っています。
そして、次のようなループを作っています。
また、このコード内ででてくる配列cardsは、一つの要素につき、一つの連想配列を持っています。
今回は、フィールドに出ているカード番号一覧を配列arrで所得し、(要素数は3個で限定)
そのカード番号のカードの名前(cards[添え字]["name"])をarrnに入れたいのですが、
一つでもフィールドにカードが存在すると、無限ループ(?)になっているようです。
どうしてでしょうか…。

function checkfiled(arr){ //フィールドのカード番号一覧
arrn = []; //チェックする関数に渡す配列
for(i=0;i<3;i++){
if(arr[i] != -1){ //カード番号が-1のときは、カードが無いことを表す
b = cards[arr[i]]["name"]; //カードの名前をbに代入
arrn.push(b); //それをarrnに
}else
arrn.push(""); //カードが無いときは、空文字列をarrnに
}
}

1   名前: m035 ◆Wpzr1YKOiq : 2006/04/29(土) 11:07  [URL]  ID:7ds3vk2M
<html>
<head>
<title>test</title>
<script type="text/javascript">
<!--
cards=[[]];
cards[0]["name"]=0;
function checkfiled(arr){ //フィールドのカード番号一覧
arrn = []; //チェックする関数に渡す配列
for(i=0;i<3;i++){
if(arr[i] != -1){ //カード番号が-1のときは、カードが無いことを表す
b = cards[arr[i]]["name"]; //カードの名前をbに代入
arrn.push(b); //それをarrnに
}else
arrn.push(""); //カードが無いときは、空文字列をarrnに
}
}
checkfiled([0,-1,0]);
//-->
</script>
</head>
<body>
</body>
</html>

のようにテストしてみましたが、特に無限ループにはなりませんでした。
他のところに問題があるのでは?
もし、確実にここだと言うのなら、現象を再現できるソースか、urlを提示してください。

余談:
checkfiled()を書き直してみました。これで十分だと思います。
function checkfiled(arr){
var arrn=[];
for(var i=0;i<3;i++)arrn[i]=(arr[i]>-1?cards[arr[i]]["name"]:"");
}


2   名前: うひょ : 2006/04/29(土) 11:07  ID:Y1L64jC2
正確には、checkfiled()はもっと長いです。

function cehckfiled(arr){
	if(checksamename(arr,0))					//arrをそのまま引数にし、同じカードが3枚あればtrue、他はfalseを返す関数
		alert('カードが3枚とも同じ');
	else
		alert('バラバラ');
	var arrn=[];
	for(var i=0;i<3;i++)arrn[i]=(arr[i]>-1?cards[arr[i]]["name"]:"");
	if(check2all(arrn,'カードA','カードB'))			//名前の配列と2つのカード名を引数にとり、3つのカードがその2種類だけかを調べる関数
		alert('OK');
	else
		alert('NG');
}


このようになっているのですが、

	if(checksamename(arr,0))					//arrをそのまま引数にし、同じカードが3枚あればtrue、他はfalseを返す関数
		alert('カードが3枚とも同じ');
	else
		alert('バラバラ');

ここの部分は正常に動作し、この後の部分が無限ループになっています。
あと、checksamename()の中身はこうです。
function checksamename(arr,name){
	var a;
	if(!name){
		for(z=0;z<cards.length;z++){
			y = cards[z]["name"];
			if(checksamename(arr,y)){
				return true;
			}
		}
	}
	for(b=0;b<arr.length;b++){
		if(arr[b] == -1){
			return false;
		}
		a += cards[arr[b]]["name"];
	}
	if(a.indexOf(name + name + name) == -1)
		return true;
	else
		return false;
}


まだローカルで作成しているので、urlの提示はできません…

3   名前: しぶや : 2006/04/29(土) 11:07
回答ではないのですが、そんな風に問題を小出しにするとレス付きませんよ。
回答する側にとって一番いやなやり方です。
なぜ最初から、聞きたい本当のことを書かないのでしょうか。

4   名前: m035 ◆Wpzr1YKOiq : 2006/04/29(土) 11:07  [URL]  ID:7ds3vk2M
無限ループを起こしそうなのは、checksamename()の再帰的呼び出しの部分では?
どうして、再帰的に呼び出さないといけないのか、まったくわかりません。
以下で十分だと思われます。
function checksamename(arr){
return (arr[0]==arr[1]&&arr[1]==arr[2]&&arr[0]>-1?true:false);
}

なお、そのほかの無限ループを起こしそうな記述は今の段階のソースでは見つかりません。

5   名前: うひょ : 2006/04/29(土) 11:07  ID:Y1L64jC2
解決しました。

原因はcheckfiled()ではなく、その後のarrnを渡す関数に問題があることがわかりました。
m035様、ありがとうございました。

6   名前: Pid ◆lasOO.HuJA : 2006/04/29(土) 11:07
>>2
> for(z=0;z<cards.length;z++){
> for(b=0;b<arr.length;b++){

z,b はグローバル変数ですから,再帰呼び出しなんかしたら値が破壊されますが。変数は必ず var 宣言して下さい。


あと,>>1,>>3 で指摘されているように,「問題が再現する,最小のソース」をご自分で作成して下さい。そうすれば原因の所在を絞り込めますし,質問のポイントも明確になります。

一覧へ戻る