|
Sections
Games
More jjohn Links
|
 |
 |
 |
Joe's Journal
|
List all entries
In the software/hardware paradigm that bifurcates humanity, I'm squarely in
the software camp. However, I have successful created a CAT 5e run of
ethernet cable that goes from the basement to my second floor office
terminating in a real, honest to goodness RJ-45 jack in my wall. I couldn't
be more proud. If you attempt to install wired ethernet in your home, be
aware of the following:
1. Running the cable is the hardest part of the job
If you have a new home, running cable is as easy as getting into the walls
before the drywall/plaster is installed. Otherwise, you'll need snake the cable through those unfinished walls in your house, like those found in basements
and attics. You could also rip open your finished walls, install the wiring
and patch it later, but you're clearly more butch than I. In
my case, there was existing speaker wire that went from the basement to the
attic. I simply attached one end of a 100' spool of CAT 5e cable to top of the
speaker wires with copious tape. I then pulled (carefully) on the wire from
the basement to get whatever gravity-assist I could. Your mileage will
vary.
2. Get the right tools
You will need an ethernet jack
punch down tool. You can
get this at Lowes, Microcenter or many other
places online. Do not confuse this with a crimping tool, which is designed
to fit a male RJ-45 coupling onto the end of an ethernet cable. Punch down
tools force the individual wires of ethernet into specific recepticals on the
RJ-45 jack. You should not strip these wires before punch down. The act of
punch down removes the casing around the wire. Some tools will cut the extra
length of wire for you, but any wire cutting tool will work adequately for
the job.
You might also need fish tape to help you run the ethernet cable into the
hard to reach areas of your wall.
3. Read the mating diagram on the RJ-45 jack
Ethernet cabling consists of 4 twisted pairs of wires, which are typically
colored brown, blue, orange and yellow. Each color has a mate that striped
with white for a total of eight wires. To attach to an RJ-45 jack, each of
these eight wires needs to be punched into the right saddle. Most RJ-45 jacks
are sold with a diagram that explicitly shows where each wire goes. Follow
the directions carefully. You cannot fudge this part.
4. Unless you have a house older than 50 years old, use new
construction low voltage brackets
Low voltage brackets are the bits that are nailed or
screwed into the wood of a joist so that the face plate can be attached
to the wall. These seemingly simply devices come in a broad variety of forms.
One of the dimensions of variation is in how the bracket attaches to the wall.
Brackets that have screws or nails go parallel to the face plate
are called "new construction" mounted. Brackets that have nails or screws
that are perpendicular to the face plate are said to have "old
construction" mounting. I can't really think of a situation where old construction mounting works, but as I said, I'm not a hardware guy. That's also why
I bought an old construction mounting first. Live and learn.
It took me three days to do this admittedly simply installation, because
I didn't have all the right tools and parts initially.
This is a great project for all you home-owning nerds out there. There are
many more detailed web resources out there that explain the process in more
detail than I've provided. Also, check out You Tube for helpful videos. There
was at least one that shows how to punch down an RJ-45 jack correctly.
 |
