Balloon Ninja: Adding a Scoreboard

Back to Tutorial Contents

Making a scoreboard

In the previous section we learned how to pop balloons, which involved looking for collisions between our game’s objects. In this section, we will add a scoreboard to our game. After this, we will be able to focus on overall game logic.

Our scoreboard is really just a sprite that we write text onto. So, we are going to make a file similar to Balloon.py and Sword.py. Save the following file as Scoreboard.py:

import pygame, pygame.font
from pygame.sprite import Sprite

class Scoreboard(Sprite):

    def __init__(self, screen):

        Sprite.__init__(self)
        self.screen = screen

        # Game attributes to track for scoring
        self.balloons_popped = 0

        # Set dimensions and properties of scoreboard
        self.sb_height, self.sb_width = 50, self.screen.get_width()
        self.rect = pygame.Rect(0,0, self.sb_width, self.sb_height)
        self.bg_color=(100,100,100)
        self.text_color = (225,225,225)
        self.font = pygame.font.SysFont('Arial', 18)

        # Set positions of individual scoring elements on the scoreboard
        self.x_popped_position, self.y_popped_position = 20.0, 10.0

    def prep_scores(self):
        self.popped_string = "Popped: " + str(self.balloons_popped)
        self.popped_image = self.font.render(self.popped_string, True, self.text_color)

    def blitme(self):
        # Turn individual scoring elements into images that can be drawn
        self.prep_scores()
        # Draw blank scoreboard
        self.screen.fill(self.bg_color, self.rect)
        # Draw individual scoring elements
        self.screen.blit(self.popped_image, (self.x_popped_position, self.y_popped_position))

Let’s go through this file. In line 1 we import the pygame.font module, which gives us access to pygame’s font rendering functions. Lines 5-10 are just like Balloon.py and Sword.py. Our scoreboard is a sprite, which means once we have defined its properties and behavior we can just blit it like any other object on our screen during game play.

In line 13 we start to define the game stats that we want to report on. We will start with one statistic, the number of balloons that have been popped.

In lines 15-20 we define the properties of our scoreboard. We set its width and height, and then create a pygame.Rect object of this size, positioned at the top of the screen. We set the background color of the scoreboard, and the color we want the scores to appear in. We also set the system font we’d like to use for our scoreboard.

In line 23 we specify where on the scoreboard we want the number of popped balloons to appear.

Lines 25-27 define a function that will turn our scoring information into an image that can be displayed on the pygame surface. Line 26 creates a string to report the number of balloons popped, and line 27 turns that string into an image.

Lines 29-35 define a blitme function, much like what we saw in Balloon.py and Sword.py. We need to create images for the individual scoring elements every time we redraw the scoreboard, so line 31 calls our prep_scores function. Line 33 draws the blank scoreboard, and line 35 draws the popped balloons score onto the board.

Now let’s modify balloon_ninja.py so it creates and uses our scoreboard:

import pygame, sys
from Balloon import Balloon
from Sword import Sword
from Scoreboard import Scoreboard

def run_game():
    # screen and game parameters
    screen_width, screen_height = 800, 600
    bg_color = 200, 200, 200

    # initialize game
    pygame.init()
    screen = pygame.display.set_mode( (screen_width, screen_height), 0, 32)
    clock = pygame.time.Clock()
    scoreboard = Scoreboard(screen)

    # Create a list to hold our balloons, and include our first balloon in the list
    balloons = [Balloon(screen)]

    # Create our dagger
    sword = Sword(screen)

    # main event loop
    while True:
        time_passed = clock.tick(50)
        mouse_x, mouse_y = pygame.mouse.get_pos()[0], pygame.mouse.get_pos()[1]

        # Check for game events
        check_events(sword, mouse_x, mouse_y)

        # redraw the screen, every pass through the event loop
        screen.fill(bg_color)

        # Update the sword's position, and draw the sword on the screen
        sword.x_position = mouse_x
        if sword.grabbed:
            sword.y_position = mouse_y
        else:
            sword.y_position = sword.image_h/2
        sword.update_rect()
        sword.blitme()

        # Update our balloons, and draw them on the screen
        for balloon in balloons:
            balloon.update(time_passed)

            if balloon.rect.colliderect(sword.rect):
                balloons.remove(balloon)
                balloons.append(Balloon(screen))
                continue

            if balloon.y_position < -balloon.image_h/2:
                balloons.remove(balloon)
                balloons.append(Balloon(screen))
                continue

            balloon.blitme()

        # Display scoreboard
        scoreboard.blitme()

        pygame.display.flip()

