Joshua Radin
June 25th, 2006
Here’s another great great musician I found recently on MySpace.com, Joshua Radin
Dave Naffis Merchandise
June 16th, 2006
Show everyone how cool you are with your very own Dave Naffis gear. http://www.naffis.com/blog/pages/merchandise
Tic-Tac-Toe PHP Script
June 12th, 2006
Here’s a PHP script that plays Tic-Tac-Toe. It’s pretty dumb, makes completely random moves.
This was the starting point for a tic-tac-toe game that used a Bayes classifier classifier (Bayesian? see Baye’s Theorem) to decide its next move.
You can play it here http://www.naffis.com/randomstuff/ttt.php ttt.php
<?php
$boxes = array("", "", "", "", "", "", "", "", "");
if($HTTP_POST_VARS) {
for($i = 0; $i < count($boxes); $i++) {
$boxes[$i]= $HTTP_POST_VARS['move'.$i];
}
}
$winner = checkForWin($boxes);
$done = checkDone($boxes);
if($winner == '' && !$done) {
if(!isFirstMove($boxes)) {
$move = makeMove($boxes);
$boxes[$move] = 'o';
$winner = checkForWin($boxes);
}
}
?>
Javascript and Style info:
<script language="JavaScript">
function makeMove(cell) {
var formCell = eval("document.ttt."+cell);
if(document.ttt.play.value != '') {
alert('The game is over');
return;
}
if(formCell.value == 'x') {
alert('You already moved there');
return;
}
if(formCell.value == 'o') {
alert('You cannot move there');
return;
}
formCell.value = 'x';
document.ttt.submit();
}
</script>
<style type="text/css">
.main{
border:#9999CC solid 2px;
width:500px
}
.but{
font-family:comic sans ms,verdana,arial,helvetica;
font-size:30pt;
font-weight:bold;
background:#3300FF;
width:100px;
height:100px;
border:#000000 solid 1px;
cursor:hand;
color:#EFEFFF
}
.but_o{
font-family:comic sans ms,verdana,arial,helvetica;
font-size:30pt;
font-weight:bold;
background:#EFEFFF;
width:100px;
height:100px;
border:#CC0000 solid 1px;
cursor:hand;
color:#9999CC
}
.but_d{
font-family:comic sans ms,verdana,arial,helvetica;
font-size:30pt;
font-weight:bold;
background:#EFEFFF;
width:100px;
height:100px;
border:#CC0000 solid 1px;
cursor:hand;
color:#EFEFFF
}
</style>
Playing Board:
<?php
echo "<form name=ttt method=post action=ttt.php>";
echo "<input type=hidden name=play value=".$winner.">";
echo "<table cellspacing=0 cellpadding=0 border=0 align=center width=300 height=300>";
for($i = 0; $i < count($boxes); $i++) {
if(($i+1) % 3 == 1)
echo '<tr>';
echo '<td valign=middle align=center>';
echo "<input value='".$boxes[$i]."' type=button name=move class=but onclick=makeMove('move".$i.$j."') onMouseover=\"this.className='but_o'\" onMouseout=\"this.className='but'\" onMousedown=\"this.className='but_d'\">";
echo '<input type=hidden name=\'move'.$i.'\' value=\''.$boxes[$i].'\'>';
echo '</td>';
if(($i+1) % 3 == 0)
echo '</tr>';
}
echo "</table>";
echo "</form>";
echo "<br>";
echo "<center><font size=6 color=blue>";
if($winner == 'x') {
echo 'X Wins';
echo "<br>";
echo "<a href=http://www.naffis.com/randomstuff/ttt.php>Play Again</a>";
}
else if($winner == 'o') {
echo 'O Wins';
echo "<br>";
echo "<a href=http://www.naffis.com/randomstuff/ttt.php>Play Again</a>";
}
else if($winner == '' && $done) {
echo 'Tie Game';
echo "<br>";
echo "<a href=http://www.naffis.com/randomstuff/ttt.php>Play Again</a>";
}
echo "</font></center>";
?>
Handle the moves:
<?php
// check if someone won
function checkForWin($boxarray) {
// 0 1 2 = 3
// 3 4 5 = 12
// 6 7 8 = 21
// 0 3 6 = 9
// 1 4 7 = 12
// 2 5 8 = 15
// 0 4 8 = 12
// 2 4 6 = 12
$winner = '';
if($boxarray[0] == $boxarray[1] && $boxarray[1] == $boxarray[2])
$winner = $boxarray[0];
else if($boxarray[3] == $boxarray[4] && $boxarray[4] == $boxarray[5])
$winner = $boxarray[3];
else if($boxarray[6] == $boxarray[7] && $boxarray[7] == $boxarray[8])
$winner = $boxarray[6];
else if($boxarray[0] == $boxarray[3] && $boxarray[3] == $boxarray[6])
$winner = $boxarray[0];
else if($boxarray[1] == $boxarray[4] && $boxarray[4] == $boxarray[7])
$winner = $boxarray[1];
else if($boxarray[2] == $boxarray[5] && $boxarray[5] == $boxarray[8])
$winner = $boxarray[2];
else if($boxarray[0] == $boxarray[4] && $boxarray[4] == $boxarray[8])
$winner = $boxarray[0];
else if($boxarray[2] == $boxarray[4] && $boxarray[4] == $boxarray[6])
$winner = $boxarray[2];
return $winner;
}
function isFirstMove($boxarray) {
// check if this is the first move
$firstmove = true;
for($i = 0; $i < count($boxarray); $i++) {
if($boxarray[$i] != '')
$firstmove = false;
}
return $firstmove;
}
function makeMove($boxarray) {
// computer makes a move
// pick a random box to move to (0 to 8)
srand((double)microtime()*1000000);
$slot = rand(0,8);
while($boxarray[$slot] == 'x' || $boxarray[$slot] == 'o')
$slot = rand(0,8);
return $slot;
}
function checkDone($boxarray) {
$done = true;
for($i = 0; $i < count($boxarray); $i++) {
if($boxarray[$i] == '')
$done = false;
}
return $done;
}
?>
Running Command Line Tools from Ruby or RoR
June 8th, 2006
A recent project of mine was a website which allowed users to upload and share videos. The requirement was to take the uploaded videos and convert them on-the-fly in real time to various formats to support flash, psp, ipod, mobile phones and some others. ffmpeg turned out to be the best free option on linux.
So how do you execute something like ffmpeg on the command line from your Ruby or RoR app? Basically by using backticks.
Here’s an example that converts your original file to a flash video file:
def create_flash(mainfile, flashfile)
args = "-i #{mainfile} -s 400x400 #{flashfile}"
output = run_command("ffmpeg", args)
logger.info(output)
end
def run_command(command, *args)
args = args.collect {|a| a.to_s}
output = `#{command} #{args.join(' ')}`
if $? != 0
return "ffmpeg command (#{command} #{args.join(' ')}) failed: Error Given #{$?}"
else
return output
end
end
DRY database config with Rails
June 6th, 2006
During the process of installing Typo I noticed something interesting in the database.yml file.
It turns out that the Rails database config file is written in YAML (http://www.yaml.org/) which is a data serialization format with a lot of nifty features. I just skimmed through the specs which can be found here: http://yaml.org/spec/current.html
Anyway, one of my pet peeves so far with setting up applications has been rewriting database config information. For small non-production projects I don’t use separate test, development, and production databases. Or sometimes the username, password and host are the same for each database. So why repeat that information over and over and over? Turns out you can save yourself a few lines of editing by doing something like this:
login: &login
adapter: mysql
host: localhost
username: dbusername
password: supersecretpassword
development:
database: myapp_development
<<: *login
test:
database: myapp_test
<<: *login
production:
database: myapp_production
<<: *login
New Blog
June 5th, 2006
I moved servers a few months ago and in the process I switched my blogging software to Typo, which is built with Ruby on Rails (my latest obsession).
I’m just now getting around to cleaning up some old code and migrating all the old blog posts to this new environment.