No control over 2G/3G in Android API

Posted in Ideas on July 25th, 2010 by Mat – Be the first to comment

On phones which use google’s android OS, there’s a little checkbox buried in the settings menu, “Use only 2G networks” which turns off 3G. I use this all the time because of the huge impact 3G has on battery life; however, it’s really annoying to keep having to go into the menu, switch it on, then go back and switch it off again when I’m done using the internet (especially on my sluggish T-Mobile Pulse).

I had the idea of creating my own app which would switch on 3G for a set amount of time only. By integrating this with the fantastic Locale application it would also be possible to automatically trigger this by shaking the phone or something cool like that. I had it all planned out, except for one minor detail: how to actually toggle the setting. You’d think this would be pretty simple, seeing as plenty of other useful settings are exposed through the API, but no, the fascists at google do not allow it!

So now, when I am left helpless and alone as my anthropomorphised battery breathes it’s final breath, I will remember this day with a tear in my eye, and I will never forgive the murderers who cruelly condemned this poor innocent battery to death. So much for “don’t be evil”.

Planet simulator and Goserver

Posted in Programming on January 1st, 2010 by Mat – Be the first to comment

In an effort to revive this blog and start posting regularly I’ve decided to post some things I made ages ago which I haven’t posted online before.

The first is a solar system simulator that demonstrates Kepler’s laws of planetary motion:

kepler.tar (source)

This originated as part of a multiplayer space shooter game I worked on with Bencoder, which was never completed (mainly because we couldn’t decide how the game was supposed to work). We wanted planets which would move, but would be consistent across the network. Keplerian orbits allowed us to predict the state of the system at any given time, while still being realistic enough to satisfy my nerdiness. This is basically the map editor I wrote for the game. I think it was my first C++ application and my first GUI application (using Qt). As a result, the code is a horrible mess and it’s a bit buggy, but it’s quite fun to play around with.

Features:

  • construct systems of suns, moons and planets
  • customize the image shown for each one with user created content
  • modify the size, mass and position of the objects
  • modify the ellipticity and direction of the orbits
  • view an animation of the system in real time

Note: since the planets only interact with one other object, the system will behave a bit weirdly when the orbital paths intersect or are close to each other.

The other thing I made (this was a bit more recent) is a turn based go server in ruby on rails. It’s unfinished at the moment, but I have it running here if you want to take a look. I was using this project to try and learn rails, but I think I may have picked something a bit too ambitious. There was a problem I couldn’t figure out with the images sometimes not loading and I eventually gave up on it. I learned a lot from it though, and I really like rails for web development, even though it’s a lot of hassle to set up on my website compared to PHP.

Generating grids to use as go boards

Posted in Programming on December 29th, 2009 by Mat – Be the first to comment

So I decided to go back to my python go game I started many months ago. I have several other things I want to work on, most of which also involve go, but for some reason this interests me the most at the moment, and I haven’t done any python programming in a while so I’m going to put them on hold.

One of the main things I wanted to do with the game was to allow for playing on many different types of board, rather than limit it to the boring old 19×19 square kind, so I’ve written a module with several different classes which can be used to create board objects.

The rules of go are very simple, and are pretty much independent of the board shape. To work out what happens to the rest of the board when you place a stone, all you really need to know is how the points are connected to each other and where all the stones are. This means that an arbitrary graph can be used as the go board and what the board actually looks like is irrelevant. You can easily play go on 3D structures such as diamond structures or invent some strange irregular shape if you want. This makes it pretty easy to seperate the board structure from the game logic.

I’ve decided to limit myself to regular structures for the time being, and have stuck to 2 dimensions as I’m too lazy to mess around with 3D visualizations. I’ve implemented a regular rectangular board a board which allows the edges to be wrapped pacman style, which can be used to simulate playing on a the surface of a cylinder or torus (donut shape). To test it works ok I’ve whipped up a simple view in pygame which shows the neighbours of each point when you click on it.

The next step is to rewrite my go game around this module and create a usable gui for it.

'''Classes for modelling the goboard itself, i.e. an arrangement of points with lines connecting them. No game logic is included.
Grid/lattice coordinates should all be integers'''
from itertools import izip
import sys

#Move this somewhere else later
class Observable:
    '''Implement observer pattern'''

    def __init__(self):
        self.listeners = []

    def register_listener(self, listener):
        self.listeners.append(listener) #this object has synasthaesia

    def remove_listener(self, listener):
        self.listeners.remove(listener)

    def notify(self, *args):
        for i in self.listeners:
            if args:
                i(args)
            else:
                i()

