#!/usr/bin/perl
use strict;
package myworld;
use base 'Games::Roguelike::World';
my $WINNER;
my $world = myworld->new(w=>10,h=>10,msgw=>60,dispy=>2); # creates a world with specified width/height & map display width/height
$world->area(new Games::Roguelike::Area(name=>'1')); # create a new area in this world called "1"
# defined map and key to look like a tic-tac-toe board
my $map = '
| |
-+-+-
| |
-+-+-
| |
';
my %key = ('+'=>{color=>'yellow'});
my @WINS = (
[[0,0],[0,1],[0,2]],
[[1,0],[1,1],[1,2]],
[[2,0],[2,1],[2,2]],
[[0,0],[1,0],[2,0]],
[[0,1],[1,1],[2,1]],
[[0,2],[1,2],[2,2]],
[[0,0],[1,1],[2,2]],
[[0,2],[1,1],[2,0]],
);
# load map
$world->area->load(map=>$map, key=>\%key);
my $char = mychar->new($world->area, sym=>'@', color=>'green', pov=>-1);
$world->drawmap();
$world->showmsg("<red>Press SPACE to place your X");
while (!((my $c = $world->getch()) eq 'q')) {
if ($c eq ' ' && !$WINNER) {
# make a move
$char->putx();
} else {
# walk around
$char->kbdmove($c);
}
$world->drawmap();
}
package mychar;
use base 'Games::Roguelike::Mob';
# allow character to walk anywhere in the area
sub checkmove {
my $self = shift;
my ($x, $y) = @_;
return $self->area->inbound($x, $y);
}
sub putx {
my $self = shift;
my ($x, $y) = ($self->{x}, $self->{y});
# return unless empty
return unless $self->area->map($x, $y) eq ' ';
# translate to "game coordinates"
my ($tx, $ty) = ($x/2, $y/2);
# make player's "X" move
$self->area->setmapsym($x, $y, 'X');
my $msg = "X At $tx, $ty";
if ($self->checkwin('X')) {
$msg .= ", X Wins!";
$WINNER = 'X';
} else {
# ok, this is bad AI... just pick a random empty location
my ($ox, $oy) = $self->area->findrandmap(' ', 1);
if (defined($ox)) {
$msg .= ", O At $ox, $oy";
$self->area->setmapsym($ox, $oy, 'O');
if ($self->checkwin('O')) {
$msg .= ", O Wins!";
$WINNER = 'O';
}
}
}
$world->showmsg($msg);
}
sub checkwin {
my $self = shift;
my $xo = shift;
# loop through all win combos and see if all 3 are set to "$xo"
for my $row (@WINS) {
my $won = 1;
for my $point (@$row) {
my ($tx, $ty) = @$point;
$won = 0 unless $self->area->map($tx*2, $ty*2) eq $xo;
}
return 1 if $won;
}
return 0;
}