diff options
author | tomsmeding <tom.smeding@gmail.com> | 2018-02-19 22:59:14 +0100 |
---|---|---|
committer | tomsmeding <tom.smeding@gmail.com> | 2018-02-19 22:59:14 +0100 |
commit | 0b4ed233c73ea41e0fbe4bb147fbfaf15fe4e55c (patch) | |
tree | 8b1a7e3d0b39c5b241bfb3faabebee87c361317c /index.html |
Initial
Diffstat (limited to 'index.html')
-rw-r--r-- | index.html | 302 |
1 files changed, 302 insertions, 0 deletions
diff --git a/index.html b/index.html new file mode 100644 index 0000000..8624e20 --- /dev/null +++ b/index.html @@ -0,0 +1,302 @@ +<!doctype html> +<html> +<head> +<meta charset="utf-8"> +<title>CaptureGo</title> +<script src="/socket.io/socket.io.js"></script> +<script> +var CELL_WID=25,STONE_SIZE=0.4*CELL_WID; + +var cvs=null,ctx=null; +var myId=null,myName=null; +var currentGame=null,currentOther=null,winningPlayer=null; +var GS_WAIT=0,GS_TURN=1,GS_FINISH=2; +var gameState=GS_WAIT; +const socket=io(); + +function setStatus(str){ + document.getElementById("status").innerHTML=str; +} + +function setGameStatus(str){ + document.getElementById("game_status").innerHTML=str; +} + +function interfaceSwitch(cont){ + document.getElementById("cont_connect").classList.add("invisible"); + document.getElementById("cont_game").classList.add("invisible"); + document.getElementById("cont_"+cont).classList.remove("invisible"); +} + +function getPlayersList(){ + socket.emit("list_players",function(list){ + var sel=document.getElementById("other_player_select"); + sel.innerHTML=""; + for(var i=0;i<list.length;i++){ + if(list[i].id==myId)continue; + var option=document.createElement("option"); + option.value=list[i].id; + option.appendChild(document.createTextNode(list[i].name)); + sel.appendChild(option); + } + }); +} + +function initConnect(){ + setStatus("Connecting..."); + + socket.on("connect",function(){ + socket.emit("my_info",function(p){ + myId=p.id; myName=p.name; + document.getElementById("info").innerHTML="ID: "+myId+"<br>Name: "+myName; + setStatus("Connected."); + interfaceSwitch("connect"); + getPlayersList(); + }); + }); + + socket.on("disconnect",function(){ + location.href=location.href; + }); + + socket.on("err",function(err){ + alert(err); + }); + + socket.on("player_list_change",getPlayersList); + + socket.on("game_create",function(game){ + if(currentGame){ + socket.emit("leave_game",game.id); + return; + } + currentGame=game; + if(game.players[0].id==myId)currentOther=game.players[1]; + else currentOther=game.players[0]; + interfaceSwitch("game"); + document.getElementById("game_header").innerHTML="Game with "+currentOther.name; + setGameStatus("Preparing"); + var colourString=game.players[0].id==myId?"black":"white"; + document.getElementById("colour_note").innerHTML="You are playing "+colourString+"."; + winningPlayer=null; + redrawBoard(); + }); + + socket.on("game_leave",function(g,p){ + if(g.id!=currentGame.id)return; + currentGame=g; + socket.emit("leave_game",g.id); + interfaceGameState(GS_FINISH); + }); + + socket.on("game_turn",function(g){ + if(g.id!=currentGame.id)return; + currentGame=g; + redrawBoard(); + interfaceGameState(GS_TURN); + }); + + socket.on("game_other_turn",function(g){ + if(g.id!=currentGame.id)return; + currentGame=g; + redrawBoard(); + interfaceGameState(GS_WAIT); + }); + + socket.on("game_win",function(g,p){ + if(g.id!=currentGame.id)return; + currentGame=g; + winningPlayer=p; + redrawBoard(); + interfaceGameState(GS_FINISH); + }); +} + +function boardX(idx){ + return (~~(idx%currentGame.size)+0.5)*CELL_WID; +} + +function boardY(idx){ + return (~~(idx/currentGame.size)+0.5)*CELL_WID; +} + +function redrawBoard(){ + if(currentGame==null){ + interfaceSwitch("connect"); + return; + } + + var G=currentGame; + var bsz=G.size*CELL_WID; + + if(cvs.width!=bsz||cvs.height!=bsz){cvs.width=bsz; cvs.height=bsz;} + + ctx.fillStyle="rgb(224,177,92)"; + ctx.fillRect(0,0,cvs.width,cvs.height); + ctx.strokeStyle="rgb(0,0,0)"; + ctx.beginPath(); + for(var i=0;i<G.size;i++){ + ctx.moveTo(boardX(i),boardY(0)); + ctx.lineTo(boardX(i),boardY(G.size*G.size-1)); + ctx.moveTo(boardX(0),boardY(G.size*i)); + ctx.lineTo(boardX(G.size*G.size-1),boardY(G.size*i)); + } + ctx.stroke(); + + var dots=[]; + if(G.size==9)dots=[2*9+2,6*9+2,2*9+6,6*9+6]; + if(G.size==13)dots=[3*13+3,3*13+9,9*13+3,9*13+9,6*13+6]; + if(G.size==19)dots=[3*19+3,3*19+9,3*19+15,9*19+3,9*19+9,9*19+15,15*19+3,15*19+9,15*19+15]; + ctx.fillStyle="rgb(0,0,0)"; + ctx.beginPath(); + for(var i=0;i<dots.length;i++){ + ctx.moveTo(boardX(dots[i])+2.2,boardY(dots[i])); + ctx.arc(boardX(dots[i]),boardY(dots[i]),2.2,0,2*Math.PI,true); + } + ctx.fill(); + + for(var i=0;i<G.size*G.size;i++){ + if(G.board[i]==1)ctx.fillStyle="rgb(0,0,0)"; + else if(G.board[i]==-1)ctx.fillStyle="rgb(255,255,255)"; + else continue; + ctx.beginPath(); + ctx.moveTo(boardX(i)+STONE_SIZE,boardY(i)); + ctx.arc(boardX(i),boardY(i),STONE_SIZE,0,2*Math.PI,true); + ctx.fill(); + } +} + +function interfaceGameState(state){ + gameState=state; + cvs.classList[gameState==GS_TURN?"add":"remove"]("mouse-pointer"); + + if(gameState==GS_TURN){ + setGameStatus("Your turn."); + } else if(gameState==GS_WAIT){ + setGameStatus("Waiting for move from opponent."); + } else if(gameState==GS_FINISH){ + var linktext="<a href=\"javascript:doCloseGame()\">Click here</a> to close the game."; + if(winningPlayer!=null){ + var s="Player <b>"+winningPlayer.name+"</b> has won the game! "; + s+=["Congratulations!","Too bad, maybe better next time."][+(winningPlayer.id==myId)]; + s+="<br>"+linktext; + setGameStatus(s); + } else { + var s="The other player closed the game.<br>"+linktext; + setGameStatus(s); + } + } +} + +function doCreateGame(){ + var otherid=document.getElementById("other_player_select").value; + if(!otherid){ + alert("No other player selected!"); + return; + } + var size=+document.getElementById("board_size").value; + if(isNaN(size)||size<5||size>99||size%1!=0){ + alert("Invalid board size!"); + return; + } + + socket.emit("create_game",+otherid,size); +} + +function doCloseGame(){ + socket.emit("leave_game",currentGame.id); + interfaceSwitch("connect"); +} + +function mouseEventToIndex(ev){ + var bbox=cvs.getBoundingClientRect(); + var x=~~((ev.clientX-bbox.left)/CELL_WID),y=~~((ev.clientY-bbox.top)/CELL_WID); + if(x<0||x>=currentGame.size||y<0||y>=currentGame.size)return null; + return y*currentGame.size+x; +} + +function initCanvasListeners(){ + cvs.addEventListener("click",function(ev){ + if(!currentGame||gameState!=GS_TURN)return; + var i=mouseEventToIndex(ev); + if(i==null)return; + + if(currentGame.board[i]!=0)return; + + socket.emit("game_move",currentGame.id,i); + }); + cvs.addEventListener("mousemove",function(ev){ + if(!currentGame||gameState!=GS_TURN)return; + var i=mouseEventToIndex(ev); + if(i==null)return; + + if(currentGame.board[i]!=0)return; + + redrawBoard(); + ctx.fillStyle=["rgba(0,0,0,0.5)","rgba(255,255,255,0.5)"][currentGame.onturn]; + ctx.beginPath(); + ctx.moveTo(boardX(i)+STONE_SIZE,boardY(i)); + ctx.arc(boardX(i),boardY(i),STONE_SIZE,0,2*Math.PI,true); + ctx.fill(); + }); + cvs.addEventListener("mouseleave",function(ev){ + redrawBoard(); + }); +} + +window.addEventListener("load",function(){ + cvs=document.getElementById("cvs"); + ctx=cvs.getContext("2d"); + initConnect(); + initCanvasListeners(); +}); +</script> +<style> +body { + font-family: sans-serif; +} +canvas { + border: 1px black solid; +} +#info { + padding: 5px; + border-radius: 8px; + border: 1px black solid; + display: inline-block; + margin-bottom: 5px; +} +#status { + font-style: italic; +} +#colour_note { + font-style: italic; +} +.invisible { + display: none; +} +.mouse-pointer { + cursor: pointer; +} +</style> +</head> +<body> +<h2>CaptureGo</h2> + +<div id="info"></div><br> +<div id="status"></div> + +<div id="cont_connect" class="invisible"> + <h3>Create a game with a friend</h3> + Select the other player to invite: <select id="other_player_select"></select><br> + Board size: <input type="number" id="board_size" value="9" style="width:60px"><br> + <input type="button" value="Create Game" onclick="doCreateGame()"> +</div> + +<div id="cont_game" class="invisible"> + <h3 id="game_header"></h3> + <div id="game_status"></div> + <canvas id="cvs"></canvas><br> + <div id="colour_note"></div> +</div> +</body> +</html> |