class Grid(Observable):
    '''A representation of a 2D grid with each point holding some value.
    Stores the relative location of each point and the lines connecting them.
    Lattice is a list of points representing the lattice structure the grid is based around.
    Basis is a tuple of coordinates of the grid points relative to the lattice points.
    Connections is a list of 4-tuples of the form (x1,y1,x2,y2) indicating how points in the basis are connected'''

    def __init__(self, lattice, basis, connections, default_value=0):
        '''Store points and connections'''
        Observable.__init__(self)
        self.points = {}
        self.connections = {}

        for lx,ly in lattice.items():

            #Add the points by superimposing the basis onto each lattice point
            for b in basis:
                bx, by = b
                self.points[(lx+bx, ly+by)] = default_value
                self.connections[(lx+bx, ly+by)] = []

        #Now connect the points
        for lx,ly in lattice.items():

            try:
                for c in connections:
                    cx1, cy1, cx2, cy2 = c
                    a = (lx+cx1, ly+cy1)
                    b = (lx+cx2, ly+cy2)
                    if a in self.points and b in self.points:
                        self.connections[a].append(b)
                        self.connections[b].append(a)
                    else:
                        print 'Missing points for connection '+str(a)+'-'+str(b)
                        if a not in self.points: print a
                        if b not in self.points: print b
            except KeyError:
                raise Exception('Invalid connections')

    def neighbours(self, x, y):
        try:
            return self.connections[(x,y)]
        except KeyError:
            raise Exception('Bad grid coordinates')

    def set_point(self, x, y, val):
        try:
            self.points[(x,y)] = val
            self.notify() #notify observers on changes
        except KeyError:
            raise Exception('Bad grid coordinates')

class RectangularGrid(Grid):
    '''A rectangular grid. Aspect ratio should be a natural number (horizontal spacing >= vertical spacing)'''

    def __init__(self, width, height, aspect_ratio=1):
        aspect_ratio = int(aspect_ratio) #no floats please!
        lattice = RectangularLattice(width, height, aspect_ratio)
        basis = ((0, 0),)
        connections = ((0, 0, 1, 0), (0, 0, 0, 1))
        Grid.__init__(self, lattice, basis, connections)

class FoldedGrid(RectangularGrid):
    '''A rectangular grid where sides connect with each other.
    Joins is a list of tuples indicating which sides are joined, where each of the two values can be N, E, S or W
    Reverse_joins is the same except there is also a twist, so one side can map to another side reversed (or the same side)'''

    def __init__(self, width, height, aspect_ratio, joins = [], reverse_joins = []):
        RectangularGrid.__init__(self, width, height, aspect_ratio)

        #Lists of coordinates making up each side
        east = []
        west = []
        north = []
        south = []

        #East/West coordinates
        x1 = 0
        x2 = (width - 1) * aspect_ratio
        for i in range(height):
            east.append((x1, i))
            west.append((x2, i))

        #North/South coordinates
        y1 = 0
        y2 = height - 1
        for i in range(width):
            i *= aspect_ratio
            north.append((i, y1))
            south.append((i, y2))

        sides = {'E':east, 'W':west, 'N':north, 'S':south}

        #Make the extra connections
        try:
            for sideA, sideB in joins:
                #Zip the two sides together to get a tuple of tuples (coordinates) for each connected pair
                for c1, c2 in izip(sides[sideA], sides[sideB]):
                    self.connections[c1].append(c2)
                    self.connections[c2].append(c1)

            for sideA, sideB in reverse_joins:
                #This time the second side is reversed!
                for c1, c2 in izip(sides[sideA], reversed(sides[sideB])):
                    print str(c1) + '-' + str(c2)
                    self.connections[c1].append(c2)
                    self.connections[c2].append(c1)

        except KeyError:
            raise Exception('Invalid value for join or reverse_join')

class RectangularLattice:
    '''List of coordinates of points arranged in a grid'''

    def __init__(self, width, height, aspect_ratio, scale=1):
        aspect_ratio = int(aspect_ratio) #no floats please
        self.points = []
        for i in range(width):
            for j in range(height):
                j *= aspect_ratio
                self.points.append((i,j))

    def items(self):
        for i in self.points:
            yield i

