Friday, September 11, 2009

Code Formatting with Blogspot Posts

Recently a friend needed a little help with formatting their code with their blogger post. I spent some time looking around, and the general classification of solutions to this problem looks like this.



Currently I'm using the second option. There's a couple of things that are undesirable about the second option. Firstly, it does not do syntax highlighting. Secondly, it parses html-like content as html. Since it's a code box, we don't want that to happen. I feel that before I move on to the third option, I should outline how to use the second. If you're okay with it's faults, then read on.

Firstly, you'll want to edit the layout of your blog, and choose to edit the HTML. Now, following the instructions here, add the following code to your layout.

Under the variable definition section, put this:

<Variable name="codeBGColor" description="Code Box Background Color" type="color" default="#ffffff" value="#ffffee">
<Variable name="codeBorderColor" description="Code Box Border Color" type="color" default="#000000" value="#612e00">
<Variable name="codeTextColor" description="Code Box Text Color" type="color" default="#000000" value="#440000">
<Variable name="codeFont" description="Code Box Font" type="font" default="normal normal 100% monospace" value="normal normal 90% monospace">


And then, under the css section, put this:

.code {
font: $codeFont;
white-space: pre-wrap;
color: $codeTextColor;
background-color: $codeBGColor;
border: 1px dashed $codeBorderColor;
padding: 5px;
}


Then, save, and make sure there are no errors.
When you want a section of code in your blog post, all you have to do is wrap the code in an element and give it the "code" class. I suggest...
"<pre class='code'>Your code here.</pre>".

And there you have it! Your own easy generic code class.

Sunday, June 28, 2009

Sim City 4 Crashing to Desktop? Autosave the day!

Recently I dusted off my old copy of Sim City 4. Memories flooded back to me of all the time I had spent building up specially crafted money-making masterpieces in the Sim City series oh so many years ago. For a while, life was grand. I was banking a small, albeit legitimate, profit with a small city of about 20,000 people.


Then, with horrifying realization, the veil that time places over events long past lifted, and the novelty of nostalgia departed post-haste. Out of nowhere, the game hung on the balance of a precipice. Then my screen went black. Hello again, desktop old friend.



No! It can't be!

Yes, this was the exact reason I had ever stopped playing Sim City 4. And like an alzheimer's patient, I had crawled back into the false security that was offered, only to have my hopes shattered yet again.


But this time, I've decided that enough is enough! By george, if the developers won't fix it, I will!



That lasted 5 minutes.


Then I posed a query to myself, "Hey, what can I do with my mediocre programming skills to help this situation, since I've no way to solve the crashing issue?"

The answer came swiftly; "I know! I'll just write up an autosaver in python!"


Now you too can relish in the puny bandaid I've placed over this huge gash of a problem.


#!/usr/bin/env python
import time
import win32gui
from SendKeys import SendKeys

ExpectedProgramText = "SimCity 4"
SaveHotkey = "^s" # CTRL + S
InitialWaitTime = 5 # In minutes
SaveInterval = 5 # In minutes
Quitting = False

# Wait for a bit before we begin.
time.sleep(InitialWaitTime*60)

while not Quitting:
  # Get the active window's title.
  ForegroundWindow = win32gui.GetForegroundWindow()
  WindowText = win32gui.GetWindowText(ForegroundWindow)

  if WindowText == ExpectedProgramText:
  # Time for a save! :)
  SendKeys(SaveHotkey, pause=0.02)
  # Now let's chill some more.
  time.sleep(SaveInterval*60)


This was written using python 2.6 and requires PyWin32 and SendKeys and only works on Windows operating systems. 


Problems:

  • It seems like the autosave minimizes the UI ingame. This, as far as I can tell, is something I cannot control.
  • You have to quit by sending a keyboard interrupt to the program, or manually ending the process.

Possible improvements:

  • Command-line usage, complete with argument intake.
  • Possibly launching SimCity 4 itself, that way there's the guarantee that it's running, and that it can end when SimCity 4 does. (Unless the crashing affects the returning of focus adversely.)
  • Making a taskbar agent which can then configure the options, or shut the autosaver down.

This code is public domain. I am not liable for any results of using, executing, or having this code, except for cases wherein fun and legality are both had.

I would probably make it more user friendly if I didn't have cities to attend to.

Monday, January 12, 2009

Traversing an Isometric Ground Map

Recently I've been fiddling around with pygame, in an attempt to draft some working solutions to making a 2D trisometric tile-based ground. An example of trisometric ground which I will be using, overly simplified, is below.

Not great looking, but you get the idea.

