Merge branch 'tron' of github.com:gnieark/botsArena into tron

This commit is contained in:
root 2016-09-26 18:57:21 +02:00
commit 49ed343300
19 changed files with 945 additions and 11 deletions

View File

@ -1 +1 @@
1448
1617

@ -1 +1 @@
Subproject commit 7c8b786228bb9e1561ff60a2d6f7f6ce91be6fee
Subproject commit 1d85f9ef3ecfc42bbc4f3c70d5e37ca9a65f629a

View File

@ -0,0 +1,22 @@
<?php
class Coords{
public $x;
public $y;
public function __construct(int $x = 0, int $y = 0) {
$this->x = $x;
$this->y = $y;
}
public function __toString(){
return $this->x.",".$this->y;
}
public function addDirection(Direction $dir){
return new Coords(
$this->x + $dir->deltaX,
$this->y + $dir->deltaY
);
}
}

View File

@ -0,0 +1,92 @@
<?php
class InvalidDirectionException extends UnexpectedValueException{
}
class Direction
{
private static $top = 0;
private static $bottom = 1;
private static $left = 2;
private static $right = 3;
private $value;
public $deltaX;
public $deltaY;
public function __construct(){
$this->value = 0;
}
private function setValue($value){
$this->value = $value;
switch ($value){
case Direction::$bottom:
$this->deltaY = -1;
$this->deltaX = 0;
break;
case Direction::$top:
$this->deltaY = 1;
$this->deltaX = 0;
break;
case Direction::$left:
$this->deltaY = 0;
$this->deltaX = -1;
break;
case Direction::$right:
$this->deltaY = 0;
$this->deltaX = 1;
break;
}
}
public function __toString(){
switch ($this->value){
case Direction::$top:
return "y+";
break;
case Direction::$bottom:
return "y-";
break;
case Direction::$left:
return "x-";
break;
case Direction::$right:
return "x+";
break;
}
}
public static function make($str){
$dir = new Direction();
switch((string)$str){
case "x+":
$dir->setValue(Direction::$right);
break;
case "x-":
$dir->setValue(Direction::$left);
break;
case "y+":
$dir->setValue(Direction::$top);
break;
case "y-":
$dir->setValue(Direction::$bottom);
break;
default:
throw new InvalidDirectionException("expected 'x+', 'x-', 'y+' or 'y-'". (string)$str."received.");
}
return $dir;
}
public function opposite(){
$opposites = array(
Direction::$top => Direction::$bottom,
Direction::$bottom => Direction::$top,
Direction::$left => Direction::$right,
Direction::$right => Direction::$left
);
$opposite = new Direction();
$opposite->setValue($opposites[$this->value]);
return $opposite;
}
}

59
src/arenas/tron/Trail.php Normal file
View File

@ -0,0 +1,59 @@
<?php
class AlreadyBeenAddedException extends LogicException { }
class Trail {
private $trail;
public function __construct() {
$this->trail = new SplStack();
}
public function last() {
return $this->trail->top();
}
public function emptyTrail(){
$this->trail = new SplStack();
}
public function add($value) {
if(!$this->trail->isEmpty()) {
if(Trail::kind($this->trail->bottom()) !== Trail::kind($value)) {
throw new TypeError(
'items added to a trail must be of the same kind'
);
}
if($this->contains($value)) {
throw new AlreadyBeenAddedException(
'value has already been added to the trail'
);
}
}
$this->trail->push($value);
}
public function __toString(){
return json_encode($this->getTrailAsArray());
}
public function getTrailAsArray(){
$arr = array();
foreach($this->trail as $coord) {
$arr[] = array($coord->x,$coord->y);
}
return $arr;
}
public function contains($searchedValue) {
foreach($this->trail as $value) {
if($value == $searchedValue) return true;
}
return false;
}
public static function kind($var) {
$type = gettype($var);
if($type == 'object') $type .= ' ' . get_class($var);
return $type;
}
}