Hex maps. Every wargamer knows them. Expert D&D players broke out of
their dual-axis world during their Isle of Dread campaign to use these
six-sided monsters. Here's a close up of one:
Figure 1
Hex maps, it is claimed, offer a more natural choice of direction for players
who want to model open air terrain than the good old graph-paper, cartesian plane,
2 perpendicular axes maps. Graph paper maps do match up well to the four
cardinal points of a compass, which is nice. Even better for programmers, these
kinds of maps are easily represented with 2 dimensional arrays, a data structure
that even grumpy old C supports!
Figure 2: 2D map
And it's easy to find the neighboring squares in this
kind of map. Consider a coordinate system whose origin (0,0) is the upper most
left corner of a grid. Going to the right adds to the x coordinate, while going
left subtracts from it. Similarly, going down to the bottom of the grid adds to
the y coordinate, but going up lessens the y value. If the starting square can
be thought of as being at the coordinate (x,y), then neighbors can be found at
predictable offsets:
- Northern neighbor: (x, y-1)
- Eastern neighbor: (x+1, y)
- Southern neighbor: (x, y+1)
- Western neighbor: (x-1, y)
It's easy to extrapolate how you could find the diagonal squares too if you
wanted to, but that's not desirable for wargamers. There are at most only four
equidistant neighbors for any given square on the graph paper map. Sure, you
could include the four squares pointed to by the diagonals of the square, but
these are more distant from the center of the square than the neighbors
at the cardinal points. And that makes wargamers mad! How can you accurately
plot the range of your 18th century dutch cannon using only the cardinal compass
points?! Hex maps offer up to six equidistant neighbors for any given hex. And
that means more accurate pathing for cannon fire. Super!
But how do you model a map in which each element has six neighbors? You could
make a linked list of structures that contain pointers to each of their
neighbors. But that's not a particularly natural fit and would cause a great
deal of programming overhead to populate and search. Is there a way to get all
the benefits of a hex map into a 2D array implementation? Yes, there is but
you need to to think about a hex map in a certain way.
Look at Figure 1 again, but try to see the map as three columns of hexes
stacked on top of each other. Notice that although the first column (with
hexes A and D) are horizontally aligned with the last column (with hexes C and F)
but the the middle colum (with hexes B, E and G) is a bit offset. This is an
important detail that will affect our hex map model. We can order these hexes
from left to right, top to bottom if we take into account the offset columns that
happen every other time. That is, all the odd number columns are offset from the
even numbered ones. We can make a horizontal row by starting with a left-most
hex. Then, find the "northeastern" neighbor in the odd row. To find the
horizontal neighbor of that hex, look to its "southeastern" side.
In Figure 1, the first
horizontal row is marked out as hexes A, B and C. Continue this alternation
until you hit the last column of hexes.
Once we have a predictable sorting order for our hexes, we can use a
2D array to model this map. Why bother with a 2D for a linear list? The answer
is that a 2D array naturally maps to the way computer screens are represented in
most drawing libraries. 2D arrays also fit easily into an SQL database system.
So, even though the thing we want could be represented
in a number of ways, there's a lot of convenience to be had in thinking of (x,y)
coordinates. So given a hex coordinate, how can we determine its neighbors in
a 2D array? The answer is: it depends!
It depends on whether the hex is in a odd numbered column or an even numbered
one. Consult the two tables below. I look for neighboring hexes in a clockwise
direction starting at the top of the hex (which would be the northern neighbor).
| Neighbor |
Coordinate offset |
| North |
(x, y-1) |
| Northeast |
(x+1, y) |
| Southeast |
(x+1, y+1) |
| South |
(x, y+1) |
| Southwest |
(x-1, y+1) |
| Northwest |
(x-1, y) |
Figure 3: Calculating Neighbors for Hexes in Even Columns
| Neighbor |
Coordinate offset |
| North |
(x, y-1) |
| Northeast |
(x+1, y-1) |
| Southeast |
(x+1, y) |
| South |
(x, y+1) |
| Southwest |
(x-1, y) |
| Northwest |
(x-1, y-1) |
Figure 4: Calculating Neighbors for Hexes in Odd Columns
And for the purposes of this discussion, column 0 counts as even. Does your
brain hurt a little? Mine too. Let's make this more concrete.
Using Figure 1, let's create a 2D array that maps the hexes in the right
order.
| |
0 |
1 |
2 |
| 0 |
A (0,0) |
B (1,0) |
C (2,0) |
| 1 |
D (0,1) |
E (1,1) |
F (2,1) |
| 2 |
- |
G (2,2) |
- |
Figure 5: Mapping a Hex Map into a 2D Array
I have included the coordinates of the hex in this table for easier reference.
Let's walk through our algorithm to find all the neighbors of each point.
| Hex |
N |
NE |
SE |
S |
SW |
NW |
| A (0,0) |
(0,-1) |
D (1,0) |
E (1,1) |
B (0,1) |
(-1, 1) |
(-1,0) |
| B (1,0) |
(1,-1) |
(2,-1) |
C (2,0) |
E (1,1) |
A (0,0) |
(0,-1) |
| C (2,0) |
(2,-1) |
(3,0) |
(3,1) |
F (2,1) |
E (1,1) |
B (1,0) |
| D (0,1) |
A (0,0) |
E (1,1) |
(1,2) |
(0,2) |
(-1, 2) |
(-1,1) |
| E (1,1) |
B (1,0) |
C (2,0) |
E (2,1) |
G (1,2) |
B (0,1) |
A (0,0) |
| F (2,1) |
C (2,0) |
(3,1) |
(3,2) |
(2,2) |
G (1,2) |
E (1,1) |
Whew! That's quite a table of mind-numbing numbers! What this table is
attempting to show is the neighboring hexes for each hex appearing in the
left-hand column. Computations which result in a
valid location are shown with that area's label. Computations that produce
bum results are shown in italics, just to give you some idea how the edge
cases work.
Now that you can easily find the neighbors of any hex, you can implement
any of the class of algorithms designed to calculate shortest path, distance,
etc. Of particular note, A* pathfinding
and shortest distance routines should
fall out nicely once you wrap the neighbor calculations into some kind of
function.
Which is an exercise I leave for the reader. I realize that modeling hex maps
is a solved problem, but I worked this stuff out for myself. Thinking of these
sorts of things keeps me off the streets and high on life.
Peace out.
 |
