Hopefully I am going to write a NHaml view engine adapter for the Nancy web framework. So far I have managed to get my development environment set up under Debian. Nancy requires a version of Mono which is newer than what is currently in the Debian testing release (what I am using), so I had to re-install mono from the experimental repository.

NHaml compiled after making a couple of changes, but I haven’t tested it yet. I forked RussPAll’s repository and committed the changes to it, you can find it here: https://github.com/richiejp/NHaml

For a long time NHaml looked like it was dead, but fortunately Russell Allen decided he was going to take over the project and get it working on .Net 4.0

Personally I can’t stand writing HTML by hand and most view engines seem to espouse the view that templates should look like HTML. If anything HTML shouldn’t look like HTML; s-expressions are a good example of something which is easier to type and more flexible. The haml syntax is not exactly perfect in terms of flexibility, but it is very terse.

Speaking of s-expressions I do have half a mind to try using Iron Scheme as a view engine in Nancy, it would be interesting to see how that would turn out.

 

I put my 5 year old c examples on github and added links going to the gists on the article pages. I really like Github, it’s a shame I have been too distracted by shiny new languages to get a hobby project up on there.

Over the last year or two I have had the pleasure of being able to write code for a living. At least some of the time anyway, the rest I have spent in admin, sales and technical support. It is not the easiest transition to go from thinking about how to best implement sort and search algorithms to explaining the finer points of what the start menu is and how it can used to access ‘Computer’, which in turn contains a link the disk drive.

One thing – amongst others – I have discovered in this time is that even applications with no individually complex parts become impossible to comprehend if organised badly. A large amount of skill in software development has nothing to do with being able to understand or implement complex algorithms, but is instead in organisation.

Because I am new to software development where line counts exceed a few thousand, I naturally fucked up a project or two. They still work, but I live in fear of having to work on them again. Frankly I might start from scratch even though that is known to be death for a project.

My most recent project is looking a lot better however and I attribute that mainly to two things: Painstaking decoupling to the point where boiler plate is coming out of my ears and incremental development. I feel that to an extent Test Driven Design/Development has helped with this. I don’t believe that TDD is necessary to achieve these results, just that it helps.

It helps because it requires a certain level of program design quality in order to work. For the most part you will use unit tests and workable unit tests require lots of mocking. Unless your program is well decoupled, mocking won’t work. So it has forced a good programming practice on you with one of its chief requirements.

What I feel I am doing now though is selling TDD to you and I think enough people have done that already, possibly to the point it has give TDD a bad reputation. So, what I really want to explain, is what I had the most difficulty with and how I solved those problems. Initially my main problem was Microsoft’s MVC and Enitity Framework, so I threw those out. I replaced them with lightweight libraries which seemed to give me what I wanted in a much simpler package. PetaPoco now gives me access to the database and Nemerly serves up webpages.

I also use TinyIoC to help with decoupling, Moq to mock and… I actually still use MSTest to test rather than throwing it out for xUnit. None of that is really important though compared to the main problem I suffered. The thing that most TDD zealots fail to explain in their lust to convince you why it is amazing is what you do given a blank sheet.

You start by writing the most simple test that will fail… no shit, but testing what? Do I start writing a web app by making a request to the url and testing if we get 200 OK! back? For a start that isn’t a unit test and we are not writing a web server, we are writing a module which runs on top of it. This test doesn’t just – potentially atleast – test the module we are writing, it tests the server too.

That doesn’t actually mean we can’t start there however! I probably wouldn’t, but not all our tests have to be unit tests. What might be a better idea though is to find an entry point to our application where we can begin development using unit tests. This may require a bit of upfront design, but only in the sense that we have to decide what specific problem the module we are going to write will tackle.

This means analysing the overall problem we have been presented with and seperating out a manageable chunk of it to be turned into a test. Lets say we have been tasked with creating an application for a furniture store which will allow them to employ untrained minimum wage staff who don’t know what they are talking about, but not have to hand out too many refunds.

Lets say this store sells beds and matresses; I don’t know a lot about mattresses. However it seems feasible that based on a persons physical health, preferences, bed frame, budget and floor strength you could make an informed decision as to which products to highlight for them. You could also encode this decision making procudure into an application so that the shop assistant can start working the floor with only minimal domain knowledge.

I find that writing a test out in plain natural language (Always English in my case) first is ideal at this early stage. Especially as it lets us write silly tests which we can initially use to organize our thoughts.