def check_events(sword, mouse_x, mouse_y):
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            sys.exit()
        if event.type == pygame.MOUSEBUTTONDOWN:
            if sword.rect.collidepoint(mouse_x, mouse_y):
                sword.grabbed = True
        if event.type == pygame.MOUSEBUTTONUP:
            sword.grabbed = False

run_game()

These changes are pretty straightforward. Line 1 imports our scoreboard, and line 15 creates a scoreboard object. We draw the scoreboard on line 60. We make sure to do this after all balloons have been popped, just before we flip to the just-refreshed screen (line 62). If you run the game now you should see a scoreboard, but it won’t update the number of balloons popped quite yet:

We have created a scoreboard at the top of the screen.

We have created a scoreboard at the top of the screen.

Using the bottom of the scoreboard as the top of the screen

We can see some things to fix before we add much to the scoreboard. We need to adjust the sword and balloon behavior, so they treat the bottom of the scoreboard as the top of the screen. Let’s fix the sword positioning first. We will do this by defining the height of the scoreboard in balloon_ninja.py, and sharing this parameter with Sword and Scoreboard. Here is our new balloon_ninja.py:

import pygame, sys
from Balloon import Balloon
from Sword import Sword
from Scoreboard import Scoreboard

def run_game():
    # screen and game parameters
    screen_width, screen_height = 800, 600
    bg_color = 200, 200, 200
    scoreboard_height = 50

    # initialize game
    pygame.init()
    screen = pygame.display.set_mode( (screen_width, screen_height), 0, 32)
    clock = pygame.time.Clock()
    scoreboard = Scoreboard(screen, scoreboard_height)

    # Create a list to hold our balloons, and include our first balloon in the list
    balloons = [Balloon(screen)]

    # Create our dagger
    sword = Sword(screen, scoreboard_height)

    # main event loop
    while True:
        time_passed = clock.tick(50)
        mouse_x, mouse_y = pygame.mouse.get_pos()[0], pygame.mouse.get_pos()[1]

        # Check for game events
        check_events(sword, mouse_x, mouse_y)

        # redraw the screen, every pass through the event loop
        screen.fill(bg_color)

        # Update the sword's position, and draw the sword on the screen
        sword.x_position = mouse_x
        if sword.grabbed:
            sword.y_position = mouse_y
        else:
            sword.y_position = sword.image_h/2 + scoreboard_height
        sword.update_rect()
        sword.blitme()

        # Update our balloons, and draw them on the screen
        for balloon in balloons:
            balloon.update(time_passed)

            if balloon.rect.colliderect(sword.rect):
                balloons.remove(balloon)
                balloons.append(Balloon(screen))
                continue

            if balloon.y_position < -balloon.image_h/2:
                balloons.remove(balloon)
                balloons.append(Balloon(screen))
                continue

            balloon.blitme()

        # Display scoreboard
        scoreboard.blitme()

        pygame.display.flip()

def check_events(sword, mouse_x, mouse_y):
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            sys.exit()
        if event.type == pygame.MOUSEBUTTONDOWN:
            if sword.rect.collidepoint(mouse_x, mouse_y):
                sword.grabbed = True
        if event.type == pygame.MOUSEBUTTONUP:
            sword.grabbed = False

run_game()

We set the height of the scoreboard in line 10. We pass this value to Scoreboard in line 16, and to Sword in line 22. In line 40, when we send the sword back to the top of the screen, we add the height of the scoreboard to the y-position of the scoreboard. This moves the sword down by the height of the scoreboard.

Now let’s update Scoreboard.py to use the scoreboard_height set by our main file:

import pygame, pygame.font
from pygame.sprite import Sprite

