473,786 Members | 2,705 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Multileval data structures, tie, and indirection

Hi. I'm attempting to write a roguelike (think nethack, crawl, angband,
tome, adom, and yes, I suppose even rogue) in Perl and I've ran into a
problem regarding the data structure for the map and handling it easily.
A map is one 2D level, a simple grid. Each tile on the grid will be a
hash of data about the grid. The map object itself has other bits of
data, so that's why I don't just make the object an anonymous array:

$map->{Map}[$y][$x] = { data about this grid tile }

So far, so good. I was using methods to access and change tiles, but it
was extremely awkward. Which looks more convenient?

$map->tile($y, $x, "Type") = "wall";
$map->{Map}[$y][$x]{Type} = "wall";

Well, bad example. But anyway, I seriously despised the first form. The
syntax itself is extremely awkward and when I generate random dungeons,
I'd have to use that awkward syntax a lot. So I messed around with
Tie::Autotie, decided it wasn't up to the task, and cobbled together a
package that I tied both anonymous arrays (The first representing rows,
pointing to the second which represented columns. Y, X is easier to deal
with sometimes.) to. The hash of data describing a tile consists of
different things, but for the most part, I'd by modifying and accessing
one key in the hash. Now I'm at the point where I can do this:

print $map->{Map}[$y][$x]; # $map->{Map}[$y][$x]{Symbol} is printed,
# through FETCH
$map->{Map}[$y][$x] = "wall"; # This basically sets
# $map->{Map}[$y][$x]{Type} to a hashref
# describing a template of that type.

Convenient and easy, so far. Then I run into the first problem. What if
I want to access or change $map->{Map}[$y][$x]{foobar}? The way I tied
the arrays didn't allow for this. So I hacked together a real messy
sort of hack, which is shown somewhere below. So far, I'm coping with
the shortcomings of tie.

But then I realized that when I assign a tile to "wall", other things
should happen. Things regarding the $map object itself. Meaning that I
need a reference to $map, as well as the value of $y. From the 'point of
view' of $x's tied FETCH routine, I cannot access these.

I know Perl, each time it encounters a tied variable that's part of a
multi-level structure, it'll take a temp value and do something with
that. Step by step. It's impossible to tie an entire data structure to
where one FETCH routine could know $map, $y, and $x.

Then I realized something. I was trying to re-implement the Unix
directory structure, complete with a level of indirection that more or
less happened to be '..'

I suppose I could replace the arrays with hashes, and instead do
$map->{Map}{$y}{$x }. In the $y hash and the $x hash (technically
inaccurate, but from the point of view of $y/$x) I could have a "back"
key pointing to the data structure that contains it. This'd solve some
problems and probably create other unforseen ones. Iterating over the
hash instead of the array would be no problem with the foreach loops I
use already.

I'd still like to avoid method calls to change and access tiles. It *is*
slower, as I've experimented and tried it. Maps will get quite big,
sometimes around 300x500 and there are a great number of maps randomly
generated. And the syntax is just easier.

Anyway, the thing that started me on all this was convenience. Accessing
and modifying $map->{Map}[$y][$x] and having all the fancy stuff happen
behind the scenes. But the way I'm tying stuff down right now is
probably a bit messy, as it won't let me _cleanly_ manipulate anything
other than that one key in the hash. Is there an easier way around all
of this mess?

If interested, here's the module I ended up writing. Buggy and messy,
beware.

############### #######
# Roguelike::Tile map #
############### #######

package Roguelike::Tile map;

use strict;
use warnings;
use Roguelike::Util ity;
use Roguelike::Game ;
use Roguelike::Tile s;

our $TILE = load Roguelike::Tile s;
our $_GET = "Symbol";

sub TIEARRAY {
my $class = shift;
return bless [ @_ ], $class;
}

sub FETCH {
my $self = shift;
my $index = shift;
return $self->[$index]{$_GET} if ref $self->[$index] eq
"HASH";
return $self->[$index];
}

sub STORE {
elf = shift;
my $index = shift;
my $value = shift;
if ($_GET eq "Symbol") {
if (ref $value eq "ARRAY") {
tie my @data, "Roguelike::Til emap", @{$value};
$value = \@data;
} else {
$value = $TILE->{$value};
}
}
$self->[$index] = $value;
}

sub FETCHSIZE {
my $self = shift;
return @{$self};
}

sub STORESIZE {
my $self = shift;
my $count = shift;
if ($count > $self->FETCHSIZE) {
foreach ($count - $self->FETCHSIZE() .. $count) {
$self->STORE($_, "");
}
} elsif ($count < $self->FETCHSIZE) {
foreach (0 .. $self->FETCHSIZE() - $count - 2) {
$self->POP();
}
}
}

sub EXTEND {
my $self = shift;
my $count = shift;
$self->STORESIZE($cou nt);
}

sub EXISTS {
my $self = shift;
my $index = shift;
return defined $self->[$index];
}

sub DELETE {
my $self = shift;
my $index = shift;
}

sub CLEAR {
my $self = shift;
return $self = [];
}

sub PUSH {
my $self = shift;
my @list = @_;
my $last = $self->FETCHSIZE();
$self->STORE($last + $_, $list[$_]) foreach 0 .. $#list;
return $self->FETCHSIZE();
}

sub POP {
my $self = shift;
return pop @{$self};
}

sub SHIFT {
my $self = shift;
return shift @{$self};
}

