diff options
Diffstat (limited to 'humanbot_index.html')
| -rw-r--r-- | humanbot_index.html | 543 | 
1 files changed, 543 insertions, 0 deletions
diff --git a/humanbot_index.html b/humanbot_index.html new file mode 100644 index 0000000..7d05c7a --- /dev/null +++ b/humanbot_index.html @@ -0,0 +1,543 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>Game</title> +<script> +var S=5; +var PLAYERS=["Player 1","Player 2"]; +var MOVES=[];//[[-1,1,3],[7,23,0],[0,0,3]]; + + +var moveidx=0; +var neuidxhist=[]; + +var board=Array.apply(null,new Array(S*S)).map(function(){return 0;}); +var fgcells=board.map(function(){return null;}); +var neuidx; + +var canclick=false; + +var imPlayer=-1; + +var othermovefifo_interval=null; + +var clickenabled=[false,false]; +var input_neudir_choice=null,input_dir_choice=null,input_stone_choice=null; + +function init(){ +	var tr,td,y,x,e,span, +	    movelisttbody, +	    header=document.getElementById("header"), +	    status=document.getElementById("status"), +	    movelist=document.getElementById("movelist"), +	    bgtbody=document.getElementById("bgtbody"); + +	document.title="Game: "+PLAYERS[0]+" vs "+PLAYERS[1]; + +	header.appendChild(document.createTextNode("Game: ")); +	span=document.createElement("span"); +	span.classList.add("celltypeclr"); span.classList.add("celltypeclr_1"); +	span.appendChild(document.createTextNode(PLAYERS[0])); +	header.appendChild(span); +	header.appendChild(document.createTextNode(" vs ")); +	span=document.createElement("span"); +	span.classList.add("celltypeclr"); span.classList.add("celltypeclr_2"); +	span.appendChild(document.createTextNode(PLAYERS[1])); +	header.appendChild(span); + + +	e=document.createElement("table"); +	movelisttbody=document.createElement("tbody"); +	movelisttbody.id="movelisttbody"; +	tr=document.createElement("tr"); +	td=document.createElement("td"); td.innerHTML="Player"; tr.appendChild(td); +	td=document.createElement("td"); td.innerHTML="Neutron"; tr.appendChild(td); +	td=document.createElement("td"); td.innerHTML="Stone"; tr.appendChild(td); +	movelisttbody.appendChild(tr); +	e.appendChild(movelisttbody); +	movelist.appendChild(e); + +	tr=document.createElement("tr"); +	td=document.createElement("td"); +	td.setAttribute("colspan","3"); +	td.innerHTML=" "; +	tr.appendChild(td); +	(function(tr){ +		tr.addEventListener("click",function(ev){ +			if(moveidx==0)return; +			while(moveidx>0)prevmove(true); +			setselectedmovelistline(0); +		}); +	})(tr); +	tr.classList.add("selected"); +	movelisttbody.appendChild(tr); + +	MOVES.forEach(function(mv,i){ +		addmovelistrow(mv,i); +	}); + + +	var inputstonetbody=document.getElementById("inputstonetbody"); +	for(y=0;y<S;y++){ +		tr=document.createElement("tr"); +		for(x=0;x<S;x++){ +			td=document.createElement("td"); +			e=document.createElement("input"); +			e.setAttribute("type","radio"); +			e.setAttribute("name","inputstoneradio"); +			e.addEventListener("click",(function(x,y){return function(){ +				input_stone_choice=S*y+x; +			};})(x,y)); +			td.appendChild(e); +			tr.appendChild(td); +		} +		inputstonetbody.appendChild(tr); +	} + + +	for(y=0;y<S;y++){ +		tr=document.createElement("tr"); +		for(x=0;x<S;x++){ +			td=document.createElement("td"); +			td.classList.add("bgcell"); +			td.innerHTML=S*y+x; +			tr.appendChild(td); +		} +		bgtbody.appendChild(tr); +	} +	for(x=0;x<S;x++){ +		board[x]=1; +		e=makefgcell(x,1); +		fgcells[x]=e; +		document.body.appendChild(e); + +		board[S*(S-1)+x]=2; +		e=makefgcell(S*(S-1)+x,2); +		fgcells[S*(S-1)+x]=e; +		document.body.appendChild(e); +	} +	neuidx=S*~~(S/2)+~~(S/2); +	board[neuidx]=3; +	e=makefgcell(neuidx,3); +	fgcells[neuidx]=e; +	document.body.appendChild(e); + +	setnextenabled(MOVES.length>0); +	setprevenabled(false); +	canclick=true; + +	othermovefifo_interval=setInterval(function(){ +		if(clickenabled[0]||clickenabled[1])return; +		var xhr=new XMLHttpRequest(); +		xhr.addEventListener("readystatechange",function(){ +			if(this.readyState!=4)return; +			console.log("othermove",this.status,this.responseText); +			if(this.status!=200)return; +			if(this.responseText=="go"){ +				enableClicking(true,true); //2nd true is to disable neutron dir +				imPlayer=1; +			} else if(this.responseText=="nogo"){ +				enableClicking(false); +				imPlayer=2; +			} else { +				var mv=JSON.parse(this.responseText); +				MOVES.push(mv); +				addmovelistrow(mv); +				nextmove(); +				enableClicking(true); +			} +		}); +		xhr.open("GET",location.protocol+"//"+location.host+"/othermove"); +		xhr.send(); +	},1500); + +	enableClicking(false); +} + +function enableClicking(en,disneu){ +	var i,l; +	en=en?true:false; +	disneu=disneu?true:false; +	for(i=0;i<8;i++){ +		document.getElementById("input_neudir"+i)[en&&!disneu?"removeAttribute":"setAttribute"]("disabled"); +		document.getElementById("input_dir"+i)[en?"removeAttribute":"setAttribute"]("disabled"); +	} +	l=document.getElementsByName("inputstoneradio"); +	for(i=0;i<l.length;i++){ +		l[i][en&&(imPlayer==-1||board[i]==imPlayer)?"removeAttribute":"setAttribute"]("disabled"); +	} +	document.getElementById("input_domovebtn")[en?"removeAttribute":"setAttribute"]("disabled"); +	clickenabled=[en,disneu]; +} + +function addmovelistrow(mv,i/*optional*/){ +	var tr,td; +	var movelisttbody=document.getElementById("movelisttbody"); +	var i=i!=undefined?i:movelisttbody.children.length; +	tr=document.createElement("tr"); + +	td=document.createElement("td"); +	td.innerHTML=i%2+1; +	tr.appendChild(td); + +	td=document.createElement("td"); +	if(mv[0]==-1)td.innerHTML=" "; +	else td.innerHTML=arrowfor(mv[0]); +	tr.appendChild(td); + +	td=document.createElement("td"); +	td.innerHTML=mv[1]+": "+arrowfor(mv[2]); +	tr.appendChild(td); + +	tr.addEventListener("click",(function(target){return function(ev){ +		if(moveidx==target)return; +		while(moveidx<target)nextmove(true); +		while(moveidx>target)prevmove(true); +		setselectedmovelistline(i+1); +	};})(i+1)); + +	movelisttbody.appendChild(tr); +} + +function setselectedmovelistline(i){ +	var movelist=document.getElementById("movelist"); +	movelist.querySelectorAll("tr.selected")[0].classList.remove("selected"); +	document.getElementById("movelist").getElementsByTagName("tr")[i+1].classList.add("selected"); +} + +function arrowfor(dir){ +	return "&#x"+[2191,2197,2192,2198,2193,2199,2190,2196][dir]+";"; +} + +function bgcell(idx){ +	return document.getElementById("bgtbody").children[idx/S|0].children[idx%S]; +} +function fgcellposition(idx){ +	var rect=bgcell(idx).getBoundingClientRect(), +	    scrolltop=window.pageYOffset||document.documentElement.scrollTop; +	return [rect.left,rect.top+scrolltop]; +} +function movefgcell(e,idx){ +	var pos=fgcellposition(idx); +	e.style.left=pos[0]+"px"; +	e.style.top=pos[1]+"px"; +	e.cell_index=idx; +} +function makefgcell(idx,type){ //type in [1,2,3] +	var pos=fgcellposition(idx), +	    e=document.createElement("div"); +	e.classList.add("fgcell"); +	e.classList.add("celltype_"+type); +	e.setAttribute("style","left:"+pos[0]+"px;top:"+pos[1]+"px;"); +	e.cell_index=idx; +	e.appendChild(document.createElement("div")); +	return e; +} + +var index_deltas=[[0,-1],[1,-1],[1,0],[1,1],[0,1],[-1,1],[-1,0],[-1,-1]]; +function indexafterslide(from,dir,overshoot){ +	var x=from%S,y=~~(from/S),x2,y2; +	while(true){ +		x2=x+index_deltas[dir][0]; +		y2=y+index_deltas[dir][1]; +		if(x2<0||x2>=S||y2<0||y2>=S||board[S*y2+x2]!=0){ +			if(overshoot)return S*y2+x2; +			else return S*y+x; +		} +		x=x2; +		y=y2; +	} +} + +function setnextenabled(en){ +	document.getElementById("nextmovebtn").disabled=!en; +} +function setprevenabled(en){ +	document.getElementById("prevmovebtn").disabled=!en; +} + +function nextmove(notimeout){ +	var newidx; +	if(moveidx==MOVES.length||!canclick)return false; + +	if(MOVES[moveidx][0]!=-1){ +		neuidxhist.push(neuidx); +		newidx=indexafterslide(neuidx,MOVES[moveidx][0]); +		movefgcell(fgcells[neuidx],newidx); +		board[newidx]=board[neuidx]; +		board[neuidx]=0; +		fgcells[newidx]=fgcells[neuidx]; +		fgcells[neuidx]=null; +		neuidx=newidx; + +		if(moveidx==MOVES.length-1)bgcell(neuidx).classList.add("win"); +	} + +	newidx=indexafterslide(MOVES[moveidx][1],MOVES[moveidx][2]); +	if(MOVES[moveidx][0]!=-1&&!notimeout){ +		setTimeout( +			(function(e,idx){return function(){ +				movefgcell(e,idx); +				canclick=true; +			};})(fgcells[MOVES[moveidx][1]],newidx), +			500 +		); +		canclick=false; +	} else { +		movefgcell(fgcells[MOVES[moveidx][1]],newidx); +	} +	board[newidx]=board[MOVES[moveidx][1]]; +	board[MOVES[moveidx][1]]=0; +	fgcells[newidx]=fgcells[MOVES[moveidx][1]]; +	fgcells[MOVES[moveidx][1]]=null; + +	moveidx++; +	setprevenabled(true); +	if(moveidx==MOVES.length)setnextenabled(false); +	if(!notimeout)setselectedmovelistline(moveidx); +	return true; +} +function prevmove(notimeout){ +	var item,oldneuidx,newidx,winGlowIdxToRemove=null; +	if(moveidx==0||!canclick)return false; +	moveidx--; + +	if(MOVES[moveidx][0]!=-1&&moveidx==MOVES.length-1)winGlowIdxToRemove=neuidx; + +	newidx=indexafterslide(MOVES[moveidx][1],MOVES[moveidx][2],true); +	board[MOVES[moveidx][1]]=board[newidx]; +	board[newidx]=0; +	fgcells[MOVES[moveidx][1]]=fgcells[newidx]; +	fgcells[newidx]=null; +	movefgcell(fgcells[MOVES[moveidx][1]],MOVES[moveidx][1]); + +	if(MOVES[moveidx][0]!=-1){ +		oldneuidx=neuidxhist.pop(); +		board[oldneuidx]=board[neuidx]; +		board[neuidx]=0; +		fgcells[oldneuidx]=fgcells[neuidx]; +		fgcells[neuidx]=null; +		if(notimeout){ +			movefgcell(fgcells[oldneuidx],oldneuidx); +			if(winGlowIdxToRemove!=null)bgcell(winGlowIdxToRemove).classList.remove("win"); +		} else { +			setTimeout( +				(function(e,idx){return function(){ +					movefgcell(e,idx); +					canclick=true; +					if(winGlowIdxToRemove!=null)bgcell(winGlowIdxToRemove).classList.remove("win"); +				};})(fgcells[oldneuidx],oldneuidx), +				500 +			); +			canclick=false; +		} +		neuidx=oldneuidx; +	} + +	setnextenabled(true); +	if(moveidx==0)setprevenabled(false); +	if(!notimeout)setselectedmovelistline(moveidx); +	return true; +} + + +function input_neudir(dir){ +	var i; +	for(i=0;i<8;i++){ +		if(i==dir)document.getElementById("input_neudir"+i).classList.add("selected"); +		else document.getElementById("input_neudir"+i).classList.remove("selected"); +	} +} + +function input_dir(dir){ +	var i; +	for(i=0;i<8;i++){ +		if(i==dir)document.getElementById("input_dir"+i).classList.add("selected"); +		else document.getElementById("input_dir"+i).classList.remove("selected"); +	} +} + +function input_domove(){ +	var i,l,mv=[-1,-1,-1]; +	for(i=0;i<8;i++){ +		if(document.getElementById("input_neudir"+i).classList.contains("selected")){ +			mv[0]=i; +			break; +		} +	} +	for(i=0;i<8;i++){ +		if(document.getElementById("input_dir"+i).classList.contains("selected")){ +			mv[2]=i; +			break; +		} +	} +	l=document.getElementsByName("inputstoneradio"); +	for(i=0;i<l.length;i++){ +		if(l[i].checked){ +			mv[1]=i; +			break; +		} +	} +	if(mv[0]==-1&&!clickenabled[1]){alert("Neutron direction not set!");return;} +	if(mv[1]==-1){alert("Stone choice not set!");return;} +	if(mv[2]==-1){alert("Stone direction not set!");return;} +	var clickenabledcache=clickenabled; +	enableClicking(false); +	var xhr=new XMLHttpRequest(); +	xhr.addEventListener("readystatechange",function(){ +		if(this.readyState!=4)return; +		console.log("mynewmove",this.status,this.responseText); +		if(this.status!=200){ +			alert("Failed to submit move!"); +			enableClicking.apply(this,clickenabledcache); +		} else { +			MOVES.push(mv); +			addmovelistrow(mv); +			nextmove(); +		} +	}); +	xhr.open("POST",location.protocol+"//"+location.host+"/mynewmove"); +	xhr.send(JSON.stringify(mv)); +} + + +window.addEventListener("load",init,false); +</script> +<style> +body{ +	font-family:Georgia,Times,Serif; +	font-size:15px; +} + +table#bgtab{ +	border-spacing:4px; +} +td.bgcell{ +	width:80px; +	height:80px; +	border:3px #ddd solid; +	border-radius:12px; +	transition:background-color 0.6s ease 0.2s, box-shadow 0.6s ease 0.2s, -webkit-box-shadow 0.6s ease 0.2s; + +	text-align:right; +	vertical-align:bottom; +	font-size:14px; +} +td.bgcell.win{ +	background-color:#8f8; +	        box-shadow:inset 0 0 6px #6e6; +	-webkit-box-shadow:inset 0 0 6px #6e6; +} +div.fgcell{ +	position:absolute; +	width:82px; +	height:82px; +	border:3px rgba(0,0,0,0) solid; +	text-align:center; +	transition:left 0.6s ease 0s, top 0.6s ease 0s; +} + +div.fgcell > div{ +	height:75%; +	margin:10px; +	border-radius:30px; +} + +h1#header{ +	letter-spacing:0.5px; +} +span.celltypeclr{ +	border-radius:5px; +	padding:4px; +} + +div#status{ +	font-size:16px; +	font-weight:bold; +} + +div.fgcell.celltype_1 > div{background-color:#ddd;} +span.celltypeclr_1         {background-color:#ddd;} +div.fgcell.celltype_2 > div{background-color:#2a2a2a;} +span.celltypeclr_2         {background-color:#2a2a2a;color:#eee;} +div.fgcell.celltype_3 > div{background-color:#11e;} + +div#movelist{ +	border:1px black solid; +	width:500px; +	height:200px; +	overflow-y:scroll; +} +div#movelist table{ +	border-spacing:0; +	width:100%; +} +div#movelist tr:first-child{ +	font-weight:bold; +	background-color:#ccc; +} +div#movelist tr:first-child > td{ +	border-bottom:1px black solid; +} +div#movelist tr:nth-child(odd){background-color:#e4e4e4;} +div#movelist tr:nth-child(even){background-color:#fff;} +div#movelist tr:nth-child(n+2):hover{background-color:#bbf;cursor:pointer;} +div#movelist tr.selected{ +	background-color:#afa; +} + +input[type=button].selected{ +	background-color:#aaf; +} +</style> +</head> +<body> +<h1 id="header"></h1> +<table id="bgtab" style="display:inline-block"><tbody id="bgtbody"></tbody></table> +<table id="inputneudirtab" style="display:inline-block"><tbody id="inputneudirtbody"> +	<tr> +		<td><input type="button" id="input_neudir7" value="↖" onclick="input_neudir(7)"></td> +		<td><input type="button" id="input_neudir0" value="↑" onclick="input_neudir(0)"></td> +		<td><input type="button" id="input_neudir1" value="↗" onclick="input_neudir(1)"></td> +	</tr> +	<tr> +		<td><input type="button" id="input_neudir6" value="←" onclick="input_neudir(6)"></td> +		<td>Neu</td> +		<td><input type="button" id="input_neudir2" value="→" onclick="input_neudir(2)"></td> +	</tr> +	<tr> +		<td><input type="button" id="input_neudir5" value="↙" onclick="input_neudir(5)"></td> +		<td><input type="button" id="input_neudir4" value="↓" onclick="input_neudir(4)"></td> +		<td><input type="button" id="input_neudir3" value="↘" onclick="input_neudir(3)"></td> +	</tr> +</tbody></table> +<table id="inputdirtab" style="display:inline-block;margin-left:20px"><tbody id="inputdirtbody"> +	<tr> +		<td><input type="button" id="input_dir7" value="↖" onclick="input_dir(7)"></td> +		<td style="text-align:center"><input type="button" id="input_dir0" value="↑" onclick="input_dir(0)"></td> +		<td><input type="button" id="input_dir1" value="↗" onclick="input_dir(1)"></td> +	</tr> +	<tr> +		<td><input type="button" id="input_dir6" value="←" onclick="input_dir(6)"></td> +		<td> +			<table id="inputstonetab" style="display:inline-block"><tbody id="inputstonetbody"></tbody></table> +		</td> +		<td><input type="button" id="input_dir2" value="→" onclick="input_dir(2)"></td> +	</tr> +	<tr> +		<td><input type="button" id="input_dir5" value="↙" onclick="input_dir(5)"></td> +		<td style="text-align:center"><input type="button" id="input_dir4" value="↓" onclick="input_dir(4)"></td> +		<td><input type="button" id="input_dir3" value="↘" onclick="input_dir(3)"></td> +	</tr> +</tbody></table> +<div style="display:inline-block;margin-left:10px"> +	<input type="button" id="input_domovebtn" value="Do move" onclick="input_domove()"> +	<br> +</div> +<br> +<input type="button" id="prevmovebtn" onclick="prevmove()" value="←"> +<input type="button" id="nextmovebtn" onclick="nextmove()" value="→"><br> +<div id="movelist" style="margin-top:30px"></div> +</body> +</html>  | 
