You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

arena.html 9.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279
  1. <!DOCTYPE html>
  2. <html lang="fr">
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta name="viewport" content="width=device-width, initial-scale=1">
  6. <meta http-equiv="X-UA-Compatible" content="IE=edge">
  7. <meta name="author" content="Gnieark" />
  8. <title>Test ton bot</title>
  9. <style type="text/css">
  10. body{width:100%; font-size:100%; line-height:140%; word-wrap:break-word; text-rendering:optimizelegibility;
  11. margin:0 auto; font-family : "lucida grande", "gill sans", arial, sans-serif; left:auto;}
  12. header{ background-color:#A60800; width: 100%; overflow: hidden; height: auto;}
  13. header h1{display: block; font-size:300%; color:#FFF;float: left; margin-left: 5%;}
  14. header nav{display: block; width: 45%; color:#FFF; float: right;}
  15. #menus{ margin-left: 50px; width:100%; display: table;}
  16. #menus a{color: #fff; display: table-cell; text-decoration: none;text-align: center;border-radius: 15px 15px 0px 0px;}
  17. #menus a.selected{color:#202020; background-color:#fff;}
  18. footer{height: 70px; display: block; color: #343638; font-size: 11pt; line-height: 15pt; margin: 0; padding-top: 15pt;
  19. overflow-x: hidden; box-sizing: border-box; background-image: -webkit-linear-gradient(top, #f5f5f5,#e9e9e9);
  20. border-top: 1px solid #bebebe; color: #999; font-size: 12px; line-height: 1.5em; text-align: center;width: 100%;}
  21. footer a {margin:0px 15px 0px 15px; color: #666;text-decoration: none; font-weight: normal;}
  22. #languages{float: right; text-align: right;}
  23. section{margin: 0 auto; width: 90%;}
  24. article{float: right; width:70%;}
  25. aside{float:left; width: 28%; border-right: 1px dashed green;}
  26. aside table {width: 90%;}
  27. aside table tr td{width: 33%;}
  28. aside table tr td input, aside table tr td select {width: 100%;}
  29. .center{text-align: center;}
  30. aside p img{ width: 100%; max-width:342px;}
  31. form textarea, form input, form select {width:40%;}
  32. form input[type=checkbox], form input[type=radio] { width:15px; }
  33. form label {float:left; width:40%; margin-right:0.5em;
  34. padding-top:0.2em; text-align:right;}
  35. pre{ font-style: normal;font-size: 16px; margin-left: 32px;font-family: Consolas, "Times New Roman", Verdana;
  36. border-left: 4px solid #CCC; padding-left: 8px;}
  37. .battleGrid{padding-left:10px; border-collapse:collapse; margin: 20px 20px 20px 20px;}
  38. .battleGrid tr{}
  39. .battleGrid td{border: 1px dashed green; text-align: center; font-weight: bold;width:2em; height: 2em; vertical-align: middle;}
  40. .winCase{background-color:red;}
  41. .hidden{display: none;}
  42. #logs{font-size: 70%;}
  43. </style>
  44. <script>
  45. var grid={"0-0":"","0-1":"","0-2":"","1-0":"","1-1":"","1-2":"","2-0":"","2-1":"","2-2":""};
  46. var currentPlayer=0;
  47. var gameId=0;
  48. function createElem(type,attributes){
  49. var elem=document.createElement(type);
  50. for (var i in attributes)
  51. {elem.setAttribute(i,attributes[i]);}
  52. return elem;
  53. }
  54. function addLog(message){
  55. var p=createElem('p');
  56. p.innerHTML=message;
  57. document.getElementById('logs').appendChild(p);
  58. }
  59. function changePlayerType(player,newValue){
  60. if(newValue == "bot"){
  61. document.getElementById('url' + player).disabled="";
  62. }else{
  63. document.getElementById('url' + player).disabled="disabled";
  64. }
  65. }
  66. function playingAT(cellKey){
  67. //hide buttons
  68. var inputs = document.getElementById('grid').getElementsByTagName('input');
  69. for (var index = 0; index < inputs.length; index++) {
  70. inputs[index].setAttribute("class","hidden");
  71. }
  72. if(currentPlayer == 1){
  73. var symbol= "X";
  74. }else{
  75. var symbol="O";
  76. }
  77. //test if cell is empty
  78. if(grid[cellKey] !== ""){
  79. addLog("Player " + currentPlayer + "tente de jouer sur " + cellKey +". Cette case est déjà prise, il perd");
  80. }
  81. //placer le caractere
  82. if(currentPlayer == 1){
  83. var symbol= "X";
  84. }else{
  85. var symbol="O";
  86. }
  87. grid[cellKey]=symbol;
  88. document.getElementById(cellKey).innerHTML = symbol;
  89. addLog("Player " + currentPlayer + " joue " + cellKey);
  90. //does he win?
  91. //tester si trois caracteres allignés
  92. if(
  93. ((grid['0-0'] == grid['0-1']) && (grid['0-1'] == grid['0-2']) && (grid['0-2']!==""))
  94. || ((grid['1-0'] == grid['1-1']) && (grid['1-1'] == grid['1-2']) && (grid['1-2']!==""))
  95. || ((grid['2-0'] == grid['2-1']) && (grid['2-1'] == grid['2-2']) && (grid['2-2']!==""))
  96. || ((grid['0-0'] == grid['1-0']) && (grid['1-0'] == grid['2-0']) && (grid['2-0']!==""))
  97. || ((grid['0-1'] == grid['1-1']) && (grid['1-1'] == grid['2-1']) && (grid['2-1']!==""))
  98. || ((grid['0-2'] == grid['1-2']) && (grid['1-2'] == grid['2-2']) && (grid['2-2']!==""))
  99. || ((grid['0-0'] == grid['1-1']) && (grid['1-1'] == grid['2-2']) && (grid['2-2']!==""))
  100. || ((grid['0-2'] == grid['1-1']) && (grid['1-1'] == grid['2-0']) && (grid['2-0']!==""))
  101. ){
  102. addLog("Player " + currentPlayer + "gagne la partie");
  103. return;
  104. }
  105. //change player
  106. if(currentPlayer == 1){
  107. play(2);
  108. }else{
  109. play(1);
  110. }
  111. }
  112. function play(player){
  113. currentPlayer=player;
  114. if(document.getElementById("player" + player + "Type").value == "bot"){
  115. //call bot url
  116. if(currentPlayer == 1){
  117. var symbol= "X";
  118. }else{
  119. var symbol="O";
  120. }
  121. var arrToSend= {
  122. "game-id": "" + gameId,
  123. "action" : "play-turn",
  124. "game" : "tictactoe",
  125. "players" : 2,
  126. "board" : grid,
  127. "you" : symbol,
  128. "player-index" : player-1
  129. };
  130. var stringToSend = JSON.stringify(arrToSend);
  131. var xhr = new XMLHttpRequest();
  132. xhr.onreadystatechange = function(){if(xhr.readyState == 4){
  133. if(xhr.status == 200) {
  134. addLog('message send to bot ' + player + ':' + stringToSend);
  135. addLog('his awnser is: ' + xhr.responseText);
  136. try{
  137. var reponse = JSON.parse(xhr.responseText);
  138. var cellTarget= reponse['play'];
  139. }catch(e){
  140. addLog('player ' + player + ' a fait une réponse non conforme aux specs: ' + xhr.responseText);
  141. return;
  142. }
  143. //test format of response
  144. var reg = /^[0-2]-[0-2]$/;
  145. if (!reg.test(cellTarget)){
  146. addLog('player ' + player + ' a fait une réponse non conforme: ' + xhr.responseText);
  147. return;
  148. }
  149. playingAT(cellTarget);
  150. }else{
  151. addLog('player ' + player + ' n est pas joignable ' + xhr.status);
  152. return;
  153. }
  154. }};
  155. xhr.open("POST", document.getElementById('url' + player).value, true);
  156. xhr.setRequestHeader("Content-Type", "application/json");
  157. xhr.send(stringToSend );
  158. }else{
  159. //wait for human response, show buttons on empty cases
  160. for (var key in grid){
  161. if(grid[key] == ""){
  162. document.getElementById('button' + key).setAttribute("class", "");
  163. }
  164. }
  165. }
  166. }
  167. function startGame(){
  168. //empty div
  169. while (document.getElementById("fightResult").firstChild) {
  170. document.getElementById("fightResult").removeChild(document.getElementById("fightResult").firstChild);
  171. }
  172. //create grid
  173. var table=createElem('table',{'class':'battleGrid', 'id': 'grid'});
  174. for (var i=0; i < 3 ; i++){
  175. var tr=createElem('tr');
  176. for (var j=0;j<3; j++){
  177. var td=createElem('td',{'id': j + '-' + i});
  178. var playerButton=createElem('input',{
  179. 'type': 'button',
  180. 'id':'button' + j + '-' + i,
  181. 'onclick':"playingAT('" + j + '-' + i + "');",'value':'-',
  182. 'class': 'hidden'}
  183. );
  184. td.appendChild(playerButton);
  185. tr.appendChild (td);
  186. }
  187. table.appendChild(tr);
  188. }
  189. document.getElementById('fightResult').appendChild(table);
  190. var divLogs=createElem("div",{"id":"logs"});
  191. document.getElementById('fightResult').appendChild(divLogs);
  192. //init vars
  193. grid={"0-0":"","0-1":"","0-2":"","1-0":"","1-1":"","1-2":"","2-0":"","2-1":"","2-2":""};
  194. gameId=Math.floor((Math.random() * 10000) + 1);
  195. //envoyer les requetes d'init aux bots
  196. for (var p = 1; p < 3 ; p++){
  197. if(document.getElementById("player" + p + "Type").value == "bot"){
  198. var xhr = new XMLHttpRequest();
  199. xhr.open("POST", document.getElementById('url' + p).value, false);
  200. xhr.setRequestHeader("Content-Type", "application/json");
  201. xhr.send('{"game-id":"1126","action":"init","game":"tictactoe","players":2,"board":{},"player-index":' + (p - 1) +'}');
  202. if(xhr.status == 200) {
  203. addLog('Message d\'init envoyé au bot player ' + p );
  204. }else{
  205. addLog('player ' + p + ' n est pas joignable ' + xhr.status);
  206. return;
  207. }
  208. }
  209. }
  210. play(1);
  211. }
  212. </script>
  213. </head>
  214. <body>
  215. <header>
  216. <h1>Debug and test your tictactoe AI</h1>
  217. </header>
  218. <section>
  219. <aside>
  220. <h2>Configure the test</h2>
  221. <table>
  222. <tr>
  223. <td>Player 1</td>
  224. <td><select id="player1Type" name="player1Type" onchange="changePlayerType(1,this.value);">
  225. <option value="bot">bot</option>
  226. <option value="human">human</option>
  227. </select>
  228. </td>
  229. </tr>
  230. <tr>
  231. <td colspan="2">
  232. <input id="url1" type="text" name="player1URL" placeholder="url du bot http://localhost" value="https://ias.tinad.fr/stupidIATictactoe.php"/>
  233. </td>
  234. </tr>
  235. <tr>
  236. <td>Player 2</td>
  237. <td>
  238. <select id="player2Type" name="player2Type" onchange="changePlayerType(2,this.value);">
  239. <option value="human">human</option>
  240. <option value="bot">bot</option>
  241. </select>
  242. </td>
  243. </tr>
  244. <tr>
  245. <td colspan="2">
  246. <input id="url2" type="text" name="player2URL" placeholder="url du bot http://localhost" disabled value="https://ias.tinad.fr/stupidIATictactoe.php"/>
  247. </td>
  248. </tr>
  249. </table>
  250. <p><input type="button" onclick="startGame()" value="Fight"/></p>
  251. </aside>
  252. <article id="fightResult">
  253. </article>
  254. </section>
  255. <footer>
  256. <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>
  257. </footer>
  258. </body>
  259. </html>