View File

@ -0,0 +1,260 @@
<?php
class TronGame
{
private $bots; //array of bots
public $gameId;
private $status; //false => Game ended or not initialised
public function get_continue(){
//count bots alive. if less than 1, game is ended
$count = 0;
foreach($this->bots as $bot){
if( $bot->isAlive == true){
$count++;
}
}
if($count > 1){
return true;
}else{
return false;
}
}
private function apply_looses($loosersArr){
//save draws
if( count($loosersArr) > 1 ){
$loosersById = array();
foreach($loosersArr as $bot){
$loosersById[] = $this->bots[$bot]->id;
}
$this->save_draw_bots($loosersById);
}
//save victories
if( count($loosersArr) > 0 ){
//make victorous bots array
$vbots = array();
for ($botCount = 0; $botCount < $nbeBots; $botCount++){
if($this->bots[$botCount]->isAlive){
$vbots[] = $this->bots[$botCount]->id;
}
}
$this->save_losers_winers($loosersById,$vbots);
}
}
private function save_draw_bots($arr){
/*
* Recursive function who save all combionaisons of draw matches
*/
if(count($arr) < 2){
return;
}else{
$a = $arr[0];
array_shift($arr);
foreach($arr as $bot){
save_battle('tron',$a,$bot,0,'id');
}
$this->save_draw_bots($arr);
}
}
private function save_losers_winers($arrLoosers,$arrWiners){
foreach($arrWiners as $winner){
foreach($arrLoosers as $loser){
save_battle('tron',$winer,$loser,1,'id');
}
}
}
public function get_trails(){
//return all trails for draw svg
$trailsArr = array();
foreach($this->bots as $bot){
$trailsArr[] = $bot->trail->getTrailAsArray();
}
return $trailsArr;
}
public function new_lap(){
// for all alive bots
$logs = "";
$nbeBots = count($this->bots);
$urls = array();
$paramToSend = array();
$board = $this->get_trails();
$loosers = array();
$lastsCells = array();
for ($botCount = 0; $botCount < $nbeBots; $botCount++){
if ($this->bots[$botCount]->isAlive){
$urls[$botCount] = $this->bots[$botCount]->url;
$paramsToSend[$botCount] = array(
'game-id' => "".$this->gameId,
'action' => 'play-turn',
'game' => 'tron',
'board' => $board,
'player-index' => $botCount, // To do: verifier que ça restera le même à chaque tour
'players' => $nbeBots
);
}
}
$responses = $this->get_multi_IAS_Responses($urls,$paramsToSend);
//print_r($responses);
//grow bots'tails
for ($botCount = 0; $botCount < $nbeBots; $botCount++){
if ($this->bots[$botCount]->isAlive){
$dir = Direction::make($responses[$botCount]['responseArr']['play']);
$lastsCells[$botCount] = $this->bots[$botCount]->grow($dir);
}
}
//test if loose
for ($botCount = 0; $botCount < $nbeBots; $botCount++){
if ($this->bots[$botCount]->isAlive){
for( $botCount2 = 0; $botCount2 < $nbeBots; $botCount2++){
if(($botCount <> $botCount2)
&& ($this->bots[$botCount2]->trail->contains($lastsCells[$botCount]))
){
$loosers[] = $botCount;
$this->bots[$botCount]->loose();
break;
}
}
}
}
return $this->get_trails();
}
private function get_multi_IAS_Responses($iasUrls, $postParams){
//same as the get_IAS_Responses function
// but more than one bot requested parallely
$cmh = curl_multi_init();
for ($i = 0; $i < count($iasUrls); $i++){
$data_string = json_encode($postParams[$i]);
$ch[$i] = curl_init($iasUrls[$i]);
curl_setopt($ch[$i], CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch[$i], CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($ch[$i], CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch[$i], CURLOPT_POSTFIELDS, $data_string);
curl_setopt($ch[$i], CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch[$i], CURLOPT_HTTPHEADER, array(
'Content-Type: application/json',
'Content-Length: ' . strlen($data_string))
);
curl_multi_add_handle($cmh,$ch[$i]);
}
//send the requests
do {
$returnVal = curl_multi_exec($cmh, $runningHandles);
} while ($returnVal == CURLM_CALL_MULTI_PERFORM);
// Loop and continue processing the request
while ($runningHandles && $returnVal== CURLM_OK) {
// Wait forever for network
$numberReady = curl_multi_select($cmh);
if ($numberReady != -1) {
// Pull in any new data, or at least handle timeouts
do {
$returnVal = curl_multi_exec($cmh, $runningHandles);
} while ($returnVal == CURLM_CALL_MULTI_PERFORM);
}
}
//Get results
for ($i = 0; $i < count($iasUrls); $i++){
// Check for errors
$curlError = curl_error($ch[$i]);
if($curlError == "") {
$response = curl_multi_getcontent($ch[$i]);
if(! $arr = json_decode($response,TRUE)){
$arr=array();
}
$res[$i] = array(
'messageSend' => json_encode($postParams[$i]),
'response' => $response,
'httpStatus' => curl_getinfo($ch[$i])['http_code'],
'responseArr' => $arr
);
}else{
$res[$i] = false;
}
//close
curl_multi_remove_handle($cmh, $ch[$i]);
curl_close($ch[$i]);
}
// Clean up the curl_multi handle
curl_multi_close($cmh);
return $res;
}
public function init_game(){
//send init messages to bots
$logs = "";
$fullLogs = "";
$nbeBots = count($this->bots);
for ($botCount = 0; $botCount < $nbeBots; $botCount++){
$messageArr = array(
'game-id' => "".$this->gameId,
'action' => 'init',
'game' => 'tron',
'board' => '',
'players' => $nbeBots,
'player-index' => $botCount
);
$resp = get_IA_Response($this->bots[$botCount]->url,$messageArr);
$fullLogs .= 'Arena send to '.$this->bots[$botCount]->name.'<em>'.htmlentities($resp['messageSend']).'</em><br/>
HTTP status: <em>'.htmlentities($resp['httpStatus']).'</em><br/>
Bot anwser: <em>'.htmlentities($resp['response']).'</em><br/>';
$logs.="Init message send to ".$this->bots[$botCount]->name."<br/>";
}
return array($logs,$fullLogs);
}
public function __construct($botsInfos){
$this->gameId = get_unique_id();
$this->bots = array();
$positions = array();
$botCount = 0;
$err = "";
//print_r($botsInfos);
foreach($botsInfos as $bot){
//find a random start position
do{
$x = rand(1,999);
$y = rand(1,999);
}while(in_array($x.",".$y,$positions));
$positions[] = $x.",".$y;
$startCoord = new Coords($x,$y);
$this->bots[$botCount] = new TronPlayer();
$this->bots[$botCount]->make($bot['id'],$startCoord,$bot['name'],$bot['url']);
if ($this->bots[$botCount]->isAlive === false){
$err .= "Something went wrong for ".$this->bots[$botCount]->getName()."<br/>";
}else{
$botCount++;
}
}
return $err;
}
}

View File

@ -0,0 +1,30 @@
<?php
class TronPlayer{
public $url;
public $id;
public $name;
public $trail;
private $direction;
public $isAlive = true;
public function grow(Direction $dir){
$this->trail->add($this->trail->last()->addDirection($dir));
return $this->trail->last();
}
public function loose(){
$this->isAlive = false;
$this->trail->emptyTrail();
return false;
}
public function make($botId, Coords $initialsCoords,$name,$url){
$this->id = $botId;
$this->trail = new Trail;
$this->trail->add($initialsCoords);
$this->name = $name;
$this->url = $url;
$this->state = true;
}
public function __construct(){
$this->state = false;
}
}

87
src/arenas/tron/act.php Normal file
View File

@ -0,0 +1,87 @@
<?php
#- BEGIN LICENSE BLOCK ---------------------------------------
#
# This file is part of botsArena.
#
# Copyright (C) Gnieark et contributeurs
# Licensed under the GPL version 3.0 license.
# See LICENSE file or
# http://www.gnu.org/licenses/gpl-3.0-standalone.html
#
# -- END LICENSE BLOCK -----------------------------------------
require_once ("TronGame.php");
require_once ("TronPlayer.php");
require_once ("Direction.php");
require_once ("Trail.php");
require_once ("Coords.php");
switch ($_POST['act']){
case "initGame":
$rs = mysqli_query($lnMysql,"SELECT id,name,url FROM bots WHERE game='tron';");
while($r = mysqli_fetch_row($rs)){
$botsFullArr[$r[0]] = array('id' => $r[0], 'name' => $r[1], 'url' => $r[2]);
}
$botsArrayTemp = json_decode($_POST['bots']);
$botsInfos = array();
foreach($botsArrayTemp as $id){
//tester si le bot existe dans la bdd
if(isset($botsFullArr[$id])){
$botsInfos[] = $botsFullArr[$id];
}
}
//************
$game = new TronGame($botsInfos);
$logs = $game->init_game();
echo json_encode(array(
'status' => $game->get_continue(),
'logs' => $logs,
'gameId' => $game->gameId,
'botsPosition' => $game->get_trails()
));
$_SESSION['game'] = serialize($game);
die;
break;
case "play":
$logs = "";
if(!isset($_SESSION['game'])){
echo '{"status":"error"}';
die;
}
$game = unserialize($_SESSION['game']);
if($game->gameId <> $_POST['gameId']){
//sometimes if an ajax callback is applied after init an other game
echo '{"status":"error"}';
die;
}
$lap = $game->new_lap();
if($game->get_continue()){
$continue = 1;
}else{
$continue = 0;
}
echo json_encode(array(
'gameId' => $game->gameId,
'continue' => $continue,
'lap' => $lap
));
$_SESSION['game'] = serialize($game);
die;
break;
default:
break;
}

View File

View File

View File

@ -0,0 +1,5 @@
<?php

167
src/arenas/tron/js.js Normal file
View File

@ -0,0 +1,167 @@
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 divLogs = document.getElementById("logs");
var p=createElem('p',{});
p.innerHTML=message;
divLogs.appendChild(p);
divLogs.scrollTop = divLogs.scrollHeight;
}
function growTails(newPointsByPlayer){
var botsColor = ['cyan','darkmagenta','darkred','darkslategrey','deeppink','dodgerblue','goldenrod','grey','indigo','lightgreen','mediumslateblue','midnightblue'];
//document.getElementById('map');
for (var botId in newPointsByPlayer){
var tail = newPointsByPlayer[botId]['tail'];
for(var coordsIx in tail){
coords = tail[coordsIx];
//draw the point
var rect=createElemNS('rect',{'x':coords[0],'y':coords[1],'width':'2','height':'2','style':'fill:' + botsColor[botId] + ';'});
document.getElementById('map').appendChild(rect);
}
}
}
function createElemNS(type,attributes){
//same as createElem but with ns for svg file
var elem=document.createElementNS("http://www.w3.org/2000/svg",type);
for (var i in attributes)
{elem.setAttributeNS(null,i,attributes[i]);}
return elem;
}
function changeSelect(number,botId){
//show an other selector if bot is chosen
var next = parseInt(number) + 1;
if((botId > 0) && (number < 12)){
if(document.getElementById('selectBot' + next)){
return;
}else{
show_bot_panel(next);
}
if(number > 0){
document.getElementById('fightButton').disabled = false;
}
}
}
function show_bot_panel(number){
//configurePlayers
var fieldset = createElem('fieldset',{'class':'botFormulaire'});
var legend = createElem('legend',{});
legend.innerHTML = 'bot ' + number;
fieldset.appendChild(legend);
var p=createElem('p');
var select = createElem('select',{'id':'selectBot' + number, 'onchange':'changeSelect(' + number + ',this.value);'});
var option = createElem('option',{'value': '0', 'selected': 'selected','disabled':'disabled'});
option.innerHTML = '';
select.appendChild(option);
for (var i = 0; i < botsAvailable.length; i++){
var option = createElem('option',{'value': botsAvailable[i]['id']});
option.innerHTML = botsAvailable[i]['name'];
select.appendChild(option);
}
p.appendChild(select);
fieldset.appendChild(p);
document.getElementById('configurePlayers').appendChild(fieldset);
}
function applyInitMessage(req,xd_check){
document.getElementById('fightButton').disabled=true;
//callback function when init game request
if(req.readyState == 4){
if(req.status == 200) {
//alert (req.responseText);
try{
var ret = JSON.parse(req.responseText);
}catch(e){
addLog('erreur' + req.responseText);
return;
}
addLog(ret['logs']);
if(ret['status'] == true){
growTails(ret['botsPosition']);
play(ret['gameId'],xd_check);
}
}else{
alert ('error ' + req.status);
document.getElementById('fightButton').disabled=false;
return;
}
}
}
function drawMap(map){
console.log(map);
var botsColor = ['cyan','darkmagenta','darkred','darkslategrey','deeppink','dodgerblue','goldenrod','grey','indigo','lightgreen','mediumslateblue','midnightblue'];
for (var botId in map){
for(var coordsI in map[botId]){
coords = map[botId][coordsI];
//draw the point
var rect=createElemNS('rect',{'x':coords[0],'y':coords[1],'width':'2','height':'2','style':'fill:' + botsColor[botId] + ';'});
document.getElementById('map').appendChild(rect);
}
}
}
function play(gameId,xd_check){
var req = new XMLHttpRequest();
req.onreadystatechange = function(){
if(req.readyState == 4){
if(req.status == 200) {
addLog(req.responseText);
var reponse = JSON.parse(req.responseText);
drawMap(reponse['lap']);
if(reponse['continue'] == '1'){
play(gameId,xd_check);
}
}else{
}
}
};
req.open("POST", '/tron', true);
req.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
req.send('act=play&xd_check=' + xd_check + '&gameId=' + gameId + '&fullLogs=' + document.getElementById("fullLogs").checked);
}
function tron(xd_check){
//empty
while (document.getElementById('fightResult').firstChild) {
document.getElementById('fightResult').removeChild(document.getElementById('fightResult').firstChild);
}
// draw border;
var svg = createElemNS('svg',{'id':'map','width':'500','height':'500','viewBox':'0 0 1000 1000'});
var rect=createElemNS('rect',{'x':'0','y':'0','width':'1000','height':'1000','style':'stroke:#000000; fill:none;'});
svg.appendChild(rect);
document.getElementById("fightResult").appendChild(svg);
var plogs = createElem("p",{'id':'logs'});
document.getElementById("fightResult").appendChild(plogs);
//get bot list
var botsList=[];
var i=0;
while(document.getElementById('selectBot' + i)){
botsList.push(document.getElementById('selectBot' + i).value);
i++;
}
//ask arena to send bots init messages
var request = new XMLHttpRequest();
request.onreadystatechange = function(){applyInitMessage(request,xd_check)};
request.open("POST", '/tron', true);
request.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
request.send('act=initGame&xd_check=' + xd_check + '&bots=' + JSON.stringify(botsList) + '&fullLogs=' + document.getElementById("fullLogs").checked);
}

