#!/usr/bin/perl use strict; use warnings; use Carp qw(); package Character; sub new { my ($class, %props) = @_; # Validation of %props here as required Carp::confess "Characters require a 'name' property" if !$props{name}; return bless \%props, $class; } sub newFromStr { my ($class, $str) = @_; my $config = extract($str); return $class->new(%$config); } sub newFromFile { my ($class, $filename) = @_; open my $fin, '<', $filename or Carp::confess "Can't open $filename: $!\n"; my $str = do {local $/; <$fin>}; close $fin; return $class->newFromStr($str); } sub extract { my ($str) = @_; require 'YAML.pm'; return YAML::Load($str); } # subs defining what a Character is here sub Name { my ($self) = @_; return $self->{name}; } sub SetAttributes { my ($self, %attribs) = @_; for my $attrib (keys %attribs) { my ($rolls, $die) = $attribs{$attrib} =~ /(\d+)d(\d+)/i or next; $self->{$attrib} = 0; $self->{$attrib} += int(1 + rand($die)) for 1 .. $rolls; } } package Game; sub new { my ($class, %props) = @_; # Validation of %props here as required return bless \%props, $class; } sub AddCharacter { my ($self, $character) = @_; my $name = $character->Name(); Carp::confess "Character name must be unique. $name is already in use!" if exists $self->{characters}{$name}; $self->{characters}{$name} = $character; } sub LoadCharacters { my ($self, $source) = @_; opendir my ($scan), $source or Carp::confess "Can't open $source: $!\n"; my @files = grep {-f $_} map {"$source\\$_"} readdir $scan; closedir $scan; foreach my $file (@files) { my $character = Character->newFromFile($file); $character->SetAttributes(hp => '1d20'); $self->AddCharacter($character); } } sub DumpCharacters { my ($self) = @_; my $format = "%-15s %5s %5s %5s\n"; printf $format, qw(Name init dex hp); for my $name (sort keys %{$self->{characters}}) { printf $format, $name, @{$self->{characters}{$name}}{qw(init dex hp)}; } } package main; my $testFolder = "./Characters"; createTestCharacters($testFolder); my $game = Game->new(); $game->LoadCharacters($testFolder); $game->DumpCharacters(); sub createTestCharacters { my ($folder) = @_; my @characters = ( {name => 'Red', init => 5, dex => 10}, {name => 'Spotty', init => 8, dex => 15}, {name => 'Night Runner', init => 15, dex => 17}, ); require 'YAML.pm'; for my $character (@characters) { my $name = $character->{name}; YAML::DumpFile("$folder\\$name.yaml", $character); } }