class Scoreboard(Sprite):

    def __init__(self, screen, sb_height):

        Sprite.__init__(self)
        self.screen = screen

        # Game attributes to track for scoring
        self.balloons_popped = 0

        # Set dimensions and properties of scoreboard
        self.sb_height, self.sb_width = sb_height, self.screen.get_width()
        self.rect = pygame.Rect(0,0, self.sb_width, self.sb_height)
        self.bg_color=(100,100,100)
        self.text_color = (225,225,225)
        self.font = pygame.font.SysFont('Arial', 18)

        # Set positions of individual scoring elements on the scoreboard
        self.x_popped_position, self.y_popped_position = 20.0, 10.0

    def prep_scores(self):
        self.popped_string = "Popped: " + str(self.balloons_popped)
        self.popped_image = self.font.render(self.popped_string, True, self.text_color)

    def blitme(self):
        # Turn individual scoring elements into images that can be drawn
        self.prep_scores()
        # Draw blank scoreboard
        self.screen.fill(self.bg_color, self.rect)
        # Draw individual scoring elements
        self.screen.blit(self.popped_image, (self.x_popped_position, self.y_popped_position))

There is nothing very significant here. We simply take the height in as a parameter when a scoreboard is initialized, and use it to define the height of our Rect object. Sword.py looks pretty similar:

import pygame
from pygame.sprite import Sprite

class Sword(Sprite):

    def __init__(self, screen, scoreboard_height):

        Sprite.__init__(self)
        self.screen = screen
        self.image = pygame.image.load('sword_75px.png').convert_alpha()
        self.image_w, self.image_h = self.image.get_size()

        self.x_position = self.screen.get_width()/2
        self.y_position = self.image_h/2 + scoreboard_height

        self.grabbed = False

        self.update_rect()

    def blitme(self):
        draw_pos = self.image.get_rect().move(self.x_position-self.image_w/2, self.y_position-self.image_h/2)
        self.screen.blit(self.image, draw_pos)

    def update_rect(self):
        self.rect = pygame.Rect(self.x_position-self.image_w/2, self.y_position-self.image_h/2,
                                self.image_w, self.image_h)

We take in the height on line 6 when the sword is initialized, and we use the scoreboard height to set the initial y-position of the sword. From then on, balloon_ninja.py takes care of setting the sword’s y-position. When you run the game now, you should see the sword sitting just below the scoreboard:

The sword now sits just beneath the scoreboard, as it should.

The sword now sits just beneath the scoreboard, as it should.

We need to make the balloon objects aware of the scoreboard, and then we can move on to using our scoreboard. Let’s make the balloons disappear once they have cleared the bottom of the scoreboard. This requires changing just one line in balloon_ninja.py:

import pygame, sys
from Balloon import Balloon
from Sword import Sword
from Scoreboard import Scoreboard

def run_game():
    # screen and game parameters
    screen_width, screen_height = 800, 600
    bg_color = 200, 200, 200
    scoreboard_height = 50

    # initialize game
    pygame.init()
    screen = pygame.display.set_mode( (screen_width, screen_height), 0, 32)
    clock = pygame.time.Clock()
    scoreboard = Scoreboard(screen, scoreboard_height)

    # Create a list to hold our balloons, and include our first balloon in the list
    balloons = [Balloon(screen)]

    # Create our dagger
    sword = Sword(screen, scoreboard_height)

    # main event loop
    while True:
        time_passed = clock.tick(50)
        mouse_x, mouse_y = pygame.mouse.get_pos()[0], pygame.mouse.get_pos()[1]

        # Check for game events
        check_events(sword, mouse_x, mouse_y)

        # redraw the screen, every pass through the event loop
        screen.fill(bg_color)

        # Update the sword's position, and draw the sword on the screen
        sword.x_position = mouse_x
        if sword.grabbed:
            sword.y_position = mouse_y
        else:
            sword.y_position = sword.image_h/2 + scoreboard_height
        sword.update_rect()
        sword.blitme()

        # Update our balloons, and draw them on the screen
        for balloon in balloons:
            balloon.update(time_passed)

            if balloon.rect.colliderect(sword.rect):
                balloons.remove(balloon)
                balloons.append(Balloon(screen))
                continue

            if balloon.y_position < -balloon.image_h/2 + scoreboard_height:
                balloons.remove(balloon)
                balloons.append(Balloon(screen))
                continue

            balloon.blitme()

        # Display scoreboard
        scoreboard.blitme()

        pygame.display.flip()

