This commit is contained in:
Gnieark 2016-06-15 01:09:21 +02:00
parent f6cade5fe3
commit 2d1c0575c6
2 changed files with 178 additions and 343 deletions

View File

@ -1,142 +1,58 @@
<?php <?php
/*
Bot for connectfour https://botsarena.tinad.fr/connectFour
by Gnieark https://blog-du-grouik.tinad.fr/ june 2016
GNU GPL License
+--+--+--+--+--+--+--+
5 | | | | | | | |
+--+--+--+--+--+--+--+
4 | | | | | | | |
+--+--+--+--+--+--+--+
3 | | | | | | | |
+--+--+--+--+--+--+--+
2 | | | | | | | |
+--+--+--+--+--+--+--+
1 | | | | | | | |
+--+--+--+--+--+--+--+
0 | | | | | | | |
+--+--+--+--+--+--+--+
0 1 2 3 4 5 6
*/
header('Access-Control-Allow-Origin: *'); header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: GET, POST'); header('Access-Control-Allow-Methods: GET, POST');
header('Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept'); header('Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept');
/* function can_win($line,$myChar){
* stupid IA for battle ship //retourne la position du caractere a remplacer dans la ligne pour gagner
* choose by random a free column
*/
function score($board,$me,$opponent,$colToPlay,$depth){ if (strpos("+".$myChar.$myChar.$myChar,$line) !== false ){
return strpos("+".$myChar.$myChar.$myChar,$line);
$newBoard = $board;
//add cell
for($y = 0; $board[$y][$colToPlay] <> "+"; $y++){
}
$newBoard[$y][$colToPlay] = $me;
//do I win?
$searchValue="";
for($i = 0 ; $i < 4; $i++){
$searchValue.=$me;
}
//horizontaly
$line="";
for ($i=0; $i < 7; $i++){
$line.=$newBoard[$y][$i];
}
if(strpos($searchValue,$line) !== false ){
return 200;
}
//verticaly
$line="";
for ($i=0; $i < 6; $i++){
$line.=$newBoard[$i][$colToPlay];
}
//echo $line."p".$searchValue." ".strpos($searchValue,$line)."|\n";
if(strpos($searchValue,$line) !== false){
return 200;
}
//diagonal \
$line="";
$b = $y + $colToPlay;
if($b < 6){
$ix = 0;
$iy = $b;
}else{
$ix = $b - 5;
$iy = 5;
}
for($jx = $ix, $jy = $iy; ($jx < 7) && ($jy > -1); $jx++, $jy--){
$line.=$newBoard[$jy][$jx];
}
if(strpos($searchValue,$line) !== false ){
return 200;
}
//diagonal /
$b = $y - $colToPlay;
if($b > -1){
$ix = 0;
$iy = $b;
}else{
$iy=0;
$ix = -$b;
}
$line="";
for ($jx = $ix , $jy = $iy ; ($jx < 7) && ($jy < 6) ; $jx++ , $jy++){
$line.=$newBoard[$jy][$jx];
}
if(strpos($searchValue,$line) !== false){
return 200;
}
//if grid is full
$full = true;
for($i = 0; $i < 7; $i++){
if($newBoard[5][$i] == "+"){
$full = false;
break;
} }
} if (strpos($myChar.$myChar.$myChar."+",$line) !== false ){
if($full){ return strpos($myChar.$myChar.$myChar."+",$line) + 3;
return 0; }
} return false;
if($depth < 6){
//CO
if(($depth % 2) == 0){
return better_col($newBoard,$opponent,$me,$depth + 1) - $depth;
}else{
return $depth - better_col($newBoard,$opponent,$me,$depth + 1);
}
}else{
return 0;
}
} }
function can_loose($line,$hisChar){
function worst_col($board,$me,$opponent,$depth){ //je pourrai perdre aux 2 prochains tours de jeu
$worstScore= 1000; // retourne la place du caractere à remplacer pour éviter ça
$worstCol= -1; if (strpos("+".$hisChar.$hisChar.$hisChar,$line) !== false ){
for( $i = 0; $i < 7; $i++){ return strpos("+".$hisChar.$hisChar.$hisChar,$line);
if($board[5][$i] == "+"){
$sc = score($board,$me,$opponent,$i,$depth);
if( $sc < $worstScore){
$worstScore = $sc -$depth;
$worstCol = $i;
//echo $i.":".$sc."|";
}
} }
} if (strpos($hisChar.$hisChar.$hisChar."+",$line) !== false ){
return $worstScore; return strpos($hisChar.$hisChar.$hisChar."+",$line) + 3;
}
if (strpos("+".$hisChar.$hisChar."+",$line) !== false ){
return strpos("+".$hisChar.$hisChar."+",$line);
}
return false;
} }
function better_col($board,$me,$opponent,$depth){
$betterScore= -1000;
$betterCol= -1;
for( $i = 0; $i < 7; $i++){
if($board[5][$i] == "+"){
$sc = score($board,$me,$opponent,$i,$depth);
if( $sc > $betterScore){
$betterScore = $sc;
$betterCol = $i;
//echo $i.":".$sc."|";
}
}
}
return $betterCol;
}
//replace "" by " ", it will simplify my code. //replace "" by " ", it will simplify my code.
$in=str_replace('""','"+"',file_get_contents('php://input')); $in=str_replace('""','"_"',file_get_contents('php://input'));
$params=json_decode($in, TRUE); $params=json_decode($in, TRUE);
switch($params['action']){ switch($params['action']){
@ -144,12 +60,22 @@ switch($params['action']){
echo '{"name":"Gnieark"}'; echo '{"name":"Gnieark"}';
break; break;
case "play-turn": case "play-turn":
//find $opponent //find $opponent and clean grid
for($x = 0; $x < 7 ; $x++){ for($x = 0; $x < 7 ; $x++){
for($y = 0; $y < 6 ; $y++){ for($y = 0; $y < 6 ; $y++){
if(($params['board'][$y][$x] <> "+" ) && ($params['board'][$y][$x] <> $params['you'] )){
//find opponent
if(($params['board'][$y][$x] <> "_" ) && ($params['board'][$y][$x] <> $params['you'] )){
$opponent= $params['board'][$y][$x]; $opponent= $params['board'][$y][$x];
} }
//tester si la case est jouable (s'il y a un support en dessous)
if (($params['board'][$y][$x] == "_" )
AND (($y==0) OR ($params['board'][$y - 1][$x] <> "_"))
){
//la case est jouable, je la marque par un "+"
$params['board'][$y][$x] = "+";
}
} }
} }
if((!isset($opponent)) && ($params['you'] == "X")){ if((!isset($opponent)) && ($params['you'] == "X")){
@ -158,7 +84,126 @@ switch($params['action']){
$opponent="X"; $opponent="X";
} }
echo '{"play":"'.better_col($params['board'],$params['you'],$opponent,0).'"}'; //transformer la grille en lignes horizontales, verticales et diagonales
//verticales
for($x = 0; $x <7; $x ++){
$colStr="";
for($y = 0; $y <6; $y ++){
$colStr.= $params['board'][$y][$x];
}
if(can_win($colStr,$params['you']) !== false){
echo '{"play":'.$x.'}';
die;
}
if (can_loose($colStr,$opponent) !== false){
$colForNoLose = $x;
}
}
//horizontales
for($y = 0; $y <6; $y ++){
$lnStr="";
for($x = 0; $x <7; $x ++){
$lnStr.= $params['board'][$y][$x];
}
if(can_win($lnStr,$params['you']) !== false){
echo '{"play":'.can_win($lnStr,$params['you']).'}';
die;
}
if (can_loose($lnStr,$opponent) !== false){
$colForNoLose = can_loose($lnStr,$opponent);
}
}
//tester seulement les diagonales >= 4 cases
for ($k = 0; $k < 4; $k ++){
//diagonale /
$diagStr="";
for($x=$k , $y=0; isset($params['board'][$y][$x]); $x++, $y++){
$diagStr.=$params['board'][$y][$x];
}
if(can_win($diagStr,$params['you']) !== false){
echo '{"play":'.$x.'}';
die;
}
if (can_loose($diagStr,$opponent) !== false){
$colForNoLose = $x;
}
//diagonale \
$diagStr="";
for($x=$k , $y=5; isset($params['board'][$y][$x]); $x++, $y--){
$diagStr.=$params['board'][$y][$x];
}
if(can_win($diagStr,$params['you']) !== false){
echo '{"play":'.$x.'}';
die;
}
if (can_loose($diagStr,$opponent) !== false){
$colForNoLose = $x;
}
}
for ($k = 0; $k < 3; $k ++){
//diagonale /
$diagStr="";
for($x = 0, $y = $k ; isset($params['board'][$y][$x]); $x++, $y++){
$diagStr.=$params['board'][$y][$x];
}
if(can_win($diagStr,$params['you']) !== false){
echo '{"play":'.$x.'}';
die;
}
if (can_loose($diagStr,$opponent) !== false){
$colForNoLose = $x;
}
}
for ($k = 3 ; $k < 6 ; $k++){
//diagonales \
$diagStr="";
for($x=0 , $y=$k; isset($params['board'][$y][$x]); $x++, $y--){
$diagStr.=$params['board'][$y][$x];
}
if(can_win($diagStr,$params['you']) !== false){
echo '{"play":'.$x.'}';
die;
}
if (can_loose($diagStr,$opponent) !== false){
$colForNoLose = $x;
}
}
//si j'arrive là, je ne gagne pas à ce tour
if(isset($colForNoLose)){
echo '{"play":'.$colForNoLose.'}';
die;
}
//still there? random
$colAvailable=array();
//dont play on full colomns
for($i=0;$i<7;$i++){
if(($params['board'][5][$i] == "+") OR ($params['board'][5][$i] == "_")){
$colAvailable[]=$i;
}
}
shuffle($colAvailable);
echo '{"play":'.$colAvailable[0].'}';
//echo '{"play":"'.better_col($params['board'],$params['you'],$opponent,0).'"}';
break; break;
default: default:
break; break;

View File

@ -1,210 +0,0 @@
<?php
/*
Bot for connectfour https://botsarena.tinad.fr/connectFour
by Gnieark https://blog-du-grouik.tinad.fr/ june 2016
GNU GPL License
+--+--+--+--+--+--+--+
5 | | | | | | | |
+--+--+--+--+--+--+--+
4 | | | | | | | |
+--+--+--+--+--+--+--+
3 | | | | | | | |
+--+--+--+--+--+--+--+
2 | | | | | | | |
+--+--+--+--+--+--+--+
1 | | | | | | | |
+--+--+--+--+--+--+--+
0 | | | | | | | |
+--+--+--+--+--+--+--+
0 1 2 3 4 5 6
*/
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: GET, POST');
header('Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept');
function can_win($line,$myChar){
//retourne la position du caractere a remplacer dans la ligne pour gagner
if (strpos("+".$myChar.$myChar.$myChar,$line) !== false ){
return strpos("+".$myChar.$myChar.$myChar,$line);
}
if (strpos($myChar.$myChar.$myChar."+",$line) !== false ){
return strpos($myChar.$myChar.$myChar."+",$line) + 3;
}
return false;
}
function can_loose($line,$hisChar){
//je pourrai perdre aux 2 prochains tours de jeu
// retourne la place du caractere à remplacer pour éviter ça
if (strpos("+".$hisChar.$hisChar.$hisChar,$line) !== false ){
return strpos("+".$hisChar.$hisChar.$hisChar,$line);
}
if (strpos($hisChar.$hisChar.$hisChar."+",$line) !== false ){
return strpos($hisChar.$hisChar.$hisChar."+",$line) + 3;
}
if (strpos("+".$hisChar.$hisChar."+",$line) !== false ){
return strpos("+".$hisChar.$hisChar."+",$line);
}
return false;
}
//replace "" by " ", it will simplify my code.
$in=str_replace('""','"_"',file_get_contents('php://input'));
$params=json_decode($in, TRUE);
switch($params['action']){
case "init":
echo '{"name":"Gnieark"}';
break;
case "play-turn":
//find $opponent and clean grid
for($x = 0; $x < 7 ; $x++){
for($y = 0; $y < 6 ; $y++){
//find opponent
if(($params['board'][$y][$x] <> "_" ) && ($params['board'][$y][$x] <> $params['you'] )){
$opponent= $params['board'][$y][$x];
}
//tester si la case est jouable (s'il y a un support en dessous)
if (($params['board'][$y][$x] == "_" )
AND (($y==0) OR ($params['board'][$y - 1][$x] <> "_"))
){
//la case est jouable, je la marque par un "+"
$params['board'][$y][$x] = "+";
}
}
}
if((!isset($opponent)) && ($params['you'] == "X")){
$opponent="O";
}elseif(!isset($opponent)){
$opponent="X";
}
//transformer la grille en lignes horizontales, verticales et diagonales
//verticales
for($x = 0; $x <7; $x ++){
$colStr="";
for($y = 0; $y <6; $y ++){
$colStr.= $params['board'][$y][$x];
}
if(can_win($colStr,$params['you']) !== false){
echo '{"play":'.$x.'}';
die;
}
if (can_loose($colStr,$opponent) !== false){
$colForNoLose = $x;
}
}
//horizontales
for($y = 0; $y <6; $y ++){
$lnStr="";
for($x = 0; $x <7; $x ++){
$lnStr.= $params['board'][$y][$x];
}
if(can_win($lnStr,$params['you']) !== false){
echo '{"play":'.can_win($lnStr,$params['you']).'}';
die;
}
if (can_loose($lnStr,$opponent) !== false){
$colForNoLose = can_loose($lnStr,$opponent);
}
}
//tester seulement les diagonales >= 4 cases
for ($k = 0; $k < 4; $k ++){
//diagonale /
$diagStr="";
for($x=$k , $y=0; isset($params['board'][$y][$x]); $x++, $y++){
$diagStr.=$params['board'][$y][$x];
}
if(can_win($diagStr,$params['you']) !== false){
echo '{"play":'.$x.'}';
die;
}
if (can_loose($diagStr,$opponent) !== false){
$colForNoLose = $x;
}
//diagonale \
$diagStr="";
for($x=$k , $y=5; isset($params['board'][$y][$x]); $x++, $y--){
$diagStr.=$params['board'][$y][$x];
}
if(can_win($diagStr,$params['you']) !== false){
echo '{"play":'.$x.'}';
die;
}
if (can_loose($diagStr,$opponent) !== false){
$colForNoLose = $x;
}
}
for ($k = 0; $k < 3; $k ++){
//diagonale /
$diagStr="";
for($x = 0, $y = $k ; isset($params['board'][$y][$x]); $x++, $y++){
$diagStr.=$params['board'][$y][$x];
}
if(can_win($diagStr,$params['you']) !== false){
echo '{"play":'.$x.'}';
die;
}
if (can_loose($diagStr,$opponent) !== false){
$colForNoLose = $x;
}
}
for ($k = 3 ; $k < 6 ; $k++){
//diagonales \
$diagStr="";
for($x=0 , $y=$k; isset($params['board'][$y][$x]); $x++, $y--){
$diagStr.=$params['board'][$y][$x];
}
if(can_win($diagStr,$params['you']) !== false){
echo '{"play":'.$x.'}';
die;
}
if (can_loose($diagStr,$opponent) !== false){
$colForNoLose = $x;
}
}
//si j'arrive là, je ne gagne pas à ce tour
if(isset($colForNoLose)){
echo '{"play":'.$colForNoLose.'}';
die;
}
//still there? random
$colAvailable=array();
//dont play on full colomns
for($i=0;$i<7;$i++){
if(($params['board'][5][$i] == "+") OR ($params['board'][5][$i] == "_")){
$colAvailable[]=$i;
}
}
shuffle($colAvailable);
echo '{"play":'.$colAvailable[0].'}';
//echo '{"play":"'.better_col($params['board'],$params['you'],$opponent,0).'"}';
break;
default:
break;
}