sub UNSHIFT {
my $self = shift;
my @list = @_;
my $size = scalar(@list);
@{$self}[$size .. $#{$self} + $size] = @{$self};
$self->STORE($_, $list[$_]) foreach 0 .. $#list;
}

sub new {
my $class = shift;
tie my @map, "Roguelike::Til emap";
my $width = shift;
my $height = shift;
my $tile = shift || " ";
foreach my $y (0 .. $height - 1) { # starting at 1 blows up
$map[$y] = [];
foreach my $x (0 .. $width - 1) { # starting at 1 blows up
$map[$y][$x] = $tile;
}
}
my $self = bless { Map => \@map, Data => [] }, $class;
return $self;
}

sub get {
my $self = shift;
my $y = shift;
my $x = shift;
my $attrib = shift;
my $value = shift;
$_GET = $attrib;
$self->{Map}[$y][$x] = $value if defined $value;
my $data = $self->{Map}[$y][$x];
$_GET = "Symbol";
return $data;
}

42;
And a test script, which sort of works.

#!/usr/bin/perl
use strict;
use warnings;
use lib "/home/dabreegster/tilemap";
use Roguelike::Tile map;
use Roguelike::Util ity;

my $map = new Roguelike::Tile map 2, 5;

dump $map; # doesn't quite work!

print "Y" if $map->{Map}[2][0] eq " ";

print $map->get(2, 0, "Type");
$map->get(3, 3, "foo" => "bar");
print $map->get(3, 3, "foo");

# always give em a width and height. Then go through each one slowly and assign
# it (these comments won't make sense, don't worry)

# if the Tile hash contains a ref to another hash, array, whatever, it doesn't
# work. Ohwell.

Any tips?

~ 'dabreegster' in #perl and #perlcafe on irc.freenode.or g
Aug 5 '05 #1
1 5111
In article <sl************ ************@lo calhost.localdo main>,
Da-Breegster <da*********@gm ail.com> wrote:
Hi. I'm attempting to write a roguelike (think nethack, crawl, angband,
tome, adom, and yes, I suppose even rogue) in Perl and I've ran into a
problem regarding the data structure for the map and handling it easily.
A map is one 2D level, a simple grid. Each tile on the grid will be a
hash of data about the grid. The map object itself has other bits of
data, so that's why I don't just make the object an anonymous array:


[rest of long post snipped]

I am afraid you have wasted your time by posting to a defunct
newsgroup. Try comp.lang.perl. misc in the future.
----== Posted via Newsfeeds.Com - Unlimited-Uncensored-Secure Usenet News==----
http://www.newsfeeds.com The #1 Newsgroup Service in the World! >100,000 Newsgroups
---= East/West-Coast Server Farms - Total Privacy via Encryption =---
Aug 5 '05 #2

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

4
3863
by: Thomas Paul Diffenbach | last post by:
Can anyone point me to an open source library of /statically allocated/ data structures? I'm writing some code that would benefit from trees, preferably self balancing, but on an embedded system that doesn't offer dynamic memory allocation (to be clear: no malloc, no realloc), and with rather tight memory constraints. Writing my own malloc to do dynamic allocation from some static pool isn't really an option, for various reasons, not...
10
4789
by: Bart Goeman | last post by:
Hi, I have a question about how to put redundant information in data structures, initialized at compile time. This is often necessary for performance reasons and can't be done at run time (data structures are read only) Ideally one should be able to put the redundant information there automatically so no mistakes are possible, but in a lot of case I see no way how to do it.
19
3066
by: santosh | last post by:
Hi all, In the following program I allocate a block of pointers to type char, initialised to zero. I then point each of those pointers to a block of allocated memory of fixed size (33 bytes). A unique 'string' is then generated using itoa() and rand() for each block of memory. Finally using pointer-to-pointer of type char, I print the contents of the blocks of memory, i.e. the strings, using both printf() and manually, character by...
3
2318
by: osp | last post by:
hi to every one.... i just started out with c++ and i think i am doing well.i use Robert Laffore to study. which book should i use for data structures ? please help. thank you with regards osp
11
3783
by: efrat | last post by:
Hello, I'm planning to use Python in order to teach a DSA (data structures and algorithms) course in an academic institute. If you could help out with the following questions, I'd sure appreciate it: 1. What exactly is a Python list? If one writes a, then is the complexity Theta(n)? If this is O(1), then why was the name "list" chosen? If this is indeed Theta(n), then what alternative should be used? (array does not seem suited for...
29
6361
by: Mik0b0 | last post by:
Hallo to everyone. This fall I am going to start data structures as a part of C language course. The problem is I could not find any satisfying tutorial about structures in C. There are plenty of books about data structures in C+ + etc., could anyone please recommend me such a C -specific book ? And another question: are data structures (like stack, structure etc.) used in C++ identical to those in C and is it possible to use C++ books to...
4
2059
by: jehugaleahsa | last post by:
Hello: When developing data structures for C#, there is an obvious performance hit when utilizing primitive types. For instance, a recent hash table implementation I wrote works exceedingly fast on strings. It can run through a million randomly generated strings in less than half of a second (in most tests). The built-in dictionary class takes close to 10 seconds. (Just trust my measurements; I don't want to argue about the correctness...
3
10824
by: imaloner | last post by:
I am posting two threads because I have two different problems, but both have the same background information. Common Background Information: I am trying to rebuild code for a working, commercially sold application with only partial build instructions. The previous maintainer of the code (a mixture of C and C++) is no longer with the company, but when he built the code he used MSVC++, and though I am not certain of the version he was ...
1
3454
Markus
by: Markus | last post by:
I'm having a hard time grasping the concept of multiple levels of indirection, that is for example a char **. I understand that passing a pointer to some data to a function means that memory for that data doesn't have to be allocated on the stack, thereby reducing overhead (of course memory for the pointer has to be allocated to the stack, 'though). Another use as I understand (and see the benefits for) is that if a pointer to data is given to a...
0
9647
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
10363
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
10164
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
7512
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
6745
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
5534
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
4066
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
2
3669
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
3
2894
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.