Merge pull request #64 from gnieark/dev
Connect Four, New API full JSON
This commit is contained in:
commit
75e3ea1e46
|
@ -1,221 +0,0 @@
|
|||
<?php
|
||||
function is_it_possible_to_place_ships_on_grid($gridWidth,$gridHeight,$nbShipsSize1,$nbShipsSize2,$nbShipsSize3,$nbShipsSize4,$nbShipsSize5,$nbShipsSize6){
|
||||
//return false or true
|
||||
//not a perfect solution
|
||||
$shipsArea=$nbShipsSize1 + 2 * $nbShipsSize2 + 3 * $nbShipsSize3 + 4 * $nbShipsSize4 + 5 * $nbShipsSize5 + 6 * $nbShipsSize6;
|
||||
if( $shipsArea > $gridHeight * $gridWidth / 2){
|
||||
return false;
|
||||
}
|
||||
//longest ship
|
||||
for($i=6; $i > 0; $i--){
|
||||
$var='nbShipsSize'.$i;
|
||||
if($$var > 0){
|
||||
$longestShip=$$var;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if( (!isset($longestShip))
|
||||
OR(($longestShip > $gridWidth) && ($longestShip > $gridHeight))
|
||||
){
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
function place_ship_on_map($x1,$y1,$x2,$y2,$map){
|
||||
if ((($x1 <> $x2) && ($y1 <> $y2))
|
||||
OR (!isset($map[$y1][$x1]))
|
||||
OR (!isset($map[$y2][$x2]))){
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
if($x1 == $x2){
|
||||
//horizontal ship
|
||||
if($y1 <= $y2 ){
|
||||
$start=$y1;
|
||||
$end=$y2;
|
||||
}else{
|
||||
$start=$y2;
|
||||
$end=$y1;
|
||||
}
|
||||
for($i = $start; $i <= $end; $i++){
|
||||
if($map[$i][$x1]==0){
|
||||
$map[$i][$x1]=1;
|
||||
}else{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return $map;
|
||||
}
|
||||
if($y1 == $y2){
|
||||
//vertical ship
|
||||
if( $x1 <= $x2){
|
||||
$start=$x1;
|
||||
$end=$x2;
|
||||
}else{
|
||||
$start=$x2;
|
||||
$end=$x1;
|
||||
}
|
||||
for( $i = $start; $i <= $end; $i++){
|
||||
if( $map[$y1][$i] == 0){
|
||||
$map[$y1][$i]=1;
|
||||
}else{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return $map;
|
||||
}
|
||||
}
|
||||
|
||||
switch($_POST['act']){
|
||||
case "init":
|
||||
file_put_contents(__DIR__."/log.txt",print_r($_POST,true));
|
||||
$wantedVars=array(
|
||||
'match_id' => false, //false-> string ; true -> integer
|
||||
'opponent' => false,
|
||||
'width' => true,
|
||||
'height' => true,
|
||||
'ship1' => true,
|
||||
'ship2' => true,
|
||||
'ship3' => true,
|
||||
'ship4' => true,
|
||||
'ship5' => true,
|
||||
'ship6' => true
|
||||
);
|
||||
foreach($wantedVars as $key => $shouldBeInteger){
|
||||
if(($shouldBeInteger) && (!is_numeric($_POST[$key]))){
|
||||
echo "var is not numeric"; die;
|
||||
}
|
||||
$$key=$_POST[$key];
|
||||
}
|
||||
if(!preg_match('/^[0-9]+-(1|2)$/',$match_id)){
|
||||
echo "parametre incorrect"; die;
|
||||
}
|
||||
|
||||
if(!is_it_possible_to_place_ships_on_grid($width,$height,$ship1,$ship2,$ship3,$ship4,$ship5,$ship6)){
|
||||
echo "I don't want play this game";
|
||||
die;
|
||||
}
|
||||
|
||||
a:
|
||||
$map=array();
|
||||
//construire une grille
|
||||
for($i=0; $i < $width; $i++){
|
||||
for($j=0; $j < $height; $j++){
|
||||
$map[$j][$i]=0;
|
||||
}
|
||||
}
|
||||
|
||||
$shipsCoords=array();
|
||||
|
||||
//pour toutes les tailles de bateau
|
||||
for($shipWidth = 6; $shipWidth > 0; $shipWidth--){
|
||||
//nombre de bateau à placer de cette taille
|
||||
$dynVar='ship'.$shipWidth;
|
||||
$shipCount=$$dynVar; // #trollface
|
||||
for( $sh = 0; $sh < $shipCount; $sh++){ //loop for all boats witch size is $shipWidth
|
||||
//find free cases
|
||||
$freeCases=array();
|
||||
for($y=0; $y < $height; $y++){
|
||||
for($x=0; $x < $width; $x++){
|
||||
if($map[$y][$x] == 0){
|
||||
$directions=array();
|
||||
//test top
|
||||
$top=true;
|
||||
for($i = $y; $i > $y - $shipWidth; $i--){
|
||||
if((!isset($map[$i][$x])) OR ($map[$i][$x]==1)){
|
||||
$top=false;
|
||||
$break;
|
||||
}
|
||||
}
|
||||
if($top){
|
||||
$directions[]='top';
|
||||
}
|
||||
//test Bottom
|
||||
$bottom=true;
|
||||
for($i = $y; $i < $y + $shipWidth; $i++){
|
||||
if(((!isset($map[$i][$x])) OR $map[$i][$x]==1)){
|
||||
$bottom=false;
|
||||
$break;
|
||||
}
|
||||
}
|
||||
if($bottom){
|
||||
$directions[]='bottom';
|
||||
}
|
||||
//test left
|
||||
$left=true;
|
||||
for($i = $x; $i > $x - $shipWidth; $i--){
|
||||
if((!isset($map[$y][$i])) OR ($map[$y][$i]==1)){
|
||||
$left=false;
|
||||
$break;
|
||||
}
|
||||
}
|
||||
if($left){
|
||||
$directions[]='left';
|
||||
}
|
||||
//test right
|
||||
$right=true;
|
||||
for($i = $x; $i < $x + $shipWidth; $i++){
|
||||
if((!isset($map[$y][$i])) OR ($map[$y][$i]==1)){
|
||||
$right=false;
|
||||
$break;
|
||||
}
|
||||
}
|
||||
if($right){
|
||||
$directions[]='right';
|
||||
}
|
||||
|
||||
if(count($directions)>0){
|
||||
$freeCases[]=array($x,$y,$directions);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(count($freeCases) == 0){
|
||||
//can't place the ship
|
||||
goto a; //#facepalm
|
||||
}
|
||||
shuffle($freeCases); //choose start case for this ship
|
||||
shuffle($freeCases[0][2]); //choose random direction
|
||||
$x=$freeCases[0][0];
|
||||
$y=$freeCases[0][1];
|
||||
switch($freeCases[0][2][0]){
|
||||
case 'top':
|
||||
$shipsCoords[]=$x.",".$y."-".$x.",".($y - $shipWidth + 1);
|
||||
$map= place_ship_on_map($x,$y,$x,$y - $shipWidth + 1,$map);
|
||||
break;
|
||||
case 'bottom':
|
||||
$shipsCoords[]=$x.",".$y."-".$x.",".($y + $shipWidth - 1);
|
||||
$map= place_ship_on_map($x,$y,$x,$y + $shipWidth -1 ,$map);
|
||||
break;
|
||||
case 'left':
|
||||
$shipsCoords[]=$x.",".$y."-".($x - $shipWidth + 1).",".$y;
|
||||
$map= place_ship_on_map($x,$y,$x - $shipWidth + 1 ,$y,$map);
|
||||
break;
|
||||
case 'right':
|
||||
$shipsCoords[]=$x.",".$y."-".($x + $shipWidth - 1 ).",".$y;
|
||||
$map= place_ship_on_map($x,$y,$x + $shipWidth -1 ,$y,$map);
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
echo json_encode($shipsCoords);
|
||||
file_put_contents(__DIR__."/log.txt",json_encode($shipsCoords),FILE_APPEND);
|
||||
break;
|
||||
case "fight":
|
||||
//for debog arena
|
||||
file_put_contents(__DIR__."/log.txt",print_r($_POST,true),FILE_APPEND);
|
||||
|
||||
echo rand(0,$_POST['width'] -1).",".rand(0,$_POST['height'] -1);
|
||||
|
||||
|
||||
die;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
||||
}
|
|
@ -1,18 +0,0 @@
|
|||
<?php
|
||||
/*
|
||||
* stupid IA for battle ship
|
||||
* choose by random a free column
|
||||
*/
|
||||
$in=file_get_contents('php://input');
|
||||
$params=json_decode($in, TRUE);
|
||||
$grid=$params['grid'];
|
||||
$colAvailable=array();
|
||||
|
||||
for($i=0;$i<7;$i++){
|
||||
if($grid[5][$i] == ""){
|
||||
$colAvailable[]=$i;
|
||||
}
|
||||
}
|
||||
shuffle($colAvailable);
|
||||
echo $colAvailable[0];
|
||||
die;
|
|
@ -36,21 +36,25 @@ pre{ font-style: normal;font-size: 16px; margin-left: 32px;font-family: Consolas
|
|||
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;}
|
||||
.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 grid=[["","","","","","",""],
|
||||
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)
|
||||
|
@ -81,10 +85,10 @@ function playingAT(col){
|
|||
|
||||
//find the first line empty
|
||||
var i=0;
|
||||
for(i = 0; i < 6 , grid[i][col] !== ""; i++){
|
||||
for(i = 0; i < 6 , board[i][col] !== ""; i++){
|
||||
//nothing juste a counter
|
||||
}
|
||||
grid[i][col]=symbol;
|
||||
board[i][col]=symbol;
|
||||
document.getElementById('td' + col + '_' + i).innerHTML = symbol;
|
||||
addLog('player ' + currentPlayer + ', symbol ' + symbol + ' played col ' + col);
|
||||
|
||||
|
@ -92,17 +96,17 @@ function playingAT(col){
|
|||
var x=col;
|
||||
var y=i;
|
||||
var searchValue="";
|
||||
for var k=0; k < 4; k++){
|
||||
for (var k=0; k < 4; k++){
|
||||
searchValue +=symbol;
|
||||
}
|
||||
|
||||
//horizontaly
|
||||
var line="";
|
||||
for (var k=0; k < 7; k++){
|
||||
if(grid[y][k] == ""){
|
||||
if(board[y][k] == ""){
|
||||
line += " ";
|
||||
}else{
|
||||
line += grid[y][k];
|
||||
line += board[y][k];
|
||||
}
|
||||
}
|
||||
if (line.indexOf(searchValue) > -1){
|
||||
|
@ -113,10 +117,10 @@ function playingAT(col){
|
|||
//verticaly
|
||||
var line="";
|
||||
for (var k=0; k < 6; k++){
|
||||
if(grid[k][x] == ""){
|
||||
if(board[k][x] == ""){
|
||||
line += " ";
|
||||
}else{
|
||||
line += grid[k][x];
|
||||
line += board[k][x];
|
||||
}
|
||||
}
|
||||
if (line.indexOf(searchValue) > -1){
|
||||
|
@ -124,10 +128,64 @@ function playingAT(col){
|
|||
return;
|
||||
}
|
||||
|
||||
//diagonals
|
||||
//\
|
||||
//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];
|
||||
}
|
||||
}
|
||||
|
||||
for (var kx=x, var ky=y; kx < 7, ky
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
//change player
|
||||
if(currentPlayer == 1){
|
||||
|
@ -140,32 +198,44 @@ 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.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) );
|
||||
|
||||
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)){
|
||||
playingAT(colTarget);
|
||||
}else{
|
||||
addLog ('bot response must be a digit betwin 0 and 7, witch indicate the conumn number where he wants play. Voici sa réponse: "' + colTarget + '"' );
|
||||
}
|
||||
}else{
|
||||
addLog('le bot ' + player + ' does not respond. ' + xhr.status);
|
||||
return;
|
||||
}
|
||||
}else{
|
||||
//wait for human response, show buttons
|
||||
document.getElementById("playerButtons").setAttribute("class", "");
|
||||
|
@ -174,9 +244,11 @@ function play(player){
|
|||
}
|
||||
function startGame(){
|
||||
//empty div
|
||||
document.getElementById("fightResult").innerHTML="";
|
||||
//create grid
|
||||
var table=createElem('table',{'class':'battleGrid', 'id': 'grid'});
|
||||
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=6; i > -1; i--){
|
||||
var tr=createElem('tr');
|
||||
for (var j=0;j<7; j++){
|
||||
|
@ -197,14 +269,31 @@ function startGame(){
|
|||
newTr.appendChild(newTd);
|
||||
}
|
||||
|
||||
document.getElementById('grid').appendChild(newTr);
|
||||
document.getElementById('board').appendChild(newTr);
|
||||
|
||||
grid=[["","","","","","",""],
|
||||
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>
|
||||
|
@ -225,7 +314,7 @@ function startGame(){
|
|||
</select>
|
||||
</td>
|
||||
<td>
|
||||
<input id="url1" type="text" name="player1URL" placeholder="url du bot http://localhost" value="https://botsarena.tinad.fr/StupidIAconnectFour.php"/>
|
||||
<input id="url1" type="text" name="player1URL" placeholder="url du bot http://localhost" value="https://ias.tinad.fr/StupidIAconnectFour.php"/>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
|
@ -237,7 +326,7 @@ function startGame(){
|
|||
</select>
|
||||
</td>
|
||||
<td>
|
||||
<input id="url2" type="text" name="player2URL" placeholder="url du bot http://localhost" disabled value="https://botsarena.tinad.fr/StupidIAconnectFour.php"/>
|
||||
<input id="url2" type="text" name="player2URL" placeholder="url du bot http://localhost" disabled value="https://ias.tinad.fr/StupidIAconnectFour.php"/>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
@ -250,4 +339,4 @@ function startGame(){
|
|||
<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>
|
||||
</html>
|
||||
|
|
|
@ -182,7 +182,6 @@ function play(player){
|
|||
}
|
||||
function startGame(){
|
||||
//empty div
|
||||
document.getElementById("fightResult").innerHTML="";
|
||||
while (document.getElementById("fightResult").firstChild) {
|
||||
document.getElementById("fightResult").removeChild(document.getElementById("fightResult").firstChild);
|
||||
}
|
||||
|
@ -215,20 +214,17 @@ function startGame(){
|
|||
//envoyer les requetes d'init aux bots
|
||||
for (var p = 1; p < 3 ; p++){
|
||||
|
||||
if(document.getElementById("player" + p + "Type").value == "bot"){
|
||||
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.onreadystatechange = function(){if(xhr.readyState == 4){
|
||||
if(xhr.status == 200) {
|
||||
addLog('Message d\'init envoyé au bot player ' + p );
|
||||
}else{
|
||||
addLog('player ' + p + ' n est pas joignable ' + xhr.status);
|
||||
return;
|
||||
}
|
||||
}};
|
||||
xhr.open("POST", document.getElementById('url' + p).value, true);
|
||||
xhr.setRequestHeader("Content-Type", "application/json");
|
||||
xhr.send(' {"game-id":"1126","action":"init","game":"tictactoe","players":2,"board":"","player-index":' + (p - 1) +'}');
|
||||
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":"1126","action":"init","game":"tictactoe","players":2,"board":"","player-index":' + (p - 1) +'}');
|
||||
if(xhr.status == 200) {
|
||||
addLog('Message d\'init envoyé au bot player ' + p );
|
||||
}else{
|
||||
addLog('player ' + p + ' n est pas joignable ' + xhr.status);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
play(1);
|
||||
|
|
|
@ -48,6 +48,23 @@ switch ($_POST['act']){
|
|||
$_SESSION['matchId']=get_unique_id();
|
||||
$_SESSION['game']="connectFou";
|
||||
|
||||
//send init message
|
||||
|
||||
for($player = 0; $player < 2; $player++){
|
||||
$params[$player]=array(
|
||||
'game-id' => $_SESSION['matchId'],
|
||||
'action' => 'init',
|
||||
'game' => 'connectFou',
|
||||
'players' => 2,
|
||||
'board' => '',
|
||||
'player-index' => $player
|
||||
);
|
||||
}
|
||||
get_IA_Response($_SESSION['bot1']['url'],$params[0]); //don't care about result
|
||||
get_IA_Response($_SESSION['bot2']['url'],$params[1]); //don't care about result
|
||||
|
||||
|
||||
|
||||
//echo "plop".json_encode($_SESSION['map']);
|
||||
case "fight":
|
||||
|
||||
|
@ -77,29 +94,41 @@ switch ($_POST['act']){
|
|||
$you="X";
|
||||
}
|
||||
}
|
||||
/*
|
||||
|
||||
|
||||
game-id string identifiant la partie.
|
||||
action string identifiant la phase, init tout de suite, sera play-turn dans le châpitre suivant.
|
||||
game string identifiant le jeu. Ici, ce sera forcément tictactoe. ça peut servir si vous donnez une seule URL pour plusieurs bots.
|
||||
players Int indiquant le nombre de joueurs dans la partie, toujours 2 au morpion.
|
||||
board Vide à cette étape, voir chapitre suivant.
|
||||
player-index int, L'ordre de votre bot dans les tours de jeu. Le premier joueur a la valeur 0, le deuxième 1.
|
||||
*/
|
||||
//make post datas to send
|
||||
$postDatas=array(
|
||||
'game' => 'connectFour',
|
||||
'match_id' => $_SESSION['matchId']."-".$_SESSION['currentPlayer'],
|
||||
'opponent' => $opponentName,
|
||||
'you' => $you,
|
||||
'grid' => $_SESSION['map']
|
||||
|
||||
'game-id' => $_SESSION['matchId'],
|
||||
'action' => 'play-turn',
|
||||
'game' => 'connectFour',
|
||||
'players' => 2,
|
||||
'opponent' => $opponentName,
|
||||
'you' => $you,
|
||||
'board' => $_SESSION['map'],
|
||||
'player-index' => $_SESSION['currentPlayer'] - 1
|
||||
);
|
||||
//send query
|
||||
$anwserPlayer=get_IA_Response($botUrl,$postDatas);
|
||||
//for test ***************************
|
||||
//echo $anwserPlayer; die;
|
||||
$tempPlayer = get_IA_Response($botUrl,$postDatas);
|
||||
$anwserPlayer = $tempPlayer['play'];
|
||||
|
||||
//vérifier la validité de la réponse
|
||||
if((isset($_SESSION['map'][5][$anwserPlayer])) && ($_SESSION['map'][5][$anwserPlayer] == "")){
|
||||
//reponse conforme
|
||||
|
||||
for($y = 0; $_SESSION['map'][$y][$anwserPlayer] <> ""; $y++){
|
||||
}
|
||||
$_SESSION['map'][$y][$anwserPlayer]=$you;
|
||||
$strikeX=$anwserPlayer;
|
||||
$strikeY=$y;
|
||||
|
||||
$_SESSION['map'][$y][$anwserPlayer]=$you;
|
||||
$strikeX=$anwserPlayer;
|
||||
$strikeY=$y;
|
||||
|
||||
//does he win?
|
||||
$wins=false;
|
||||
|
|
|
@ -6,29 +6,42 @@
|
|||
</ul>
|
||||
</p>
|
||||
|
||||
<h3>Requête générée par l'arène (ce site) vers votre bot</h3>
|
||||
L'arène fait une requête http(s) avec les parametres POST suivants vers votre site:
|
||||
<h2>Communications entre l'arène et votre bot</h2>
|
||||
<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>
|
||||
<p>Votre bot répond par un array au format JSON.</p>
|
||||
<h3>Message d'initialisation de votre partie</h3>
|
||||
l'arène envoie le message suivant:
|
||||
<pre>{"game-id":"1126","action":"init","game":"connectFour","players":2,"board":"","player-index":0}</pre>
|
||||
<p>Si on décompose le tableau pour l'expliquer:</p>
|
||||
<ul>
|
||||
<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 connectFour. ç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, voire non fourni, 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>
|
||||
<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>
|
||||
|
||||
<table class="tabledoc">
|
||||
<tr><th>paramètre</th><th>valeur</th></tr>
|
||||
<tr>
|
||||
<td>game</td>
|
||||
<td>
|
||||
Chaîne de caractères, sera toujours "connectFour".<br/>
|
||||
Peut servir si votre url sert à plusieurs jeux.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>match_id</td>
|
||||
<td>
|
||||
Chaîne de caractères. Répond à l'expression régulière suivante: ^[0-9]+-(1|2)$<br/>
|
||||
Le premier nombre (digits avant le tiret) identifie le match.<br/>
|
||||
Le numéro après le tiret vous indique si vous êtes le bot 1 ou le bot 2 dans l'ordre de jeu.<br/>
|
||||
Ça vous servira si votre IA fait des statistiques sur les matchs.
|
||||
</td>
|
||||
</tr>
|
||||
<tr><td>you</td><td>vous indique quel est votre symbole dans la grille</td></tr>
|
||||
<tr><td>grid</td><td>tableau à deux dimmensions au format JSON vous indiquant l'état de la grille<br/>
|
||||
<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":"9916","action":"play-turn","game":"connectFour","players":2,"board":[["","","","","","",""],["","","","","","",""],["","","","","","",""],["","","","","","",""],["","","","","","",""],["","","","","","",""]],"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 contenue dans le champs board du message JSON.C'est un tableau à deux dimmensions au format JSON vous indiquant l'état de la grille.<br/>
|
||||
Exemple:<br/>
|
||||
<pre>
|
||||
[["","","","X","0","",""],
|
||||
|
@ -39,8 +52,33 @@ L'arène fait une requête http(s) avec les parametres POST suivants vers v
|
|||
["","","","","","",""]]
|
||||
</pre>
|
||||
|
||||
</td></tr>
|
||||
</table>
|
||||
<p>Visuellement, Le tableau est inversé par rapport à un plateau de puissance 4. La ligne ayant l'index zéro (en haut dans l'extrait ci dessus) représente la ligne du bas.</p>
|
||||
<p>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>
|
||||
|
||||
<h3>Réponse de votre bot</h3>
|
||||
<p>Seulement un caractère. Il indique la colonne dans laquelle vous souhaitez jouer 0 à 7</p>
|
||||
<p>Au format JSON, Seulement un caractère. Il indique la colonne dans laquelle vous souhaitez jouer 0 à 6 bornes incluses.</p>
|
||||
<pre>
|
||||
{"play":"3"}
|
||||
</pre>
|
||||
<p>Pour indiquer que vous souhaitez dans la troisième colonne. <br/>
|
||||
Evidemment l'arène respecte la gravité et placera votre pion dans la première case libre de la colonne (en partant de l'index 0).</p>
|
||||
|
||||
<h2>Outils pour développer et tester votre bot</h2>
|
||||
<p>Afin de vous aider sur la façon de gérer les communications entre le bot et l'arène, n'hésitez pas à jeter un coup d'oeil dans le <a href="https://github.com/gnieark/IAS/blob/master/StupidIAconnectFour.php">code source PHP de stupidIA</a>.<p>
|
||||
|
||||
<h3><a href="/testBotScripts/connectfour.html">Script Botsarena</a></h3>
|
||||
<p>Cette petite page html+javascript vous permettra de tester et débogguer votre bot.<br/> Elle vous permettra de tester votre boot via son url, contre lui même, un humain ou stupidIA.<br/> Une fois prêt, vous l'inscrirez dans l'arène.</p>
|
||||
<p> Par défaut, les navigateurs ne permettent pas en javascript de faire des requettes Cross domaine. C'est une sécurité du navigateur. Il y a donc trois possibilités:</p>
|
||||
<ul><li>Vous ajoutez à votre bot les <a href="https://www.qwant.com/?q=allow%20cross%20domain%20query%20http%20header&t=all">headers permettant les requettes de type POST provenant d'un autre domaine</a>.</li>
|
||||
<li>Plus simple, vous téléchargez la page (click droit, enregistrer la cible du lien sous)et la mettez dans le VHOST de votre bot le temps des tests. Tout son code (html, css et javascript) est inclus dans la page sans ressource externe, dans le but qu'elle puisse etre facilement téléchargée et utilisable.</li>
|
||||
<li>Vous utilisez un navigateur web qui supporte le javascript et permet les requetes cross domain. <a href="https://www.thepolyglotdeveloper.com/2014/08/bypass-cors-errors-testing-apis-locally/">Ça semble possible</a>.</li>
|
||||
</ul>
|
||||
<p>Ce problème ne se posera pas au niveau de l'arène une fois que votre bot sera inscrit. Car dans ce cas, c'est le serveur qui fait les requetes vers les bots, pas un navigateur web.</p>
|
||||
<h3><a href="https://github.com/moul/bolosseum">Bolosseum</a></h3>
|
||||
<p>Vous trouverez des outils en ligne de commande pour tester et déboguer votre bot sur le projet github Bolosseum de @moul.</p>
|
||||
<h2>Faire entrer votre bot dans cette arène</h2>
|
||||
<p>Le formulaire d'inscription de votre bot est sur la page d'accueil du site.</p>
|
|
@ -1,21 +1,12 @@
|
|||
<?php
|
||||
function get_IA_Response($iaUrl,$postParams){
|
||||
//send params JSON as body
|
||||
|
||||
$data_string = json_encode($postParams);
|
||||
/*
|
||||
$ch = curl_init();
|
||||
curl_setopt($ch, CURLOPT_URL, $iaUrl);
|
||||
curl_setopt($ch, CURLOPT_POST, true);
|
||||
curl_setopt($ch, CURLOPT_POSTFIELDS, $postParams);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
|
||||
$output = curl_exec($ch);
|
||||
curl_close($ch);
|
||||
|
||||
*/
|
||||
|
||||
$data_string = json_encode($postParams);
|
||||
|
||||
$ch = curl_init($iaUrl);
|
||||
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
|
||||
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
|
||||
curl_setopt($ch, CURLOPT_POSTFIELDS, $data_string);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
|
||||
|
@ -24,8 +15,7 @@ function get_IA_Response($iaUrl,$postParams){
|
|||
);
|
||||
$output= curl_exec($ch);
|
||||
curl_close($ch);
|
||||
|
||||
return htmlentities($output);
|
||||
return json_decode($output,TRUE);
|
||||
}
|
||||
function get_Post_Params($botsCount){
|
||||
$keysBots=array('bot1','bot2');
|
||||
|
|
|
@ -58,7 +58,7 @@ switch ($_POST['act']){
|
|||
default:
|
||||
error(500,"oups");
|
||||
die;
|
||||
}
|
||||
}
|
||||
|
||||
$paramsToSend=array(
|
||||
'game-id' => $game_id,
|
||||
|
|
Loading…
Reference in New Issue
Block a user