This commit is contained in:
Gnieark 2016-11-08 19:27:55 +01:00
parent c4e99fccc7
commit 8ea8d66e05
7 changed files with 170 additions and 157 deletions

View File

@ -1 +1 @@
1747
1784

80
src/DUEL.php Normal file
View File

@ -0,0 +1,80 @@
<?php
class DUEL{
public $rank1;
public $rank2;
private $factor = 400;
public function __construct($r1,$r2){
$this->rank1 = $r1;
$this->rank2 = $r2;
}
private function get_k($rank){
if ($rank < 1000) return 80;
if ($rank < 2000) return 50;
if ($rank <= 2400) return 30;
return 20;
}
private function changeScores($score){
$this->rank1 = $this->rank1 + $this->get_k($this->rank1) * ($score - (1/ (1 + pow(10,(($this->rank2 - $this->rank1) / $this->factor)))));
$this->rank2 = $this->rank2 + $this->get_k($this->rank2) * (1 - $score - (1/ (1 + pow(10,(($this->rank1 - $this->rank2) / $this->factor)))));
}
public function oneWinsAgainstTwo(){
$this->changeScores(1);
}
public function twoWinsAgainstOne(){
$this->changeScores(0);
}
public function drawGame(){
$this->changeScores(0.5);
}
}
class ELO
{
public $rank = 1500; //default rank
public function __construct($v=1500) {
$this->rank = $v;
}
private function ELO_get_new_ranks($elo1,$elo2,$score){
/*
* return an array containing new ELO scores after a battle
* $score : 0 player 2 won
* 0.5 draws
* 1 player 1 won
*/
//good luck for understanding it
//(see https://blog.antoine-augusti.fr/2012/06/maths-et-code-le-classement-elo/)
return array(
$elo1 + ELO_get_k($elo1) * ($score - (1/ (1 + pow(10,(($elo2 - $elo1) / 400))))),
$elo2 + ELO_get_k($elo2) * (1 - $score - (1/ (1 + pow(10,(($elo1 - $elo2) / 400)))))
);
}
public function looseAgainst(ELO $winer){
}
public function winAgainst(ELO $looser){
}
public function drawAgainst(ELO $drawPlayer){
}
}

View File

