diff --git a/countBattles.txt b/countBattles.txt
index faf0797..f84ccb2 100644
--- a/countBattles.txt
+++ b/countBattles.txt
@@ -1 +1 @@
-1448
\ No newline at end of file
+1617
\ No newline at end of file
diff --git a/src/PHPMailer b/src/PHPMailer
index 7c8b786..1d85f9e 160000
--- a/src/PHPMailer
+++ b/src/PHPMailer
@@ -1 +1 @@
-Subproject commit 7c8b786228bb9e1561ff60a2d6f7f6ce91be6fee
+Subproject commit 1d85f9ef3ecfc42bbc4f3c70d5e37ca9a65f629a
diff --git a/src/arenas/tron/Coords.php b/src/arenas/tron/Coords.php
new file mode 100644
index 0000000..31a42b3
--- /dev/null
+++ b/src/arenas/tron/Coords.php
@@ -0,0 +1,22 @@
+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
+ );
+ }
+}
\ No newline at end of file
diff --git a/src/arenas/tron/Direction.php b/src/arenas/tron/Direction.php
new file mode 100644
index 0000000..4f1396f
--- /dev/null
+++ b/src/arenas/tron/Direction.php
@@ -0,0 +1,92 @@
+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;
+ }
+}
\ No newline at end of file
diff --git a/src/arenas/tron/Trail.php b/src/arenas/tron/Trail.php
new file mode 100644
index 0000000..8150eb2
--- /dev/null
+++ b/src/arenas/tron/Trail.php
@@ -0,0 +1,59 @@
+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;
+ }
+}
diff --git a/src/arenas/tron/TronGame.php b/src/arenas/tron/TronGame.php
new file mode 100644
index 0000000..86c210d
--- /dev/null
+++ b/src/arenas/tron/TronGame.php
@@ -0,0 +1,260 @@
+ 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.''.htmlentities($resp['messageSend']).'
+ HTTP status: '.htmlentities($resp['httpStatus']).'
+ Bot anwser: '.htmlentities($resp['response']).'
';
+ $logs.="Init message send to ".$this->bots[$botCount]->name."
";
+ }
+ 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()."
";
+ }else{
+ $botCount++;
+ }
+ }
+ return $err;
+ }
+}
\ No newline at end of file
diff --git a/src/arenas/tron/TronPlayer.php b/src/arenas/tron/TronPlayer.php
new file mode 100644
index 0000000..60115f8
--- /dev/null
+++ b/src/arenas/tron/TronPlayer.php
@@ -0,0 +1,30 @@
+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;
+ }
+}
\ No newline at end of file
diff --git a/src/arenas/tron/act.php b/src/arenas/tron/act.php
new file mode 100644
index 0000000..5cc1d81
--- /dev/null
+++ b/src/arenas/tron/act.php
@@ -0,0 +1,87 @@
+ $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;
+
+}
\ No newline at end of file
diff --git a/src/arenas/tron/doc-en.html b/src/arenas/tron/doc-en.html
new file mode 100644
index 0000000..e69de29
diff --git a/src/arenas/tron/doc-fr.html b/src/arenas/tron/doc-fr.html
new file mode 100644
index 0000000..e69de29
diff --git a/src/arenas/tron/functions.php b/src/arenas/tron/functions.php
new file mode 100644
index 0000000..0705b1d
--- /dev/null
+++ b/src/arenas/tron/functions.php
@@ -0,0 +1,5 @@
+ 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);
+}
diff --git a/src/arenas/tron/public.php b/src/arenas/tron/public.php
new file mode 100644
index 0000000..7479ade
--- /dev/null
+++ b/src/arenas/tron/public.php
@@ -0,0 +1,32 @@
+ $bot['id'], 'name' => $bot['name']);
+}
+?>
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/arenas/tron/style.css b/src/arenas/tron/style.css
new file mode 100644
index 0000000..eac3e3a
--- /dev/null
+++ b/src/arenas/tron/style.css
@@ -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;}
\ No newline at end of file
diff --git a/src/arenas/tron/test/CoordsTest.php b/src/arenas/tron/test/CoordsTest.php
new file mode 100644
index 0000000..e70966f
--- /dev/null
+++ b/src/arenas/tron/test/CoordsTest.php
@@ -0,0 +1,27 @@
+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);
+ }
+}
\ No newline at end of file
diff --git a/src/arenas/tron/test/DirectionTest.php b/src/arenas/tron/test/DirectionTest.php
new file mode 100644
index 0000000..89359b6
--- /dev/null
+++ b/src/arenas/tron/test/DirectionTest.php
@@ -0,0 +1,71 @@
+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);
+ }
+
+}
\ No newline at end of file
diff --git a/src/arenas/tron/test/TrailTest.php b/src/arenas/tron/test/TrailTest.php
new file mode 100644
index 0000000..fc3d5c0
--- /dev/null
+++ b/src/arenas/tron/test/TrailTest.php
@@ -0,0 +1,64 @@
+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) { }
+ }
+}
diff --git a/src/arenas_lists.php b/src/arenas_lists.php
index 2e990a9..cea47f7 100644
--- a/src/arenas_lists.php
+++ b/src/arenas_lists.php
@@ -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"
)
);
\ No newline at end of file
diff --git a/src/functions.php b/src/functions.php
index 45cc289..8fd041a 100644
--- a/src/functions.php
+++ b/src/functions.php
@@ -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
);
-}
\ No newline at end of file
+}