So beggining with:

Given a whole host of information about the customer.
Choose approximately best matress(es).

This begs the questions, what information and which matress? So we can see there is a lot of work to be done here. However because our test is supposed to start out very simply we don’t want to go through every possible parameter the customer may give us or even which matress is actually best. We definately don’t want to get into how the customer or assistant will enter their requirements or where a list of matresses will come from. In fact we are just going to decide on one thing that we want.

Returns matress.

That is our first test and it fails because we don’t even have a way of representing a matress. Even if we did, we don’t have a method to call to get the matress and we certainly don’t have a GUI which would call the method on the user’s behalf.

At this point I think it is safe to say that we can ignore the lack of a GUI for now and make a test which is just targeted at a single method on a class. It would be possible to make a test which requires the user to look at the screen and confirm if they are being presented with something resembling a particular matress. It would also be possible to write some software which performs the same test programatically without user intervention. I hope I don’t have to explain why those methods would be counter productive compared to a unit test at this stage.

So our first test goes from being natural language to something like the following (probably invalid) C#:

[TestMethod]
public void Assistant_ChooseMattress_ReturnsMattress()
{
Assistant target = new Assistant();
IMatress actual = target.ChooseMattress();

Assert.IsTrue(actual != null);
}

Assuming that I have sketched out the IMatress interface and Assistant class MSTest would run this method and signal failure because I have just told ChooseMatress to return null. We could of course tell it to return an object which implements IMatress in order to complete the first test. Once we have done that it is time to think of a constructive way to make the test fail again.

Maybe at this point you decide that you don’t want the method to return just any old Mattress, but one which is actually in the database. We don’t have a database at this point though and I personally, wouldn’t want to introduce one. So what we could do instead is define an interface for getting mattress data which can then be mocked in our test. The mock can be passed to the Assistant objects constructor and we can rewrite the implementation to get the mattress from the new component. This would also allow us to mock the implementation of IMatress so that the Assistant class can be decoupled from any implementation of IMatress.

There are other routes we could go down in extending our test as well. You just need to think about where you eventually want to be and what the next step in getting there might be. Maybe we could extend the test so that it takes the customers budget into account and checks the value of the returned IMattress’s Price property. IMattress doesn’t have a Price property, but it will once the test compiles and passes.

Hopefully I have given you an idea of how to start from a blank page. Initially I didn’t understand how you could write a test that wasn’t targeted at a method you had already planned in your design. TDD primarily uses unit tests and that is all some evangelists seem to talk about. However something similiar to a user acceptance test or use case seems to the best place to start. Given a high level test you can dig down until you find a level where you think a single method could be programatically tested for some subset of the functionality required.

In order to fulfil this test I will end up deferring most of the functionality to new interfaces and services which can then be developed through TDD themselves. Thus the program is created in a recursive top down approach. There are downsides to creating programs in this fashion, but with a fully pervasive test suit you can refactor till your hearts content, combating the problems associated with a semi-organic design.

PC gaming is almost dead and soon their won’t be any new games in production for it. This is an obvious lie, but it makes certain people happy when they hear and repeat it so it keeps getting said. It could be suggested with reasonable legitimacy that big budget PC gaming is in decline, but to be frank with you I don’t think the money being spent on producing big name flashy PC titles has ever been greater. Of course relative to consoles PC gaming is becoming smaller, but it’s not too hard to see that the increasing size of the console industry doesn’t necessarily mean the death of PC gaming.

Besides if you include games like the computerized version of solitaire then PC gaming would (in terms of player count) most likely be the largest. (Un)Fortunately the likes of solitaire don’t require a myriad of expensive PC components to run them and thus can’t create demand in the hardware industry that has grown up around gaming. Games like Crysis, which do create demand for expensive computer parts, have the problem that people don’t want to pay for them. It so happens that the type of gamer who spends thousands on hardware doesn’t feel the need to spend a little bit more on the games themselves.

Because it is so easy to pirate games these days and because it is becoming increasingly expensive to create games with cutting edge graphics. The developers who make these eye candy masterpieces may decide to move on to greener pastures. Epic and Crytek seem to have this idea, but I won’t weep for their loss.

So certain kinds of PC games are most likely going to become rare, but not disappear altogether because there is still a demand for this type of nonsense. The 3D graphics accelerator arms race may slow down, but it’s not only games that use these things and in fact ATI and Nvidia are in the console market so R&D they do there could be transferred to PC. For the current console generation it’s more the other way round; technology made for PC was then put into consoles.