@ -20,16 +20,22 @@ class ScoreLap
}
public function getLoosersList(){
return $this->$loosers;
//return losers as a digest array
$arr = array();
foreach($this->loosers as $looser){
$arr[] = array("id" => $looser->id,"order" => $looser->playerIndex);
}
return $arr;
}
private function ApplyDraws(){
//apply draw match to all losers
if(count($this->looserList) < 2) return;
if(count($this->loosers) < 2) return;
foreach($loosers as $$looser1){
foreach($loosers as $looser2){
foreach($this->loosers as $looser1){
foreach($this->loosers as $looser2){
if($looser1->playerIndex == $looser2->playerIndex) continue;
save_battle('tron', $looser1->id, $looser2->id, 0, 'id' );
}
@ -41,7 +47,7 @@ class ScoreLap
//need to make losers List. simply array of orders
$loosersIndexArr = array();
foreach($this->looserList as $looser){
foreach($this->loosers as $looser){
$loosersIndexArr[] = $looser->playerIndex;
}
foreach($this->loosers as $looser){

View File

@ -18,11 +18,18 @@ class Trail {
public function emptyTrail(){
$this->trail = new SplStack();
}
public function mergeWith($trailToMerge){
foreach($trailToMerge as $value) {
$this->trail->add($value);
}
public function getTrail(){
return $this->trail;
}
public function mergeWith($trailToMerge){
if($trailToMerge->getTrail()->isEmpty()) return;
foreach($trailToMerge->getTrail() as $value) {
$this->trail->push($value);
}
}
public function add($value) {
if(!$this->trail->isEmpty()) {
if(Trail::kind($this->trail->bottom()) !== Trail::kind($value)) {

View File

@ -48,14 +48,16 @@ class TronGame
foreach($this->bots as $bot){
$trailsArr[] = $bot->trail->getTrailAsArray();
}
//error_log("*********".json_encode($trailsArr,true)."********");
return $trailsArr;
}
private function get_map_as_an_unique_trail(){
$trail = new Trail;
foreach($this->bots as $bot){
$trail->mergeWith($bot->trail);
}
return trail;
return $trail;
}
public function get_lasts_trails(){
@ -125,24 +127,33 @@ class TronGame
$response = curl_multi_getcontent($cr);
if($curlError !== "") {
//erreur curl, he loses
$scoreObj-> addLoser($currentBot);
$currentBot->loose();
error_log("no curl response".$playerIndex); //debug
}elseif(! $arr = json_decode($response,TRUE)){
//la reponse n'est pas un json, il a perdu
$scoreObj-> addLoser($currentBot);
$currentBot->loose();
error_log("la reponse est pas JSON".$playerIndex); //debug
}elseif(Direction::make($arr['play']) === false){
//tester ici la réponse
//he loose il utilise probablement une de ses propres cases
$scoreObj-> addLoser($currentBot);
$currentBot->loose();
error_log("La reponse ne contient pas une direction".$playerIndex); //debug
}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();
error_log("Il joue sur une case deja prise".$playerIndex); //debug
}else{
//mettre de coté la direction du bot
$currentBot->nextDir = Direction::make($arr['play']);
@ -157,7 +168,7 @@ class TronGame
//pour tous les bots encore vivants, on teste si deux d'entre eux ne cibleraient pas la même case
foreach ($aliveBots as $bot1){
foreach ($aliveBots as $bot2){
if($bot1-> $playerIndex == $bot2-> $playerIndex) continue;
if($bot1->playerIndex == $bot2->playerIndex) continue;
if($bot1->trail->last()->addDirection($bot1->nextDir) == $bot2->trail->last()->addDirection($bot2->nextDir)){
//he loose
$scoreObj-> addLoser($bot1);
@ -183,74 +194,8 @@ class TronGame
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
// but more than one bot requested parallely
$cmh = curl_multi_init();
for ($i = 0; $i < count($iasUrls); $i++){
if(isset($postParams[$i])){ //dont use already deads bots
$data_string = json_encode($postParams[$i]);
//error_log($data_string);
$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($runningHandles > 0);
//Get results
for ($i = 0; $i < count($iasUrls); $i++){
if(isset($postParams[$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 = "";

View File

@ -141,7 +141,7 @@ Les champs qui différent sont:
&nbsp;&nbsp;]<br />
</p>
<p>L'ordre des "queues" des serpents dans ce tableau correspond à l'ordre des joueurs. Donc votre serpent est representée par la queue correspondant à player-index (le décompte de player-index commence par 0).</p>
<p>L'ordre des couples de coordonnées de chaque bot, est dans le sens queue vers la tête. Les bots grandissent à chaque tour en déplaçant leur tête.</p>
<p>L'ordre des couples de coordonnées de chaque bot, est dans le sens tête vers queue. Les bots grandissent à chaque tour en déplaçant leur tête.</p>
<h2>Scoring</h2>
<p>Le scorring (classement EHLO) reste sur une logique de duels, bien que ce jeu puisse contenir plus de deux bots par match. Le score est modifié au fur et à mesure de la partie à chaque fois qu'un bot "décède":</p>
<ul>

View File

@ -9,6 +9,7 @@
# http://www.gnu.org/licenses/gpl-3.0-standalone.html
#
# -- END LICENSE BLOCK -----------------------------------------
include(__DIR__."/DUEL.php");
function get_arenas_list(){
include (__DIR__."/arenas_lists.php");
@ -203,99 +204,73 @@ function ELO_get_podium($arena){
}
return $podium;
}
function ELO_get_k($elo){
if ($elo < 1000){
return 80;
}
if ($elo < 2000){
return 50;
}
if ($elo <= 2400){
return 30;
}
return 20;
}
function ELO_get_new_ranks($elo1,$elo2,$score){
function save_battle($game,$bot1,$bot2,$result,$nameOrIds = 'name'){
/*
* return an array containing new ELO scores after a battle
* $score : 0 player 2 won
* 0.5 draws
* 1 player 1 won
*/
//good luck for understanding it
//(see https://blog.antoine-augusti.fr/2012/06/maths-et-code-le-classement-elo/)
return array(
$elo1 + ELO_get_k($elo1) * ($score - (1/ (1 + pow(10,(($elo2 - $elo1) / 400))))),
$elo2 + ELO_get_k($elo2) * (1 - $score - (1/ (1 + pow(10,(($elo1 - $elo2) / 400)))))
);
}
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
* Calculate new ELO ranks and save them on conn_bdd
*/
global $lnMysql;
$game=substr($game,0,8); //limit 8 char for limitting mysql index size
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)."'");
for( $i=1; $i<3; $i++){
$str = "bot".$i;
$botName = $$str;
$rs=mysqli_query($lnMysql,"SELECT id,ELO FROM bots WHERE name='".mysqli_real_escape_string($lnMysql,$botName)."'");
$r = mysqli_fetch_row($rs);
$bot[$i] = array(
'id' => $r[0],
'ELO' => $r[1]
);
}
}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];
//the same, but query by id
for( $i=1; $i<3; $i++){
$str = "bot".$i;
$botName = $$str;
$rs=mysqli_query($lnMysql,"SELECT id,ELO FROM bots WHERE id='".mysqli_real_escape_string($lnMysql,$botName)."'");
$r = mysqli_fetch_row($rs);
$bot[$i] = array(
'id' => $r[0],
'ELO' => $r[1]
);
}
}
if((!isset($bots[$bot1])) OR (!isset($bots[$bot2]))){
error (500,"database corrupt");
die;
}
//apply $result
$duel = new DUEL( $bot[1]["ELO"] , $bot[2]["ELO"]);
switch($resultat){
switch ($result){
case 0:
$duel->drawGame();
$field="nulCount";
$eloScore = 0.5;
break;
case 1:
$field="player1_winsCount";
$eloScore = 1;
$duel->oneWinsAgainstTwo();
$field="player1_winsCount";
break;
case 2:
$field="player2_winsCount";
$eloScore = 0;
break;
$duel->twoWinsAgainstOne();
$field="player2_winsCount";
break;
default:
error (500,"something impossible has happened");
error (500,"Oups");
break;
}
$newRanks = ELO_get_new_ranks($actualELO[$bot1],$actualELO[$bot2],$eloScore);
mysqli_multi_query($lnMysql,
"
UPDATE bots
SET ELO='".$newRanks[0]."'
WHERE id='".$bots[$bot1]."';
UPDATE bots
SET ELO='".$newRanks[1]."'
WHERE id='".$bots[$bot2]."';
INSERT INTO arena_history(game,player1_id,player2_id,".$field.") VALUES
//update ELO rank on database
mysqli_multi_query($lnMysql,"
UPDATE bots SET ELO = '".$duel->rank1."' WHERE id='".$bot[1]["id"]."';
UPDATE bots SET ELO = '".$duel->rank2."' WHERE id='".$bot[2]["id"]."';
INSERT INTO arena_history(game,player1_id,player2_id,".$field.") VALUES
('".mysqli_real_escape_string($lnMysql,$game)."',
'".$bots[$bot1]."',
'".$bots[$bot2]."',
'".$bot[1]["id"]."',
'".$bot[2]["id"]."',
'1')
ON DUPLICATE KEY UPDATE ".$field." = ".$field." + 1;");
ON DUPLICATE KEY UPDATE ".$field." = ".$field." + 1;
");
}
function get_unique_id(){
//increment the number