class GridViewPygame:
    '''Draw grids using pygame'''

    def __init__(self, grid, surface, scale=None, rotation=0, zoom_to_fit=False, join_connected=False, highlight_connected=True):
        grid_width = max([x for x,y in grid.points])
        grid_height = max([y for x,y in grid.points])
        width = surface.get_width()
        height = surface.get_height()

        if zoom_to_fit:
            scale = min(width/float(grid_width), height/float(grid_height))
        elif scale is None:
            scale = 1

        self.scale = scale
        self.grid = grid
        self.surface = surface
        self.grid.register_listener(self.draw)
        self.highlighted = None

        self.highlight_connected = highlight_connected
        self.join_connected = join_connected

    def draw(self, *args):
        '''Draw the grid'''
        print 'redrawing'
        scale = self.scale
        self.surface.fill((255,255,255))

        for p in self.grid.points:
            x,y = p
            x *= scale
            y *= scale
            if (p == self.highlighted):
                pygame.draw.circle(self.surface, (0,0,255), (x,y), 3)
            else:
                pygame.draw.circle(self.surface, (0,0,0), (x,y), 2)

        #This actually draws the line for each connection twice but never mind
        if self.join_connected:
            for a,bs in self.grid.connections.items():
                for b in bs:
                    ax,ay = a
                    bx,by = b
                    ax *= scale
                    ay *= scale
                    bx *= scale
                    by *= scale
                    if (a == self.highlighted or b == self.highlighted):
                        pygame.draw.line(self.surface, (0,0,255), (ax,ay), (bx,by))
                    else:
                        pygame.draw.line(self.surface, (0,0,0), (ax,ay), (bx,by))

        if self.highlight_connected and self.highlighted:
            for x,y in self.grid.connections[self.highlighted]:
                x *= scale
                y *= scale
                pygame.draw.circle(self.surface, (0,255,0), (x,y), 2)

        pygame.display.flip()

    def board_to_grid(self, pos):
        '''Convert view coordinates to grid ones'''
        x,y = pos
        x = int(round(x/self.scale))
        y = int(round(y/self.scale))
        return (x,y)

    def onClick(self, pos):
        '''Highlight the nearest point'''
        pos = self.board_to_grid(pos)
        print pos
        self.highlighted = pos
        self.draw(False,True)

if __name__ == '__main__':

    #Initialize pygame
    import pygame
    pygame.init()
    from pygame.locals import *
    screen = pygame.display.set_mode((800, 600))

    #Create grid
#    grid = RectangularGrid(19,19)
    grid = FoldedGrid(19,19,1,[('N','S'),('E','W')])
#    grid = FoldedGrid(19,19,1,[],[('N','S'),('E','W')])
    view = GridViewPygame(grid, screen, zoom_to_fit=True)
    view.draw()

    #Handle events
    while True:
        for event in pygame.event.get():
            if event.type == QUIT:
                pygame.quit()
                sys.exit()
            elif event.type == MOUSEBUTTONDOWN:
                view.onClick(pygame.mouse.get_pos())

One day game (continued)

Posted in Ideas, One day games, Programming on June 5th, 2009 by Mat – Be the first to comment

Game 1 ended up being a huge failure. I think the main reason for this was a lack of experience in game development in general, and a poor choice of programming language, which I didn’t really know how to use properly when I started (flash/actionscript). As a result I wasted a lot of time trying to learn stuff and wasn’t able to put together anything playable within the time span I set myself.

Trying to come up with good ideas in so short a time was challenging, but I think I did have some workable ideas. While the obvious interpretation of “space” is a broad enough theme in itself, I decided to explore other meanings rather than immediately settling for some kind of spaceship game. Some of the ideas I had -

  • An abstract game where the player manipulates empty space somehow, by rearranging or destroying things
  • A tetris variant
  • Human expansion has left the solar system overcrowded and you have to destroy things to make space, possibly related to the Vogons in h2g2 (reflecting the theme in two ways)
  • Something related to recycling and consumerism (not enough space for all the garbage we produce?)
  • Any kind of space in the mathematical sense
  • Something related to the concept of personal space. e.g. avoiding other commuters on a crowded train (I rejected this but kept the general idea for my final game)

The idea I went with was a game in which you have to maintain a certain amount of space around you to survive. The player is a boy who is trying to avoid catching “cooties” from girls who run at the player from offscreen. Also the player is armed with a baseball bat.

This is as far as I got:
Failed game

24 hour game

Posted in One day games, Programming on June 4th, 2009 by Mat – Be the first to comment

