rewrite trongame

pull/96/head
root 8 years ago
parent 87d2c4cf1e
commit c4e99fccc7

@ -1 +1 @@
1726 1747

@ -1,14 +1,15 @@
<?php <?php
class Coords{ class Coords{
private $min = 0; private static $min = 0;
private $max = 999; private static $max = 999;
public $x; public $x;
public $y; public $y;
public function __construct(int $x = 0, int $y = 0) { public function __construct(int $x = 0, int $y = 0) {
if (($x < $this->min) || ($x > $this->max) || ($y < $this->min) || ($y > $this->max)){ if (($x < Coords::$min) || ($x > Coords::$max) || ($y < Coords::$min) || ($y > Coords::$max)){
//out of limits //out of limits
error_log("a bot out of limits");
return false; return false;
} }

@ -2,71 +2,57 @@
class ScoreLap class ScoreLap
{ {
private $playersIdsByOrder; //array containing id's of alive players at the beginning of the match, Put only alive bots in!
private $looserList; //idem but only loosers
public function addBotOnLap($order,$id){ private $participants; //array containing bots objects
$this->playersIdsByOrder[$order] = $id; private $loosers; //those who losed
public function addBotOnLap(TronPlayer $bot){
$this->participants[] = $bot;
} }
public function addLoser($order,$id){ public function addLoser(TronPlayer $bot){
$this->looserList[$order] = $order; $this->loosers[] = $bot;
} }
public function __construct() { public function __construct() {
$this->playersIdsByOrder = array(); $this->participants= array();
$this->looserList = array(); $this->loosers = array();
} }
public function getLoosersList(){ public function getLoosersList(){
return $this->looserList; return $this->$loosers;
} }
//NO! private function ApplyDraws(){
// public function make($botsList){
// //$botsList must be like array[{botOrder:BotId},{botOrder:BotId}]
// $this->looserList = $botsList;
// }
private function ApplyDraws(){
//apply draw match to all losers //apply draw match to all losers
if(count($this->looserList) > 1){ //no draw if only 0 or one user at this lap if(count($this->looserList) < 2) return;
foreach($looserList as $order1 => $looser1){
foreach($looserList as $order2 => $looser2){ foreach($loosers as $$looser1){
if($order1 <> $order2){ foreach($loosers as $looser2){
save_battle('tron', if($looser1->playerIndex == $looser2->playerIndex) continue;
$this->playersIdsByOrder[$looser1], save_battle('tron', $looser1->id, $looser2->id, 0, 'id' );
$this->playersIdsByOrder[$looser2],
0,
'id');
}
}
} }
} }
} }
private function ApplyWins(){
private function ApplyWins(){
//need to make losers List. simply array of orders //need to make losers List. simply array of orders
$loosersOrdersArr = array(); $loosersIndexArr = array();
foreach($this->looserList as $order => $looser){ foreach($this->looserList as $looser){
$loosersOrdersArr[] = $order; $loosersIndexArr[] = $looser->playerIndex;
} }
foreach($this->loosers as $looser){
foreach($this->looserList as $looserOrder => $looserId){ foreach($this->participants as $participant){
foreach($playersIdsByOrder as $order=>$player){ if(in_array($participant->playerIndex,$loosersIndexArr)) continue;
if(!in_array($order,$this->looserList)){ save_battle('tron', $looser->id, $participant->id, 2, 'id');
save_battle('tron',
$this->playersIdsByOrder[$looser],
$player,
2,
'id');
}
} }
} }
} }
public function ApplyScores(){ public function ApplyScores(){
$this-> ApplyDraws(); $this-> ApplyDraws();
$this-> ApplyWins(); $this-> ApplyWins();
} }
} }

@ -18,15 +18,14 @@ class Trail {
public function emptyTrail(){ public function emptyTrail(){
$this->trail = new SplStack(); $this->trail = new SplStack();
} }
public function mergeWith($trailToMerge){
foreach($trailToMerge as $value) {
$this->trail->add($value);
}
}
public function add($value) { public function add($value) {
if(!$this->trail->isEmpty()) { if(!$this->trail->isEmpty()) {
if(Trail::kind($this->trail->bottom()) !== Trail::kind($value)) { if(Trail::kind($this->trail->bottom()) !== Trail::kind($value)) {
//
// throw new TypeError(
// 'items added to a trail must be of the same kind'
// );
return false; return false;
} }
@ -43,7 +42,7 @@ class Trail {
public function __toString(){ public function __toString(){
return json_encode($this->getTrailAsArray()); return json_encode($this->getTrailAsArray());
} }
public function getTrailAsArray(){ public function getTrailAsArray(){
$arr = array(); $arr = array();
foreach($this->trail as $coord) { foreach($this->trail as $coord) {

@ -4,16 +4,38 @@ class TronGame
private $bots; //array of bots private $bots; //array of bots
public $gameId; public $gameId;
private $status; //false => Game ended or not initialised private $status; //false => Game ended or not initialised
private function getAliveBots(){
$aliveBots = array();
foreach($this->bots as $bot){
if($bot->isAlive){
$aliveBots[] = $bot;
}
}
return $aliveBots;
}
public function get_continue(){ private function getBotByPlayerIndex($index){
//count bots alive. if less than 1, game is ended
$count = 0;
foreach($this->bots as $bot){ foreach($this->bots as $bot){
if( $bot->isAlive == true){ if($bot->playerIndex == $index){
$count++; return $bot;
} }
} }
if($count > 1){ return false;
}
private function initScoring(){
/*
*Add all alive bots on a ScoreLap object and return it
*/
$scoring = new ScoreLap();
foreach($this->getAliveBots()as $bot){
$scoring->addBotOnLap($bot);
}
return $scoring;
}
public function get_continue(){
//count bots alive. if less than 1, game is ended
if(count($this->getAliveBots()) > 1){
return true; return true;
}else{ }else{
return false; return false;
@ -28,6 +50,14 @@ class TronGame
} }
return $trailsArr; return $trailsArr;
} }
private function get_map_as_an_unique_trail(){
$trail = new Trail;
foreach($this->bots as $bot){
$trail->mergeWith($bot->trail);
}
return trail;
}
public function get_lasts_trails(){ public function get_lasts_trails(){
//return only the lasts coords for each tail //return only the lasts coords for each tail
$trailsArr = array(); $trailsArr = array();
@ -37,83 +67,126 @@ class TronGame
return $trailsArr; return $trailsArr;
} }
public function new_lap(){ public function new_lap(){
// for all alive bots
$logs = ""; if($this->get_continue() === false){
$nbeBots = count($this->bots); return false;
$urls = array(); }
$paramToSend = array();
$board = $this->get_trails(); $scoreObj = $this->initScoring();
//$board = $this->get_lasts_trails(); $aliveBots = $this->getAliveBots();
$lastsCells = array();
$scoring = new ScoreLap(); //fixed Query parameters
$nbeBots = count($this->bots);
$board = $this->get_trails(); //same for each bot
$initialMapAsATrail = $this->get_map_as_an_unique_trail();
//Open curl multi
$cmh = curl_multi_init();
$ch = array();
for ($botCount = 0; $botCount < $nbeBots; $botCount++){
if ($this->bots[$botCount]->isAlive){
foreach($aliveBots as $bot){
$scoring->addBotOnLap($botCount,$this->bots[$botCount]->id); $i = $bot->playerIndex; //because $i is shorter
$urls[$botCount] = $this->bots[$botCount]->url;
$bodyRequestArr[$i] = array(
$paramsToSend[$botCount] = array(
'game-id' => "".$this->gameId, 'game-id' => "".$this->gameId,
'action' => 'play-turn', 'action' => 'play-turn',
'game' => 'tron', 'game' => 'tron',
'board' => $board, 'board' => $board,
'player-index' => $botCount, // To do: verifier que ça restera le même à chaque tour 'player-index' => $i,
'players' => $nbeBots 'players' => $nbeBots
); );
} $data_string = json_encode($bodyRequestArr[$i]);
$ch[$i] = curl_init($bot->url);
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]);
} }
$responses = $this->get_multi_IAS_Responses($urls,$paramsToSend);
//grow bots'tails //send the requests
for ($botCount = 0; $botCount < $nbeBots; $botCount++){ do {
if ($this->bots[$botCount]->isAlive){ $returnVal = curl_multi_exec($cmh, $runningHandles);
}while($runningHandles > 0);
//get results
foreach($ch as $playerIndex=>$cr){
$currentBot = $this->getBotByPlayerIndex($playerIndex);
// Check for errors
$curlError = curl_error($cr);
$response = curl_multi_getcontent($cr);
if(!$dir = Direction::make($responses[$botCount]['responseArr']['play'])){ if($curlError !== "") {
//he loses , non conform response //erreur curl, he loses
$scoring-> addLoser($botCount,$this->bots[$botCount]->id); $scoreObj-> addLoser($currentBot);
$this->bots[$botCount]->loose(); $currentBot->loose();
}else{
}elseif(! $arr = json_decode($response,TRUE)){
//la reponse n'est pas un json, il a perdu
$scoreObj-> addLoser($currentBot);
$currentBot->loose();
$lastsCells[$botCount] = $this->bots[$botCount]->grow($dir); }elseif(Direction::make($arr['play']) === false){
//tester ici la réponse
if($lastsCells[$botCount] === false){ //he loose il utilise probablement une de ses propres cases
//$loosers[] = $botCount; $scoreObj-> addLoser($currentBot);
$scoring-> addLoser($botCount,$this->bots[$botCount]->id); $currentBot->loose();
$this->bots[$botCount]->loose(); }elseif($initialMapAsATrail->contains($currentBot->trail->last()->addDirection(Direction::make($arr['play'])))){ //ounch
} //le bot tente d'aller sur une case qui était prise au début du round
$scoreObj-> addLoser($currentBot);
} $currentBot->loose();
}else{
//mettre de coté la direction du bot
$currentBot->nextDir = Direction::make($arr['play']);
} }
//close curl
curl_multi_remove_handle($cmh, $cr);
curl_close($cr);
} }
//test if loose
for ($botCount = 0; $botCount < $nbeBots; $botCount++){ $aliveBots = $this->getAliveBots();
if ($this->bots[$botCount]->isAlive){ //pour tous les bots encore vivants, on teste si deux d'entre eux ne cibleraient pas la même case
foreach ($aliveBots as $bot1){
//tester si collusion avec les cases actuelles foreach ($aliveBots as $bot2){
for( $botCount2 = 0; $botCount2 < $nbeBots; $botCount2++){ if($bot1-> $playerIndex == $bot2-> $playerIndex) continue;
if(($botCount <> $botCount2) if($bot1->trail->last()->addDirection($bot1->nextDir) == $bot2->trail->last()->addDirection($bot2->nextDir)){
&& ($this->bots[$botCount2]->trail->contains($lastsCells[$botCount])) //he loose
){ $scoreObj-> addLoser($bot1);
$bot1->loose();
$scoring-> addLoser($botCount,$this->bots[$botCount]->id); break;
$this->bots[$botCount]->loose();
break;
}
} }
} }
} }
//$this->apply_looses($loosersList); //ok, faire grossir les bots qui restent
foreach($this->getAliveBots() as $bot){
$bot-> applyNextDir();
}
//apply scores:
$scoreObj-> ApplyScores();
return array( return array(
'last_points' => $this->get_lasts_trails(), 'last_points' => $this->get_lasts_trails(),
'loosers' => $scoring->getLoosersList() 'loosers' => $scoreObj->getLoosersList()
); );
} }
private function get_multi_IAS_Responses($iasUrls, $postParams){ private function get_multi_IAS_Responses($iasUrls, $postParams){
//bug here le resultat retourné ne prend pas les bots ayant déjà perdus
//same as the get_IAS_Responses function //same as the get_IAS_Responses function
// but more than one bot requested parallely // but more than one bot requested parallely
@ -158,7 +231,7 @@ class TronGame
} }
$res[$i] = array( $res[$i] = array(
'messageSend' => json_encode($postParams[$i]), 'messageSend' => json_encode($postParams[$i]),
'response' => $response, 'response' => $response,
'httpStatus' => curl_getinfo($ch[$i])['http_code'], 'httpStatus' => curl_getinfo($ch[$i])['http_code'],
'responseArr' => $arr 'responseArr' => $arr
); );
@ -222,7 +295,7 @@ class TronGame
$startCoord = new Coords($x,$y); $startCoord = new Coords($x,$y);
$this->bots[$botCount] = new TronPlayer(); $this->bots[$botCount] = new TronPlayer();
$this->bots[$botCount]->make($bot['id'],$startCoord,$bot['name'],$bot['url']); $this->bots[$botCount]->make($bot['id'],$startCoord,$bot['name'],$bot['url'],$botCount);
if ($this->bots[$botCount]->isAlive === false){ if ($this->bots[$botCount]->isAlive === false){
$err .= "Something went wrong for ".$this->bots[$botCount]->getName()."<br/>"; $err .= "Something went wrong for ".$this->bots[$botCount]->getName()."<br/>";

@ -4,12 +4,14 @@ class TronPlayer{
public $id; public $id;
public $name; public $name;
public $trail; public $trail;
private $direction;
public $isAlive = true; public $isAlive = true;
public $playerIndex = -1; //if unset is -1
public $looseCause = "";
public $nextDir;
public function grow(Direction $dir){ public function grow(Direction $dir){
$dest = $this->trail->last()->addDirection($dir); $dest = $this->trail->last()->addDirection($dir);
if($dest == false){ if($dest === false){
$this->loose(); $this->loose();
return false; return false;
} }
@ -17,19 +19,25 @@ class TronPlayer{
$this->trail->add($this->trail->last()->addDirection($dir)); $this->trail->add($this->trail->last()->addDirection($dir));
return $this->trail->last(); return $this->trail->last();
} }
public function applyNextDir(){
$this-> grow($this->nextDir);
}
public function loose(){ public function loose(){
$this->isAlive = false; $this->isAlive = false;
$this->trail->emptyTrail(); $this->trail->emptyTrail();
//error_log($this->name." a perdu"); //error_log($this->name." a perdu");
return false; return false;
} }
public function make($botId, Coords $initialsCoords,$name,$url){ public function make($botId, Coords $initialsCoords,$name,$url,$playerIndex = -1){
$this->id = $botId; $this->id = $botId;
$this->trail = new Trail; $this->trail = new Trail;
$this->trail->add($initialsCoords); $this->trail->add($initialsCoords);
$this->name = $name; $this->name = $name;
$this->url = $url; $this->url = $url;
$this->state = true; $this->state = true;
$this->playerIndex = $playerIndex;
} }
public function __construct(){ public function __construct(){
$this->state = false; $this->state = false;

Loading…
Cancel
Save