def check_events(sword, mouse_x, mouse_y):
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            sys.exit()
        if event.type == pygame.MOUSEBUTTONDOWN:
            if sword.rect.collidepoint(mouse_x, mouse_y):
                sword.grabbed = True
        if event.type == pygame.MOUSEBUTTONUP:
            sword.grabbed = False

run_game()

Showing some statistics

Now we can have some fun by displaying some statistics. Let’s use our scoreboard to actually display the number of balloons that have been popped. Again, since our code is pretty well organized, this is a simple change. Line 48 in balloon_ninja.py detects when the sword pops a balloon, so we add one line here to increment the number of balloons that have been popped. Since the scoreboard is refreshed after this check, this is all we have to do:

import pygame, sys
from Balloon import Balloon
from Sword import Sword
from Scoreboard import Scoreboard

def run_game():
    # screen and game parameters
    screen_width, screen_height = 800, 600
    bg_color = 200, 200, 200
    scoreboard_height = 50

    # initialize game
    pygame.init()
    screen = pygame.display.set_mode( (screen_width, screen_height), 0, 32)
    clock = pygame.time.Clock()
    scoreboard = Scoreboard(screen, scoreboard_height)

    # Create a list to hold our balloons, and include our first balloon in the list
    balloons = [Balloon(screen)]

    # Create our dagger
    sword = Sword(screen, scoreboard_height)

    # main event loop
    while True:
        time_passed = clock.tick(50)
        mouse_x, mouse_y = pygame.mouse.get_pos()[0], pygame.mouse.get_pos()[1]

        # Check for game events
        check_events(sword, mouse_x, mouse_y)

        # redraw the screen, every pass through the event loop
        screen.fill(bg_color)

        # Update the sword's position, and draw the sword on the screen
        sword.x_position = mouse_x
        if sword.grabbed:
            sword.y_position = mouse_y
        else:
            sword.y_position = sword.image_h/2 + scoreboard_height
        sword.update_rect()
        sword.blitme()

        # Update our balloons, and draw them on the screen
        for balloon in balloons:
            balloon.update(time_passed)

            if balloon.rect.colliderect(sword.rect):
                scoreboard.balloons_popped += 1
                balloons.remove(balloon)
                balloons.append(Balloon(screen))
                continue

            if balloon.y_position < -balloon.image_h/2 + scoreboard_height:
                balloons.remove(balloon)
                balloons.append(Balloon(screen))
                continue

            balloon.blitme()

        # Display scoreboard
        scoreboard.blitme()

        pygame.display.flip()

def check_events(sword, mouse_x, mouse_y):
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            sys.exit()
        if event.type == pygame.MOUSEBUTTONDOWN:
            if sword.rect.collidepoint(mouse_x, mouse_y):
                sword.grabbed = True
        if event.type == pygame.MOUSEBUTTONUP:
            sword.grabbed = False

run_game()

Now when you play the game, you should see the number of balloons you have popped reported accurately on the scoreboard:

The number of balloons popped is displayed on the scoreboard.

The number of balloons popped is displayed on the scoreboard.

With all of this work completed on our game, it becomes much easier to add whatever statistics we want to our scoreboard. Let’s track the number of balloons missed as well. To do this, we add a few things to Scoreboard.py:

import pygame, pygame.font
from pygame.sprite import Sprite

class Scoreboard(Sprite):

    def __init__(self, screen, sb_height):

        Sprite.__init__(self)
        self.screen = screen

        # Game attributes to track for scoring
        self.balloons_popped = 0
        self.balloons_missed = 0

        # Set dimensions and properties of scoreboard
        self.sb_height, self.sb_width = sb_height, self.screen.get_width()
        self.rect = pygame.Rect(0,0, self.sb_width, self.sb_height)
        self.bg_color=(100,100,100)
        self.text_color = (225,225,225)
        self.font = pygame.font.SysFont('Arial', 18)

        # Set positions of individual scoring elements on the scoreboard
        self.x_popped_position, self.y_popped_position = 20.0, 10.0
        self.x_missed_position, self.y_missed_position = 150.0, 10.0

    def prep_scores(self):
        self.popped_string = "Popped: " + str(self.balloons_popped)
        self.popped_image = self.font.render(self.popped_string, True, self.text_color)

        self.missed_string = "Missed: " + str(self.balloons_missed)
        self.missed_image = self.font.render(self.missed_string, True, self.text_color)

    def blitme(self):
        # Turn individual scoring elements into images that can be drawn
        self.prep_scores()
        # Draw blank scoreboard
        self.screen.fill(self.bg_color, self.rect)
        # Draw individual scoring elements
        self.screen.blit(self.popped_image, (self.x_popped_position, self.y_popped_position))
        self.screen.blit(self.missed_image, (self.x_missed_position, self.y_missed_position))

