small medium large xlarge

Generic-user-small
12 Feb 2016, 00:46
Desmond Daignault (3 posts)

I am using the book (way cool book btw. thanks.) to update a CPAN module Games::Maze. I am having a blast! Repo: on github

I decided to modify the to_s function and put it into the subclass for the cell type. Each cell returns back an array of lines needed to print it. I use the row iterator to grab a row of cells though the eachCell iterator would have worked just as well. I also allowed for increasing the cell size. 8) (took me an hour to get it right late last night).

Spoiler alert: this also limits the use of + on the corners… and the box characters. 8)

Square cell toString method:

sub toString {
    my ($self, %params) = @_;
    my $cellSize = $params{cellsize} || 3;
    $cellSize = 3 if $cellSize < 3;
    my $charset = $params{utf8} ? 'utf8' : 'ascii';
    my $bodyContent = " " x $cellSize;
    my $characters = {
        utf8 => {
            topleftcorner => "\x{250c}",
            horizontalwall => "\x{2500}",
            toprightcorner => "\x{2510}",
            verticalwall => "\x{2502}",
            door => " ",
            fourwaycorner => "\x{253c}",
            body => $bodyContent,
            bottomleftcorner => "\x{2514}",
            bottomrightcorner => "\x{2518}",
            flattopwall => "\x{252c}",
            flatleftwall => "\x{251c}",
            flatrightwall => "\x{2524}",
            flatbottomwall => "\x{2534}",
        },
        ascii => {
            topleftcorner => "+",
            horizontalwall => "-",
            toprightcorner => "+",
            verticalwall => "|",
            door => " ",
            fourwaycorner => "+",
            body => $bodyContent,
            bottomleftcorner => "+",
            bottomrightcorner => "+",
            flattopwall => "+",
            flatleftwall => "+",
            flatrightwall => "+",
            flatbottomwall => "+",
        },
    };

    my $bodyRows = int($cellSize / 3);
    my @cellText;

    # top line of the maze
    unless ($self->north) {
        my $top = '';
        if (!$self->west) {
            # top left corner
            $top .= $characters->{$charset}{topleftcorner};
        }
        $top .= $characters->{$charset}{horizontalwall} x $cellSize;
        if ($self->east) {
            if ($self->linked($self->east)) {
                $top .= $characters->{$charset}{horizontalwall};
            } else {
                $top .= $characters->{$charset}{flattopwall};
            }
        } else {
            $top .= $characters->{$charset}{toprightcorner};
        }
        push @cellText, $top;
    }

    # body
    while ($bodyRows--) {
        my $body = '';
        if (!$self->west) {
            $body .= $characters->{$charset}{verticalwall};
        }
        $body .= $characters->{$charset}{body};
        if ($self->east) {
            if ($self->linked($self->east)) {
              $body .= $characters->{$charset}{door};
            } else {
              $body .= $characters->{$charset}{verticalwall};
            }
        } else {
            $body .= $characters->{$charset}{verticalwall};
        }
        push @cellText, $body;
    }

    # bottom
    my $bottom = '';
    if (!$self->west) {
        if ($self->south) {
            if ($self->linked($self->south)) {
                $bottom .= $characters->{$charset}{verticalwall};
            } else {
                $bottom .= $characters->{$charset}{flatleftwall};
            }
        } else {
          $bottom .= $characters->{$charset}{bottomleftcorner};
        }
    }
    if ($self->south) {
        if ($self->linked($self->south)) {
            $bottom .= $characters->{$charset}{door} x $cellSize;
        } else {
            $bottom .= $characters->{$charset}{horizontalwall} x $cellSize;
        }
    } else {
        $bottom .= $characters->{$charset}{horizontalwall} x $cellSize;
    }

    if ($self->east && $self->south) {
        if ($self->linked($self->east) && $self->linked($self->south)) {        # linked east and linked south
            # south not linked to it's east and east not linked to it's south
            if (!$self->south->linked($self->south->east) && !$self->east->linked($self->east->south)) {
                $bottom .= $characters->{$charset}{topleftcorner};
            # south not linked to it's east and east linked to it's south
            } elsif (!$self->south->linked($self->south->east) && $self->east->linked($self->east->south)) {
                $bottom .= $characters->{$charset}{verticalwall};
            # south linked to it's east and east not linked to it's south
            } elsif ($self->south->linked($self->south->east) && !$self->east->linked($self->east->south)) {
                $bottom .= $characters->{$charset}{horizontalwall};
            # south linked to it's east and east linked to it's south
            } elsif ($self->south->linked($self->south->east) && $self->east->linked($self->east->south)) {
                $bottom .= $characters->{$charset}{door};
            }
        } elsif ($self->linked($self->east) && !$self->linked($self->south)) {  # linked east not linked south
            # south not linked to it's east and east not linked to it's south
            if (!$self->south->linked($self->south->east) && !$self->east->linked($self->east->south)) {
                $bottom .= $characters->{$charset}{flattopwall};
            # south not linked to it's east and east linked to it's south
            } elsif (!$self->south->linked($self->south->east) && $self->east->linked($self->east->south)) {
                $bottom .= $characters->{$charset}{toprightcorner};
            # south linked to it's east and east not linked to it's south
            } elsif ($self->south->linked($self->south->east) && !$self->east->linked($self->east->south)) {
                $bottom .= $characters->{$charset}{horizontalwall};
            # south linked to it's east and east linked to it's south
            } elsif ($self->south->linked($self->south->east) && $self->east->linked($self->east->south)) {
                $bottom .= $characters->{$charset}{horizontalwall};
            }
        } elsif (!$self->linked($self->east) && $self->linked($self->south)) {  # not linked east linked south
            # south not linked to it's east and east not linked to it's south
            if (!$self->south->linked($self->south->east) && !$self->east->linked($self->east->south)) {
                $bottom .= $characters->{$charset}{flatleftwall};
            # south not linked to it's east and east linked to it's south
            } elsif (!$self->south->linked($self->south->east) && $self->east->linked($self->east->south)) {
                $bottom .= $characters->{$charset}{verticalwall};
            # south linked to it's east and east not linked to it's south
            } elsif ($self->south->linked($self->south->east) && !$self->east->linked($self->east->south)) {
                $bottom .= $characters->{$charset}{bottomleftcorner};
            # south linked to it's east and east linked to it's south
            } elsif ($self->south->linked($self->south->east) && $self->east->linked($self->east->south)) {
                $bottom .= $characters->{$charset}{verticalwall};
            }
        } elsif (!$self->linked($self->east) && !$self->linked($self->south)) { # not linked east not linked south
            # south not linked to it's east and east not linked to it's south
            if (!$self->south->linked($self->south->east) && !$self->east->linked($self->east->south)) {
                $bottom .= $characters->{$charset}{fourwaycorner};
            # south not linked to it's east and east linked to it's south
            } elsif (!$self->south->linked($self->south->east) && $self->east->linked($self->east->south)) {
                $bottom .= $characters->{$charset}{flatrightwall};
            # south linked to it's east and east not linked to it's south
            } elsif ($self->south->linked($self->south->east) && !$self->east->linked($self->east->south)) {
                $bottom .= $characters->{$charset}{flatbottomwall};
            # south linked to it's east and east linked to it's south
            } elsif ($self->south->linked($self->south->east) && $self->east->linked($self->east->south)) {
                $bottom .= $characters->{$charset}{bottomrightcorner};
            }
        }
    } elsif ($self->east) {
        if ($self->linked($self->east)) {
            $bottom .= $characters->{$charset}{horizontalwall};
        } else {
            $bottom .= $characters->{$charset}{flatbottomwall};
        }
    } elsif ($self->south) {
        if ($self->linked($self->south)) {
            $bottom .= $characters->{$charset}{verticalwall};
        } else {
            $bottom .= $characters->{$charset}{flatrightwall};
        }
    } else {
        $bottom .= $characters->{$charset}{bottomrightcorner};
    }

    push @cellText, $bottom;

    return @cellText;
}


