commit
0254556bbf
|
@ -3,9 +3,9 @@
|
||||||
* stupid IA for battle ship
|
* stupid IA for battle ship
|
||||||
* choose by random a free column
|
* choose by random a free column
|
||||||
*/
|
*/
|
||||||
|
$in=file_get_contents('php://input');
|
||||||
$grid=json_decode($_POST['grid']);
|
$params=json_decode($in, TRUE);
|
||||||
|
$grid=$params['grid'];
|
||||||
$colAvailable=array();
|
$colAvailable=array();
|
||||||
|
|
||||||
for($i=0;$i<7;$i++){
|
for($i=0;$i<7;$i++){
|
||||||
|
|
253
html/testBot.html
Normal file
253
html/testBot.html
Normal file
|
@ -0,0 +1,253 @@
|
||||||
|
<!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>Test ton bot</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{width: 100%;}
|
||||||
|
.center{text-align: center;}
|
||||||
|
aside p img{ width: 100%; max-width:342px;}
|
||||||
|
form textarea, form input, form select {width:40%;}
|
||||||
|
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 tr td{border: 1px dashed green; text-align: center; font-weight: bold;min-width:20px; height:20px;}
|
||||||
|
.winCase{background-color:red;}
|
||||||
|
.hidden{display: none;}
|
||||||
|
#logs{font-size: 70%;}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
var grid=[["","","","","","",""],
|
||||||
|
["","","","","","",""],
|
||||||
|
["","","","","","",""],
|
||||||
|
["","","","","","",""],
|
||||||
|
["","","","","","",""],
|
||||||
|
["","","","","","",""]];
|
||||||
|
var currentPlayer=1;
|
||||||
|
|
||||||
|
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";
|
||||||
|
}
|
||||||
|
|
||||||
|
//find the first line empty
|
||||||
|
var i=0;
|
||||||
|
for(i = 0; i < 6 , grid[i][col] !== ""; i++){
|
||||||
|
//nothing juste a counter
|
||||||
|
}
|
||||||
|
grid[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(grid[y][k] == ""){
|
||||||
|
line += " ";
|
||||||
|
}else{
|
||||||
|
line += grid[y][k];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (line.indexOf(searchValue) > -1){
|
||||||
|
wins(currentPlayer);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//verticaly
|
||||||
|
var line="";
|
||||||
|
for (var k=0; k < 6; k++){
|
||||||
|
if(grid[k][x] == ""){
|
||||||
|
line += " ";
|
||||||
|
}else{
|
||||||
|
line += grid[k][x];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (line.indexOf(searchValue) > -1){
|
||||||
|
wins(currentPlayer);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//diagonals
|
||||||
|
//\
|
||||||
|
|
||||||
|
for (var kx=x, var ky=y; kx < 7, ky
|
||||||
|
|
||||||
|
//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 xhr = new XMLHttpRequest();
|
||||||
|
xhr.onreadystatechange = function(){if(xhr.readyState == 4){
|
||||||
|
if(xhr.status == 200) {
|
||||||
|
var response=xhr.responseText;
|
||||||
|
var t = new RegExp('^[0-6]$');
|
||||||
|
if (t.test(response)){
|
||||||
|
playingAT(response);
|
||||||
|
}else{
|
||||||
|
alert ('la reponse du bot doit etre un digit compris entre 0 et 7, correspondant à la colonne. Voici sa réponse: "' + response + '"' );
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
alert (xhr.status);
|
||||||
|
die;
|
||||||
|
}
|
||||||
|
}};
|
||||||
|
xhr.open("POST", document.getElementById('url' + player).value, true);
|
||||||
|
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
|
||||||
|
xhr.send('game=connectFour&match_id=666-' + player + '&you=' + symbol + '&grid=' + JSON.stringify(grid) );
|
||||||
|
|
||||||
|
}else{
|
||||||
|
//wait for human response, show buttons
|
||||||
|
document.getElementById("playerButtons").setAttribute("class", "");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
function startGame(){
|
||||||
|
//empty div
|
||||||
|
document.getElementById("fightResult").innerHTML="";
|
||||||
|
//create grid
|
||||||
|
var table=createElem('table',{'class':'battleGrid', 'id': 'grid'});
|
||||||
|
for (var i=6; 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('grid').appendChild(newTr);
|
||||||
|
|
||||||
|
grid=[["","","","","","",""],
|
||||||
|
["","","","","","",""],
|
||||||
|
["","","","","","",""],
|
||||||
|
["","","","","","",""],
|
||||||
|
["","","","","","",""],
|
||||||
|
["","","","","","",""]];
|
||||||
|
play(1);
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<header>
|
||||||
|
<h1>Debug and test your connectFour AI</h1>
|
||||||
|
</header>
|
||||||
|
<section>
|
||||||
|
<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>
|
||||||
|
<td>
|
||||||
|
<input id="url1" type="text" name="player1URL" placeholder="url du bot http://localhost" value="https://botsarena.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>
|
||||||
|
<td>
|
||||||
|
<input id="url2" type="text" name="player2URL" placeholder="url du bot http://localhost" disabled value="https://botsarena.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>
|
0
src/arenas/Battleship/testBot.html
Normal file
0
src/arenas/Battleship/testBot.html
Normal file
|
@ -84,12 +84,13 @@ switch ($_POST['act']){
|
||||||
'match_id' => $_SESSION['matchId']."-".$_SESSION['currentPlayer'],
|
'match_id' => $_SESSION['matchId']."-".$_SESSION['currentPlayer'],
|
||||||
'opponent' => $opponentName,
|
'opponent' => $opponentName,
|
||||||
'you' => $you,
|
'you' => $you,
|
||||||
'grid' => json_encode( $_SESSION['map'])
|
'grid' => $_SESSION['map']
|
||||||
|
|
||||||
);
|
);
|
||||||
//send query
|
//send query
|
||||||
$anwserPlayer=get_IA_Response($botUrl,$postDatas);
|
$anwserPlayer=get_IA_Response($botUrl,$postDatas);
|
||||||
|
//for test ***************************
|
||||||
|
//echo $anwserPlayer; die;
|
||||||
//vérifier la validité de la réponse
|
//vérifier la validité de la réponse
|
||||||
if((isset($_SESSION['map'][5][$anwserPlayer])) && ($_SESSION['map'][5][$anwserPlayer] == "")){
|
if((isset($_SESSION['map'][5][$anwserPlayer])) && ($_SESSION['map'][5][$anwserPlayer] == "")){
|
||||||
//reponse conforme
|
//reponse conforme
|
||||||
|
|
|
@ -1,5 +1,9 @@
|
||||||
<?php
|
<?php
|
||||||
function get_IA_Response($iaUrl,$postParams){
|
function get_IA_Response($iaUrl,$postParams){
|
||||||
|
//send params JSON as body
|
||||||
|
|
||||||
|
$data_string = json_encode($postParams);
|
||||||
|
/*
|
||||||
$ch = curl_init();
|
$ch = curl_init();
|
||||||
curl_setopt($ch, CURLOPT_URL, $iaUrl);
|
curl_setopt($ch, CURLOPT_URL, $iaUrl);
|
||||||
curl_setopt($ch, CURLOPT_POST, true);
|
curl_setopt($ch, CURLOPT_POST, true);
|
||||||
|
@ -7,6 +11,20 @@ function get_IA_Response($iaUrl,$postParams){
|
||||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
|
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
|
||||||
$output = curl_exec($ch);
|
$output = curl_exec($ch);
|
||||||
curl_close($ch);
|
curl_close($ch);
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
$ch = curl_init($iaUrl);
|
||||||
|
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
|
||||||
|
curl_setopt($ch, CURLOPT_POSTFIELDS, $data_string);
|
||||||
|
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||||
|
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
|
||||||
|
'Content-Type: application/json',
|
||||||
|
'Content-Length: ' . strlen($data_string))
|
||||||
|
);
|
||||||
|
$output= curl_exec($ch);
|
||||||
|
curl_close($ch);
|
||||||
|
|
||||||
return htmlentities($output);
|
return htmlentities($output);
|
||||||
}
|
}
|
||||||
function get_Post_Params($botsCount){
|
function get_Post_Params($botsCount){
|
||||||
|
|
|
@ -47,6 +47,9 @@ function connectFour(bot1,bot2,xd_check, newGame){
|
||||||
var xhr = Ajx();
|
var xhr = Ajx();
|
||||||
xhr.onreadystatechange = function(){if(xhr.readyState == 4){
|
xhr.onreadystatechange = function(){if(xhr.readyState == 4){
|
||||||
if(xhr.status == 200) {
|
if(xhr.status == 200) {
|
||||||
|
//for test
|
||||||
|
// alert(xhr.responseText);
|
||||||
|
|
||||||
try{
|
try{
|
||||||
var reponse = JSON.parse(xhr.responseText);
|
var reponse = JSON.parse(xhr.responseText);
|
||||||
}catch(e){
|
}catch(e){
|
||||||
|
|
|
@ -21,25 +21,59 @@ switch ($_POST['act']){
|
||||||
'2-0' => '','2-1' => '','2-2' => '');
|
'2-0' => '','2-1' => '','2-2' => '');
|
||||||
|
|
||||||
$end=false;
|
$end=false;
|
||||||
|
|
||||||
|
//send init message to bots
|
||||||
|
$game_id = "".get_unique_id();
|
||||||
|
for($player = 0; $player < 2; $player++){
|
||||||
|
$params[$player]=array(
|
||||||
|
'game-id' => $game_id,
|
||||||
|
'action' => 'init',
|
||||||
|
'game' => 'tictactoe',
|
||||||
|
'players' => 2,
|
||||||
|
'board' => '',
|
||||||
|
'player-index' => $player
|
||||||
|
);
|
||||||
|
}
|
||||||
|
get_IA_Response($bots[$bot1]['url'],$params[0]); //don't care about result
|
||||||
|
get_IA_Response($bots[$bot2]['url'],$params[1]); //don't care about result
|
||||||
|
|
||||||
|
//"game-id":"gameid","action":"init","game":"tictactoe","players":2,"board":null,"you":null,"player-index":0}
|
||||||
|
//[0000] body> {"name":"moul-tictactoe","play":null,"error":null}
|
||||||
|
|
||||||
$playerPlayingNow=1;
|
$playerPlayingNow=1;
|
||||||
|
|
||||||
while($end==false){
|
while($end==false){
|
||||||
switch($playerPlayingNow){
|
switch($playerPlayingNow){
|
||||||
case 1:
|
case 1:
|
||||||
$playerURL=$bots[$bot1]['url'];
|
$playerURL=$bots[$bot1]['url'];
|
||||||
$playerCHAR='X';
|
$playerCHAR='X';
|
||||||
$playerName=$bots[$bot1]['name'];
|
$playerName=$bots[$bot1]['name'];
|
||||||
|
$playerIndex=0;
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
$playerURL=$bots[$bot2]['url'];
|
$playerURL=$bots[$bot2]['url'];
|
||||||
$playerCHAR='O';
|
$playerCHAR='O';
|
||||||
$playerName=$bots[$bot2]['name'];
|
$playerName=$bots[$bot2]['name'];
|
||||||
|
$playerIndex=1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
error(500,"oups");
|
error(500,"oups");
|
||||||
die;
|
die;
|
||||||
}
|
}
|
||||||
$playerResponse=get_IA_Response($playerCHAR,$playerURL,$map);
|
|
||||||
|
$paramsToSend=array(
|
||||||
|
'game-id' => $game_id,
|
||||||
|
'action' => 'play-turn',
|
||||||
|
'game' => 'tictactoe',
|
||||||
|
'players' => 2,
|
||||||
|
'board' => $map,
|
||||||
|
'you' => $playerCHAR,
|
||||||
|
'player-index' =>$playerIndex
|
||||||
|
);
|
||||||
|
|
||||||
|
$playerResponse=get_IA_Response($playerURL,$paramsToSend)['play'];
|
||||||
|
|
||||||
//tester la validité de la réponse
|
//tester la validité de la réponse
|
||||||
if((isset($map[$playerResponse])) && ($map[$playerResponse]=="")){
|
if((isset($map[$playerResponse])) && ($map[$playerResponse]=="")){
|
||||||
//reponse conforme
|
//reponse conforme
|
||||||
|
|
|
@ -1,42 +1,181 @@
|
||||||
<h1>Fonctionnement des duels de morpion</h1>
|
<h1>Fonctionnement des duels de morpion</h1>
|
||||||
<p>
|
<p>
|
||||||
Ne vous fiez pas au GIF animé de la page d'accueil du site.<br/>
|
Ne vous fiez pas au GIF animé de la page d'accueil du site.<br/>
|
||||||
Il est là pour illustrer le fonctionnement global de l'arène, mais il est faux : le tictactoe n'a besoin d'envoyer que 10 variables, de longueur maîtrisée, aux bots.<br/>
|
Il est là pour illustrer le fonctionnement global de l'arène, mais il est faux.
|
||||||
Le choix a donc été fait de les passer en paramètres GET et non POST comme indiqué sur l'animation.
|
|
||||||
</p>
|
</p>
|
||||||
<h2>Spécifications : variables GET et retour HTML</h2>
|
<h2>Communications entre l'arène et votre bot</h2>
|
||||||
<p>
|
<p>Pour communiquer, l'arène (le serveur hébergeant botsarena) fait des requetes http(s) de type POST vers les bots. Le message est dans le corps de la requête au format JSON.</p>
|
||||||
Votre programme n'a pas à gérer une partie entière de morpion, juste un tour.
|
<p>Votre bot répond par un array au format JSON.</p>
|
||||||
</p>
|
<h3>Message d'initialisation de votre partie</h3>
|
||||||
<p>
|
l'arène envoie le message suivant:
|
||||||
Le programme arbitre (cette arène) fait une requête construite de la manière suivante :
|
<pre>{"game-id":"1126","action":"init","game":"tictactoe","players":2,"board":"","player-index":0}</pre>
|
||||||
</p>
|
<p>Si on décompose le tableau pour l'expliquer:</p>
|
||||||
<pre>
|
<ul>
|
||||||
https://votreUrl/?you=O&0-0=&0-1=O&0-2=X&1-0=X&1-1=X&1-2=O&2-0=O&2-1=&2-2=X
|
<li><em>game-id</em> string identifiant la partie.</li>
|
||||||
|
<li><em>action</em> string identifiant la phase, <em>init</em> tout de suite, sera <em>play-turn</em> dans le châpitre suivant.</li>
|
||||||
|
<li><em>game</em> string identifiant le jeu. Ici, ce sera forcément tictactoe. ça peut servir si vous donnez une seule URL pour plusieurs bots.</li>
|
||||||
|
<li><em>players</em> Int indiquant le nombre de joueurs dans la partie, toujours 2 au morpion.</li>
|
||||||
|
<li><em>board</em> Vide à cette étape, voir chapitre suivant.</li>
|
||||||
|
<li><em>player-index</em> int, L'ordre de votre bot dans les tours de jeu. Le premier joueur a la valeur 0, le deuxième 1.</li>
|
||||||
|
</ul>
|
||||||
|
<p>Votre bot doit retourner le nom de votre bot format JSON:</p>
|
||||||
|
<pre>
|
||||||
|
{"name":"botName"}
|
||||||
|
</pre>
|
||||||
|
<ul>
|
||||||
|
<li><em>name</em> le nom de votre bot (actuellment non pris en compte par cette arène).</li>
|
||||||
|
</ul>
|
||||||
|
<p>L'arène ne vérifie pas actuellement cette réponse, l'étape d'init a été insérée pour assurer la compatibilité avec <a href="https://github.com/moul/bolosseum">Bolosseum</a>.
|
||||||
|
Si votre bot repond une page blanche à cette étape (action=init), ça marchera dans le cadre de botsarena.</p>
|
||||||
|
<h3>Message vous demandant de jouer (seulement un tour)</h3>
|
||||||
|
<p>L'arène vous envoie par exemple le message suivant:</p>
|
||||||
|
<pre>{"game-id":"1126","action":"play-turn","game":"tictactoe","players":2,"board":{"0-0":"","0-1":"","0-2":"","1-0":"","1-1":"","1-2":"","2-0":"","2-1":"","2-2":""},"you":"X","player-index":0}</pre>
|
||||||
|
<ul>
|
||||||
|
<li><em>game-id</em> String identifiant la partie.</li>
|
||||||
|
<li><em>action</em> String identifiant la phase, <em>play-turn</em> tout de suite, qui vous indique que vous devez jouer.</li>
|
||||||
|
<li><em>game</em> String identifiant le jeu. Ici, ce sera forcément tictactoe. ça peut servir si vous donnez une seulle URL pour plusieurs bots.</li>
|
||||||
|
<li><em>players</em> Int indiquant le nombre de joueurs dans la partie, toujours 2 au morpion</li>
|
||||||
|
<li><em>board</em> La carte je donne le détail ci dessous</li>
|
||||||
|
<li><em>you</em> String, Votre caractère dans la grille</li>
|
||||||
|
<li><em>player-index</em> Int, L'ordre de votre bot dans les tours de jeu. Le premier joueur a la valeur 0, le deuxième 1.</li>
|
||||||
|
</ul>
|
||||||
|
<h4>la map</h4>
|
||||||
|
<p>Elle est représentée par un sous-tableau. Les index correspondent aux coordonnées x-y de la case. x et y sont compris entre 0 et 2. Les valeurs peuvent être:</p>
|
||||||
|
<ul>
|
||||||
|
<li>Vide, personne n'a joué à cette case</li>
|
||||||
|
<li>"X" ou "O", le joueur ayant ce symbole a déjà joué cette case.</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<h2>Exemple de partie</h2>
|
||||||
|
<pre class="arrenaMessage">
|
||||||
|
{"game-id":"1126","action":"init","game":"tictactoe","players":2,"board":"","player-index":0}
|
||||||
</pre>
|
</pre>
|
||||||
<p>
|
<pre class="botResponse">
|
||||||
Le paramètre GET "you" vous indique quel est votre symbole dans la grille de morpion.<br/>
|
{"name":"moul-tictactoe"}
|
||||||
Classiquement : "X" ou "O"
|
</pre>
|
||||||
</p>
|
<pre class="arrenaMessage">
|
||||||
<p>
|
{"game-id":"1126","action":"init","game":"tictactoe","players":2,"board":"","player-index":1}
|
||||||
Pour chaque case de la grille de morpion, un paramètre GET correspondant à ses coordonnées ("0-0", "0-1", etc ...) vous est indiqué.<br/>
|
</pre>
|
||||||
Il peut être :
|
<pre class="botResponse">
|
||||||
</p>
|
{"name":"moul-tictactoe"}
|
||||||
<ul>
|
</pre>
|
||||||
<li>Votre symbole (ce qui signifie que vous avez déjà joué là)</li>
|
<pre class="arrenaMessage">
|
||||||
<li>Le symbole de votre adversaire. Il a déjà joué dans cette case</li>
|
{"game-id":"1126","action":"play-turn","game":"tictactoe","players":2,"board":{"0-0":"","0-1":"","0-2":"","1-0":"","1-1":"","1-2":"","2-0":"","2-1":"","2-2":""},"you":"X","player-index":0}
|
||||||
<li>Rien, la case est disponible</li>
|
</pre>
|
||||||
</ul>
|
<pre class="botResponse">
|
||||||
<p>
|
{"play":"0-1"}
|
||||||
Votre programme choisit la case sur laquelle il souhaite jouer compte tenu de la grille et retourne ses coordonnées.
|
</pre>
|
||||||
</p>
|
<pre>
|
||||||
<p>
|
Player 1 joue en 0-1 la nouvelle grille est
|
||||||
Le résultat de la requête HTTP(s) ne peut qu'être : "0-0" ou "0-1" ou "0-2" ou "1-0" etc.
|
X
|
||||||
</p>
|
</pre>
|
||||||
<p>
|
|
||||||
Un joueur (une IA) qui répond autre chose (au caractère près), ou qui répond avec les coordonnées d'une case déjà jouée, perd la partie.
|
<pre class="arrenaMessage">
|
||||||
</p>
|
{"game-id":"1126","action":"play-turn","game":"tictactoe","players":2,"board":{"0-0":"","0-1":"X","0-2":"","1-0":"","1-1":"","1-2":"","2-0":"","2-1":"","2-2":""},"you":"O","player-index":1}
|
||||||
<h2>Publier votre programme pour le tester puis le lâcher dans l'arène</h2>
|
</pre>
|
||||||
<p>
|
<pre class="botResponse">
|
||||||
Le formulaire est sur la <a href="/">page d'accueil du site</a> !
|
{"play":"1-1"}
|
||||||
</p>
|
</pre>
|
||||||
|
<pre>
|
||||||
|
Player 2 joue en 1-1 la nouvelle grille est
|
||||||
|
X
|
||||||
|
O
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<pre class="arrenaMessage">
|
||||||
|
{"game-id":"1126","action":"play-turn","game":"tictactoe","players":2,"board":{"0-0":"","0-1":"X","0-2":"","1-0":"","1-1":"O","1-2":"","2-0":"","2-1":"","2-2":""},"you":"X","player-index":0}
|
||||||
|
</pre>
|
||||||
|
<pre class="botResponse">
|
||||||
|
{"play":"0-0"}
|
||||||
|
</pre>
|
||||||
|
<pre>
|
||||||
|
Player 1 joue en 0-0 la nouvelle grille est
|
||||||
|
X X
|
||||||
|
O
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<pre class="arrenaMessage">
|
||||||
|
{"game-id":"1126","action":"play-turn","game":"tictactoe","players":2,"board":{"0-0":"X","0-1":"X","0-2":"","1-0":"","1-1":"O","1-2":"","2-0":"","2-1":"","2-2":""},"you":"O","player-index":1}
|
||||||
|
</pre>
|
||||||
|
<pre class="botResponse">
|
||||||
|
{"play":"0-2"}
|
||||||
|
</pre>
|
||||||
|
<pre>
|
||||||
|
Player 2 joue en 0-2 la nouvelle grille est
|
||||||
|
X X O
|
||||||
|
O
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<pre class="arrenaMessage">
|
||||||
|
{"game-id":"1126","action":"play-turn","game":"tictactoe","players":2,"board":{"0-0":"X","0-1":"X","0-2":"O","1-0":"","1-1":"O","1-2":"","2-0":"","2-1":"","2-2":""},"you":"X","player-index":0}
|
||||||
|
</pre>
|
||||||
|
<pre class="botResponse">
|
||||||
|
{"play":"2-0"}
|
||||||
|
</pre>
|
||||||
|
<pre>
|
||||||
|
Player 1 joue en 2-0 la nouvelle grille est
|
||||||
|
X X O
|
||||||
|
O
|
||||||
|
X
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<pre class="arrenaMessage">
|
||||||
|
{"game-id":"1126","action":"play-turn","game":"tictactoe","players":2,"board":{"0-0":"X","0-1":"X","0-2":"O","1-0":"","1-1":"O","1-2":"","2-0":"X","2-1":"","2-2":""},"you":"O","player-index":1}
|
||||||
|
</pre>
|
||||||
|
<pre class="botResponse">
|
||||||
|
{"play":"1-0"}
|
||||||
|
</pre>
|
||||||
|
<pre>
|
||||||
|
Player 2 joue en 1-0 la nouvelle grille est
|
||||||
|
X X O
|
||||||
|
O O
|
||||||
|
X
|
||||||
|
</pre>
|
||||||
|
<pre class="arrenaMessage">
|
||||||
|
{"game-id":"1126","action":"play-turn","game":"tictactoe","players":2,"board":{"0-0":"X","0-1":"X","0-2":"O","1-0":"O","1-1":"O","1-2":"","2-0":"X","2-1":"","2-2":""},"you":"X","player-index":0}
|
||||||
|
</pre>
|
||||||
|
<pre class="botResponse">
|
||||||
|
{"play":"1-2"}
|
||||||
|
</pre>
|
||||||
|
<pre>
|
||||||
|
Player 1 joue en 1-2 la nouvelle grille est
|
||||||
|
X X O
|
||||||
|
O O X
|
||||||
|
X
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<pre class="arrenaMessage">
|
||||||
|
{"game-id":"1126","action":"play-turn","game":"tictactoe","players":2,"board":{"0-0":"X","0-1":"X","0-2":"O","1-0":"O","1-1":"O","1-2":"X","2-0":"X","2-1":"","2-2":""},"you":"O","player-index":1}
|
||||||
|
</pre>
|
||||||
|
<pre class="botResponse">
|
||||||
|
{"play":"2-1"}
|
||||||
|
</pre>
|
||||||
|
<pre>
|
||||||
|
Player 2 joue en 2-1 la nouvelle grille est
|
||||||
|
X X O
|
||||||
|
O O X
|
||||||
|
X O
|
||||||
|
</pre>
|
||||||
|
<pre class="arrenaMessage">
|
||||||
|
{"game-id":"1126","action":"play-turn","game":"tictactoe","players":2,"board":{"0-0":"X","0-1":"X","0-2":"O","1-0":"O","1-1":"O","1-2":"X","2-0":"X","2-1":"O","2-2":""},"you":"X","player-index":0}
|
||||||
|
</pre>
|
||||||
|
<pre class="botResponse">
|
||||||
|
{"play":"2-2"}
|
||||||
|
</pre>
|
||||||
|
<pre>
|
||||||
|
Player 1 joue en 2-2 la nouvelle grille est
|
||||||
|
X X O
|
||||||
|
O O X
|
||||||
|
X O X
|
||||||
|
|
||||||
|
Match nul
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<h2>Outils pour développer et tester votre bot</h2>
|
||||||
|
<h3>Script à télécharger</h3>
|
||||||
|
<p>En cours de développement</p>
|
||||||
|
<h3>Bolosseum</h3>
|
||||||
|
|
||||||
|
<p>Vous trouverez des outils en ligne de commande pour tester et déboguer votre bot sur <a href="https://github.com/moul/bolosseum">le projet github Bolosseum de @moul</a></p>
|
||||||
|
|
||||||
|
<h2>Faire entrer votre bot dans cette arène</h2>
|
|
@ -16,6 +16,9 @@ function get_Post_Params($botsCount){
|
||||||
return array('bot1' => $_POST['bot1'],'bot2' => $_POST['bot2']);
|
return array('bot1' => $_POST['bot1'],'bot2' => $_POST['bot2']);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
function get_Bots_Array(){
|
function get_Bots_Array(){
|
||||||
//Recupérer la liste des Bots
|
//Recupérer la liste des Bots
|
||||||
|
@ -31,20 +34,20 @@ function get_Bots_Array(){
|
||||||
return $bots;
|
return $bots;
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
function get_IA_Response($youChar,$iaBaseUrl,$grille){
|
function get_IA_Response($iaUrl,$postParams){
|
||||||
/*transforme la grille en parametres http GET
|
//send params JSON as body
|
||||||
* et fait la requete vers $iaBaseUrl
|
|
||||||
* Retourne la réponse de l'IA
|
$data_string = json_encode($postParams);
|
||||||
*/
|
|
||||||
$paramsGrille="";
|
$ch = curl_init($iaUrl);
|
||||||
foreach($grille as $key => $case){
|
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
|
||||||
$paramsGrille.="&".$key."=".$case;
|
curl_setopt($ch, CURLOPT_POSTFIELDS, $data_string);
|
||||||
}
|
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||||
$url=$iaBaseUrl."?you=".$youChar.$paramsGrille;
|
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
|
||||||
$ch = curl_init();
|
'Content-Type: application/json',
|
||||||
curl_setopt($ch, CURLOPT_URL, $url);
|
'Content-Length: ' . strlen($data_string))
|
||||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
|
);
|
||||||
$output = curl_exec($ch);
|
$output= curl_exec($ch);
|
||||||
curl_close($ch);
|
curl_close($ch);
|
||||||
return htmlentities($output);
|
return json_decode($output,TRUE);
|
||||||
}
|
}
|
|
@ -3,3 +3,7 @@ td {min-width: 10px; height: 10px;}
|
||||||
.cellj2{border-top:1px dotted black;}
|
.cellj2{border-top:1px dotted black;}
|
||||||
.celli0{border-right:1px dotted black;}
|
.celli0{border-right:1px dotted black;}
|
||||||
.celli2{border-left:1px dotted black;}
|
.celli2{border-left:1px dotted black;}
|
||||||
|
.arrenaMessage{color: green;}
|
||||||
|
.arrenaMessage::before{content: "arena message:"; color: grey; font-size: 70%; test-transform:italic;}
|
||||||
|
.botResponse{color: red;}
|
||||||
|
.botResponse::before{content: "bot response:";color: grey; font-size: 70%; test-transform:italic;}
|
0
src/arenas/tictactoe/testBot.html
Normal file
0
src/arenas/tictactoe/testBot.html
Normal file
Loading…
Reference in New Issue
Block a user