Picture of me at the Javaroom in Chelmsford taken with my Macbook's
Photobooth app. Compare to the one I took here with my XO.
UPDATE: The Chelmsford Public Library is #^(%ing great. It's clean, brightly lit, full of electrical outlets and WIFI! Of course, PPTP, FTP, SMTP and some other ports are blocked, but not SSH. W00t!
Visited Lowell General Hospital today for the first time, in which a doctor looking very much like Alton Brown informed me that my eye was swollen from non-viral conjunctivitis. I get to put jelly in my eye for three days.
So, I have that going for me.
 |
It seems that a few of you are using or trying to use the XML::RSS::Podcast
module I published on this blog. As was mentioned there,
modern version of XML::RSS do not support the encode function required for
generating well-formed XML documents.
That's all changed thanks to Rohan Carly. [Add your thanks to Rohan in the comments.]
I present the complete version of XML::RSS::Podcast below. If you find this module
useful, I'll attempt to create a CPAN module for it.
package XML::RSS::Podcast;
use XML::RSS;
use HTML::Entities qw[encode_entities_numeric encode_entities];
@XML::RSS::Podcast::ISA = qw[XML::RSS];
our $VERSION = q[1.1];
# encode by Rohan Carly
# Stolen from XML::RSS::Private::Output::Base;
sub encode {
my ($self,$text) = @_;
return unless defined($text);
my $encoded_text = '';
while ($text =~ s,(.*?)(<!\[CDATA\[.*?\]\]>),,s) {
# we use &named; entities here because it's HTML
$encoded_text .= encode_entities($1) . $2;
}
# we use numeric entities here because it's XML
$encoded_text .= encode_entities_numeric($text);
return $encoded_text;
};
sub as_string {
my $self = shift;
return $self->as_podcast_rss;
}
sub as_podcast_rss {
my $self = shift;
my $enc = $self->{encoding};
my $output = qq[<?xml version="1.0" encoding="$enc"?>
<rss xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd"
version="2.0">];
$output .= $self->podcast_start_channel;
for my $i (@{$self->{items}}) {
$output .= $self->podcast_item($i);
}
$output .= $self->podcast_end_channel;
return $output .= "\n</rss>\n";
}
sub podcast_start_channel {
my $self = shift;
my @fields = qw[ttl title description link language
pubDate lastBuildDate creator
webMaster copyright
];
my @image_fields = qw[title url description link
width height];
my @itunes_fields = qw[subtitle author summary
image explicit]; # Thanks Rohan
my $output = "<channel>\n";
for my $f (@fields) {
if (defined($self->{channel}->{$f})) {
my $s = $self->encode($self->{channel}->{$f});
$output .= "\t<$f>$s</$f>\n";
}
}
my $seen_image = 0;
for my $f (@image_fields) {
if (defined($self->{image}->{$f})) {
unless ($seen_image) {
$output .= "\t<image>\n";
$seen_image = 1;
}
my $s = $self->encode($self->{image}->{$f});
$output .= "\t\t<$f>$s</$f>\n";
}
}
if ($seen_image) {
$output .= "\t</image>\n";
}
# Owner name/email not handled
for my $f (@itunes_fields) {
if (defined($self->{channel}->{itunes}->{$f})) {
my $s=$self->encode($self->{channel}->{itunes}->{$f});
$output .= "\t<itunes:$f>$s</itunes:$f>\n";
}
}
# Rohan's sub-cat handling code
# Expects an array: [category, sub-category]
if (ref $self->{channel}->{itunes}->{category} eq 'ARRAY') {
my $major = $self->encode(${$self->{channel}->{itunes}->{category}}[0]);
my $minor = $self->encode(${$self->{channel}->{itunes}->{category}}[1]);
$output .= qq[\t<itunes:category text="$major">\n];
$output .= qq[\t\t<itunes:category text="$minor">\n];
$output .= qq[\t\t</itunes:category>\n];
$output .= qq[\t</itunes:category>\n];
}
return $output . "\n";
}
sub podcast_end_channel {
return "</channel>\n";
}
sub podcast_item {
my $self = shift;
my $item = shift;
my @fields = qw[title guid pubDate description link];
my @itunes_fields = qw[author subtitle summary
duration keywords explicit];
my $output = "\t<item>\n";
for my $f (@fields) {
if (defined($item->{$f})) {
$s = $self->encode($item->{$f});
my $perma = "";
if ($f eq "guid") {
$perma = qq[isPermaLink="false"];
}
$output .= "\t\t<$f$perma>$s</$f>\n";
}
}
if (ref $item->{enclosure}) {
$output .= "<enclosure";
for my $f (qw[url length type]) {
if (defined $item->{enclosure}->{$f}) {
$output .= sprintf("$f=%s", $self->encode($item->{enclosure}->{$f}));
}
}
$output .= "/>";
}
for my $f (@itunes_fields) {
if (defined $item->{itunes}->{$f}) {
$s = $self->encode($item->{itunes}->{$f});
$output .= "\t\t<itunes:$f>$s</itunes:$f>\n";
}
}
return $output .= "\t</item>\n";
}
1;
For an example of usage, please see the previous post cited above.
Report bugs in the comments or through email. Thanks.
 |
