<!--
////////////////////////////////////////////////////////////////////////////
// J-Reverse (_Masa)

Rect = new Array(63);	// ます配列
EMPTY = 0;	// 空
USER = 1;	// ユーザー
COMP = 2;	// コンピュータ
WTurn = 0;	// 誰のターンか？(0:まだゲーム始まってない,1:自分,2:コンピュータ)
eWho = 0;	// 対戦相手
WCol = 0;	// 白か黒か？(1:白,2:黒)
Wfore = 0;	// 先手か後手か？(0:後手,1:先手)
UserScore = 0;	// ユーザーの枚数
ComScore = 0;	// コンピュータの枚数

DIR = new Array(-9, -8, -7, -1, 1, 7, 8, 9);	// サーチ方向テーブル
WSq = new Array("Empty.gif", "White.gif", "Black.gif");	// 「gif画像」テーブル

function init(eWho)
{
	// オセロますを初期化する
	switch(eWho){
	case 0:
		// ノーマルタイプ
		l1 = "00000000";
		l2 = "00000000";
		l3 = "00000000";
		l4 = "00012000";
		l5 = "00021000";
		l6 = "00000000";
		l7 = "00000000";
		l8 = "00000000";
		UserScore = 2;
		ComScore = 2;
		break;
	case 1:
		l1 = "00000000";
		l2 = "00000000";
		l3 = "00001000";
		l4 = "00002000";
		l5 = "00010000";
		l6 = "00020000";
		l7 = "00000000";
		l8 = "00000000";
		UserScore = 2;
		ComScore = 2;
		break;
	case 2:
		l1 = "00000000";
		l2 = "00000000";
		l3 = "00012000";
		l4 = "00121200";
		l5 = "00212100";
		l6 = "00021000";
		l7 = "00000000";
		l8 = "00000000";
		UserScore = 4;
		ComScore = 4;
		break;
	case 3:
		l1 = "00000000";
		l2 = "00000000";
		l3 = "00012000";
		l4 = "00200100";
		l5 = "00100200";
		l6 = "00021000";
		l7 = "00000000";
		l8 = "00000000";
		UserScore = 4;
		ComScore = 4;
		break;
	case 4:
		l1 = "00000000";
		l2 = "00000000";
		l3 = "00001200";
		l4 = "00000100";
		l5 = "00100000";
		l6 = "00210000";
		l7 = "00000000";
		l8 = "00000000";
		UserScore = 2;
		ComScore = 4;
		break;
	case 5:
		l1 = "00000000";
		l2 = "01000010";
		l3 = "00200200";
		l4 = "00012000";
		l5 = "00021000";
		l6 = "00200200";
		l7 = "01000010";
		l8 = "00000000";
		UserScore = 6;
		ComScore = 6;
		break;
	case 6:
		l1 = "00000000";
		l2 = "00000000";
		l3 = "20000002";
		l4 = "20012002";
		l5 = "20021002";
		l6 = "20000002";
		l7 = "00000000";
		l8 = "00000000";
		UserScore = 2;
		ComScore = 10;
		break;
	case 7:
		l1 = "20000002";
		l2 = "00000000";
		l3 = "00000000";
		l4 = "00012000";
		l5 = "00021000";
		l6 = "00000000";
		l7 = "00000000";
		l8 = "20000002";
		UserScore = 2;
		ComScore = 6;
		break;
	}
	ComCol = (WCol % 2) + 1;
	l = l1 + l2 + l3 + l4 + l5 + l6 + l7 + l8;
	for (i = 0; i < 64; i++){
		switch(l.charAt(i))
		{
		case '0':	// 空
			Rect[i] = EMPTY;
			document.images[i].src = WSq[EMPTY];
			break;
		case '1':	// ユーザー
			Rect[i] = WCol;
			document.images[i].src = WSq[WCol];
			break;
		case '2':	// コンピュータ
			Rect[i] = ComCol;
			document.images[i].src = WSq[ComCol];
		}
	}
	document.score.user.value = UserScore;
	document.score.com.value = ComScore;

	if (WTurn == 2) ComTurn();
}

