The last time I thought of what I want, I ended up working for what I need.

Originally posted here.

No, I’m not here to re-sell the career choosing drama. I’m here to talk about the situation that the statement suggests. Well this may be partly because I’ve nothing to do at the moment, partly because I (or perhaps we) seem to always encounter the same thing, and partly because I’m experiencing a severe bout of verbal diarrhea that I better put in here so I could be a little creative with it.

So when was the last time? I guess the last time, the serious one, was when I was on my way home after taking a series of exams and a short interview in a (forgive me) small time IT company. For someone like me who has his own share of being “choosy” it could have been easy to say that I’m never gonna go back to that company. I don’t like it there. The place was just not fit for any business concerning technology. It reminded me of this lousy office that I visit at least twice or thrice a year in the past four years where everybody talks more and works less in a room brimming with papers and bulky file jackets that I certainly do not want to work at.

A more pleasant office, that’s what I want. A place where you can breathe without worrying about taking in a lung-ful of dust. One that has a perfectly working air conditioning unit that has no pails under it to catch the dripping water. One that you will at least appreciate seeing after waking up early in the morning (your house being far from work) and traveling the distance trying for hours to get a good seat in loaded jeepneys and buses. One with decent looking workstations. One you cannot call perfect but at least okay.

But considering the country’s economy… whoops let’s not dig too deep into that.

But considering the current situation in the country where a lot of businesses, even in the IT industry which are supposed to be in good status right now with all the demands, struggle for stability, I guess it is understandable that providing the employees’ every desire is not that easy. After all, what I was talking about in the last paragraphs was just WHAT I WANT. Obviously, although you can suggest such things to your employer, they might find it quite selfish. Why? For a starting company like the case of that one where I took the exams, they will surely prioritize what they need. Legalities, clients, and good software developers. They would rather work for WHAT THEY NEED.

How about you?

That afternoon while I was on my way home I was thinking. I don’t like the place but as always said, beggars can’t be choosers. I needed a job to pay for everything I cost people when I was still studying so I gave the exams my best. My college fees barely reached a thousand in those four years of stay and people will surely call me lucky but come on, that’s not all you pay for when you try to earn a degree. Just the stress will cost you platefuls of a good meal. How much more is your daily fare, emergency expenses, personal things, clothes to keep you decent, and the other stuffs? Mahal!

Truth is, sometimes the things we want are too grand for us, for our current state. Sometimes we’re too in a hurry for the things we want and we don’t attend first to the things we need, when in fact it should be a step-by-step process. At home, when one of us thinks of something grand that they want, they will surely hear this from another saying it in a loose sense. You don’t have the right to dream of that. Not yet. And it is not suppose to discourage people of dreaming big. It’s suppose to keep people sane that there are still stuffs they got to deal with on their way there to that big dream, not to mention to make them laugh as well for the seemingly unfortunate situation. I know I sound like your father now, but hey this is reality at least for people living a barely average life.

How about that company I was talking about?

I assume we know that any starting company wishes they can offer something good to applicants they really want. Perhaps a good paycheck, plus a little more than the basic benefits, and a good work environment. But they need something to work on. They need clients and projects and equipments and certainly they cannot afford to lose everything to demanding applicants no matter how excellent those applicants may be. And I think that’s just the right way of viewing things. Unless your goals are too low, I guess it’s always a struggle to achieve them anyway.

Just a quick evaluation, how many of your long term goals are things you need? All? Long term goals sweety, I doubt it.

Reality check, how many small time companies NEED excellent professionals who do not WANT them?

This is not to condemn these professionals for turning down these companies. After all, they have every right for it. We just want to expose both sides of the story. It’s not always them offering you a small salary, but also them offering you a small salary for a good reason, and we always want to be reasonable.

That afternoon I prayed. I said I don’t want to work for that company but if they will offer me a job I guess I have no right to decline it. I’m jobless, I’m not a Suma Cum Laude, maarte lang ako. I asked for a sign. Since I knew I didn’t have the right to be choosy I asked God to choose for me. I said “Since I don’t feel I have the right to decline an offer, give me just one offer and let it be it, for I’m afraid that my judgement is clouded by the things I desire.”

Well I guess He listened and recognized my effort stressing myself thinking of stuffs like this. I didn’t get a call from the company, I didn’t have to bear that place. And I can say I got to learn a few things from it.

So for now, I’m keeping my “wants” achievable. I want a life-size cow paper mache in our living room and I don’t care if it will fit there. I want that one they call Holstein. I know the breed, I searched the net for it. Give one for this poor soul please. :)

Tagged , , , , ,

Flood-it! Game in Python 2.7 with Pygame

it has been quite a long while since i last posted a game tutorial. well i did not in any way intended this blog to be one, but the only project i’m dealing with right now has to be confidential so there’s no way it’s going out here in my blog. i’m also currently taking a short online course in game theory under Stanford and that’s what gets me occupied most of the time so it’s not ideal to discuss something rather complex as an actual IT project. so here i am with another game tutorial.

a couple of weeks ago (or maybe a month ago), i’ve encountered the game Flood-it! while checking out some games in Google Plus. i was idle then. i could have actually checked out some other games with better graphics, complex goals and all that, but i was at the office and thought i should not try those games that would catch too much attention from people who would probably pass by my work station. so i just chose Flood-it! and well it was okay to pass one’s time. the goal was very simple yet challenging, and Google Plus added a way for you and your friends to compete against each other. that was added coolness for those who are really competitive when it comes to games. the goal was simple, one has to fill/flood the 14×14 grid with only one color in 25 moves by selecting one of the six colors on the palette. you can check out an online sample here.

since i was idle and looking for something fun to do, i decided i would create a version of the game in python. the graphics needed was not very sophisticated and the logic was simple so i thought it was the perfect game to code while waiting for better tasks. now i know that sounds a little nerdy but i already said before that i’m learning python and it would be good to code using it in simple yet not ridiculous applications.

finally, let’s get to coding. i did not have time to refactor the codes so i have everything in a single file but i will try to discuss everything in detail.

we of course start with the essential initialization as shown below.

import pygame
import pygame._view
from pygame import *
import random

pygame.init()

DEFAULT_SCREEN_SIZE = [608, 448]
DEFAULT_TILE_SIZE = [32, 32]
DEFAULT_STEP_SIZE = 32
screen = pygame.display.set_mode(DEFAULT_SCREEN_SIZE)
display.set_caption('Flood-it!')

like the other tutorials, we start by importing pygame, and the random class library. we initialize the game by calling pygame.init() then we set the default values for the screen size, tile size, and the step size to use when iterating across the grid. finally we set the display mode and the caption to use in the window.

we then declare all variables the global variables needed in the game.

#declares all global variables
watchlist = None       #list of coordinates of all "flooded" tiles
checkedlist = None     #list of coordinates of tiles already updated
tiles = None           #list of coordinates of all tiles in the game
is_done = False        #tells whether game is done
update = False         #tells whether display must update
for_restart = False    #tells whether player opted to restart
movecount = None       #counts moves taken by the player
btncol = None          #list of control buttons

next, we create the essential functions. following are a few short ones.

#returns a color RGB values given a number from 1-6
def _getcolor(colornum):
    if colornum == 1:
        return [255, 105, 180] #hot pink
    elif colornum == 2:
        return [138, 43, 226] #blue violet
    elif colornum == 3:
        return [255, 255, 0] #yellow
    elif colornum == 4:
        return [255, 69, 0] #orange red
    elif colornum == 5:
        return [110, 139, 61] #dark olive green
    elif colornum == 6:
        return [0, 191, 255] #deep skyblue

#tells whether the two colors are the same
def _issamecolor(color1, color2):
    if color1[0] == color2[0] and color1[1] == color2[1] and color1[2] == color2[2]:
        return True
    return False

#adds a tile's coordinate to list of flooded tiles
def _addtowatchlist(coord, color):
    global tiles
    global watchlist
    adjcolor = tiles[str(coord[0])+"-"+str(coord[1])]
    if _issamecolor(color, adjcolor):
        _fill([coord[0], coord[1]], color)

#updates the color of the flooded tiles to the newly selected one
def _colorwatchlist(color):
    global checkedlist
    global watchlist
    for i in range(len(watchlist)):
        screen.blit(color, watchlist[i])
        checkedlist.remove(watchlist[i])
    pygame.display.update()

a built-in function for determining intersection of two lists exists but i took the long way of telling whether the two colors are the same because the built-in function got an issue with RGB values equal to 0.

next we create the function that will update the look of the grid after a user selects a color. the function basically checks if a tile must be flooded or not, adds it to the watch list if it must, then proceed to check adjacent tiles.