This will be the first of hopefully many small games. Me and my friend Ben will both be attempting to design and make fun, playable games within a one day time frame. Each time, there will be a theme chosen at the start by one of us (the theme chooser will change each time) which both the games will have to fit in with. At the end, people will be able to vote on which is the best over at Ben’s blog.

The theme this time is “space” (chosen by Ben) and the challenge ends at 19.00 23.59 UTC+1 tommorow (5th of june).

Tesselating hexagons and Go

Posted in Programming on March 3rd, 2009 by Mat – Be the first to comment

These handy go board templates have enlightened to me to the awesomeness of postscript, so I decided to have a go at creating my own.

It’s a hexagonal go board. Stones have either 3 (playing on the intersections) or 6 (playing inside the hexagons) liberties instead of the usual 4. I have yet to try it out, but apparently having less liberties makes the game more tactical, as its a lot easier to capture stones. See here for some more info on different board variations.

You can download it as pdf or postscript (both are A4 sized)

Also seeing as how I’m probably not going to be working on my go program for a while I’ve uploaded the code for that here.
I haven’t tested it on other computers at all but it should work as long as you have python and wxpython (for the GUI) installed. The GUI is pretty crappy at the moment as it only supports 9×9 games but the text version is a bit more flexible. Also theres no way of playing against a computer or internet person yet.

run it with
python run.py
or
python run_gui.py

Go

Posted in Programming on December 4th, 2008 by Mat – 2 Comments

I’ve gotten really into Go lately, so I decided to make my own Go app. I’m not really planning to accomplish anything useful, seeing as there’s a lot of good software already out there, so features will be added if and when I feel like it.

I’ve written a few classes for it now… you can play stones and it will try to work out if the move is legal and remove captured stones, which seems to work but probably doesn’t. I’ll test it properly later. I’m going to make a text only interface first, then add a gui once I’ve got it working properly.

*edit* made the text interface for playing a 2 player game on the same computer. Everything is working but it doesn’t calculate the score yet.

Go game

Go game

Super simple blog using text files

Posted in Programming on October 18th, 2008 by Mat – Be the first to comment

Here’s something I made in php to run a blog without a database. The posts are written in text files and the filename contains the post number and date. I wanted something I could put on my webspace at university that would allow me to keep a diary of everything I do for my final year project.

Features:
Umm… it has permalinks or you can view recent posts 10 at a time. And it automagically inserts the html for paragraphs for you. That’s pretty much it.

Simple blog

Yeah.

Posted in Programming on September 26th, 2008 by Mat – 1 Comment

I was curious about which words I say the most when talking on msn so I decided to write a quick python script to find out:

import re,os,string
logdir = "/home/mat/.purple/logs/msn/[my email]"
regex = re.compile("\(\d\d:\d\d:\d\d\) Mat: (.*)")
info = {}

def compareVal(a,b):
	"""Compare a list of tuples using their 2nd value"""
	return b[1]-a[1]

def removePunc(word):
	"""Couldn't find an existing function for this, strip only removes characters from the ends :( """
	return "".join([i for i in word if i not in string.punctuation])

#go through all files in the subdirectories
for root, dirs, files in os.walk(logdir, topdown=True):
	for f in files:
		fullPath = os.path.join(root,f)
		text = open(fullPath)
		for line in text:
			m = regex.match(line)
			if m: #only look at stuff I've said
				words = m.group(1).split()
				words = [removePunc(i) for i in words] #remove punctuation
				words = [i for i in words if len(i)>3] #filter out short words
				for word in words: #increment the frequency for this word
					if word in info: info[word] += 1
					else: info[word] = 1

li = info.items()
li.sort(compareVal) #sort by frequency (highest first)
for i in li:
	print "%s: %d" % i

(It ignores anything with 3 letters or less)

The results were kind of boring. Here’s the top 10:
yeah: 1984
that: 1956
have: 1565
what: 1321
like: 1148
just: 993
dont: 937
think: 870
well: 832
with: 722

PyWeek 7

Posted in Programming on September 15th, 2008 by Mat – Be the first to comment

Last week I took part in pyweek, a week long programming contest where you have to write a game in python that fits a theme.

The theme this time was “the length of a piece of string” and my entry can be found here. (You’ll need to have python and pygame installed to run it)

I haven’t played through all the other entries yet, but so far my favourite is Kite Story (has a windows .exe as well as the python source) which involves wrapping things up in the string of your kite. It’s really well made, has lovely graphics and music and more importantly, it’s fun. I’m impressed.