function Start()
{
	if (WTurn != 0) return;	// 既にスタートしている場合は無効
	if (document.score.wh1.selectedIndex == 0){ WCol = 1; }else{ WCol = 2; }
	if (document.score.wh2.selectedIndex == 0){ WTurn = 1; }else{ WTurn = 2; }
	
	t = 0;
	if(document.list.elements[0].checked == true) t = 0;
	if(document.list.elements[1].checked == true) t = 1;
	if(document.list.elements[2].checked == true) t = 2;
	if(document.list.elements[3].checked == true) t = 3;
	if(document.list.elements[4].checked == true) t = 4;
	if(document.list.elements[5].checked == true) t = 5;
	if(document.list.elements[6].checked == true) t = 6;
	if(document.list.elements[7].checked == true) t = 7;

	init(t);
}

function Stop()
{
	WTurn = 0;
	init(0);
}

function UClick(x, y)
{
	p = x + 8 * y;

	if (WTurn != 1) return;	// 自分のターンでない場合は無効
	if (Rect[p] != EMPTY){	// すでにこまがある時
		alert('Miss move');
		return;
	}

	// 置けるかどうかのチェックと裏返し処理(8方向ある)
	CanR = 0;	// 置けるかどうかのフラグ(0:置けない,1:置けた)
	for (i = 0; i < 8; i++){
		chp = Search(p, DIR[i], WCol);
		if (chp != -1 && chp != -2 && chp != p){	// 裏返せる
			if(CanR == 0){	// 元のこまを置く(既に置いてある場合は無視)
				Rect[p] = WCol;
				document.images[p].src = WSq[WCol];
				UserScore++;
				CanR = 1;
			}

			// 裏返し処理
			// 途中画像(アニメーション)
			revp = p + DIR[i];
			while(chp != revp){
				ComScore--;
				UserScore++;
				Rect[revp] = WCol;
				document.images[revp].src = "Reverse.gif";
				revp += DIR[i];
			}
			ComScore--;
			UserScore++;
			Rect[chp] = WCol;
			document.images[chp].src = "Reverse.gif";

			// 裏返した画像
			revp = p + DIR[i];
			while(chp != revp){
				document.images[revp].src = WSq[WCol];
				revp += DIR[i];
			}
			document.images[chp].src = WSq[WCol];
		}
	}

	if (CanR == 0){
		alert('Incorrect move');
		return;
	}

	document.score.user.value = UserScore;
	document.score.com.value = ComScore;

	// ユーザーの勝ち判定(全部埋まった時)
	if ((UserScore + ComScore) == 64){
		WTurn = 0;
		if (UserScore == 64){
			alert('Victory!!!');
			return;
		}
		if (UserScore > 32){
			alert('You won');
			return;
		}
		if (UserScore == 32){
			alert('Drawn game');
			return;
		}
		alert('You lost');
		return;
	}

	WTurn = 2;	// コンピュータのターン
	ComTurn();	// コンピュータの処理
}

function ComTurn()
{
	// コンピュータの処理
	while(1){
		CrevP = ComBrain();
		document.score.user.value = UserScore;
		document.score.com.value = ComScore;
		if (UserScore == 0){
			WTurn = 0;
			alert('Defeat');
			return;
		}

		// ユーザー置けるか？
		if (CanPutUser() == 1){
			break;
		}
		else{
			if (CrevP == 0){
				// どちらも置けない？！(勝ち判定)
				WTurn = 0;
				if (UserScore > ComScore){
					alert('You won');
					return;
				}
				if (UserScore == ComScore){
					alert('Drawn game');
					return;
				}
				alert('You lost');
				return;
			}
		}
	}

	WTurn = 1;	// ユーザーのターン
}

