#!/usr/bin/perl

use POSIX qw[floor];

my $state = $ENV{PATH_INFO} || shift @ARGV;
$state =~ s/[^0-8]//g;

my $board  = [[], [], []];

for (my $i = 0; $i < length $state; $i++)
{
	my $char = substr($state, $i, 1);
	die "Inconsistent state: $state" if defined $board->[floor($char / 3)][$char % 3];
	$board->[floor($char / 3)][$char % 3] = ($i % 2 ? 'O' : 'X');
}

my $string_rep;
foreach my $i (0..2)
{
	my $line = $board->[$i];
	$string_rep .= sprintf("% 1s|% 1s|% 1s\n",
		$line->[0],
		$line->[1],
		$line->[2],
		);
	$string_rep .= "-+-+-\n" unless $i==2;
}

my $win;

foreach my $i (0..2)
{
	if (defined $board->[$i][0]
	and $board->[$i][0] eq $board->[$i][1]
	and $board->[$i][0] eq $board->[$i][2])
	{
		$win = [$board->[$i][0], 'Row', $i+1];
	}
	if (defined $board->[0][$i]
	and $board->[0][$i] eq $board->[1][$i]
	and $board->[0][$i] eq $board->[2][$i])
	{
		$win = [$board->[0][$i], 'Column', $i+1];
	}
}

if (defined $board->[0][0]
and $board->[0][0] eq $board->[1][1]
and $board->[0][0] eq $board->[2][2])
{
	$win = [$board->[$i][0], 'Diagonal', '(backslash)'];
}

if (defined $board->[0][2]
and $board->[0][2] eq $board->[1][1]
and $board->[0][2] eq $board->[2][0])
{
	$win = [$board->[$i][2], 'Diagonal', '(slash)'];
}

if (9 == length $state)
{
	$win = [undef, undef, undef];
}

my $next_player = ((length $state) % 2 ? 'O' : 'X');
$next_player = undef if $win;

my $available_moves = {};
unless ($win)
{
	for my $i (0..8)
	{
		unless (defined $board->[floor($i / 3)][$i % 3])
		{
			my $key = $state.$i;
			my $val = sprintf("%s %s",
				{0=>'top',1=>'centre',2=>'bottom'}->{floor($i / 3)},
				{0=>'left',1=>'middle',2=>'right'}->{$i % 3});
			$available_moves->{$key} = $val;
		}
	}
}

print "Content-Type: text/turtle\r\n\r\n";

if (defined $win and !defined $win->[0])
{
print <<TURTLE;
\@prefix game: <http://purl.org/NET/game#> .
\@prefix dc:   <http://purl.org/dc/terms/> .

<$state>
	a game:Node ;
	dc:title "A friendly game of naughts and crosses..." ;
	dc:description """
The board is in this state:

$string_rep

X and O were equally matched in this mighty battle of wit.
""" .
TURTLE
}
elsif (defined $win)
{
print <<TURTLE;
\@prefix game: <http://purl.org/NET/game#> .
\@prefix dc:   <http://purl.org/dc/terms/> .

<$state>
	a game:Node ;
	dc:title "A friendly game of naughts and crosses..." ;
	dc:description """
The board is in this state:

$string_rep

$win->[0] has won on $win->[1] $win->[2]!
""" .
TURTLE
}
else
{
print <<TURTLE;
\@prefix game: <http://purl.org/NET/game#> .
\@prefix dc:   <http://purl.org/dc/terms/> .
\@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .

<$state>
	a game:Node ;
	dc:title "A friendly game of naughts and crosses..." ;
	dc:description """
The board is in this state:

$string_rep

$next_player gets ready to move. What move should be played??
""" .
TURTLE

while (my ($state2, $desc) = each %$available_moves)
{
	my $uri = '#'.$desc; $uri =~ s/ /_/;
	print <<TURTLE;

<$uri>
	rdfs:subPropertyOf game:exit ;
	rdfs:label "$desc" .
<$state> <$uri> <$state2> .
TURTLE
}

}