In the process of looking for ways to form good representations, I've come to see a lot of different ways that people suggest to express these "maps" of the ground. Usually I'm put-off by the suggestion, because it's one or more of the following:

  • Difficult to understand.
  • Tricky for no good reason.
  • Too wasteful for my purposes.
  • Lacking a specification for iteration that is back-to-front rendering ordered.

As such, I've come up with a sort of solution of my own, to the above, and I thought that I might share it with the world. In my travels, I haven't seen anything similar, so perhaps it will be of some use to someone, despite it's as-forseen-by-me limited applications.


The Way We Might Express a Map

Some people have suggested (long long ago) that a good way to express a map of ground in a 2D tile-based game would be to simply stagger a 2D array, or any expression of a 2D table of accessible data, such that odd rows are offset by the radius of the tile's width. Indeed, most of the material I've seen that covers the subject of tile-based games' maps are variations to this theme.

There is something that I feel will be detrimental to memory and execution speed with this method, in the context of the maps that I will be creating.

  • There will be too many empty places.

For instance, take the following, this is a stylized and simplified example of what I hope to end up with. My maps will all be variations of a rhombus shape, most likely of an equal ratio on all the sides (Read, a diamond shape, most likely a square shape tilted over.) For lack of space, I've only begun to show one corner here, the uppermost one, but you will be able to imagine the shape in it's entirety easily enough.

Now, though, what would happen if we were to try to express this using the standard "stagger every other row" solution? We'd end up wasting lots of space! Consider the transluscent tiles below to be the places in whichever data structure that we choose to express this map, and how useless they would be.

If we were to finish this to completion, we would see that half of the data structure would be used to contain purely empty space! This is not good.


Another Thing We Don't Want

Other possible ways to express this map in data structures lack a well defined way to properly iterate through, in order to obtain back-to-front rendering. Let's look at why we want this real quickly. Consider the example below, where a simple order for iteration has been established, and the way this might affect our rendering.

You might be able to tell from this that all we've done here is set the leftmost corner of our map as the top left of a 2D tabular data structure expressing our map. So, simply, we're going from left to right, top to bottom. In actuality, this was what I did for my first attempt, and how I discovered the problem that lead to the solution of this post! What sort of result does this beget, though?

Let's see.

Hey! So far so good, we've got the leftmost tile up there, and soon the rest will follow.

Hey, what the heck? What happened? Well, since we wrote the next tile after the first, we've just overwritten part of the first tile, and since the first tile is supposed to be in front, and not behind, that spells trouble. If we continue on, let's see what happens.

Well, at least some of the mess-up is overwritten by the next row's first tile. But then, it's still clearly visible that something is not right.

Unfortunately, all illusions of realism, however frail, are lost when you don't render from back to front, as you see here. What's the moral of the story? Badly iterated data structures representing these maps are a bad thing!


What We Do Want

So, knowing that, what do we really want? Well, why not just change the order of the numbers on the previous example?

If you were to run through this, and imagine it rendering, you can see that anything of the previous tiles will be overwritten, and that we end up with this nice realistic looking set of tiles.

A simple and wasteless way to do this is exactly what I'm attempting to achieve.

In order to do this, I took a step back, and looked at not only what I wanted in the previous picture above, but at how I was currently ordering my ground tiles. It looked abstractly like this.

Each coordinate pair in that table is representative of a single tile. As it was, 0,0 was the leftmost tile, and as you saw above, this will not work the way that we want it to. So what are we to do? Well, all you have to do is tilt your head! Observe.

Doesn't that look an awful lot like the shape we're seeing in the previous examples? That's because it is! By simply changing our viewpoint on the data, we've just solved the problem. By looking at it this way, we're able to trim excess waste, and, provided we can iterate through it properly, render from back-to-front.

"Great!" you say, "But, how do we iterate through it properly?"

You're in luck, because that was the next logical progression in the series of steps that led to (I think) a great solution of mine.

Firstly, let's expand on our simple grid, to make a more representative demonstration. A 5 by 5 table should suffice.

First and foremost, we need to set our beginning point. 0,0 is the only logical place, in this context, due to not only it's easily accessible spot, but also by our back-to-front iteration requirements. Remember that when displaying the tiles visually, the result is tilted from our usual view of the tabular data.

Now we need to define rules for moving to the next diagonal row. Check out the numbers in Y's 0 row, and X's N column (in this case, 5), notice any similarities that we can depend on?

Indeed, The Y values are all 0, and the X values are all N, where N is the width. Knowing this, we can craft a pretty good conditional statement to figure out whether we need to go to the next diagonal row or not.

(Y == 0 or X == Width)

So, what do we do when we see that we need to go to the next diagonal row?

If you look at the correlation between the X value of any diagonal row's last position, and the Y value of the next diagonal row's start position, you will usually see that it is greater by 1, unless the X value happens to be the Height, in which case it will be that instead. Also note that the X value will always be 0. Using this, we can just set the coordinate pair as follows. (Current X + 1) Modulo Height, 0