// コンピュータの思考
function ComBrain()
{
	ComCol = (WCol % 2) + 1;	// コンピュータのこまの色
	crevp = new Array(8);		// 作業用配列(裏返せる最終位置)
	cflg = 0;	// 置ける場所数
	maxnum = 0;	// 裏返せる最高枚数
	maxrp = 0;	// １番裏返せる枚数の多い場所
	okcrp = new Array(8);	// 裏返す最終位置

	// 作業用配列(置く候補位置)計８８
	scomp = new Array(
		// コーナー
		0,7,56,63,
		// エッジ(上、下、左、右)各６個所
		1,2,3,4,5,6,57,58,59,60,61,62,8,16,24,32,40,48,15,23,31,39,47,55,
		// 中央４×４のコーナー
		18,21,42,45,
		// 中央４×４のコーナー以外
		19,20,26,27,28,29,34,35,36,37,43,44,
		// 残りの内コーナーとられない場所(エッジは重複)２４個所
		3,4,59,60,24,32,31,39,10,11,12,13,50,51,52,53,17,25,33,41,22,30,38,46,
		// コーナーとられる可能性のある場所(エッジは重複)２０個所
		1,2,5,6,8,9,14,15,16,23,40,47,48,49,54,55,57,58,61,62
	);

	// コーナーをとれるか？(４個所)
	for (p = 0; p < 4; p++){
		if (Rect[scomp[p]] != EMPTY) continue;
		for (i = 0; i < 8; i++){
			crevp[i] = Search(scomp[p], DIR[i], ComCol);
			if (crevp[i] != -1 && crevp[i] != -2 && crevp[i] != scomp[p]) cflg++;
		}
		if (maxnum < cflg){
			// 候補の中で１番多く裏返せれる場所を保存
			maxnum = cflg;
			maxrp = scomp[p];
			for(j = 0; j < 8; j++){
				if (scomp[p] != crevp[j]){
					okcrp[j] = crevp[j];
				}
				else{
					okcrp[j] = -1;
				}
			}
		}
		cflg = 0;
	}

	// エッジがとれるか？(２４個所)
	if (maxnum == 0){
		for (; p < 28; p++){
			if (Rect[scomp[p]] != EMPTY) continue;
			for (i = 0; i < 8; i++){
				crevp[i] = Search(scomp[p], DIR[i], ComCol);
				if (crevp[i] != -1 && crevp[i] != -2 && crevp[i] != scomp[p]) cflg++;
			}
			// 置けない場合は以下スルー
			if (cflg == 0) continue;

			//////////////////////////////////////////////////////
			// 裏返されるかどうかチェック
			chk1 = 0; chk2 = 0; sdir1 = 0; sdir2 = 0;
			crevp1 = 0;crevp2 = 0;
			if (p < 16){	// 上端、下端
				chk1 = scomp[p] - 1; chk2 = scomp[p] + 1;
				sdir1 = -1; sdir2 = 1;
				crevp1 = 3; crevp2 = 4;
			}
			else{	// 左端、右端
				chk1 = scomp[p] - 8; chk2 = scomp[p] + 8;
				sdir1 = -8; sdir2 = 8;
				crevp1 = 1; crevp2 = 6;
			}
			// 両側がユーザーこまの時、即決定
			if (Rect[chk1] == WCol && Rect[chk2] == WCol){
				maxnum = cflg;
				maxrp = scomp[p];
				for(j = 0; j < 8; j++){
					if (scomp[p] != crevp[j]){
						okcrp[j] = crevp[j];
					}
					else{
						okcrp[j] = -1;
					}
				}
				break;
			}
			sres1 = 0; sres2 = 0;	// Search()戻り値格納用

			if (Rect[chk1] == EMPTY && Rect[chk2] == WCol){
				// ComCol:crevp[crevp2]で右(下)側調べる
				if (crevp[crevp2] == -1 || crevp[crevp2] == -2){
					cflg = 0;
					continue;
				}
				sres2 = Search(crevp[crevp2], sdir2, WCol);
				if (sres2 == -1  || sres2 == -2){
					maxnum = cflg;
					maxrp = scomp[p];
					for(j = 0; j < 8; j++){
						if (scomp[p] != crevp[j]){
							okcrp[j] = crevp[j];
						}
						else{
							okcrp[j] = -1;
						}
					}
					break;
				}
				else{
					cflg = 0;
					continue;
				}
			}
			if (Rect[chk1] == WCol && Rect[chk2] == EMPTY){
				// ComCol:crevp[crevp1]で左(上)側調べる
				if (crevp[crevp1] == -1 || crevp[crevp1] == -2){
					cflg = 0;
					continue;
				}
				sres2 = Search(crevp[crevp1], sdir1, WCol);
				if (sres2 == -1  || sres2 == -2){
					maxnum = cflg;
					maxrp = scomp[p];
					for(j = 0; j < 8; j++){
						if (scomp[p] != crevp[j]){
							okcrp[j] = crevp[j];
						}
						else{
							okcrp[j] = -1;
						}
					}
					break;
				}
				else{
					cflg = 0;
					continue;
				}
			}
			if (Rect[chk1] == ComCol && Rect[chk2] == WCol){
				// WColで左(上)側調べる
				sres1 = Search(scomp[p], sdir1, WCol);
				if (sres1 == -1){	// 端
					maxnum = cflg;
					maxrp = scomp[p];
					for(j = 0; j < 8; j++){
						if (scomp[p] != crevp[j]){
							okcrp[j] = crevp[j];
						}
						else{
							okcrp[j] = -1;
						}
					}
					break;
				}
				if (sres1 != -2){	// 左(上)側が空白でない
					// ComCol:crevp[crevp2]で右(下)側調べる
					if (crevp[crevp2] == -1 || crevp[crevp2] == -2){
						// 端、空白の時決定
						maxnum = cflg;
						maxrp = scomp[p];
						for(j = 0; j < 8; j++){
							if (scomp[p] != crevp[j]){
								okcrp[j] = crevp[j];
							}
							else{
								okcrp[j] = -1;
							}
						}
						break;
					}
					else{
						sres2 = Search(crevp[crevp2], sdir2, WCol);
						if (sres2 == -2){
							cflg = 0;
							continue;
						}
						else{
							maxnum = cflg;
							maxrp = scomp[p];
							for(j = 0; j < 8; j++){
								if (scomp[p] != crevp[j]){
									okcrp[j] = crevp[j];
								}
								else{
									okcrp[j] = -1;
								}
							}
							break;
						}
					}
				}
				else{	// 左(上)側が空白の時
					// ComCol:crevp[crevp2]右(下)側調べる
					if (crevp[crevp2] == -1 || crevp[crevp2] == -2){
						// 端、空白の時だめ
						cflg = 0;
						continue;
					}
					else{
						sres2 = Search(crevp[crevp2], sdir2, WCol);
						if (sres2 != -1 && sres2 != -2){
							cflg = 0;
							continue;
						}
						else{
							maxnum = cflg;
							maxrp = scomp[p];
							for(j = 0; j < 8; j++){
								if (scomp[p] != crevp[j]){
									okcrp[j] = crevp[j];
								}
								else{
									okcrp[j] = -1;
								}
							}
							break;
						}
					}
				}
			}
			
			if (Rect[chk1] == WCol && Rect[chk2] == ComCol){
				// WColで右側調べる
				sres1 = Search(scomp[p], sdir2, WCol);
				// 右(下)側が端の時は即決定
				if (sres1 == -1){
					maxnum = cflg;
					maxrp = scomp[p];
					for(j = 0; j < 8; j++){
						if (scomp[p] != crevp[j]){
							okcrp[j] = crevp[j];
						}
						else{
							okcrp[j] = -1;
						}
					}
					break;
				}
				if (sres1 != -2){	// 右(下)側が空白でない
					// ComCol:crevp[crevp1]左側調べる
					if (crevp[crevp1] == -1 || crevp[crevp1] == -2){
						// 端、空白の時決定
						maxnum = cflg;
						maxrp = scomp[p];
						for(j = 0; j < 8; j++){
							if (scomp[p] != crevp[j]){
								okcrp[j] = crevp[j];
							}
							else{
								okcrp[j] = -1;
							}
						}
						break;
					}
					else{
						sres2 = Search(crevp[crevp1], sdir1, WCol);
						if (sres2 == -2){
							cflg = 0;
							continue;
						}
						else{
							maxnum = cflg;
							maxrp = scomp[p];
							for(j = 0; j < 8; j++){
								if (scomp[p] != crevp[j]){
									okcrp[j] = crevp[j];
								}
								else{
									okcrp[j] = -1;
								}
							}
							break;
						}
					}
				}
				else{	// 右(下)側が空白の時
					// ComCol:crevp[crevp1]左(上)側調べる
					if (crevp[crevp1] == -1 || crevp[crevp1] == -2){
						// 端、空白の時だめ
						cflg = 0;
						continue;
					}
					else{
						sres2 = Search(crevp[crevp1], sdir1, WCol);
						if (sres2 != -1 && sres2 != -2){
							cflg = 0;
							continue;
						}
						else{
							maxnum = cflg;
							maxrp = scomp[p];
							for(j = 0; j < 8; j++){
								if (scomp[p] != crevp[j]){
									okcrp[j] = crevp[j];
								}
								else{
									okcrp[j] = -1;
								}
							}
							break;
						}
					}
				}
			}

			if (maxnum < cflg){
				// 候補の中で１番多く裏返せれる場所を保存
				maxnum = cflg;
				maxrp = scomp[p];
				for(j = 0; j < 8; j++){
					if (scomp[p] != crevp[j]){
						okcrp[j] = crevp[j];
					}
					else{
						okcrp[j] = -1;
					}
				}
			}
			cflg = 0;
		}
	}

	// 中央の４×４のかどをとれるか？(４個所)コーナー･エッジは安全
	if (maxnum == 0){
		for (; p < 32; p++){
			if (Rect[scomp[p]] != EMPTY) continue;
			for (i = 0; i < 8; i++){
				crevp[i] = Search(scomp[p], DIR[i], ComCol);
				if (crevp[i] != -1 && crevp[i] != -2 && crevp[i] != scomp[p]) cflg++;
			}
			if (maxnum < cflg){
				// 候補の中で１番多く裏返せれる場所を保存
				maxnum = cflg;
				maxrp = scomp[p];
				for(j = 0; j < 8; j++){
					if (scomp[p] != crevp[j]){
						okcrp[j] = crevp[j];
					}
					else{
						okcrp[j] = -1;
					}
				}
			}
			cflg = 0;
		}
	}

	// 中央の４×４のかど以外をとれるか？(１２個所)コーナー･エッジは安全
	if (maxnum == 0){
		for (; p < 44; p++){
			if (Rect[scomp[p]] != EMPTY) continue;
			for (i = 0; i < 8; i++){
				crevp[i] = Search(scomp[p], DIR[i], ComCol);
				if (crevp[i] != -1 && crevp[i] != -2 && crevp[i] != scomp[p]) cflg++;
			}
			if (maxnum < cflg){
				// 候補の中で１番多く裏返せれる場所を保存
				maxnum = cflg;
				maxrp = scomp[p];
				for(j = 0; j < 8; j++){
					if (scomp[p] != crevp[j]){
						okcrp[j] = crevp[j];
					}
					else{
						okcrp[j] = -1;
					}
				}
			}
			cflg = 0;
		}
	}

	// 残りの内コーナーを取られない場所(２４個所)
	if (maxnum == 0){
		for (; p < 68; p++){
			if (Rect[scomp[p]] != EMPTY) continue;
			for (i = 0; i < 8; i++){
				crevp[i] = Search(scomp[p], DIR[i], ComCol);
				if (crevp[i] != -1 && crevp[i] != -2 && crevp[i] != scomp[p]) cflg++;
			}
			if (maxnum < cflg){
				// 候補の中で１番多く裏返せれる場所を保存
				maxnum = cflg;
				maxrp = scomp[p];
				for(j = 0; j < 8; j++){
					if (scomp[p] != crevp[j]){
						okcrp[j] = crevp[j];
					}
					else{
						okcrp[j] = -1;
					}
				}
			}
			cflg = 0;
		}
	}

	// コーナーを取られる可能性のある場所(２０個所)
	if (maxnum == 0){
		for (; p < 88; p++){
			if (Rect[scomp[p]] != EMPTY) continue;
			for (i = 0; i < 8; i++){
				crevp[i] = Search(scomp[p], DIR[i], ComCol);
				if (crevp[i] != -1 && crevp[i] != -2 && crevp[i] != scomp[p]) cflg++;
			}
			if (maxnum < cflg){
				// 候補の中で１番多く裏返せれる場所を保存
				maxnum = cflg;
				maxrp = scomp[p];
				for(j = 0; j < 8; j++){
					if (scomp[p] != crevp[j]){
						okcrp[j] = crevp[j];
					}
					else{
						okcrp[j] = -1;
					}
				}
			}
			cflg = 0;
		}
	}

	// 置けなかった
	if (maxnum == 0) return 0;

	////////////////////////////////////////////////////////////////
	// 裏返し処理(maxrp:原点,okcrp[]:裏返せる最終位置)

	// 原点置く
	Rect[maxrp] = ComCol;
	document.images[maxrp].src = WSq[ComCol];
	ComScore++;

	// 途中画像(アニメーション)
	for (i = 0; i < 8; i++){
		if (okcrp[i] == -1 || okcrp[i] == -2) continue;

		revp = maxrp + DIR[i];
		while(okcrp[i] != revp){
			ComScore++;
			UserScore--;
			Rect[revp] = ComCol;
			document.images[revp].src = "Reverse.gif";
			revp += DIR[i];
		}
		ComScore++;
		UserScore--;
		Rect[okcrp[i]] = ComCol;
		document.images[okcrp[i]].src = "Reverse.gif";

		// 裏返した画像
		revp = maxrp + DIR[i];
		while(okcrp[i] != revp){
			document.images[revp].src = WSq[ComCol];
			revp += DIR[i];
		}
		document.images[okcrp[i]].src = WSq[ComCol];
	}

	return 1;
}