I have lots of updates to make, but no time.
I saw George Carlin on stage three times -- once at the Cape Cod Melody Tent, a prime venue. Mr. Carlin's comedy was formative for me as it was for many people. His Occupation: Foole album was the first comedy album I'd ever heard.
Many comedians benefitted from the doors he open with his racy stuff. Lenny Bruce is rightly credited with being an earlier adopter of blue language into his routine, but Carlin made the rough stuff palatably rather than merely raunchy and angry.
His political stuff was always a decade ahead of the pack. As he drifted into his golden years, he didn't mellow, but became more pointed on his attacks at the establishment. He was the very icon of what stand-up comedy means to me.
The seven famous words on his web site sum up it best: we love you and we'll miss you.
Finally, a meaningful survey on the web (via classicaljunkie).
Don't let their size fool you: these critters are dangerous in numbers.
I have bought my first house. It's the biggest thing I've ever bought and it will require more care and feeding than any pet I've owned.
On the upside, I now have the right to vote and smoke old guy cigars.
Level me up one.
 |
After five years, Leostream is finally got a careers page with [EDIT: some] content on it. The times, they are a-changin'!
If you're a self-motivated developer interested in working in the virtualization market (which is ridiculously hot right now), please consider sending your resume to Leostream. You'll find all the particulars on the company web site, but I can list some of the things we're looking for in an engineer:
- C++ or Perl. These are the two primary development languages we use. C++ for Windows dev and Perl for Linux dev. Java is also a nice to have.
- You need to understand socket programming and networking cold. I don't care if you can actually resolve the address space of a given netmask, but you should know what a netmask is.
- You should have some experience with RPC mechanisms and XML-RPC/SOAP in particular.
- At least understand what a virtual machine is. If I said, "what's a VMX file", you should know that it's the VMware config file for virtual machines. If I said "VHD", you should think of the MSVS/Xen virtual disk format.
- You have to be self-directed. Leostream is growing fast and you'll need to puzzle out a lot of details for yourself. Of course, that's not to say there's no support for new developers. But, you'll need to keep your own task list up to date. :-D
- Tolerance for start-ups. Leostream does not have the amenities of larger companies. If that's important to you, you'll need to look elsewhere.
Also note that I'm not the hiring manager. Please do not send your resumes to me.
Cheers.
 |
|
|
|