def _fill(coord, color):
    global checkedlist
    global tiles
    global watchlist

    #stops updates of already checked coordinates
    if checkedlist.__contains__(coord):
        return
    else:
        checkedlist.append(coord)
        #adds coordinate to watchlist if not existing
        if not watchlist.__contains__(coord):
            watchlist.append(coord)

    tile = pygame.Surface(DEFAULT_TILE_SIZE)
    tile.fill(color)
    screen.blit(tile, coord)
    if coord[0] - DEFAULT_STEP_SIZE >= 0:
        X = coord[0] - DEFAULT_STEP_SIZE
        Y = coord[1]
        _addtowatchlist([X, Y], color)

    if coord[0] + DEFAULT_STEP_SIZE < DEFAULT_SCREEN_SIZE[1]:         X = coord[0] + DEFAULT_STEP_SIZE         Y = coord[1]         _addtowatchlist([X, Y], color)     if coord[1] - DEFAULT_STEP_SIZE >= 0:
        X = coord[0]
        Y = coord[1] - DEFAULT_STEP_SIZE
        _addtowatchlist([X, Y], color)

    if coord[1] + DEFAULT_STEP_SIZE < DEFAULT_SCREEN_SIZE[1]:
        X = coord[0]
        Y = coord[1] + DEFAULT_STEP_SIZE
        _addtowatchlist([X, Y], color)

we then create the function that will render the game’s controls which are the six color buttons. the function basically draws the buttons on the screen and stores their location for later reference.

def _render_controls():
    #button initialization
    global btncol
    btncol = [dict(), dict(), dict(), dict(), dict(), dict()]

    #button color initialization
    btncol[0]['color'] = _getcolor(1)
    btncol[1]['color'] = _getcolor(2)
    btncol[2]['color'] = _getcolor(3)
    btncol[3]['color'] = _getcolor(4)
    btncol[4]['color'] = _getcolor(5)
    btncol[5]['color'] = _getcolor(6)

    #button position initialization
    btncol[0]['position'] = [512, 21]
    btncol[1]['position'] = [512, 95]
    btncol[2]['position'] = [512, 169]
    btncol[3]['position'] = [512, 243]
    btncol[4]['position'] = [512, 317]
    btncol[5]['position'] = [512, 391]

    #button bounds initialization
    btncol[0]['bounds'] = pygame.Rect(512, 21, 32, 32)
    btncol[1]['bounds'] = pygame.Rect(512, 95, 32, 32)
    btncol[2]['bounds'] = pygame.Rect(512, 169, 32, 32)
    btncol[3]['bounds'] = pygame.Rect(512, 243, 32, 32)
    btncol[4]['bounds'] = pygame.Rect(512, 317, 32, 32)
    btncol[5]['bounds'] = pygame.Rect(512, 391, 32, 32)

    for i in range(len(btncol)):
        pygame.draw.circle(screen, btncol[i]['color'] \
            , [btncol[i]['position'][0]+16, btncol[i]['position'][1]+16] \
            , 16)

    pygame.display.update()

the following functions are not really necessary but i wanted to add a little something to the game, rage faces! yes i’m at times pretty shallow that i enjoy rage faces. because of that, i created a function that will display a random rage face if a user wins or loses.

def _gameover():
    shade = pygame.Surface(DEFAULT_SCREEN_SIZE)
    shade.fill([0, 0, 0])
    shade.set_alpha(200)
    screen.blit(shade, [0, 0])

    imggameover = pygame.image.load('gameover.png')
    tilenum = random.randint(1, 4)
    rectangle = None
    if tilenum == 1:
        rectangle = pygame.Rect(0, 0, 320, 240)
    elif tilenum == 2:
        rectangle = pygame.Rect(320, 0, 320, 240)
    elif tilenum == 3:
        rectangle = pygame.Rect(0, 240, 320, 240)
    elif tilenum == 4:
        rectangle = pygame.Rect(320, 240, 320, 240)

    screen.blit(imggameover, [64, 104], rectangle)

    pygame.display.update()

def _success():
    shade = pygame.Surface(DEFAULT_SCREEN_SIZE)
    shade.fill([0, 0, 0])
    shade.set_alpha(200)
    screen.blit(shade, [0, 0])

    imgwin = pygame.image.load('win.png')
    tilenum = random.randint(1, 4)
    rectangle = None
    if tilenum == 1:
        rectangle = pygame.Rect(0, 0, 320, 240)
    elif tilenum == 2:
        rectangle = pygame.Rect(320, 0, 320, 240)
    elif tilenum == 3:
        rectangle = pygame.Rect(0, 240, 320, 240)
    elif tilenum == 4:
        rectangle = pygame.Rect(320, 240, 320, 240)

    screen.blit(imgwin, [64, 104], rectangle)

    pygame.display.update()

lastly, for the set of functions, we have the _init function that is supposed to start the game. it starts with initializing global variables then it proceeds to fill the grid with randomly colored tiles before. it then assigns the starting tile, then renders the controls.

def _init():
    global checkedlist
    global watchlist
    global tiles
    global movecount
    global for_restart
    checkedlist  = list()
    watchlist = list()
    tiles = dict()
    movecount = 0
    for_restart = False

    screen.fill(0) #color screen black

    #fills the grid with randomly colored tiles
    for i in range(14):
        for j in range(14):
            #sets coordinates
            X = DEFAULT_STEP_SIZE*i
            Y = DEFAULT_STEP_SIZE*j

            #gets random tile
            colornum = random.randint(1, 6)
            tile = pygame.Surface(DEFAULT_TILE_SIZE)
            color = _getcolor(colornum)
            tile.fill(color)
            tiles[str(X)+"-"+str(Y)] = color
            screen.blit(tile, [X, Y])

    #adds starting tile to watch list
    _fill([0, 0], tiles['0-0'])

    #initializes first time coloring of watch list
    tile = pygame.Surface(DEFAULT_TILE_SIZE)
    tile.fill(tiles['0-0'])
    _colorwatchlist(tile)

    #renders the controls
    _render_controls()

finally, the _init function has to be called before the game begins. then program will enter the loop that contains the logic of the game as shown below.

_init()

while is_done == False:
    global is_done
    global update
    global movecount
    global for_restart
    global btncol

    #checks for changes in direction and validates it
    for e in event.get():
        color = None

        if e.type == MOUSEBUTTONDOWN:
            for i in range(len(btncol)):
                if btncol[i]['bounds'].collidepoint(e.pos):
                    color = _getcolor(i+1)
        elif e.type == QUIT:
            is_done = True
        elif e.type == KEYUP:
            update = True
            if e.key == K_ESCAPE:
                is_done = True
            elif e.key == K_r:
                _init()
            elif e.key == K_a:
                color = _getcolor(1)
            elif e.key == K_s:
                color = _getcolor(2)
            elif e.key == K_d:
                color = _getcolor(3)
            elif e.key == K_z:
                color = _getcolor(4)
            elif e.key == K_x:
                color = _getcolor(5)
            elif e.key == K_c:
                color = _getcolor(6)

        if color != None and movecount < 25:
            if not for_restart:
                movecount += 1
                tile = pygame.Surface(DEFAULT_TILE_SIZE)
                tile.fill(color)
                for i in range(len(watchlist)):
                    _fill(watchlist[i], color)
                _colorwatchlist(tile)
                display.set_caption('Flood-it! '+str(movecount)+'/25')

        if len(watchlist) == 196:
            if not for_restart:
                _success()
                for_restart = True
            display.set_caption('Flood-it! Congratulations. You won!')

        if movecount == 25 and len(watchlist) != 196:
            if not for_restart:
                _gameover()
                for_restart = True
            display.set_caption('Flood-it! GAME OVER!')

    if update == True:
        #TODO: call update function
        update = False

first, the program will go through the events that might have occurred. a valid event could be a mouse-click on a button or pressing of any of the dedicated keys to any color. the program will then attempt to update the grid then see if user has reached the move limit or the goal of flooding the whole grid was already achieved.