View File

@ -0,0 +1,32 @@
<?php
#- BEGIN LICENSE BLOCK ---------------------------------------
#
# This file is part of botsArena.
#
# Copyright (C) Gnieark et contributeurs
# Licensed under the GPL version 3.0 license.
# See LICENSE file or
# http://www.gnu.org/licenses/gpl-3.0-standalone.html
#
# -- END LICENSE BLOCK -----------------------------------------
require_once(__DIR__."/functions.php");
$bots=get_Bots_Array('tron');
$botsArr=array();
foreach($bots as $bot){
$botsArr[]=array('id' => $bot['id'], 'name' => $bot['name']);
}
?>
<article id="mainArticle">
<h2><?php echo $lang['MAKE_DUEL'];?></h2>
<aside id="configurePlayers">
</aside>
<script>
var botsAvailable = <?php echo json_encode($botsArr); ?>;
show_bot_panel(0);
</script>
<p><input type="checkbox" id="fullLogs"/><label for="fullLogs">view the full logs</label></p>
<p><input id="fightButton" disabled="disabled" type="button" value="<?php echo $lang['FIGHT']; ?>" onclick="tron('<?php echo xd_check_input(2); ?>');"></p>
<div id="fightResult"></div>
</article>

View File

@ -0,0 +1,4 @@
#configurePlayers{width: 100%;}
#configurePlayers fieldset{display: block; width: 100px; float:left;}
#logs{display:block;padding-left:10px; height: 200px; overflow-y: scroll;}
#logs p em {color: grey; font-size: 70%; test-transform:italic;}