However, next we face a new dilemma. How do we move to the next item on a diagonal row if it's not the end, or final item in the table alltogether? Can you spot any consistant similarities between the values from any given position to the next?

Indeed, it seems that the Y value is always one less than the previous, and the X value is always one more than the previous. Knowing that, we can decrement Y, increment X, and then we're at the next given position along the same diagonal row.

And we're done...

but not quite! You see, we need a final case, one which determines when we're done looking through this thing altogether. You may be able to see right away what this will be, or at least where it is, but for the sake of completeness, consider the following.

Yup, that's all there is to it, we're always going to find that the last position has the values of X = Width, and Y = Height. So all we have to do is test for that, and when we find it, we're completely done.

A little tip for those who did indeed bother to look at the last example (You avid readers are appreciated, after all!) Note that since this will only ever occur at the end of a diagonal row, that there's an added benefit of only ever having to test for this when you note that we're at the end of a diagonal row. This makes me a happy panda.


Some Concerns

Of course, every solution is not without it's problems and constraints. One such constraint that I've forseen (as alluded to at the beginning of this post) is that this solution will absolutely, I guarantee it, only work for maps that take a diamond shape. It might even only work for those which have equal ratios on all sides. (More on this in a later post.)

This means that if you're considering having dynamically shaped maps, either now or the possibility of such in the future (Like one that may be shaped like an L, or such like that.) then this will not work for you in it's current form.

Another concern is that this may not be the absolute speediest way to do things, in this particular area, where I'm sure that my knowledge is by no means complete.

Given all of that, however, I think the strength of this lies in:

  • It's simplicity of expression, compared to other solutions.
  • It's accurate space usage.
  • It's natural iteration resulting in back-to-front rendering order.


And Finally

I'd like to thank the following people:

  • the #gamedev community on irc.afternet.org for their ongoing support, and, perhaps disproportionately greater, their ongoing distraction of my attention from things like this blog, and other projects mentioned therein.
  • Gamedev.net (the website with which #gamedev is associated) with it's copious articles, forum posts, and journals related to not only this subject, but game development in general.
  • The authors of Dia, because it's a kickass data/organization/etc. visualization expression tool.
  • The authors of Adobe Photoshop, because, while not as kickass at what Dia does, it's still a kickass painting program.

Thanks for reading, and as always, discussion is welcome. :-)

Monday, December 29, 2008

Structure and Interpretation of Computer Programs

In the efforts of forever growing and learning, I've decided to break out of my shell a little bit, and work my way through a popular MIT course-book, Structure and Interpretation of Computer Programs or SICP written by Hal Abelson, Jerry Sussman and Julie Sussman. It's available freely online, and comes with useful exercises along with it, as well as videos by two of the book's authors, (Hal Abelson and Gerald Jay Sussman.)


One of the reasons that I think this would be a good practice for me is it's return in the long road on my path towards becoming a programming craftsman. I've begun to note a bit of a rut that I've gotten stuck in. It all began when I revived a 100-200 member social community as admin, mainly centered around a forum. In the process of administrating this community, I was exposed to a lot of technical issues. Most of my work at that time was in managing the social dynamics, as well as extending the forum software with "skins", or new looks. At the time, it was difficult, as I did not know much about HTML, CSS, or Web Standards.


As time went on, I began to grow more confident in my skills, and began to look at what was "under the hood" of the forum (Invision Power Board 1.x-2.x, for the curious.) With that, I began to learn about, and use, PHP. All was well, in that I was learning how to make interesting web pages, and it was easy to pick up.


Fast forward some amount of years, to the time I began attending Midwestern State University. I was cocky, and sure of my skills, despite only being a "web guy." It wasn't long before I was exposed directly to C++ and Assembly. Learning them academically for the time that I was attending, however, was not enough. I began to dabble in communities of programmers, observing the way that they operate. In particular, I looked at game programmers, and open source application developers. Fortunately, what I found out was that I knew very little.


At this point, I decided to strike out in a new direction, and picked up Python. Quickly. It was extremely easy to become comfortable with it, and with my newfound language, I became satisfied.


But this isn't good, is it? If I become complacent, and decide to stop learning about everything else that is going on, then how will I be able to tell what is good, and what is not? This dilemma, then, is why I've resolved for the new year to work my way through the SICP, and it's exercises, all the while logging my thoughts down.


If you're still reading, then congratulations. You were able to withstand some of my personal history, and that's quite an accomplishment! In any case, onwards with the learning, onwards with mastery!


-AndrewBC

Sunday, December 28, 2008

RedArena - Core War and Warrior Evolution