and it gets called like this:


    my $output = '';
    my $utf8 = 0; # not implemented yet
    my $cellSize = 3;

    my $iterator = $self->eachRow();
    while (my $cells = $iterator->()) {
        my @rowText;
        foreach my $cell (@$cells) {
            my @cellText = $cell->toString(cellsize => $cellSize, utf8 => $utf8);
            for (my $i = 0; $i < scalar @cellText; $i++) {
                $rowText[$i] .= $cellText[$i];  # .= is concat in perl
            }
        }
        $output .= "$_\n" foreach (@rowText);
    }

    print $output;
Generic-user-small
12 Feb 2016, 00:39
Desmond Daignault (3 posts)

cell size = 3

+-------+-----------+
|       |           |
|   ----+   |   ----+
|       |   |       |
|   |   |   +---+   |
|   |       |   |   |
|   +---+   |   |   |
|   |   |       |   |
|   |   +-------+   |
|   |               |
+---+---------------+

and with box characters

┌───────┬───────────┐
│       │           │
│   ────┤   │   ────┤
│       │   │       │
│   │   │   ├───┐   │
│   │       │   │   │
│   ├───┐   │   │   │
│   │   │       │   │
│   │   └───────┘   │
│   │               │
└───┴───────────────┘


cell size = 6

+-------------+--------------------+
|             |                    |
|             |                    |
|      -------+      |      -------+
|             |      |             |
|             |      |             |
|      |      |      +------+      |
|      |             |      |      |
|      |             |      |      |
|      +------+      |      |      |
|      |      |             |      |
|      |      |             |      |
|      |      +-------------+      |
|      |                           |
|      |                           |
+------+---------------------------+

and with box characters

┌─────────────┬────────────────────┐
│             │                    │
│             │                    │
│      ───────┤      │      ───────┤
│             │      │             │
│             │      │             │
│      │      │      ├──────┐      │
│      │             │      │      │
│      │             │      │      │
│      ├──────┐      │      │      │
│      │      │             │      │
│      │      │             │      │
│      │      └─────────────┘      │
│      │                           │
│      │                           │
└──────┴───────────────────────────┘


Generic-user-small
12 Feb 2016, 00:47
Desmond Daignault (3 posts)

a minor improvement would be to use the half vertical walls (there are 2) and the half horizontal walls to terminate the wall. (eg the wall separating 1,2 and 1,3 needs half lower vertical wall so the wall doesn’t stick out into the passage)

Generic-user-small
12 Feb 2016, 03:43
Jamis Buck (30 posts)

That looks great! The box characters make it look very clean. Thanks for sharing!

You must be logged in to comment