View File

@ -0,0 +1,27 @@
<?php
use PHPUnit\Framework\TestCase;
require_once '../Coords.php';
require_once '../Direction.php';
class CoordsTest extends TestCase {
public function testCirculaire(){
$startCoord = new Coords(15,3);
$endCoord = $startCoord->addDirection(Direction::make('x+'))
->addDirection(Direction::make('y-'))
->addDirection(Direction::make('x-'))
->addDirection(Direction::make('y+'));
$this->assertTrue($endCoord == $startCoord);
}
public function testIsDifferent(){
$startCoord = new Coords(15,3);
$endCoord = $startCoord->addDirection(Direction::make('x+'));
fwrite(STDERR, $startCoord ."\n");
fwrite(STDERR, $endCoord ."\n");
$this->assertFalse($endCoord == $startCoord);
}
}

View File

@ -0,0 +1,71 @@
<?php
use PHPUnit\Framework\TestCase;
require_once '../Direction.php';
class Directiontest extends TestCase {
public function invalidStrings() {
return array(
array('jhgjhg'),
array('X+'),
array(4)
);
}
/**
* @dataProvider invalidStrings
* @expectedException invalidDirectionException
*/
public function testRejectInvalidString($invalidString){
Direction::make($invalidString);
}
public function validStrings(){
return array(
array('x+'),
array('y+'),
array('x-'),
array('y-'),
);
}
/**
* @dataProvider validStrings
*/
public function testAcceptValidString($validString){
$this->assertInstanceOf(Direction::class,Direction::make($validString));
}
/**
* @dataProvider validStrings
*/
public function testDeltaXY($validString){
$dir = Direction::make($validString);
$this->assertTrue($dir->deltaX != 0 || $dir->deltaY != 0);
}
/**
* @dataProvider validStrings
*/
public function testToString($validString){
$this->assertTrue(Direction::make($validString) == $validString);
}
/**
* @dataProvider validStrings
*/
public function testOpposite($validString){
$dir = Direction::make($validString);
$op = $dir->opposite();
$this->assertInstanceOf(Direction::class,$op);
$this->assertFalse($dir == $op);
}
/**
* @dataProvider validStrings
*/
public function testOppositeOpposite($validString){
$dir = Direction::make($validString);
$opop = $dir->opposite()->opposite();
$this->assertTrue($dir == $opop);
}
}