There was something interesting going on before I was born, and it was called Core War. If you prefer the short overview, it's something of a programmer's game. Warriors written (or not written, but we'll get to that...) by people battle for space in a Core by utilizing Redcode. (A sort of assembly language.)


When I first found out about this, about a week ago, my first thought was "Where has this been all my life?" Maybe I've just been living under a rock, but it's never too late to start now. Yes, you heard me right. This game is still going strong, even after almost 25 years!


So what have I accomplished so far? Not very much. I've attempted to hand-code some warriors, but none have yet to be successful. Will that stop me from trying again? Of course not. I'll just change tactics. It wasn't long after I began looking around for information about Core War and Redcode, and chatting with some very nice competitors on IRC (#corewars on irc.koth.org) that I discovered that people were actually utilizing their programming skills to evolve warriors, as opposed to hand-writing them.


I bet you can tell where I'm going with this. Naturally, since I'm not doing so well at hand-coding warriors, I think it's time I gave this whole evolution bit a try. Hopefully my higher level programming skills will really shine through. I've dubbed my entire evolution process RedArena (or "the process"), and to start off with, it will be mostly, if not entirely, in python. Right now, it's very abstract, and I haven't coded a single line, and won't until I get the design down as I want it. To start off with, I have some core ideas about the process, which will be guidelines throughout, and they are (but not limited to):

  1. Never throw good data away.
  2. Give second chances.
  3. Analyze the data, and use the analysis.
  4. Start from scratch. Measure against the Elite.


Never throw good data away.

Because the evolution process is dependant on generational building for progress, I think it would be great to never throw any warriors away. Sure, they can lose, burn, and die, but they won't be forgotten, because they're all part of the process of "life."


There are other benefits to this, like being able to rewind through the process, in case we want to start off from somewhere besides the bare ground on a future run, or for logging, statistical, or bragging purposes.


However, there may be some downsides to this. One is that it adds complexity to the process. The second downside that I can envision is that, depending on what way we store this data, there may be issues with the speed of access (or lack thereof) bogging down the process.


Give second chances.

A warrior is not doing well. In fact, it's at the bottom of it's generation. What's a warrior to do? Usually they would probably just be discarded as useless, but what if just one little change was enough to make it into a Tron? (Much to my MCP's chagrin...) In order to try to catch these very rare happenstances, I will give these poor contenders a second chance. It will take the form of a forced mutation, and only ever a forced mutation. (Bad code cannot be rewarded with reproduction.) The degree of this mutation is, as of yet, undecided; The mutation will have to be more dramatic than a normal one, though, as to give the bad code a solid second chance at being good.


Should the rare program actually turn out well, then all the better! However, I can see some issues with this. Firstly, I have little knowledge of how often this will actually work for the better, and there will be a steady drain on the speed of execution caused by having this extra logic and "another" warrior to process. We shall see, I suppose.


Analyze the data, and use the analysis.

Since we're going to have oodles and oodles of data, including the warriors, their scores, and other things, I'll be doing a large amount of analysis of this data, and depending on how things turn out, shake things up a bit, or leave it as is. In the beginning, this may be more of a manual process until I can get a feel for how things are affected by the changes, if any. An example of this kind of change would be toggling the chances for mutation, mating warriors randomly, generating new warriors based on statistics, (e.g. This strategy isn't used much, so let's increase it's chance to be a mutation, so the pool can work effectively with and/or against warriors who use it.) or other changes that I have yet to envision.


Some good things with this is that it will enable a deeper understanding of just what is going on with my precious babies, and furthermore, should make for more well-performing warriors, when done correctly.


Of course, this is not without it's drawbacks. As always, it adds complexity, and more processing to the requirement. Despite that, I feel that this is one of the most useful things that I could do within the process.


Start from scratch. Measure against the Elite.

This is something of a risky venture, I think, but I can't be sure until I see it in action. The idea is to start from completely random warriors, but benchmark against well established already-evolved or hand-written warriors that have done well on actual hills.


This is good, because it should ensure a good measuring of how well my precious babies will perform on the same actual hills. However, beginning from scratch may add a lot of time to the process, particularly in the beginning, where chances are my precious babies will be slaughtered in the benchmarks.


Community

One thing of note is that so far, I've noticed that there exists a core community centered around Core War, which is very active, though things seem to have died down some in the past 24 years. Nevertheless, I've found a great deal of good code, good advice, and camaraderie from contenders John Metcalf, bvowk, and flyduck. (All from the #corewars IRC channel on irc.koth.org)


I probably would have lost interest in competing vicariously through my precious babies, hand-written or not, and quickly, if it weren't for these friendly folks.


I'm opening this up to all, for comments, ideas, debates... Whatever you feel I should know, comment here, and your voice will be heard!


-AndrewBC