function CanPutUser()
{
	// ユーザー置けるか？
	for(p = 0; p < 64; p++){
		if(Rect[p] != EMPTY) continue;
		for (i = 0; i < 8; i++){
			chp = Search(p, DIR[i], WCol);
			if (chp != -1 && chp != -2 && chp != p){	// 裏返せる
				return 1;
			}
		}
	}

	return 0;	// 置けれない
}

// 再帰を使って、どの位置まで裏返すか調べる(方向にあるますを調べ、そこに他のこまがある時はどんどん再帰させる)
// 引数(nowp:現在位置,dir:サーチ方向,which:元駒が白か黒か)、戻り値(-1,-2:置けない,その他:裏返す最終位置)
function Search(nowp, dir, which)
{
	// エッジの判定をする
	// 上方向
	if (dir == -9 || dir == -8 || dir == -7){
		if (nowp >= 0 && nowp <= 7) return -1;	// 現在上端に接している
	}
	// 下方向
	if (dir == 7 || dir == 8 || dir == 9){
		if (nowp >=56 && nowp <= 63) return -1;	// 現在下端に接している
	}
	// 左方向
	if (dir == -9 || dir == -1 || dir == 7){
		if (nowp % 8 == 0) return -1;	// 現在左端に接している
	}
	// 右方向
	if (dir == -7 || dir == 1 || dir == 9){
		if (nowp % 8 == 7) return -1;	// 現在右端に接している
	}

	// 方向にあるますを調べる
	if(Rect[nowp + dir] == which) return nowp;	// 同じこま(サーチストップし、現在位置を返す)
	if(Rect[nowp + dir] == EMPTY) return -2;	// 空の時

	// 他のこま(再帰)
	return Search(nowp + dir, dir, which);
}
// -->