View File

@ -0,0 +1,64 @@
<?php
use PHPUnit\Framework\TestCase;
require_once '../Direction.php';
require_once '../Coords.php';
require_once '../TronPlayer.php';
class TronPlayerTest extends TestCase {
public function validPlayer(Direction $direction) {
return new TronPlayer(
'http://127.0.0.1',
'test',
new Coords(0, 0),
$direction
);
}
public function testTronPlayerCreation() {
$this->assertInstanceOf(
TronPlayer::class,
$this->validPlayer(Direction::make('x+'))
);
}
public function directions() {
return array(
array(Direction::make('x+')),
array(Direction::make('x-')),
array(Direction::make('y+')),
array(Direction::make('y-')),
);
}
/**
* @dataProvider directions
* @expectedException OppositeForbiddenException
*/
public function testOppositeForbidden(Direction $direction) {
$player = $this->validPlayer($direction);
$player->changeDirection($direction->opposite());
}
public function testAlreadyLost() {
$right = Direction::make('x+');
$down = Direction::make('y-');
$left = Direction::make('x-');
$up = Direction::make('y+');
$player = $this->validPlayer($right);
$player->nextMove($right);
$player->nextMove($down);
$player->nextMove($left);
try {
$player->nextMove($up);
throw new Exception('TronPlayer did not throw AlreadyPlayedException');
} catch(AlreadyPlayedException $e) { }
try {
$player->nextMove($up);
throw new Exception('TronPlayer did not throw AlreadyLostException');
} catch(AlreadyLostException $e) { }
}
}