The thinking behind all of these changes is identical to what we did in order to display the number of balloons popped. It is worth noting that if we wanted to, we could have determined the width of the text string displaying the number of popped balloons. We could have used “self.font.size(self.popped_string)” after line 28 to determine how much space the popped balloons string takes up. I didn’t bother doing that here, but you might want to use the font.size function if you are building a more complicated scoreboard.

We also need to make a slight modification to balloon_ninja.py:

import pygame, sys
from Balloon import Balloon
from Sword import Sword
from Scoreboard import Scoreboard

def run_game():
    # screen and game parameters
    screen_width, screen_height = 800, 600
    bg_color = 200, 200, 200
    scoreboard_height = 50

    # initialize game
    pygame.init()
    screen = pygame.display.set_mode( (screen_width, screen_height), 0, 32)
    clock = pygame.time.Clock()
    scoreboard = Scoreboard(screen, scoreboard_height)

    # Create a list to hold our balloons, and include our first balloon in the list
    balloons = [Balloon(screen)]

    # Create our dagger
    sword = Sword(screen, scoreboard_height)

    # main event loop
    while True:
        time_passed = clock.tick(50)
        mouse_x, mouse_y = pygame.mouse.get_pos()[0], pygame.mouse.get_pos()[1]

        # Check for game events
        check_events(sword, mouse_x, mouse_y)

        # redraw the screen, every pass through the event loop
        screen.fill(bg_color)

        # Update the sword's position, and draw the sword on the screen
        sword.x_position = mouse_x
        if sword.grabbed:
            sword.y_position = mouse_y
        else:
            sword.y_position = sword.image_h/2 + scoreboard_height
        sword.update_rect()
        sword.blitme()

        # Update our balloons, and draw them on the screen
        for balloon in balloons:
            balloon.update(time_passed)

            if balloon.rect.colliderect(sword.rect):
                scoreboard.balloons_popped += 1
                balloons.remove(balloon)
                balloons.append(Balloon(screen))
                continue

            if balloon.y_position < -balloon.image_h/2 + scoreboard_height:
                scoreboard.balloons_missed += 1
                balloons.remove(balloon)
                balloons.append(Balloon(screen))
                continue

            balloon.blitme()

        # Display scoreboard
        scoreboard.blitme()

        pygame.display.flip()

def check_events(sword, mouse_x, mouse_y):
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            sys.exit()
        if event.type == pygame.MOUSEBUTTONDOWN:
            if sword.rect.collidepoint(mouse_x, mouse_y):
                sword.grabbed = True
        if event.type == pygame.MOUSEBUTTONUP:
            sword.grabbed = False

run_game()

The code for detecting balloons that disappear off the top of the screen begins on line 54. So we add a line right after that which increments the balloons_missed scoreboard property. If you run the program now, you will see the number of balloons popped and the number of balloons missed:

The scoreboard now reports the number of balloons that have been popped, and the number of balloons that have disappeared off the top of the screen.

The scoreboard now reports the number of balloons that have been popped, and the number of balloons that have disappeared off the top of the screen.

Let’s do one last thing with our scoreboard. Let’s add a score. For now, we will set a value of 10 points for every balloon that is popped. The changes to Scoreboard.py should look familiar:

import pygame, pygame.font
from pygame.sprite import Sprite