What would it take then to kill the gaming PC? (apart from global catastrophe) Well for me personally it requires a console which has the following features (in no particular order):

Mouse and keyboard support

And not just a really awful after thought that pretends the mouse is a thumb stick. Games need to be designed to use a mouse otherwise it’s like trying to put a circle in a square hole. If someone came up with an even better pointing device than a mouse then that would be brilliant, but thumb sticks are not it. While they may be of a convenient size and have many different uses, they just aren’t very good at a lot of things. Driving games are better when made for a steering wheel, Flight simulators are better with a joystick, FPS and RTS games with a mouse. Control pads are good for platform games and the Wii mote is good for a laugh. Consoles not only seem have every wacky peripheral you can imagine, but also games made just for that peripheral. Yet they still lack a decent mouse and keyboard.

A desktop and allows for game development and modification

When I say desktop I mean something like windows or Gnome where you can do all the things you would usually do on a PC. You see, a large part of PC gaming is user created content, even games which were never designed to allow for it can end up with a huge mod community. It’s a double edged sword for multiplayer games however, where every server admin has their own idea of how the game should look and play.

The PS3 supports Linux which shows initiative on Sony’s part, however they backed out of actually packaging Linux with the console. Also only the Game OS currently has access to the graphics subsystem (RSX) which sort of ruins everything. Microsoft is apparently going to allow people to develop games for Xbox360 on PC using XNA. We’ll see how that works out.

It can run Counter-Strike Source

Complete with mouse, keyboard and user created content. Frankly I have played this game for years and I am not about to stop. I’d also need to be able to play all my other PC games. With a mouse and keyboard no less, except for the ones involving driving which I want to play with a steering wheel.

Except for the Counter-Strike source bit which will be different for different PC gamers, a lot of people share these opinions. Enough in fact that we make up a market big enough to continue financing PC gaming until something else better caters to our gaming desires. That something doesn’t necessarily have to fulfill the listed requirements, but it will have to be damn good if it doesn’t… if the Matrix came along that might suffice, but even then I might be tempted to crack out Command & Conquer once in a while.

Now I’m going to list a few things that are often used to explain why the PC is going to die, but aren’t really all that bad or in some cases even relevant.

Cheaters

They really have managed to drive people from the PC. The problem is that cheating comes hand in hand with user created content. If you give people the freedom to change the system then they can cheat. Even just letting people change a fairly innocuous configuration file can lead to cheating. So if you want an open system, which I do, then you must put up with cheating.

Pirates

Even though they know they can get it for free some people will pay for games. So you make games that target these people. Also people who do pirate games will still pay for certain ones at a low enough price. Personally I think that with few exceptions the developers complaining the most about piracy also happen to make bad games. No coincidence if you ask me.

[Insert something else which consoles are better at]

So people will buy a console if they like those things and it may mean they then don’t feel the need to bother with PC gaming. On the other hand they may not care about those things which consoles do better and buy a PC. Further to that they may just decide they want the features of both and buy both. Regardless, the PC has major advantages which consoles don’t and thus it stays.

Finally it is worth mentioning that PC gamers do tend to eventually find a single game they adore above all else and play almost exclusively for years. This of course means they buy fewer other games, but not so few that companies can’t sell new games. Occasionally people will also change their favorite or at least try new ones and that is all they need to do to finance a new game. This does mean a slow down for the PC game industry, but not it’s death.

PC gaming is here to stay until the PC itself is made redundant.

I’v redone my Python implementation of the A* (A-star) path finding method. I’m now using Classes instead of plain lists for my data structures, this has had the effect of speeding it up and has possibly made it more readable. I have also made a new interface for creating mazes and showing the results of the algorithm.

completed maze by A*

My last post displayed a program which found the correct path using what I believe to be a uniform cost algorithm. After doing some actual course work I have learned of the A* method which unlike uniform cost doesn’t explore every single cell, but has similar results. I’m not sure if I have implemented it correctly, but it works pretty well with my fairly small maze so I’m happy with it.

I’v included the source code, but good luck reading it. Having said that you should be able to understand it if you know Python and roughly how the A* method works.

aMap = [[ 0, 0, 0, 0,-1, 0],
        [ 0, 0, 0, 0,-1, 0],
        [ 0,-1, 0, 0,-1, 0],
        [ 0,-1, 0, 0,-1, 0],
        [ 0,-1, 0,-1,-1, 0],
        [ 0, 0, 0, 0, 0, 0]]