View File

@ -36,6 +36,14 @@ $arenas=array(
'jsFile'=> "js.js",
'cssFile'=> "style.css",
'ludusUrl' => "/testBotScripts/connectfour.html"
),
array(
'id' => "tron",
'url' => "/tron",
'title' => "Tron",
'metaDescription' => 'Affrontements de bots à Tron',
'jsFile'=> "js.js",
'cssFile'=> "style.css"
)
);

View File

@ -151,7 +151,7 @@ function conn_bdd(){
}
mysqli_select_db($linkMysql,$mysqlParams['database']);
mysqli_set_charset($linkMysql, 'utf8');
return $linkMysql; //does PHP can do that?
return $linkMysql;
}
function get_battles_history($game){
@ -229,18 +229,24 @@ function ELO_get_new_ranks($elo1,$elo2,$score){
$elo2 + ELO_get_k($elo2) * (1 - $score - (1/ (1 + pow(10,(($elo1 - $elo2) / 400)))))
);
}
function save_battle($game,$bot1,$bot2,$resultat){
function save_battle($game,$bot1,$bot2,$resultat,$nameOrIds = 'name'){
//$bots1 and $bots2 are bots'names
//resultat: 0 match nul, 1 bot1 gagne 2 bot 2 gagne
global $lnMysql;
$game=substr($game,0,8); //limit 8 char for limitting mysql index size
//chercher les id de bot 1 et bot2
$rs=mysqli_query($lnMysql,"SELECT name,id,ELO FROM bots
WHERE name='".mysqli_real_escape_string($lnMysql,$bot1)."'
OR name='".mysqli_real_escape_string($lnMysql,$bot2)."'");
if($nameOrIds == "name"){
//chercher les id de bot 1 et bot2
$rs=mysqli_query($lnMysql,"SELECT name,id,ELO FROM bots
WHERE name='".mysqli_real_escape_string($lnMysql,$bot1)."'
OR name='".mysqli_real_escape_string($lnMysql,$bot2)."'");
}else{
$rs = mysqli_query($lnMysql, "SELECT name,id,ELO FROM bots
WHERE id='".mysqli_real_escape_string($lnMysql,$bot1)."'
OR id='".mysqli_real_escape_string($lnMysql,$bot2)."'");
}
while($r=mysqli_fetch_row($rs)){
$bots[$r[0]]=$r[1];
$actualELO[$r[0]]=$r[2];
@ -381,4 +387,4 @@ function get_IA_Response($iaUrl,$postParams){
'response' => $output,
'responseArr' => $arr
);
}
}