Proudly hosted with Dreamhost

Save $20 when signing up for Dreamhost by using the promo code amnuts20
If you find these scripts useful to you, appreciate the free support, or are just an all round nice person, then why not donate a little dosh to encourage me to continue? Every little helps!
|
Battleships By Email (BBE)
Play battleships against an opponent via email! No database required as all information is passed along a URL.
A database is used in the script, however, to allow for recording of wins and losses.
One problem with this script is that Outlook's maximum querystring length seems to be 255 characters (or there abouts), and the URL created by this script is almost always longer than that. However, it works great with other mail clients such as Mozilla, Eudora, Pine, Elm, Mutt, etc.
index.php
<?
// // Battleships By Email // version 1.0.0 // // Andrew Collington, 2002 // php@amnuts.com, http://php.amnuts.com/ // include "setup.php";
?>
<html> <head> <title>BBE - Battleships By Email</title> <script language="JavaScript"> <!-- //
// compile info and send to website function sendAttack(data) { data += "&taunt=" + escape(document.theform.taunt.value); location.href = "<?=BBEURL?>?"+data; } // disable the 'return' key if (document.layers) document.captureEvents(Event.KEYDOWN); document.onkeydown = function (evt) { var keyCode = evt ? (evt.which ? evt.which : evt.keyCode) : event.keyCode; if (keyCode == 13) { return false; } else return true; };
// --> </script> </head>
<body bgcolor="white">
<?php
//------------------------------------------------------------------------ // Variable declarations //------------------------------------------------------------------------
$bs_struct = array( "turn" => PLAYER1, "players" => array( PLAYER1 => array( "email" => "", "last" => "" ), PLAYER2 => array( "email" => "", "last" => "" ) ), "ships" => array( PLAYER1 => $ships, PLAYER2 => $ships ), "boards" => array( PLAYER1 => init_board(), PLAYER2 => init_board() ), "hits" => array( PLAYER1 => init_board(), PLAYER2 => init_board() ) );
//------------------------------------------------------------------------ // Run the program //------------------------------------------------------------------------
if (isset($d)) $data = $d; // hack! if (!isset($data) || $data == "") { if (!$ns && ((!isset($uemail) || $uemail == "") || (!isset($oemail) || $oemail == ""))) { echo "<p>Hey there! I cannot find any game information, nor do I have your email ", "address, so I'm gonna guess this is a new game, right?.</p>\n"; echo "<p>So what I need you to do before you can start sinkin' some ships is give ", "me your email address and the email address of the person you wanna fight against. ", "Once I have those, you can start doing some damage.</p>\n"; echo "<p>So chuck 'em down in the text boxes supplied below.</p>\n"; echo "<form action=\"$PHP_SELF\" method=\"POST\">\n"; echo "<input type=\"hidden\" name=\"ns\" value=\"1\">\n"; echo "<p>Your email<br><input type=\"text\" size=\"50\" name=\"uemail\"></p>\n"; echo "<p>Your opponents email<br><input type=\"text\" size=\"50\" name=\"oemail\"></p>\n"; echo "<p><input type=\"submit\" value=\"let's do some damage!\"></p>\n</form>\n"; } else { if ($oemail == "" || $uemail == "") { echo "<p>How do you expect to play if you don't enter all the details, huh?</p>\n"; echo "<form action=\"$PHP_SELF\" method=\"POST\">\n"; echo "<input type=\"hidden\" name=\"ns\" value=\"1\">\n"; echo "<p>Your email<br><input type=\"text\" size=\"50\" name=\"uemail\" value=\"$uemail\"></p>\n"; echo "<p>Your opponents email<br><input type=\"text\" size=\"50\" name=\"oemail\" value=\"$oemail\"></p>\n"; echo "<p><input type=\"submit\" value=\"let's do some damage!\"></p>\n</form>\n"; } else if (!validate_email($uemail) || !validate_email($oemail)) { echo "<p>Hold hard there, bub! I need a <b>real</b> email address, thank you very much!</p>\n"; echo "<form action=\"$PHP_SELF\" method=\"POST\">\n"; echo "<input type=\"hidden\" name=\"ns\" value=\"1\">\n"; echo "<p>Your email<br><input type=\"text\" size=\"50\" name=\"uemail\" value=\"$uemail\"></p>\n"; echo "<p>Your opponents email<br><input type=\"text\" size=\"50\" name=\"oemail\" value=\"$oemail\"></p>\n"; echo "<p><input type=\"submit\" value=\"let's do some damage!\"></p>\n</form>\n"; } else { echo "<p>Okay, so I have your email. But I ain't got no game data. So just give me a second and I'll set it up.</p>\n"; echo "<p>Setting up the boards for you and your opponent</p>\n"; $ts = getmicrotime(); setup_placements(); $te = getmicrotime(); echo "<p>Okay, done that. It took all of ",showmicrotime($ts,$te)," seconds.</p>\n"; $bs_struct[players][PLAYER1][email] = $uemail; $bs_struct[players][PLAYER2][email] = $oemail; echo "<p>Right, now we're ready to sink some ships. Your boats are on the left, and where you're hitting your opponent is on the right. "; echo "Just click on a square (on the right table) to strike a hit, and hope it's bang on target!</p>\n"; echo "<p>If you want to taunt your opponent, then type your message in here before you make your move.</p>\n"; echo "<form action=\"\" name=\"theform\" method=\"get\"><p><input type=\"text\" size=\"50\" maxlength=\"128\" name=\"taunt\"></p></form>\n"; $whojustwent = PLAYER2; $whoishit = PLAYER1; display_boards_graphical(); } } } else { // get the structure and update player info $bs_struct = array(); $bs_struct = uncompress_structure_from_url($data);
// send the email or see results (sr = 1) if (isset($r)) $sr = $r; // hack! if (!isset($sr) || !$sr) { if ($bs_struct[turn] == PLAYER1) { $uemail = $bs_struct[players][PLAYER1][email]; $oemail = $bs_struct[players][PLAYER2][email]; } else { $uemail = $bs_struct[players][PLAYER2][email]; $oemail = $bs_struct[players][PLAYER1][email]; } $first = ($bs_struct[players][PLAYER1][last] == "" ? 1 : 0); // send the email send_move_email($uemail,$oemail,$first); echo "<p>Great! Now just wait and see what your opponent ($oemail) does next.</p>\n"; echo "<br><br><br><br><br><br><br>really... You can go away now. You have to wait for them. This is by email, remember?<br>\n"; } else { if ($bs_struct[turn] == PLAYER1) { $whojustwent = PLAYER1; $whoishit = PLAYER2; $bs_struct[players][PLAYER1][last] = sprintf("%s|%s|%s",$x,$y,$bs_struct[boards][$whoishit][$x][$y]); $bs_struct[turn] = PLAYER2; } else { $whojustwent = PLAYER2; $whoishit = PLAYER1; $bs_struct[players][PLAYER2][last] = sprintf("%s|%s|%s",$x,$y,$bs_struct[boards][$whoishit][$x][$y]); $bs_struct[turn] = PLAYER1; } // give report on what they last did, if they did anything if ($bs_struct[players][$whoishit][last] != "") { list ($oldx,$oldy,$oldhit,$oldsink) = explode("|",$bs_struct[players][$whoishit][last]); $sname = $ships[(get_ship_number($oldhit))][name]; echo "<p>Your last shot ({$oldx}-{$oldy}) ", ($bs_struct[boards][$whojustwent][$oldx][$oldy]!="0"?"scored a hit on their $sname":"missed big time!"), "</p>\n"; if ($oldsink != "-1") echo "<p>Way to go - you sunk their $sname!</p>\n"; } // show what just happened to them $id = get_ship_number($bs_struct[boards][$whoishit][$x][$y]); echo "<p>{$bs_struct[players][$whojustwent][email]} fired a shell at $x-$y and scored a ", ($id==-1?"miss!":"hit!"),"</p>\n"; if ($id == -1) { $bs_struct[hits][$whojustwent][$x][$y] = MISS; $bs_struct[players][$whojustwent][last] .= "|-1"; } else { $bs_struct[hits][$whojustwent][$x][$y] = HIT; $bs_struct[ships][$whoishit][$id][hits]++; // check sinkage if (is_sunk($bs_struct[ships][$whoishit],$id)) { echo "<p>Oh no! Your {$ships[$id][name]} has just been sunk!</p>\n"; $bs_struct[players][$whojustwent][last] .= "|$id"; } else { $bs_struct[players][$whojustwent][last] .= "|-1"; } } // give the display - if the game continues if (all_sunk($bs_struct[ships][$whoishit])) { echo "<p>All of your ships have been sunk! Glug, glug, glug.... You loose!</p>\n"; echo "<p><a href=\"$PHP_SELF\">Click here for a new game.</a></p>\n"; // send email to winner send_winner_email($bs_struct[players][$whoishit][email],$bs_struct[players][$whojustwent][email]); display_boards_graphical(1); record_stats(); } else { echo "<p>Now it's your turn to fire back.</p>\n"; echo "<p>If you want to taunt your opponent, then type your message in here before you make your move.</p>\n"; echo "<form action=\"\" name=\"theform\" method=\"get\"><p><input type=\"text\" size=\"50\" maxlength=\"128\" name=\"taunt\"></p></form>\n"; display_boards_graphical(); } } }
//------------------------------------------------------------------------ // Initalization //------------------------------------------------------------------------
function init_board() { for ($x=0; $x<BWIDTH; $x++) { for ($y=0; $y<BDEPTH; $y++) $board[$x][$y] = "0"; } return $board; }
//------------------------------------------------------------------------ // URL (de)compression //------------------------------------------------------------------------
function compress_board($board) { $newb = array(); for ($i=0; $i<BDEPTH; $i++) { $newb[$i] = join('',$board[$i]); } return join('^',$newb); }
function uncompress_board($board) { $foo = explode('^',$board); for ($i=0; $i<count($foo); $i++) { $newb[$i] = preg_split('//', $foo[$i], -1, PREG_SPLIT_NO_EMPTY); } return $newb; }
function compress_ships($ships) { $news = array(); for ($i=0; $i<SHIPTYPES; $i++) { $foo = array(); foreach($ships[$i] as $key => $value) $foo[] = "{$key}:{$value}"; $news[$i] = join("^",$foo); } return join("|",$news); }
function uncompress_ships($ships) { $foo = explode('|',$ships); for ($i=0; $i<count($foo); $i++) { $ship = explode('^',$foo[$i]); for ($s=0; $s<count($ship); $s++) { list($key,$value) = explode(":",$ship[$s]); $news[$i][$key] = $value; } } return $news; }
function compress_player($player) { $foo = array(); foreach($player as $key => $value) $foo[] = "{$key}:{$value}"; return join("^",$foo); }
function uncompress_player($player) { $foo = explode('^',$player); for ($p=0; $p<count($foo); $p++) { list($key,$value) = explode(":",$foo[$p]); $newp[$key] = $value; } return $newp; }
function compress_structure_for_url($struct) { $news = array(); $news['t'] = $struct[turn]; $news['p'] = compress_player($struct[players][PLAYER1]) . "~" . compress_player($struct[players][PLAYER2]); $news['s'] = compress_ships($struct[ships][PLAYER1]) . "~" . compress_ships($struct[ships][PLAYER2]); $news['b'] = compress_board($struct[boards][PLAYER1]) . "~" . compress_board($struct[boards][PLAYER2]); $news['h'] = compress_board($struct[hits][PLAYER1]) . "~" . compress_board($struct[hits][PLAYER2]); return urlencode(base64_encode(gzcompress(serialize($news)))); }
function uncompress_structure_from_url($struct) { $foo = unserialize(gzuncompress(base64_decode(urldecode($struct)))); // another hack!! list($p1,$p2) = ($foo[players]!="" ? explode('~',$foo['players']) : explode('~',$foo['p'])); list($s1,$s2) = ($foo[ships]!="" ? explode('~',$foo['ships']) : explode('~',$foo['s'])); list($b1,$b2) = ($foo[boards]!="" ? explode('~',$foo['boards']) : explode('~',$foo['b'])); list($h1,$h2) = ($foo[hits]!="" ? explode('~',$foo['hits']) : explode('~',$foo['h'])); $news = array( "turn" => $foo['t'], "players" => array( PLAYER1 => uncompress_player($p1), PLAYER2 => uncompress_player($p2) ), "ships" => array( PLAYER1 => uncompress_ships($s1), PLAYER2 => uncompress_ships($s2) ), "boards" => array( PLAYER1 => uncompress_board($b1), PLAYER2 => uncompress_board($b2) ), "hits" => array( PLAYER1 => uncompress_board($h1), PLAYER2 => uncompress_board($h2) ) ); if ($news[players][PLAYER1][turn] == 1) $news[turn] = PLAYER1; else if ($news[players][PLAYER2][turn] == 1) $news[turn] = PLAYER2; return $news; }
//------------------------------------------------------------------------ // Battleship functions //------------------------------------------------------------------------
function onboard($x,$y) { return ($x >= 0 && $x < BWIDTH && $y >= 0 && $y < BDEPTH); }
function is_ship($c) { return (preg_match("/[A-Z]/",$c) ? 1 : 0); }
function rnd($n) { return(((rand() & 0x7FFF) % $n)); }
function collidecheck($who, $y, $x) { global $bs_struct,$yincr,$xincr; $theboard = $bs_struct[boards][$who];
$collide = 0;
/* anything on the square */ if (($collide = is_ship($theboard[$x][$y])) != 0) return($collide);
/* anything on the neighbors */ for ($i = 0; $i < 8; $i++) { $xend = $yend = 0; $yend = $y + $yincr[$i]; $xend = $x + $xincr[$i]; if (onboard($xend, $yend) && is_ship($theboard[$xend][$yend])) { $collide = 1; break; } } return($collide); }
function checkplace($who, $ship) { global $bs_struct,$yincr,$xincr; $theship = $bs_struct[ships][$who][$ship]; /* first, check for board edges */ $xend = $theship[x] + ($theship[length] - 1) * $xincr[($theship[dir])]; $yend = $theship[y] + ($theship[length] - 1) * $yincr[($theship[dir])];
if (!onboard($xend, $yend)) return 0;
for ($l=0; $l<$theship[length]; ++$l) { if (collidecheck($who, $theship[y]+$l*$yincr[($theship[dir])], $theship[x]+$l*$xincr[($theship[dir])])) return 0; } return 1; }
function randomplace($who, $ship) { global $bs_struct; $theship = $bs_struct[ships][$who][$ship]; do { $theship[dir] = rnd(2) ? E : S; $theship[x] = rnd(BWIDTH - ($theship[dir] == E ? $theship[length] : 0)); $theship[y] = rnd(BDEPTH - ($theship[dir] == S ? $theship[length] : 0)); $bs_struct[ships][$who][$ship] = $theship; } while (!checkplace($who,$ship)); $bs_struct[ships][$who][$ship] = $theship; }
function placeship($who, $ship) { global $bs_struct,$yincr,$xincr; $theship = $bs_struct[ships][$who][$ship]; $theboard = $bs_struct[boards][$who];
for ($l=0; $l<$theship[length]; ++$l) { $newx = $theship[x] + $l * $xincr[($theship[dir])]; $newy = $theship[y] + $l * $yincr[($theship[dir])]; $theboard[$newx][$newy] = $theship[symbol]; } $theship[hits] = 0; $theship[placed] = 1; $bs_struct[boards][$who] = $theboard; $bs_struct[ships][$who][$ship] = $theship; }
function setup_placements() { srand((double)microtime()*1000000); for ($i=0; $i<SHIPTYPES; $i++) { randomplace(PLAYER1, $i); placeship(PLAYER1, $i); } for ($i=0; $i<SHIPTYPES; $i++) { randomplace(PLAYER2, $i); placeship(PLAYER2, $i); } }
function get_ship_number($id) { global $ships; for ($i=0; $i<SHIPTYPES; $i++) { if ($id == $ships[$i][symbol]) return $i; } return -1; }
function is_sunk($pships,$id) { if ($pships[$id][hits] == $pships[$id][length]) return 1; return 0; }
function all_sunk($pships) { for ($i=0; $i<SHIPTYPES; $i++) { if ($pships[$i][hits] != $pships[$i][length]) return 0; } return 1; }
//------------------------------------------------------------------------ // Viewing functions //------------------------------------------------------------------------
function display_boards_ascii() { global $bs_struct,$PHP_SELF,$whojustwent,$whoishit;
echo "\n\n<!--\n\n"; echo "Your board\n\n"; for ($i=0; $i<BDEPTH; $i++) { echo join(" ",$bs_struct[boards][$whoishit][$i]), "\n"; } echo "\n\nTheir board\n\n"; for ($i=0; $i<BDEPTH; $i++) { echo join(" ",$bs_struct[boards][$whojustwent][$i]), "\n"; } echo "\n\n-->\n\n"; }
function display_boards_graphical($winner=0) { global $bs_struct,$PHP_SELF,$whojustwent,$whoishit;
$b1 = urlencode(base64_encode(gzcompress(serialize(($bs_struct[boards][$whoishit]))))); $bh = urlencode(base64_encode(gzcompress(serialize(($bs_struct[hits][$whojustwent]))))); $h1 = urlencode(base64_encode(gzcompress(serialize(($bs_struct[hits][$whoishit]))))); echo "<table border=\"0\" cellpadding=\"10\">\n"; echo "<tr><td align=\"center\">your board</td><td align=\"center\">where you've hit</td><td> </td></tr>\n"; echo "<tr>\n"; echo "<td valign=\"middle\"><img src=\"makeboard.php?board=$b1&hits=$bh\" alt=\"your board\" border=\"0\"></td>\n"; echo "<td valign=\"middle\"><img src=\"makeboard.php?board=$h1\" alt=\"your hits\" usemap=\"#hits\" border=\"0\"></td>\n"; echo "<td valign=\"middle\"><br><img src=\"makelegend.php\" alt=\"legend\" border=\"0\"></td>\n"; echo "</tr>\n"; echo "<tr><td valign=\"top\">",display_statistics(),"</td></tr>\n</table>\n"; $data = compress_structure_for_url($bs_struct); if (!$winner) include("makemap.php"); }
function display_statistics() { global $bs_struct,$PHP_SELF,$whojustwent,$whoishit;
// how many shots in total, how many hits, how many misses, how many sunk
$hit = 0; $miss = 0; for ($y=0; $y<BDEPTH; $y++) { for ($x=0; $x<BWIDTH; $x++) { switch($bs_struct[hits][$whoishit][$y][$x]) { case HIT: $hit++; break; case MISS: $miss++; break; } } } $total = $hit+$miss; echo "<p>You have taken $total shot", ($total==1?"":"s"), "<br>\n"; echo "$hit ",($hit==1?"was a hit":"were hits"),"<br>\n"; echo "$miss ",($miss==1?"was a miss":"were misses"),".</p>\n";
$sunk = 0; for ($i=0; $i<SHIPTYPES; $i++) { if (is_sunk($bs_struct[ships][$whojustwent],$i)) $sunk++; } echo "<p>You have sunk $sunk ship", ($sunk==1?"":"s"), " of theirs.</p>\n";
}
//------------------------------------------------------------------------ // Email functions //------------------------------------------------------------------------
function validate_email($email="") { if (eregi("[0-9a-z]([-_.]?[0-9a-z])*@[0-9a-z]([-.]?[0-9a-z])*\\.[a-z]{2,3}", $email)) return 1; else return 0; }
function send_move_email($uemail="",$oemail="",$first=0) { global $data,$x,$y,$taunt;
if ($uemail=="" || $oemail=="") return; $headers = "From: $uemail\n"; $headers .= "Return-Path: $uemail\n"; $headers .= "X-Mailer: BBE - Battleships By Email\n"; if ($first) $body = "\n$uemail has challenged you to a game of Battleships by email.\n\n"; else $body = "\n$uemail returns fire and tried to blow up more of your battleships.\n\n"; if ($taunt != "") { $body.= "They had this to say to you:\n\n" . stripslashes($taunt) . "\n\n"; } $body .= "To see what they did, click on the following link to the BBE (Battleships By Email) website.\n\n"; $body .= BBEURL . "?d=" . urlencode($data) . "&x=$x&y=$y&r=1\n\n"; $body .= "\nOf course, if you wanna play chicken and not lose to your opponent (did we say lose? We meant beat, of course ;) "; $body .= "then just don't reply to this email. Just delete it and forget that $uemail ever existed!\n\n"; $body .= "Hugs 'n' stuff, BBE Staff\n\n"; $body = wordwrap($body,78); @mail($oemail,"Battleships By Email: Your move!",$body,$headers); }
function send_winner_email($uemail="",$oemail="") { global $data,$x,$y;
$headers = "From: $uemail\n"; $headers .= "Return-Path: $uemail\n"; $headers .= "X-Mailer: BBE - Battleships By Email\n"; $body = "\nUh-oh! $uemail hates to tell you this, but you're the Big Winner.\n\n"; $body .= "You managed to kick severe bootie, sunk all their ships, and generally made them "; $body .= "feel rather sad and pathetic (we think you should send chocolates to apologise!).\n\n"; $body .= "Click on the link below to see the glorious last shot.\n\n"; $body .= BBEURL . "?d=" . urlencode($data) . "&x=$x&y=$y&r=1\n\n"; $body .= "\nHugs 'n' stuff, BBE Staff\n\n"; $body = wordwrap($body,78); @mail($oemail,"Battleships By Email: You won!",$body,$headers); }
//------------------------------------------------------------------------ // Timing functions //------------------------------------------------------------------------
function getmicrotime() { list($usec, $sec) = explode(" ",microtime()); return ((float)$usec + (float)$sec); }
function showmicrotime($t1,$t2) { $time = $t2 - $t1; echo sprintf("%0.05f",$time); }
//------------------------------------------------------------------------ // database functions //------------------------------------------------------------------------
function record_stats() { global $dbVars,$bs_struct,$whoishit,$whojustwent; if (($id = @mysql_connect($dbVars['host'],$dbVars['user'],$dbVars['pass']))) { if (@mysql_select_db($dbVars['name'],$id)) { $result = @mysql_query("SELECT id FROM {$dbVars['tbl_results']} WHERE email='{$bs_struct['players'][$whoishit]['email']}'",$id); // looser if (@mysql_num_rows($result)) { @mysql_query("UPDATE {$dbVars['tbl_results']} SET lost=lost+1 WHERE email='{$bs_struct['players'][$whoishit]['email']}'",$id); } else { @mysql_query("INSERT INTO {$dbVars['tbl_results']} (email,won,lost) VALUES ('{$bs_struct['players'][$whoishit]['email']}',0,1)",$id); } // winner $result = @mysql_query("SELECT id FROM {$dbVars['tbl_results']} WHERE email='{$bs_struct['players'][$whojustwent]['email']}'",$id); if (@mysql_num_rows($result)) { @mysql_query("UPDATE {$dbVars['tbl_results']} SET won=won+1 WHERE email='{$bs_struct['players'][$whojustwent]['email']}'"); } else { @mysql_query("INSERT INTO {$dbVars['tbl_results']} (email,won,lost) VALUES ('{$bs_struct['players'][$whojustwent]['email']}',1,0)"); } } } }
?>
</body> </html>
20.36kb in size last modified May 6, 2006 at 1:54pm 6172 views, 6373 downloads
makeboard.php
3.29kb in size last modified May 6, 2006 at 1:54pm 4708 views, 5552 downloads
makelegend.php
3.29kb in size last modified May 6, 2006 at 1:54pm 4772 views, 5478 downloads
makemap.php
437b in size last modified May 6, 2006 at 1:54pm 4432 views, 5501 downloads
setup.php
2.27kb in size last modified May 6, 2006 at 1:54pm 4523 views, 5571 downloads
|