def findRoute(sXy, fXy):
  ol = [] #Open list of cells
  cl = [] #closed

  sc = cell(sXy)
  if sc[2] < 0:
    print "Invalid start cell" 
    return []

  #Search for the finnish from the start
  ol.append(sc)
  while True:
    #If there are no open cells we have run out of things to try
    if len(ol)  0:
      route.append(pc)
      pc = ml[0]
    else:
      print "There is a cell which points to no cell in closed list"
      print route
      break
  route.append(pc)
  route.reverse()
  return route

def distance(sXy, fXy):
  sx, sy = sXy
  fx, fy = fXy

  return abs(sx - fx) + abs(sy - fy)

#get/create a cell
def cell(xy, offset=(0, 0)):
  x = xy[0] + offset[0]
  y = xy[1] + offset[1]

  if x < 0 or y = len(aMap) or y >= len(aMap):
    cv = -1
  else:
    cv = aMap[y][x]
    
  return [(x, y), xy, cv]

#Get cells(c) neighbores
def neighbors(c, inv, pre):
  xy = c[0]
  nh = [cell(xy, (1, 0)), cell(xy, (0, 1)),
        cell(xy, (-1, 0)), cell(xy, (0, -1))]

  #filter out cells that are invalid
  def byThis(nc):
    if nc[2] < 0: return False
    for ic in inv:
      if ic[0] == nc[0]: return False
    return True
  nh = filter(byThis, nh)

  #Calculate neighborhood cells' incured cost and then check to see
  #if it's already in the open list. Compare costs if it is and delete
  #the copy with the highest cost.
  for nc in nh: 
    nc[2] += c[2] + 1
    for oc in pre:
      if nc[0] == oc[0]:
        if nc[2] <= oc[2]:
          pre.remove(oc)
        else:
          nh.remove(nc)
        break
  
  return nh

def printCells(li):
  for c in li:
    print c
  print

if __name__ == "__main__": 
  printCells(findRoute((0, 0), (5, 0)))

I wrote a script to draw the map and route as well. It’s terrible and you need pygame installed to run it, but don’t let that put you off.

from pygame import *
from astar import *

BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
RED   = (255, 0, 0)
BLUE  = (0, 0, 255)

def drawMap(screen):
  ws = Surface((50, 50))
  ws.fill(WHITE)
  cs = Surface((50, 50))

  for x in range(len(aMap)):
    for y in range(len(aMap)):
      if aMap[y][x] == 0:
        screen.blit(ws, (50 * x, 50 * y))
      elif aMap[y][x] > 0:
        wv = 255 - aMap[y][x] * 20
        cs.fill((wv, wv, wv))
        screen.blit(cs, (50 * x, 50 * y))

def drawRoute(r, screen):
  bs = Surface((25, 25))
  bs.fill(BLACK)
  for c in r:
    x, y = c[0]
    screen.blit(bs, (50 * x + 12, 50 * y + 12))

def go():
  init()
  
  screen = display.set_mode((640, 480))
  screen.fill(BLACK)
  display.flip()

  drawMap(screen)
  drawRoute(findRoute((0,0), (5,0)), screen)
  display.flip()
  
  while 1:
    for e in event.get():
      if e.type == QUIT:
        quit()
        sys.exit()

if __name__ == "__main__":
  go()

There are many ways of doing pathfinding; most of them too complex for my pedestrian intellect so I’m quite pleased to have rediscovered one which is relatively simple to understand, implement and finds the optimal solution to most problems. It should work in any number of dimentions although I have stuck to 2D space for the sake of simplicity.

It’s probably quite expensive compared to some methods, but for the time being I’m not concerned with that. It works on the basic principle of starting at the finish and then working backwards in every direction, valueing each position with the number of steps it took to get there untill every position is marked with how close it is to the finnish. The route finder then merely has to look at the value of the cells around it and move to the one with the lowest value. Repeating this sequence untill it arives at the target destination.

maze one

The above picture was rendered by pygame and shows a simple maze which the path finder has completed. The bottom right square is the exit and the top left is the entrance. White squares are walls, greenish squares are close to the exit and reddish ones are far away or unreachable. The small black squares are located on cells which are on the path finders chosen route.

maze two

This is a slightly altered version of the first maze. As you can see one of the routes has been blocked off and cells that were previously considered close to the exit (were green) are now far away (red). The path finder has of course chosen a new route which avoids the dead end.

