<!DOCTYPE html>
<html lang="fr">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="author" content="Gnieark" />
    <title>ConnectFour's Ludus</title>
      <style type="text/css">
body{width:100%; font-size:100%; line-height:140%; word-wrap:break-word; text-rendering:optimizelegibility;
  margin:0 auto; font-family : "lucida grande", "gill sans", arial, sans-serif; left:auto;}
header{ background-color:#A60800; width: 100%; overflow: hidden; height: auto;}
header h1{display: block; font-size:300%; color:#FFF;float: left; margin-left: 5%;}
header nav{display: block; width: 45%; color:#FFF; float: right;}
#menus{ margin-left: 50px; width:100%; display: table;}
#menus a{color: #fff; display: table-cell; text-decoration: none;text-align: center;border-radius: 15px 15px 0px 0px;}
#menus a.selected{color:#202020; background-color:#fff;}
footer{height: 70px; display: block; color: #343638; font-size: 11pt; line-height: 15pt; margin: 0; padding-top: 15pt;
    overflow-x: hidden;    box-sizing: border-box; background-image: -webkit-linear-gradient(top, #f5f5f5,#e9e9e9);
    border-top: 1px solid #bebebe; color: #999; font-size: 12px; line-height: 1.5em; text-align: center;width: 100%;}
footer a {margin:0px 15px 0px 15px; color: #666;text-decoration: none; font-weight: normal;}
#languages{float: right; text-align: right;}
section{margin: 0 auto; width: 90%;}
article{float: right; width:70%;}
aside{float:left; width: 28%; border-right: 1px dashed green;}
aside table {width: 90%;}
aside table tr td{width: 33%;}
aside table tr td input, aside table tr td select {width: 100%;}
.center{text-align: center;}
aside p img{ width: 100%; max-width:342px;} 
form textarea, form input, form select {width:100%;}
form input[type=checkbox], form input[type=radio] {  width:15px; }
form label {float:left; width:40%; margin-right:0.5em;
  padding-top:0.2em; text-align:right;}
pre{ font-style: normal;font-size: 16px; margin-left: 32px;font-family: Consolas, "Times New Roman", Verdana;
  border-left: 4px solid #CCC; padding-left: 8px;}
  .battleGrid{display:table-cell; padding-left:10px; border-collapse:collapse; margin: 20px 20px 20px 20px;}
.battleGrid tr{}
.battleGrid td{border: 1px dashed green; text-align: center; font-weight: bold;width:2em; height: 2em; vertical-align: middle;}
.winCase{background-color:red;}
.hidden{display: none;}
#logs{font-size: 70%;}
</style>

<script>
var board=[["","","","","","",""],
   ["","","","","","",""],
   ["","","","","","",""],
   ["","","","","","",""],
   ["","","","","","",""],
   ["","","","","","",""]];
var currentPlayer=1;
var gameId="0";

function wins(player){
    addLog('player ' + player + ' wins'); 
}
function createElem(type,attributes){
    var elem=document.createElement(type);
    for (var i in attributes)
    {elem.setAttribute(i,attributes[i]);}
    return elem;
}
function addLog(message){
  var p=createElem('p');
  p.innerHTML=message;
  document.getElementById('logs').appendChild(p);
}
function changePlayerType(player,newValue){
  if(newValue == "bot"){
    document.getElementById('url' + player).disabled="";
  }else{
     document.getElementById('url' + player).disabled="disabled";
  }
}
function playingAT(col){
    //hide buttons
     document.getElementById("playerButtons").setAttribute("class", "hidden");
     
    if(currentPlayer == 1){
      var symbol= "X";
    }else{
      var symbol="O";
    }
    
    if(board[5][col]!== ""){
      addLog('Player ' + currentPlayer + ', symbol ' + symbol + ' wants to play on column  ' + col + ' but that column is already full. He loses.');
      return;
    }
    
    //find the first line empty
    var i=0;
    for(i = 0; i < 6 , board[i][col] !== ""; i++){
      //nothing juste a counter
    }
    board[i][col]=symbol;
    document.getElementById('td' + col + '_' + i).innerHTML = symbol;
    addLog('player ' + currentPlayer + ', symbol ' + symbol + ' played col ' + col); 
    
    //does he win?
    var x=col;
    var y=i;
    var searchValue="";
    for (var k=0; k < 4; k++){
      searchValue +=symbol;
    }
    
    //horizontaly
    var line="";
    for (var k=0; k < 7; k++){
      if(board[y][k] == ""){
	line += " ";
      }else{
	line += board[y][k];
      }
    }
    if (line.indexOf(searchValue) > -1){
      wins(currentPlayer);
      return;
    }
    
    //verticaly
    var line="";
    for (var k=0; k < 6; k++){
      if(board[k][x] == ""){
	line += " ";
      }else{
	line += board[k][x];
      }
    }
    if (line.indexOf(searchValue) > -1){
      wins(currentPlayer);
      return;
    }
    
    //diagonal \
    /*
    * diagonal is an affin function:
    * y=-x+b
    */
    //find b
    var b = parseInt(y + x);
    if (b < 6){
        //first point of the diagonal has x=0;
        var kx = 0;
        var ky = b; //:aga: 
    }else{
        //first point of the diagonal has y=5
        var kx = b - 5;
        var ky = 5;
    }
    var line="";
    var lx , ly;
    for (lx = kx, ly = ky; (lx < 7) && (ly > -1); lx++ , ly-- ){
        if( board[ly][lx] == ""){
            line += " ";
        }else{
            line += board[ly][lx];
        }
    }
    
    if (line.indexOf(searchValue) > -1){
      wins(currentPlayer);
      return;
    }
    //diagonal / affin function like y=x+b
    b = parseInt(y - x);
    if( b > -1){
        //first point has x=0
        kx = 0;
        ky = b

    }else{
        //first point has y=0
        ky = 0;
        kx = -b;
    }
    
    var line="";
    var lx , ly;
    for (lx = kx , ly = ky ; (lx < 7) && (ly < 6) ; lx++ , ly++){
       if( board[ly][lx] == ""){
            line += " ";
        }else{
            line += board[ly][lx];
        }   
    }
    
    if (line.indexOf(searchValue) > -1){
      wins(currentPlayer);
      return;
    }
    
    //if it was the last cell
    var full=true;
    for (var i = 0; i < 7; i ++){
      if( board[5][i] == "" ){
	full = false;
      }
    }
    if (full){
      addLog('match nul');
      return;
    }
    
    //change player
    if(currentPlayer == 1){
        play(2);
    }else{
        play(1);
    } 
}
function play(player){
  currentPlayer=player;  
  if(document.getElementById("player" + player + "Type").value == "bot"){
    //call bot url
    if(currentPlayer == 1){
        var symbol= "X";
    }else{
        var symbol="O";
    }
    var arrToSend= {
        "game-id": "" + gameId,
        "action"        : "play-turn",
        "game"          : "connectFour",
        "players"       : 2,
        "board"         : board,
        "you"           : symbol,
        "player-index"  : player-1
    };
    
    var xhr = new XMLHttpRequest(); 
    xhr.open("POST", document.getElementById('url' + player).value,  false);
    xhr.setRequestHeader("Content-Type", "application/json");
    xhr.send(JSON.stringify(arrToSend) );
    addLog('Message send to player ' + player + ': ' +JSON.stringify(arrToSend) );
    if(xhr.status  == 200) {
        try{
            var reponse = JSON.parse(xhr.responseText);
            var colTarget= reponse['play'];
        }catch(e){
            addLog('player ' + player + ' made a non confom response: ' + xhr.responseText);
            return;
        }
        var t = new RegExp('^[0-6]$');
        if (t.test(colTarget)){
	    addLog('His rsponse is:' +  xhr.responseText); 
            playingAT(colTarget);
        }else{
            addLog ('bot response must be a digit betwin 0 and 7, witch indicate the conumn number where he wants play. His response his: "' + colTarget + '"' );
        }
    }else{	
            alert ('Bot ' + player + ' replied with an error code: ' + xhr.status + ' ' + xhr.responseText);
            addLog('Bot ' + player + ' replied with an error code: ' + xhr.status + ' ' + xhr.responseText);
            return;
    }
  }else{
    //wait for human response, show buttons
    document.getElementById("playerButtons").setAttribute("class", "");
  }

}
function startGame(){
  //empty div
  while (document.getElementById("fightResult").firstChild) {
    document.getElementById("fightResult").removeChild(document.getElementById("fightResult").firstChild);
  }
  //create board
  var table=createElem('table',{'class':'battleGrid', 'id': 'board'});
  for (var i=5; i > -1; i--){
      var tr=createElem('tr');
      for (var j=0;j<7; j++){
	  var td=createElem('td',{'id': 'td' + j + '_' + i});
	  tr.appendChild (td);
      }
      
      table.appendChild(tr);
  }
  document.getElementById('fightResult').appendChild(table);
  var divLogs=createElem("div",{"id":"logs"});
  document.getElementById('fightResult').appendChild(divLogs); 
    var newTr=createElem('tr',{'id':'playerButtons','class':'hidden'});
    for(var i = 0; i < 7; i++){   
        var newTd=createElem('td');
        var button=createElem('input',{'type':'button','value': i, 'onclick': "playingAT('" + i + "');"});
        newTd.appendChild(button);
        newTr.appendChild(newTd);
    }
    
    document.getElementById('board').appendChild(newTr);
    
    board=[["","","","","","",""],
      ["","","","","","",""],
      ["","","","","","",""],
      ["","","","","","",""],
      ["","","","","","",""],
      ["","","","","","",""]];
    gameId=Math.floor((Math.random() * 10000) + 1); 
    //send init messages
    for (var p = 1; p < 3 ; p++){
    
      if(document.getElementById("player" + p + "Type").value == "bot"){
	  var xhr = new XMLHttpRequest(); 
	  xhr.open("POST", document.getElementById('url' + p).value,  false);
	  xhr.setRequestHeader("Content-Type", "application/json");
	  xhr.send(' {"game-id":"' + gameId + '","action":"init","game":"connectFour","players":2,"board":"","player-index":' + (p - 1) +'}');
	  if(xhr.status  == 200) {
	    addLog('Message d\'init envoyé au bot player ' + p + ' {"game-id":"' + gameId + '","action":"init","game":"connectFour","players":2,"board":"","player-index":' + (p - 1) +'} <br/> il a répondu ' +  xhr.responseText );
	    }else{		    
	      addLog('player ' + p + ' n est pas joignable ' + xhr.status);
	      return;
	  } 
	 }
    }
    play(1);
}
</script>
</head>
<body>
<header>
<h1>ConnectFour's Ludus</h1>
</header>
  <section>
    <p>Here you can test and fix your bot, against himself, against human or against any other bot if you know the URL.
   <br/>No scoring here, it's a Ludus (gladiators training center).</p>
 
    <aside>
    <h2>Configure the test</h2>
    <table>
    <tr>
	<td>Player 1</td>
	<td><select id="player1Type" name="player1Type" onchange="changePlayerType(1,this.value);">
	      <option value="bot">bot</option>
	      <option value="human">human</option>
	    </select>
	</td>

    </tr>
    <tr>
    	<td colspan="2">
	    <input id="url1" type="text" name="player1URL" placeholder="url du bot http://localhost" value="https://ias.tinad.fr/StupidIAconnectFour.php"/>
	 </td>
    </tr>
    
    
    <tr>
      <td>Player 2</td>
      <td>
	<select id="player2Type" name="player2Type" onchange="changePlayerType(2,this.value);">
	    <option value="human">human</option>
	    <option value="bot">bot</option>
	</select>
      </td>
    </tr>
    <tr>
          <td colspan="2">
	<input id="url2" type="text" name="player2URL" placeholder="url du bot http://localhost" disabled value="https://ias.tinad.fr/StupidIAconnectFour.php"/>
      </td>
    </tr>
    
    </table>
    <p><input type="button" onclick="startGame()" value="Fight"/></p>
    </aside>
    <article id="fightResult">
    </article>
  </section>
  <footer>
    <a href="/p/About">About</a><a href="https://github.com/gnieark/botsArena">Bots'Arena source code</a><a href="/p/legals">Mentions légales</a>
  </footer>
</body>
</html>