whew, that was quite long. i hope you will get to enjoy this game and add your own enhancements (better tiles perhaps). you can download the codes and the images here. again, make sure you have python 2.7 and the compatible pygame library. until next time! (:

Tagged , , , , , ,

when a program throws an exception, the problem is not always in the code

it has been quite awhile since i last posted something. well although i could say that a number of things came up, i cannot say that they ate most of my time so as to prevent me from posting anything. truth is i could have posted a few lines but held myself back at the last moment for behind all the wordplay there was really nothing much to glean from them. well i’m no writer really but i’m writing here and i believe that if you want to be a good one, take it as a responsibility to feed your readers something sensible. surely there could be some sense in everybody’s life.

anyway, just last week i began testing this web service i created for our client. it was supposed to be utilized by the online banking system for the activation of various requests. this web service should run in the frontend and should call another web service from the backend (the mainframe specifically) for backend side request processing. during the development i had to work with stubs because i was working in our office. one can argue that i should’ve done it in the client’s development environment if permitted but i actually prefer working with stubs until i got most of the requirements done since the solution is easier to test that way.

so the time for testing the code came and i had to deploy the web service in our client’s development environment. it was pretty easy since i basically only had to change connection strings and a few more values in the web configuration file. i was informed that it was okay to input any value for the parameters of the web service method since there was no validation at the moment but when i did BAM! i received the error “Conversion from SOAP failed” when my code tried to invoke the exposed method of the mainframe web service and the mainframe’s transaction counter did not increment. i was cool at first thinking that surely i just got a line or two wrong. but when i found out that the exception was thrown by .Net’s wsdl.exe generated proxy when it called invoke, my expression was like “what the hell happened? what’s wrong?” i’ve used it before and i knew that the generated proxy is supposed to work with very little or no modification. still i tried to think of things that could’ve caused it like maybe i used the wrong wsdl file or i could not connect to the backend web service, etc. i tried applying the fixes i could think of but to no avail.

when i got back to the office, i was like “okay we’re unsuccessful but surely a lot of people could be encountering the same problem. if i could solve this, it will be something good to blog about” so i spent the remaining office hours researching on ways to connect to a mainframe web service and the common problems but surprisingly none of the google hits helped or even enlightened me. i thought i was doomed. i thought the best source would be the ones who previously worked with the web service but they are all not connected to our client now. another testing day passed and the problem remained unsolved until just last monday i tried inputting nothing in the parameters and the mainframe web service returned a different error code that was more expected. it was talking of invalid inputs. that gave me the idea that my problem was just a matter of giving the right inputs from the very beginning since there was very minimal modification done to my code. i went to the person in charge with the mainframe side of the project and asked for sample inputs and everything worked fine. well we’re not done yet testing the web service until the end of the defined transaction flow but it put end to the problem with the mainframe side of requests.

now this post was supposed to offer some sort of fix in a form of codes or instructions like i mentioned earlier. but since the problem was somewhere between the keyboard and the chair let me just leave an advice.

do not overanalyze.

we got as far as thinking of capturing packets exchanged between servers to check for discrepancies. it was a good thing that we had to postpone it because of the absence of the needed tools in the service. it would have been another failed fix in the list.

take time to consider all possible sources of the problem no matter how little or ridiculous they are.

in my case i completely ignored the possibility that the problem was caused by the wrong inputs. hadn’t i thought of giving the web service blank inputs, i wouldn’t have found out the answer to my problem.

lastly, use valid inputs whenever possible.

seriously, there’s no harm trying the right inputs especially when someone who knows them is just around.

hope you learned something from my experience. have a nice day!

Tagged , , , , , , , , ,

On Being a Poor Host

i love get-togethers. i love seeing my friends after long uneventful months at work. i have quite a small circle of friends and i don’t get to go out a lot, that’s probably one of the greatest reasons why. i want to stay in touch and know what’s happening in their lives. not that i need to know or they need me to be there for them but i just want to know what’s up with them. because of that, i always try to push dinners and day-outs be it my treat or other people’s. you could assume that i’d be “in” to whatever event there is that could get us to meet each other. i’m just like that. but i got a problem about being the pushy one. people will naturally expect me to have a good plan for the event and i always haven’t any.

i’m a poor host. i myself have no doubt about it. my friends are kind enough not to let out any remark about me trying to push get-togethers but having nothing in mind for us to do. but just the look on their faces tells me they are bored. whenever i see that look i always get to questioning myself what has gone to my head again.

i’m like a child when it comes to events and surprises. i’m very easy to please. quite embarrassing to admit, the phrase “it’s the thought that counts” must be so deeply ingrained in me that i live by it. my friends don’t really need to try to come up with something extraordinary to make me enjoy being with them. they could simply come over and laugh with me about random stuffs and that could be it. that is probably because it takes time for me to really consider someone a close friend and being my close friend means i’m totally comfortable having you around that you don’t have to do anything fancy or impressive.

the problem lies with having things the other way around. people aren’t the same even when they are friends. what’s pleasing to me may not be as much as pleasing to others. that makes me a poor host. i could settle with just about anything and i couldn’t get it out of my head that they could enjoy things just like i do but it doesn’t always work that way.

last time we had an all-nighter almost like for nothing. one of my friends adel, invited us out for dinner and we knew we couldn’t make it early enough for a good chat, ‘cause most of us would have to travel quite far to get to the place. there were eight of us in the dinner. i was one of the three people who got to the place too late for the buffet that we only had iced teas. that was pretty expected because it was almost ten in the evening. i, adel, and my girlfriend eunice planned the all-nighter before just so the opportunity of having everybody gathered won’t be wasted. the other five were hesitant. they all got other plans for the following day and we understood although we really want them to join us. one more decided to join us even though she had no clothes with her to change to and we thought that would be it. there would be four of us for the night and two more pulling the graveyard shift in ortigas will be joining three o’clock the next morning.

it was a pleasant surprise when the three people we just said goodbye to before we waited for our ride showed up again and said they decided to join us. i was already anxious then of what to do by the time we get to the house where we will be having the all-nighter. when they showed up, i knew things will be okay. like the overused phrase, the more the merrier.

not so much sensible talk happened that night but there definitely was a lot of laughing going on because of this movie title which meaning was changing as we were rearranging the words. they also decided to watch 28 days later on a laptop’s small screen but were too sleepy to finish the film.

the following morning three of us had to go early and i felt a little anxious once again if they enjoyed the night. not satisfied with my brain’s answer i decided to treat what’s left of us to the movies. we watched the devil inside. it was not shocking at all for me because of my high tolerance to thriller films having watched a lot of violent horror/thriller/slasher films at my early teens. but i guess they enjoyed it. that was what mattered most. on the way home my girlfriend asked me why i suddenly decided to treat them to the movies. i said i was supposed to treat everybody anyway because that was part of the original plan. but to be a little more honest, i’m practicing to be a better host i guess.

Took this when I got home around 8pm. I was alone in the house.

Tagged , , ,

Everything’s a Surprise

I remember back in high school, I must have had taken everybody by surprise whenever they would ask me about my plans for college because the truth was, I had none. While all my classmates and friends were getting agitated about their applications in various colleges and universities I could not even think of one that I want to enter for a college education. It wouldn’t have mattered that much if I was just an ordinary student who didn’t really have much in his head to earn himself a degree but no. I was on top of my class back then and naturally everybody was expecting me to have a good plan for my future. I remember when a friend asked me if I will be taking the UPCAT and I told him I didn’t know, that I wasn’t sure. He seemed really puzzled by that reply and I was like “what’s wrong with that?” as if it was really natural for an honor student to not want to enter the country’s premier university.

To tell the truth, I knew nothing then about the importance of getting into a known university whether for the quality of education or even just the bragging rights you would have. I knew University of the Philippines but I couldn’t remember desiring to enter it until I got a copy of their application form. As of courses I couldn’t also give a good reply to people asking what I would take. Almost all the boys in class were planning to study a field of engineering, some of my other classmates were planning to take accountancy, and the rest were considering nursing for its high demand back then in US and Canada. I would tell them I might take up engineering as well but the truth was I hadn’t even got a good reason to take the course other than the fact that I was quite good at math. For my ignorant mind good mathematical skills already meant survival on the course and to survive was all. Survival meant acquiring the capability to close another chapter of your life totally irrelevant to the next one which is adulthood.

I was oddly foolish then for an honor student. But to redeem myself a little, I think I could say that was because I never even wanted to be on top of the class anyway. The truth was I didn’t believe anybody could count me as grade conscious. Being someone who didn’t even know what to do with his life after high school, what should I be conscious of my grade for? I think the only thing that drove me to study hard back then was the desire to please my parents and make them happy. That is because it wasn’t really always easy to be an honor student. People will expect a lot from you, you got to be active, you got to watch your grades, and most of all you got to study more than what was enough to pass an exam. And we know that the latter will always get in the way of all your other plans whether it’s camping or as simple as watching a good TV show.

If there was one course I would’ve wanted to take, that would be creative writing. I believe I’m in constant need of expression and writing would be one good outlet. However, we were poor and I knew I couldn’t make my parents happy being jobless ‘cause it’s very difficult to be a successful writer in the Philippines nowadays. I would tell my high school Filipino teacher how I wanted to become a screenwriter but to my classmates I always said it would be engineering for me. As early as sixteen I somehow knew I couldn’t be selfish. I had to be practical for my family because we’re broke and broke people can’t be choosers. That was so right in our case.

Right now I would agree that my attitude towards getting a degree back then was pretty strange but I think my family really had something to do with it. Both my parents were just high school graduates so there was never a deep and sensible conversation about college and future career. Our dreams could just be summed up in a simple phrase, “to get by with a good life”. There was never a talk on how to get that. All we know is that if we work hard we would get there one way or another. Somehow in our heads I think, we were thinking that an excellent background was not necessary because just a good one will do. That was how simple we are, we were not a family of high achievers anyway. For us when you got a good paying job, you were already good.

I would say it would have also been that way for me but I guess I’m just different, or maybe my life’s really a big joke, or maybe God has something good in store for me. You see I was born in a family that totally has no idea of what it is to be “big”. All my life there has never been anybody to tell me that I got potential for this or that. Whatever it is in me right now were all brought by circumstances I never saw coming. I’m no movie star, or successful businessman, or super genius. The truth is I still struggle paying certain bills every month. But I guess everybody who has known me since childhood would agree that I, in my way, have come so far from what they truthfully expected of me. What would you expect from a boy who had no definite plans for his career right?

Of all the applicants to UP in our high school batch, only two of us passed. I was the one who had a lousy book for a reviewer and I was the only one to make it to UP Manila which required a higher UPG (University Predicted Grade). I graduated salutatorian which made me, my family, and my friends more than happy and earned the bragging right that I got it without really trying hard. I’m pretty lazy when it came to school projects that took days to finish just so you know and my classmates didn’t really find me serious when it came to studying. I find it difficult to stay in focus for long. I always got a lot of things in mind. I qualified for DOST scholarship which reduced all my schooling fees to P62.50 per semester and finished BS Computer Science as regular student with a good average (GWA) according to UP standards. But actually with all the problems and struggles outside education that I dealt with during college I could call it excellent. My college life story is a tear-jerker, believe me. I believe you could only call my GWA good if it was achieved by someone who got nothing else serious to really deal with but his studies.

I am now a software engineer. Just weeks ago something unexpected happened again which made me the lead of my current project. I promised God not to ask Him why for the things that were happening in my life but sometimes I really do wonder why He seems to favor me above some people. Yes my achievements were absolutely not really big but there are a lot of people doing what they can to have it while I was sitting here with totally nothing in mind that had to do with it.

I still struggle budgeting and paying for bills. I still want to buy some things for myself but I could say that things are better now. I’m pretty odd to be happy with the seemingly senseless things anyway. I could say that I have lived a good twenty two years of my life. I have learned a lot enough to make me feel old sometimes. That is because seriously there are people who live up to their forties who don’t even know how not to be selfish right?

Now that things are considerably well I sometimes feel anxious for no reason. Maybe it was because I was at all times anxious in the past years. Or maybe I want every second to matter like how it did before. I don’t know. As of now maybe I’ll just wait for the next surprise.

Tagged , , , , , ,

some random musings (part 2)

what now? currently my task at work is to populate the database with flood maps of places all over the country. for those who are into programming, the task involves parsing a KML file, creating objects from it, then saving it to the database. i already got a script for it, the only thing is, i can only upload one flood map file at a time to the server. yeah, i know, i can do multiple uploads. but considering that the machine takes at least 5 minutes to store all coordinates of one file to the database. multiple uploading no longer appear appealing to me. it will most certainly cripple the machine. so i’m doing it one by one. which in turn gives me ample time to write something and update this pretty neglected blog.

so what’s for today. i figured i better not write something that involves a lot of thinking since i will need to keep focus on my work so i chose to continue sharing my random musings. as i’ve said before, i keep a record of random musings. i write it in a little journal that i never fail to carry in my bag. here’s another set of them and some short elaborations.

April 6, 2011
if you talk shit about other people when they’re not around, how can i trust you not to do the same with me?

this one’s pretty straightforward. this is maybe one of those questions that people tend to ask others the most even just in their heads. no, i won’t say that i’ve never talk bad of others behind their back before, but i think i can say that i’m always ready to utter the same words in front of them if i have to. that’s how i live my life. you may not call me kind or a good person but i know how to be responsible with whatever i do. but don’t get it wrong, even though it’s like that for me i of course still know how and when to be careful with what i say. it pays to always think things over before saying it.

April 8, 2011
sometimes we feel extraordinarily clever that we fail to see that by natural standards, we are actually acting foolish. oh what an irony.

i remember writing this after a moment of reflection and finding out that i often over-analyze things which ironically leads me far from the right thing. unfortunately it is not very easy to tell from one’s point of view when they are just giving things a good analysis and when they are over-analyzing and confusing themselves further. it would be good to have someone who can tell you to stop once in a while.

the following entry is a mix of English and Filipino because i talk a lot that way. but i’m offering a rough translation for those who cannot understand Filipino but would like to know it.

April 13, 2011
one of my best rules in life: to survive victoriously hindi mo kailangang mang-iwan. for once, h’wag nateng i-base ang achievements naten sa narating ng iba. it is way greater to know even just by yourself, na hindi ka basta basta mapag-iiwanan. self-respect above all praises.

[Translation]
one of my best rules in life: to survive victoriously you don’t need to leave others behind. for once, let us not base our achievements from what others have reached. it is way greater to know even just by ourselves, that we’re not someone who can be easily left behind. self-respect above all praises.

i remember writing this down when i encountered another person who simply won’t settle for a position because someone else occupies a higher one and they want to be just like that. i think it’s perfectly fine to desire something. but what’s disagreeable about it is when one does it out of envy. i strongly believe that self-respect should be above all praises and titles. what’s being able to snatch a place when one has to lose self-respect for it? when i do good that’s because i’m simply good or enjoying things. it is certainly not because i want to be better than someone. i prefer it that way. it keeps my conscience clean.

April 30, 2011
in every relationship, together with knowing that there is something wrong is knowing that there’s something that needs to be fixed. and knowing that there’s a problem that must be solved and working on it is way better than pretending that everything is doing well.

i posted it on a radio station’s Facebook page for it to be read to listeners. the DJ was asking for random lessons and i figured i should share it since a lot of listeners talk about love. by now you must have had the idea that the truth matters to me a lot no matter how painful or horrible it may be. that’s right, i’m like that. i just believe that the more we hide a problem, the more we make it complicated. the more we ignore it, the more it becomes painful to bear when the time comes that we had no other choice but to face it.

in life, i always try to keep things simple. like most of us, if not all, i don’t want to have a lot of “what-ifs” in life. so whenever i got the chance to think ahead and avoid complications, i make sure that i use it well. there are certain situations in life that once we’re in it will no longer be easy to think clearly. so if we got the chance to think things over at the beginning or while it is early, i think we better grab it. we may shed a tear or two but we just know it will be better that way.

May 3, 2011
it pays great to know humility. that’s why it’s one of the most difficult things to learn and re-learn.

i wrote this after observing my own attitude towards people especially those who are younger and inexperienced compared to me at work. they may have not noticed it but being very self-critical i knew there was a trace of arrogance on my actions and i didn’t like it. there are always things to learn from other people and one could miss it if he will only pay attention to himself. this not to mention how difficult it is to swallow one’s pride once he was proven wrong by someone he considers inferior. setting aside the things one knows definitely clears his mind and makes him more open and agreeable to others. sadly, this realization added to my paranoia but i guess i’m dealing with it well lately haha.

i may be right or wrong about these things but either way i think people could always get something from somebody’s musings. for now let me just wish you well.

Tagged , , , , , , , ,

rendering background image using PyGame in Python 2.7

it has been quite a while since i last posted anything regarding my endeavors in game programming. the past weeks have been quite busy for i was working on the backend of another mobile application. anyway, i was able to continue studying python this weekend and inspired by Final Fantasy III which I’ve been playing using an emulator lately, I decided working on rendering more visually pleasing backgrounds. yes, you read that right, Final Fantasy III. why am i playing such an old game? i’m quite into light weight games. and i figured it would be better to start with 2D games.

this is a short tutorial on rendering backgrounds using a single image source. here’s a sample of the perfectly symmetric background i was able to produce.

Background Demo

the sample background of a 2D game

the codes are available HERE.

the source image

since i’m only working on a demo, i simply copied the source image from a game installed in my computer. that game is Deadly Sin. if we are going to create more maps just for practice, we can find good resource from the games already installed in our machines like this one.

Tile Set

the tile set from Deadly Sin

it is a 512px X 480px image composed of different tiles used in the game to create the various stages and maps.

the map

i decided to put all details of a particular place in one file and call it map. this way i can produce as many different maps as i want completely independent of the game.

import pygame
from pygame import *

# fills a 16 X 14 map with rectangles representing tiles to be rendered from the
# source images to the game display

#assigns source image
SOURCE = pygame.image.load('images/TileA4.png')

p = pygame.Rect(288, 0, 32, 32) #area of source image containing pavement
g = pygame.Rect(416, 0, 32, 32) #area of source image containing grass
s = pygame.Rect(288, 160, 32, 32) #area of source image containing sand/dirt
b = pygame.Rect(288, 320, 32, 32) #area of source image containing bush

#matrix containing the pattern of tiles to be rendered
MAP = [[p,p,p,p,p,p,p,p,p,p,p,p,p,p,p,p],\
       [p,b,b,b,b,b,p,p,p,p,b,b,b,b,b,p],\
       [p,b,b,g,g,g,g,p,p,g,g,g,g,b,b,p],\
       [p,b,g,g,g,g,g,p,p,g,g,g,g,g,b,p],\
       [p,b,g,g,g,p,p,p,p,p,p,g,g,g,b,p],\
       [p,b,g,s,g,p,s,s,s,s,p,g,s,g,b,p],\
       [s,s,s,s,s,s,s,g,g,s,s,s,s,s,s,s],\
       [s,s,s,s,s,s,s,g,g,s,s,s,s,s,s,s],\
       [p,b,g,s,g,p,s,s,s,s,p,g,s,g,b,p],\
       [p,b,g,g,g,p,p,p,p,p,p,g,g,g,b,p],\
       [p,b,g,g,g,g,g,p,p,g,g,g,g,g,b,p],\
       [p,b,b,g,g,g,g,p,p,g,g,g,g,b,b,p],\
       [p,b,b,b,b,b,p,p,p,p,b,b,b,b,b,p],\
       [p,p,p,p,p,p,p,p,p,p,p,p,p,p,p,p]]

as shown, we first loaded the image that will be used by the map and set it as its SOURCE. next we defined the areas from the source image that we would like to be rendered on our game screen as tiles p, g, s, and b. lastly, we created a 16 X 14 matrix that will contain the tiles we created. there could have been a better way of creating the matrix that is less space complex, but i intended it to be that way so we can directly compare the matrix with the pattern we have in mind just by looking at it.

the game

unlike the previous tutorials, this game file will not make use of any user input.

import pygame
from pygame import *
import map1

DEFAULT_SCREENSIZE = [512, 448] #16 X 14 grid with 32px X 32px cell

pygame.init()

screen = pygame.display.set_mode(DEFAULT_SCREENSIZE)
display.set_caption('Background Rendering Demo')

#loops through map to set background
for y in range(len(map1.MAP)):
    for x in range(len(map1.MAP[y])):
        location = (x*32, y*32)
        screen.blit(map1.SOURCE, location, map1.MAP[y][x])

updated = False
going = True

while going:
    if updated == False:
        pygame.display.update()
        updated = True

    for e in event.get():
        if e.type == QUIT: #checks if close button was clicked
            going = False

pygame.quit()

to discuss it in detail, first we import the modules we need including the map we created named map1.py.

import pygame
from pygame import *
import map1

next, we initialize our screen and display.

DEFAULT_SCREENSIZE = [512, 448] #16 X 14 grid with 32px X 32px cell

pygame.init()

screen = pygame.display.set_mode(DEFAULT_SCREENSIZE)
display.set_caption('Background Rendering Demo')

then we go to the most essential part of this tutorial where we need to loop through our map and assign the tiles to our screen.

#loops through map to set background
for y in range(len(map1.MAP)):
    for x in range(len(map1.MAP[y])):
        location = (x*32, y*32)
        screen.blit(map1.SOURCE, location, map1.MAP[y][x])

lastly, we perform the loop that will keep the game running. note that checking if the display was updated was only done to reduce overhead.

updated = False
going = True

while going:
    if updated == False:
        pygame.display.update()
        updated = True

    for e in event.get():
        if e.type == QUIT: #checks if close button was clicked
            going = False

pygame.quit()

that’s it for this week. hope you find this useful folks!

Tagged , , , , ,

Metro Manila Flood App (MMFA)

screenshot 1 a good news came today. after months of training, the team finally got to upload its first app in the app store. i was not part of its development but i’m breaking the news just the same because i’m proud of our three people working on iOS, namely Elbert Yagaya, Lei Montas, and Pope Abella.

the team has been around for more than a year now but there weren’t much activities in the past so i can say we are pretty much still starting. and this is a good start so far. it only took an hour or so before the app got approved. well maybe that was because it’s not very complex. but it’s doubtlessly useful.

you can get the app for free at iTunes. basically it’s an app that can monitor flood prone areas around Metro Manila and send real time notifications to its users regarding the current flood situation.

screenshot 2 screenshot 3
Tagged , , , , ,

Simple Sprite Animation in Python 2.7

a picture of the simple animation

a picture of the simple animation

the codes for this simple animation can be downloaded here.

last time i posted my sample of the snake game written in Python 2.7 using PyGame. like what i already said it was supposed to be a part of my self training on python game programming and it went pretty well. i have one comment though, i was trying to accomplish a lot in one sample project. so i decided that from this week on i’ll take it one step at a time by creating tiny projects that i could use as a template when i finally have something big to code. well not really big for i’m only programming games for leisure, the more approriate term would be complex, something more complex to code. and so for my first tiny project i’m going to have simple sprite animation.

anyway, since i’m a lover OOP i decided i’ll try creating a collection of modules that will function as a class library or, if lucky, a personal framework for creating my type of python games. my plan is to build this collection in the weeks to come. so let us begin.

THE UTILITIES LIBRARY

this library will contain classes that could be useful to most if not all other classes. classes that are not part of the game design but useful in carrying out particular tasks common to most other classes. i named the file ‘lib_utils.py’ the prefix ‘lib_’ is supposed to tell which of my python files function as libraries and which are not. it currently contains only one class which is the StaticFunction class that i use for creating static methods on my classes.

#used for creating static functions
class StaticFunction():
    def __init__(self, function):
        self.__call__ = function

THE SPRITES BASE LIBRARY

the sprites base library which i named ‘lib_spritesbase.py’ will contain classes that are essential to sprite animation. currently it contains classes such as Direction, ImageSet, and SimpleSprite

Direction class

#class enumerating valid directions
class Direction():
    UP, DOWN, RIGHT, LEFT, UPRIGHT, UPLEFT, DOWNRIGHT, DOWNLEFT = \
        'Y+', 'Y-', 'X+', 'X-', 'X+Y+', 'X-Y+', 'X+Y-', 'X-Y-'

    #checks if a given direction is valid
    def is_direction(direction):

        #compares direction to provided direction values
        if direction == Direction.UP:
            return True
        elif direction == Direction.DOWN:
            return True
        elif direction == Direction.RIGHT:
            return True
        elif direction == Direction.LEFT:
            return True
        elif direction == Direction.UPRIGHT:
            return True
        elif direction == Direction.UPLEFT:
            return True
        elif direction == Direction.DOWNRIGHT:
            return True
        elif direction == Direction.DOWNLEFT:
            return True

        #no match was found
        return False

    #makes the function 'is_direction' static to Direction class
    is_direction = StaticFunction(is_direction)

if you checked out my last post, this class and the SnakeMove class mentioned there are basically the same. the only thing i did was to give it a name that is not tied into any game and add other possible directions of movement in a game like the up right, up left, down right, and down left.

ImageSet class

#stores a collection of images to be used by a sprite
class ImageSet():
    def __init__(self, img_up=None, img_down=None, img_right=None \
                , img_left=None , img_upright=None, img_upleft=None \
                , img_dowright=None, img_downleft=None):

        #direction was used as key assuring that one direction corresponds to
        #one image
        self.images = {Direction.UP:img_up, Direction.DOWN:img_down \
            , Direction.RIGHT:img_right, Direction.LEFT:img_left \
            , Direction.UPRIGHT:img_upright, Direction.UPLEFT:img_upleft \
            , Direction.DOWNRIGHT:img_dowright, Direction.DOWNLEFT:img_downleft}

    #gets the image for a given direction
    def get_image(self, direction=None):
        #parameter validation
        if direction == None:
            raise Exception('Direction cannot be null.')
        if Direction.is_direction(direction) != True:
            raise Exception('Invalid direction.')

        return self.images[direction]

it’s not that i perfectly adhere to coding standards but we know how difficult it is whenever we don’t know the right parameters to a particular function provided in a third party class library, especially when working with weakly typed languages like python. because of this i always try to come up with a form of enumeration of valid values and provide some sort of validation no matter how shallow they maybe sometimes.

the ImageSet will be used as a container of all images that a simple sprite will use. since there could be a lot of ways to pass the filenames of images to a sprite class i made it a point that the my sprite classes will only accept an instance of ImageSet.

SimpleSprite class

class SimpleSprite(pygame.sprite.Sprite):
    def __init__(self, direction=None, position=None, images=None):

        #parameter validation
        if None in [direction, position, images]:
            raise Exception('None of the parameters could be equal to "None"')
        if Direction.is_direction(direction) != True:
            raise Exception('Invalid direction.')
        if isinstance(images, ImageSet) != True:
            raise Exception('Images assigned not of type ImageSet.')

        self.imageset = images
        self.position = position
        self.change_direction(direction)

    def change_direction(self, direction):
        #parameter validation
        if Direction.is_direction(direction) != True:
            raise Exception('Invalid direction.')
        if self.imageset.images[direction] == None:
            raise Exception('No image set for given direction.')

        self.image = image.load(self.imageset.get_image(direction))
        self.size = self.image.get_size()
        self.rect = self.image.get_rect()
        self.rect.topleft = self.position
        self.direction = direction

    #must be overridden in a sub-class
    def move(self):
        pass

SimpleSprite will be the base class of my simple sprites, meaning those sprites that has only one image per direction. as shown in the code it has a change_direction function and a stub of move function. i included change_direction since a change of direction doesn’t necessarily entail moving away from one’s position. the move function on the other hand may be omitted but i chose to include it to make it appear more like a base class.

THE SPRITES

i decided to put all my sprites in one file which i named ‘sprites.py’. currently it only has one class which is the Arrow class. the Arrow class is simply a sprite with an arrow for an image. since the whole point of this mini-project is to be able to move around a surface using a sprite that changes its appearance accordingly, i simply downloaded an image of an arrow here and rotated it to point to different directions.

class Arrow(SimpleSprite):
    def __init__(self, direction, position, images):
        super(Arrow, self).__init__(direction, position, images)

    def change_direction(self, direction):
        super(Arrow, self).change_direction(direction)

    def move(self, direction=None, limits=None):
        #parameter validation
        if Direction.is_direction(direction) != True:
            raise Exception('Invalid direction.')
        if limits == None:
            raise Exception('Limits must not be empty.')

        #gets size of step and creates new position
        newposition = self.position
        if direction in [Direction.UP, Direction.DOWN]:
            stepsize = self.size[1]
            if direction == Direction.UP:
                newposition = [self.position[0], (self.position[1]-stepsize)%limits[1]]
            else:
                newposition = [self.position[0], (self.position[1]+stepsize)%limits[1]]
        elif direction in [Direction.RIGHT, Direction.LEFT]:
            stepsize = self.size[0]
            if direction == Direction.RIGHT:
                newposition = [(self.position[0]+stepsize)%limits[0], self.position[1]]
            else:
                newposition = [(self.position[0]-stepsize)%limits[0], self.position[1]]

        self.position = newposition
        self.rect.topleft = newposition

as shown, initialization of this sub-class as well as the change_direction function simply calls that of the parent class or super class. also notice that the move function was overridden here. i intended the move function to be overridden because characters in game would not probably always move in the same way. once in a while we introduce characters that behave differently.

in the case of the Arrow class movement simply means moving to the next cell specified by a direction if we are going to take the whole surface as a grid.

THE CONFIGURATION FILE

i decided to have a separate file for configuration which i named ‘conf_arrow.py’. it isn’t really necessary but i decided to come up with it anyway. this will be loaded by the main game module everytime the game starts. this way, i can have multiple configurations with minimal modification to the main game module. with different configuration files i’ll be able to test different settings by simply changing a line in the main game module which loads the configuration to be used.

import lib_spritesbase
from lib_spritesbase import Direction, ImageSet, StaticFunction

class ArrowConfig:
    SCREENSIZE = [640, 480]
    INITIAL_DIRECTION = Direction.LEFT
    UPDATE_SPEED = 50
    INITIAL_POSITION = [0, 0]
    IMAGES = None
    BACKGROUND = 0

    def init():
        ArrowConfig.IMAGES = ImageSet('sprites/up2.png', 'sprites/down2.png' \
                , 'sprites/right2.png' , 'sprites/left2.png')

    init = StaticFunction(init)

in this file we set the size of the screen, the initial direction of the sprite, the speed by which the display is updated, the starting position of our sprite, the color of the background, and the set of images to be used. the ArrowConfig class will hold the configuration.

THE GAME MODULE

i named the main game module ‘arrow.py’. the filename of the module is not very crucial, i just figured i would name it after the sprite that i’m going to use in the game in it.

import pygame
from pygame import *

import sprites
from sprites import Arrow, Direction

import conf_arrow
from conf_arrow import ArrowConfig

pygame.init()
ArrowConfig.init()

#global variable initialization
updatetime = pygame.time.get_ticks() + ArrowConfig.UPDATE_SPEED
screen = pygame.display.set_mode(ArrowConfig.SCREENSIZE)
isdone = False

#sprite initialization
arrow = Arrow(ArrowConfig.INITIAL_DIRECTION, ArrowConfig.INITIAL_POSITION \
            , ArrowConfig.IMAGES)

while isdone == False:
    screen.fill(ArrowConfig.BACKGROUND) #color screen with default color
    direction = None
    for e in event.get():
        #checks key press and sets direction or end game
        if e.type == KEYUP:
            if e.key == K_ESCAPE:
                isdone = True
            elif e.key == K_UP:
                direction = Direction.UP
            elif e.key == K_DOWN:
                direction = Direction.DOWN
            elif e.key == K_RIGHT:
                direction = Direction.RIGHT
            elif e.key == K_LEFT:
                direction = Direction.LEFT

            #if sprite is facing wrong direction replace with appropriate sprite
            #else move sprite by one step to specified direction
            if arrow.direction != direction:
                arrow.change_direction(direction)
            else:
                arrow.move(direction, ArrowConfig.SCREENSIZE)

    currenttime = pygame.time.get_ticks()
    global updatetime
    if currenttime >= updatetime:
        screen.blit(arrow.image, arrow.rect)
        pygame.display.update()
        updatetime = currenttime + ArrowConfig.UPDATE_SPEED

since the contents of this module is pretty long. let’s try to take it few lines at a time.

import pygame
from pygame import *

import sprites
from sprites import Arrow, Direction

import conf_arrow
from conf_arrow import ArrowConfig

the first few lines are used for importing classes from the other modules mentioned earlier. observing the import lines, it is noticeable that i used * when importing from pygame. to be honest here i still don’t know the classes i need for a game by their names so i simply included all. however the following import lines are generally preferred since it specify the classes to be used from one class library and/or module. it will reduce ambiguity and possible overhead.

pygame.init()
ArrowConfig.init()

what follows is the initialization for pygame and our configuration.

#global variable initialization
updatetime = pygame.time.get_ticks() + ArrowConfig.UPDATE_SPEED
screen = pygame.display.set_mode(ArrowConfig.SCREENSIZE)
isdone = False

#sprite initialization
arrow = Arrow(ArrowConfig.INITIAL_DIRECTION, ArrowConfig.INITIAL_POSITION \
            , ArrowConfig.IMAGES)

next we initialize some variables to be used in the game. ‘updatetime’ holds the next time by which the display will update, the ‘screen’ represents the game screen, while ‘isdone’ states whether the game is over or not. ‘arrow’ on the other hand represents our sprite.

the implementation of the game flow is just a little simpler than the sample snake game.

    screen.fill(ArrowConfig.BACKGROUND) #color screen with default color
    direction = None
    for e in event.get():
        #checks key press and sets direction or end game
        if e.type == KEYUP:
            if e.key == K_ESCAPE:
                isdone = True
            elif e.key == K_UP:
                direction = Direction.UP
            elif e.key == K_DOWN:
                direction = Direction.DOWN
            elif e.key == K_RIGHT:
                direction = Direction.RIGHT
            elif e.key == K_LEFT:
                direction = Direction.LEFT

            #if sprite is facing wrong direction replace with appropriate sprite
            #else move sprite by one step to specified direction
            if arrow.direction != direction:
                arrow.change_direction(direction)
            else:
                arrow.move(direction, ArrowConfig.SCREENSIZE)

first, the screen will be filled by the set background color in our configuration file. next, we are going to check if any key was pressed. if ‘esc’ was pressed, we need to end the game by setting the ‘isdone’ variable to True. Otherwise, we get the direction then change a sprites direction or move it.

	
    currenttime = pygame.time.get_ticks()
    global updatetime
    if currenttime >= updatetime:
        screen.blit(arrow.image, arrow.rect)
        pygame.display.update()
        updatetime = currenttime + ArrowConfig.UPDATE_SPEED

we then check if it’s already time to update the screen. if it is, we update the screen and set the next update time. else we’re going to do nothing.

if you got Python2.7 installed with PyGame. you can try running this game template by downloading the code here. by default .py files open with python so you can just double click on ‘arrow.py’. or you can open console, redirect to the folder where you saved the files then type ‘python arrow.py’.

feel free to comment on this post. have a nice day everyone!

Tagged , , , , , , ,

Sample Snake Game in Python 2.7

The codes are available here.

I was kind of idle once again in the office. For some reason we could not smoothly work in our client’s office yet and proceed with the system integration testing of our work. I had a lot of time to kill and I figured I could use it to continue my study in python programming. Yes I know most CS students start with python, but for us it was C so I’m still learning the language now. I’ve read through the manual for the basic stuffs months ago but I never really worked on any exercise. And just last Tuesday (December 20) I thought, how else would you want to practice python programming than by creating a sample of the snake game? Yes I found it funny. I’m pretty shallow that way. But thinking it over, game programming is enjoyable and the snake game is pretty simple. It would be worth a shot. So here’s my work.

Note: If you want to try this on your own, please make sure that you have Python2.7 installed and the corresponding version of PyGame.

THE SPRITES

I put all the sprites in one file named sprites.py. The class names are pretty ridiculous for I was sort of doing things on the fly and I am sorry for that. I even used the name Apple instead of Food so for this game you are going to have an apple-eating snake.

To begin, we need to put the following line to import the pygame module:

import pygame

The Apple Class

class Apple(pygame.sprite.Sprite):
    #private constants
    _DEFAULT_COLOR = [255, 0, 0] #red
    _DEFAULT_SIZE = [10, 10]
    def __init__(self, color, size, position):
        #parameter validation
        if color == None:
            color = Apple._DEFAULT_COLOR
        if size == None:
            size = Apple._DEFAULT_SIZE
        if position == None:
            raise Exception('Invalid position.')

        #initialization
        self.color = color
        self.size = size
        self.image = pygame.Surface(size)
        self.image.fill(color)
        self.rect = self.image.get_rect()
        self.rect.topleft = position

This one’s pretty straight-forward. We have here an apple class accepting parameters for the color, size, and position upon creation of an instance. I provided default values for the color and size and a little parameter validation since it’s going to be a part of a class library.

Note: All sprites are just composed of square areas in the screen of about 10px X 10px filled by a certain color.

The Callable Class

class Callable:
    def __init__(self, anycallable):
        self.__call__ = anycallable

This class is only used to implement static functions in the sprite classes.

The Snake Class

The Snake class has with it three internal classes namely _SnakeTail, _SnakeHead, and SnakeMove with the first two as private. I figured, If I would like to use images rather than solid colors in the future, I would most certainly dedicate a different image to the head compared to the body. Hence, I decided to separate the snake’s head from its tail.

Like what I did in the Apple class, I also provided default values for the attributes.

    #private constants
    _DEFAULT_COLOR = [0, 255, 0] #green
    _DEFAULT_SIZE = [10, 10] #10px X 10px
    _DEFAULT_POSITION = [30, 30] #space given to tail of length 2

The _SnakeTail Class

    class _SnakeTail(pygame.sprite.Sprite):
        def __init__(self):
            #initialization
            self.tiles = []

        def add_tile(self, color, size, position):
            #creates a new tile
            tile = pygame.Surface(size)
            tile.fill(color)
            rect = tile.get_rect()
            rect.topleft = position

            self.tiles.append({'image':tile, 'rect':rect})

The snake’s tail is composed of an array of color-filled square areas that I call tiles for lack of a better term. It also has an add_tile function that will make the tail grow longer. The add_tile function creates another instance of a tile of a given color and size and adds it to the tail’s array of tiles. Once the tail is re-rendered on screen, it should appear longer.

The _SnakeHead Class

    class _SnakeHead(pygame.sprite.Sprite):
        def __init__(self, color, size, position):
            #initialization
            self.image = pygame.Surface(size)
            self.image.fill(color)
            self.rect = self.image.get_rect()
            self.rect.topleft = position

The _SnakeHead class is very similar to the Apple class.

The SnakeMove Class

    class SnakeMove():
        UP = '1Y'
        DOWN = '-1Y'
        RIGHT = '1X'
        LEFT = '-1X'

        #checks a direction's validity
        def SnakeMove_is_member(direction):
            if direction == Snake.SnakeMove.UP:
                return True
            elif direction == Snake.SnakeMove.DOWN:
                return True
            elif direction == Snake.SnakeMove.RIGHT:
                return True
            elif direction == Snake.SnakeMove.LEFT:
                return True

            return False

        #makes the function 'is_member' a static function
        SnakeMove_is_member = Callable(SnakeMove_is_member)

The creation of this class would have been avoided if I settled on accepting just some set of values for directions in making the snake move but it was against to what I’m used to. Since I wanted sprites.py to function like a standard class library I wanted it to implement a uniform way of using the classes and their functions and sort of inform developers about it. The SnakeMove class functions like an enum class in C#, this way developers won’t have to guess valid direction values once they deal with making the snake move. All they have to do is pass a constant from this class as a parameter to the Snake class’ move function.

The class has a SnakeMove_is_member static function which is used for validating the direction parameter in the Snake class’ move function. The static class was created with the help of the previously shown Callable class.

The Snake Class Functions

Initialization

    def __init__(self, color, size, position):
        #parameter validation
        if color == None:
            color = Snake._DEFAULT_COLOR
        if size == None:
            size = Snake._DEFAULT_SIZE
        if size[0] != size[1]:
            raise Exception('Invalid tile size. Width and height must be equal.')
        if position == None:
            position = Snake._DEFAULT_POSITION

        self.color = color
        self.size = size
        self.head = Snake._SnakeHead(color, size, position)
        self.tail = Snake._SnakeTail()
        tailposition = [(position[0] - size[0]), position[1]]
        self.tail.add_tile(color, size, tailposition)
        tailposition = [(position[0] - 2*size[0]), position[1]]
        self.tail.add_tile(color, size, tailposition)

The initialization of the snake class simple involves validating the parameters and assigning default values for missing paramaters and creating the instance for the snake’s head and tail. As shown in the code, the initial length of the tail is 2 tiles. All in all, the Snake sprite has a color, size, head, and tail attributes.

Movement

    def move(self, direction, frame_width, frame_height):
        #parameter validation
        if Snake.SnakeMove.SnakeMove_is_member(direction) != True:
            raise Exception('Invalid movement direction.')

        #initializes new position
        stepsize = self.head.image.get_rect()[2] #gets the size of the head tile
        newheadposition = [self.head.rect.topleft[0], self.head.rect.topleft[1]]
        if direction == Snake.SnakeMove.UP:
            newheadposition[1] = (newheadposition[1]-stepsize)%frame_height
        if direction  == Snake.SnakeMove.DOWN:
            newheadposition[1] = (newheadposition[1]+stepsize)%frame_height
        if direction == Snake.SnakeMove.RIGHT:
            newheadposition[0] = (newheadposition[0]+stepsize)%frame_width
        if direction == Snake.SnakeMove.LEFT:
            newheadposition[0] = (newheadposition[0]-stepsize)%frame_width

        if self.occupies_position(newheadposition):
            return False

        #moves the head to its new position
        newtileposition = self.head.rect.topleft
        self.head.rect.topleft = newheadposition

        #moves the tail tiles to its respective new positions
        for count in range(len(self.tail.tiles)):
            prevtileposition = self.tail.tiles[count]['rect'].topleft
            self.tail.tiles[count]['rect'].topleft = newtileposition
            newtileposition = prevtileposition

        return True

As mentioned earlier, the move function first checks if the supplied direction is valid. If not, it will raise an exception. If it is, it will proceed to determing the next position of each tile starting with the head.

stepsize = self.head.image.get_rect()[2] #gets the size of the head tile

In this line, we are assuming that the size of the head is equal with the all the other tiles in the snake’s body.

if self.occupies_position(newheadposition):
    return False

Here we are making sure that the snake is not trying to move to a space that its body already occupies. If it is, then the snake won’t be able to move and the game will be over.

The remaining lines deal with moving each tile to the position of the one before it. If all goes well then the function will return True, signifying that the movement was successful.

Collision Detection

    #checks if this snake's body occupies a given position
    def occupies_position(self, position):
        #parameter validation
        if position[0] == None or position[1] == None:
            return True

        if self.head.rect.topleft[0] == position[0] \
            and self.head.rect.topleft[1] == position[1]:
                return True

        for count in range(len(self.tail.tiles)):
            if self.tail.tiles[count]['rect'].topleft[0] == position[0] \
            and self.tail.tiles[count]['rect'].topleft[1] == position[1]:
                return True

        return False

PyGame already has a built-in function for collision detection involving objects with rect attribute but I found it quite late. I did this one and it was pretty good enough for me. As the function name implies, this function checks whether the snake is occupying a given position.

Lengthening the Tail

    def lengthen_tail(self, number, current_direction):
        #parameter validation
        if number is None:
            number = 1
        if Snake.SnakeMove.SnakeMove_is_member(current_direction) != True:
            raise Exception('Invalid movement direction.')

        size = self.size[0]
        color = self.color

        for count in range(number):
            lastindex = len(self.tail.tiles) - 1
            X = self.tail.tiles[lastindex]['rect'].topleft[0]
            Y = self.tail.tiles[lastindex]['rect'].topleft[1]

            #determines position of new tile
            if current_direction == Snake.SnakeMove.UP:
                Y = Y - size + (count*size)
            elif current_direction == Snake.SnakeMove.DOWN:
                Y = Y + size + (count*size)
            elif current_direction == Snake.SnakeMove.RIGHT:
                X = X - size + (count*size)
            elif current_direction == Snake.SnakeMove.LEFT:
                X = X + size + (count*size)

            self.tail.add_tile(color, self.size, [X, Y])

Since the _SnakeTail class is supposed to be private, I provided this function on the Snake class. This should be the one that developers using my sprites library use when making the Snake grow longer. I included an number parameter just in case someone wants to make the snake grow longer by more than one tile. Determining the position for the new tile involves checking the snake’s current direction to ensure that addition of tiles will be done on the right end and following the right direction of movement.

THE GAME

The main file for this snake game is game.py. It handles the display and game flow.

Initialization

import pygame
import pygame._view
from pygame import *
from sprites import Snake
from sprites import Apple
import random

The lines above shows the modules imported by the game file. Notice that only the Apple and Snake classes were imported from sprites.py.

pygame.init()

Initialize the game.

DEFAULT_SCREEN_SIZE = [640, 480]
INITIAL_DIRECTION = Snake.SnakeMove.RIGHT
DEFAULT_UPDATE_SPEED = 100

updatetime = pygame.time.get_ticks() + DEFAULT_UPDATE_SPEED

Some default values and update time initialization.

#screen initialization
screen = pygame.display.set_mode(DEFAULT_SCREEN_SIZE)
display.set_caption('Snake')

#sprite initialization
snake = Snake(None, None, None)
apple = None

Screen and sprites initialization.

is_done = False #signifies escape from game
is_over = False #signifies end of game by game rules
direction = None
score = 0
create_apple()

Initialization of variables that will be used in the game flow. Notice that we have is_done and is_over. create_apple was also called to create first instance of the apple.

Rendering

def render_snake():
    screen.blit(snake.head.image, snake.head.rect)
    for count in range(len(snake.tail.tiles)):
        screen.blit(snake.tail.tiles[count]['image']
            , snake.tail.tiles[count]['rect'])

This method renders the snake on screen. This simply displays all the tiles forming the image of the snake.

#renders the apple on screen
def render_apple():
    global apple
    screen.blit(apple.image, apple.rect)

Like the render_snake method, this method displays the apple on screen.

#creates a new apple
def create_apple():
    global apple
    global snake

    hlimit = (DEFAULT_SCREEN_SIZE[0]/Apple._DEFAULT_SIZE[0])-1
    vlimit = (DEFAULT_SCREEN_SIZE[1]/Apple._DEFAULT_SIZE[1])-1
    X, Y = None, None

    while snake.occupies_position([X, Y]) == True:
        X = random.randint(0, hlimit)*Apple._DEFAULT_SIZE[0]
        Y = random.randint(0, vlimit)*Apple._DEFAULT_SIZE[1]
    apple = Apple(None, None, [X, Y])

Notice that horiontal and vertical limits were computed first before generating a random position. This ensures that the position generated will be inside the area of the screen. Default values are used here ‘though, maybe we can make it configurable on a better version. We also keep on generating random positions if the current position is occupied by the snake.

The Game Flow

while is_done == False:
    screen.fill(0) #color screen black
    global direction
    if direction == None:
        direction = INITIAL_DIRECTION

    #checks for changes in direction and validates it
    for e in event.get():
        if e.type == KEYUP:
            if e.key == K_ESCAPE:
                is_done = True
            elif e.key == K_UP:
                if direction != Snake.SnakeMove.DOWN:
                    direction = Snake.SnakeMove.UP
            elif e.key == K_DOWN:
                if direction != Snake.SnakeMove.UP:
                    direction = Snake.SnakeMove.DOWN
            elif e.key == K_RIGHT:
                if direction != Snake.SnakeMove.LEFT:
                    direction = Snake.SnakeMove.RIGHT
            elif e.key == K_LEFT:
                if direction != Snake.SnakeMove.RIGHT:
                    direction = Snake.SnakeMove.LEFT

    #updates the display
    currenttime = pygame.time.get_ticks()
    global updatetime
    global is_over
    if is_over == False:
        if currenttime >= updatetime:
            moved = snake.move(direction, DEFAULT_SCREEN_SIZE[0], DEFAULT_SCREEN_SIZE[1])
            if moved == False:
                is_over = True
            if snake.occupies_position(apple.rect.topleft) == True:
                create_apple()
                snake.lengthen_tail(1, direction)
                global score
                score += 1
                display.set_caption('Snake: ' + str(score))

            render_apple()
            render_snake()
            pygame.display.update()
            updatetime += DEFAULT_UPDATE_SPEED
    else:
        display.set_caption('Snake: ' + str(score) + ' GAME OVER')

The flow as expected is implemented using a loop.

screen.fill(0) #color screen black

First we fill the screen with black.

    global direction
    if direction == None:
        direction = INITIAL_DIRECTION

    #checks for changes in direction and validates it
    for e in event.get():
        if e.type == KEYUP:
            if e.key == K_ESCAPE:
                is_done = True
            elif e.key == K_UP:
                if direction != Snake.SnakeMove.DOWN:
                    direction = Snake.SnakeMove.UP
            elif e.key == K_DOWN:
                if direction != Snake.SnakeMove.UP:
                    direction = Snake.SnakeMove.DOWN
            elif e.key == K_RIGHT:
                if direction != Snake.SnakeMove.LEFT:
                    direction = Snake.SnakeMove.RIGHT
            elif e.key == K_LEFT:
                if direction != Snake.SnakeMove.RIGHT:
                    direction = Snake.SnakeMove.LEFT

Then we check for changes in direction based on keyboard input. Notice that global direction was used to make things less confusing. After all only one direction is needed. Additional check was also placed to deem direction opposite the current one as invalid.

    #updates the display
    currenttime = pygame.time.get_ticks()
    global updatetime
    global is_over
    if is_over == False:
        if currenttime >= updatetime:
            moved = snake.move(direction, DEFAULT_SCREEN_SIZE[0], DEFAULT_SCREEN_SIZE[1])
            if moved == False:
                is_over = True
            if snake.occupies_position(apple.rect.topleft) == True:
                create_apple()
                snake.lengthen_tail(1, direction)
                global score
                score += 1
                display.set_caption('Snake: ' + str(score))

            render_apple()
            render_snake()
            pygame.display.update()
            updatetime += DEFAULT_UPDATE_SPEED
    else:
        display.set_caption('Snake: ' + str(score) + ' GAME OVER')

Updating the display depends on two things, one is if the game is not over yet and the other is if the update time was already reached.

    moved = snake.move(direction, DEFAULT_SCREEN_SIZE[0], DEFAULT_SCREEN_SIZE[1])
    if moved == False:
        is_over = True

If the game is not yet over and the update time was already reached, an attempt to move the snake is done. In case movement failed which is probably becaused the snake hit itself, the game will be over.

    if snake.occupies_position(apple.rect.topleft) == True:
        create_apple()
        snake.lengthen_tail(1, direction)
        global score
        score += 1
        display.set_caption('Snake: ' + str(score))

If movement was successful, it is determined if the snake passes through the position of the apple. If it does, then a new apple is created, the snake’s tail will be lengthened, the score will be incremented, and the score display will be updated.

    render_apple()
    render_snake()
    pygame.display.update()
    updatetime += DEFAULT_UPDATE_SPEED

To cap off the updates, all the elements will be re-rendered and the update time will be set to a future time.

On the other hand, if the game is already over, the updates will simply stop and the display will flash GAME OVER together with the score.

Wow this post is pretty lengthy but I hope someone might find it useful at least for comparisons haha. Feel free to comment ‘though I’d be moderating them. Have a nice day everyone!

Tagged , , , , ,
Follow

Get every new post delivered to your Inbox.