class Scoreboard(Sprite):

    def __init__(self, screen, sb_height):

        Sprite.__init__(self)
        self.screen = screen

        # Game attributes to track for scoring
        self.balloons_popped = 0
        self.balloons_missed = 0
        self.score = 0

        # Set dimensions and properties of scoreboard
        self.sb_height, self.sb_width = sb_height, self.screen.get_width()
        self.rect = pygame.Rect(0,0, self.sb_width, self.sb_height)
        self.bg_color=(100,100,100)
        self.text_color = (225,225,225)
        self.font = pygame.font.SysFont('Arial', 18)

        # Set positions of individual scoring elements on the scoreboard
        self.x_popped_position, self.y_popped_position = 20.0, 10.0
        self.x_missed_position, self.y_missed_position = 150.0, 10.0
        self.x_score_position, self.y_score_position = self.screen.get_width() - 200, 10.0

    def prep_scores(self):
        self.popped_string = "Popped: " + str(self.balloons_popped)
        self.popped_image = self.font.render(self.popped_string, True, self.text_color)

        self.missed_string = "Missed: " + str(self.balloons_missed)
        self.missed_image = self.font.render(self.missed_string, True, self.text_color)

        self.score_string = "Score: " + str(self.score)
        self.score_image = self.font.render(self.score_string, True, self.text_color)

    def blitme(self):
        # Turn individual scoring elements into images that can be drawn
        self.prep_scores()
        # Draw blank scoreboard
        self.screen.fill(self.bg_color, self.rect)
        # Draw individual scoring elements
        self.screen.blit(self.popped_image, (self.x_popped_position, self.y_popped_position))
        self.screen.blit(self.missed_image, (self.x_missed_position, self.y_missed_position))
        self.screen.blit(self.score_image, (self.x_score_position, self.y_score_position))

And the changes to balloon_ninja.py should be familiar as well:

import pygame, sys
from Balloon import Balloon
from Sword import Sword
from Scoreboard import Scoreboard

def run_game():
    # screen and game parameters
    screen_width, screen_height = 800, 600
    bg_color = 200, 200, 200
    scoreboard_height = 50

    # game play parameters
    points_per_balloon = 10

    # initialize game
    pygame.init()
    screen = pygame.display.set_mode( (screen_width, screen_height), 0, 32)
    clock = pygame.time.Clock()
    scoreboard = Scoreboard(screen, scoreboard_height)

    # Create a list to hold our balloons, and include our first balloon in the list
    balloons = [Balloon(screen)]

    # Create our dagger
    sword = Sword(screen, scoreboard_height)

    # main event loop
    while True:
        time_passed = clock.tick(50)
        mouse_x, mouse_y = pygame.mouse.get_pos()[0], pygame.mouse.get_pos()[1]

        # Check for game events
        check_events(sword, mouse_x, mouse_y)

        # redraw the screen, every pass through the event loop
        screen.fill(bg_color)

        # Update the sword's position, and draw the sword on the screen
        sword.x_position = mouse_x
        if sword.grabbed:
            sword.y_position = mouse_y
        else:
            sword.y_position = sword.image_h/2 + scoreboard_height
        sword.update_rect()
        sword.blitme()

        # Update our balloons, and draw them on the screen
        for balloon in balloons:
            balloon.update(time_passed)

            if balloon.rect.colliderect(sword.rect):
                scoreboard.balloons_popped += 1
                scoreboard.score += points_per_balloon
                balloons.remove(balloon)
                balloons.append(Balloon(screen))
                continue

            if balloon.y_position < -balloon.image_h/2 + scoreboard_height:
                scoreboard.balloons_missed += 1
                balloons.remove(balloon)
                balloons.append(Balloon(screen))
                continue

            balloon.blitme()

        # Display scoreboard
        scoreboard.blitme()

        pygame.display.flip()

def check_events(sword, mouse_x, mouse_y):
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            sys.exit()
        if event.type == pygame.MOUSEBUTTONDOWN:
            if sword.rect.collidepoint(mouse_x, mouse_y):
                sword.grabbed = True
        if event.type == pygame.MOUSEBUTTONUP:
            sword.grabbed = False

run_game()

We set up a space in our program for game parameters. We then add each balloon’s points to the overall score when the sword pops a balloon. Play the game, and you should see your score on the right side of the screen:

The scoreboard now keeps score.

The scoreboard now keeps score.

Now that we have a functioning scoreboard, we can create some logic to actually make the game interesting and challenging. We will start off by making the game get faster as you pop more balloons.

Next: Adding game logic

Back to Tutorial Contents

Advertisements

About ehmatthes

Teacher, hacker, new dad, outdoor guy
This entry was posted in programming and tagged , , , , . Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s