I must warn you that the implementation code may seem incomprehensible. I have just the right amount of knowledge and ignorance to confuse anyone who isn’t familiar with python and maybe functional programming. At any rate I’ll let you be the judge of that.

I generally just run this code from inside IDLE, you will have to add an event loop to mazeView.py if you don’t want to and you also need to have pygame installed regardless.

Pathfinder.py

class Maze:
  defaultMap = [[1,1,0,1,0,1,0]
               ,[1,1,0,1,0,1,1]
               ,[0,1,1,1,1,1,1]
               ,[1,0,0,1,0,0,1]
               ,[0,0,1,1,1,0,1]]
  
  def __init__(self):
    self.map = self.defaultMap
  
  def inMaze(self, xy):
    x, y = xy
    return x < len(self.map) and y = 0 and y >=0
  
  def getCell(self, xy):
    if self.inMaze(xy):
      x, y = xy
      return self.map[x][y]
    else:
      return -1
  
  def setCell(self, xy, value):
    if self.inMaze(xy):
      x, y = xy
      self.map[x][y] = value
  
  def getMoves(self, xy, validator):
    """Returns a list of all possible moves from the cell at xy. The validator decides what moves are possible"""
    x, y = xy
    left  = (x - 1, y)
    right = (x + 1, y)
    up    = (x, y - 1)
    down  = (x, y + 1)
    moves = [left, right, up, down]
    return filter(validator, moves)
  
  def scentTarget(self, startxy):
    """Casts out ascending cell values from the chosen position.

    The lower the cell value the closer (as the mouse crawls) it is to the target.
    It's like a bad smell creeping through the maze. The quickest route to the source
    will be kicking off the worst wiff, thus finding the optimal route is easy.""" 
    def creep(xy, dist):
      def validator(m):
        cv = self.getCell(m)
        return cv == 1 or (cv > 2 and (cv - dist) > 1)
      dist += 1
      self.setCell(xy, dist)
      for m in self.getMoves(xy, validator):
        creep(m, dist)
    creep(startxy, 1)
  
  def findRoute(self, startxy):
    """Trace a route towards the scented target (select target with scentTarget())."""
    route = [startxy]
    def step(xy, pxy):
      """Take a step in the direction with the lowest value and add the cell to the route."""
      def validator(m):
        return self.getCell(m) >= 2
      moves = self.getMoves(xy, validator)
      if len(moves) < 1: 
        return
      lowest, lowestm = self.getCell(moves[0]), moves[0]
      for m in moves:
        if self.getCell(m) < lowest:
          lowest, lowestm = self.getCell(m), m
      route.append(lowestm)
      if lowest == 2 or lowestm == pxy:
        return
      step(lowestm, xy)
    step(startxy, startxy)
    return route

if __name__ == "__main__":
  maze = Maze()
  maze.scentTarget((4, 6))
  for r in maze.map:
    print r
  r = maze.findRoute((0, 0))
  m = maze.map
  print
  for x, y in r:
    m[x][y] = 'X'
  for mr in m:
    print mr

mazeView.py

from pathfinder import Maze
from pygame import *

BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
RED   = (255, 0, 0)
BLUE  = (0, 0, 255)

def createMaze():
  m = Maze()
  m.scentTarget((4, 3))
  return m

def drawMaze(m, screen):
  wsquare = Surface((50, 50))
  wsquare.fill(WHITE)
  csquare = Surface((50, 50))
  
  row = 1
  for r in m.map:
    cell = 1
    for c in r:
      if c == 0:
        screen.blit(wsquare, (50 * cell, 50 * row))
      else:
        if c == 1 or c * 20 > 255:
          csquare.fill(RED)
        elif c > 1:
          csquare.fill((c * 20, 255 - (c * 20), 0))
        screen.blit(csquare, (50 * cell, 50 * row))
      cell += 1
    row += 1

def drawRoute(r, screen):
  marker = Surface((25, 25))
  marker.fill(BLACK)
  for x, y in r:
    screen.blit(marker, (50 * (y + 1) + 12, 50 * (x + 1) + 12))

if __name__ == "__main__":
  init()
  screen = display.set_mode((640, 480))
  m = Maze()
  m.scentTarget((4, 6))
  drawMaze(m, screen)
  drawRoute(m.findRoute((0,0)), screen)
  display.flip()
Follow

Get every new post delivered to your Inbox.