# Preparation: Crossword Creator in Python

I finally have found a programming problem again that kept me occupied for more than a day simply because I could not do it. But let’s start from the beginning. I wrote a “Search the Words”-Game recently (like this one here) and it worked pretty well actually. There were some limitations to it, but it gave me a good result 9 times out of 10 (I may even post the code for it).

I then figured: “Hey actually, the code I used in this program, I can easily adapt to write a CrossWord Creator!” I have tried this and I unfortunately got nowhere ðŸ˜¦ The main problem here is, that I used a fairly brute force approach in my “Search the Words”-script. In a crossword, there are many more constraints which leads to many, many dead ends. Thus either, the code does not yield a satisfactory result or it takes up all memory for a very long… and in the end does not yield a satisfactory result ðŸ˜‰ The problem here was twofold. My code was not optimized for speed (many unnecessary loops) and in most cases it was leading towards a dead end.

With this in mind, I looked a little bit into constraint logic programming, the branch that deals with these problems. Actually, crosswords are some of the more widely used constraint logic problems (alongside Sudoku and probably other Puzzles). I found a Python implementation by Bryan Helmig, as well, but I wanted to do it myself, so I only read through his approach and not his code.

I will now for myself, outline the approach I will try and possible implementations. If you, the reader, have anything to add, please feel free to chime in. Every constructive input is welcome. The only thing you need to remember is, that this is a hobby of mine and I have never ever formally studied computing science or software engineering, therefore sentence like “Just use xyz algorithm to implement concept abc…” do unfortunately not help me in the slightest ðŸ˜‰

So here is my analysis. The problem can be easily broken down into several steps.

1. Order the list of words to be used in a useful way
2. Place the words in a grid according to specific rules
3. Check the quality of the crossword (if it yielded a useful result)
4. Remember the result and repeat the first 3 steps X times to yield the best possible result.

This is a very general approach, but I will try to move within these confines and sum up my thoughts on each. How to optimise each section and get a meaningful result.

General Definition of Constraints

Before I even discuss the steps, it is first important to assess the constraints that we have for this problem. To this end, I will use the crosswords, that are common in German newspapers. I know there are international differences, but these are the ones I grew up with so I will use those.

1. Except the first word, each successive word must be placed with one or more letter overlaps with another word already placed on the grid.
2. Apart from at the overlaps, letters are not allowed to be in parallel cells of the grid (unless they are part of the same word).
3. A word placement may not be longer than the boundaries of the grid.
4. The two words of an overlap must be at right angles to each other, e.g. the words ‘creator’ and ‘random’ may not both be horizontal, otherwise you will see a grid with something like this `CREATORANDOM`

These are the constraints that I can think of and that I have to work with. Now onto the discussion of each point.

1. Order the list of words

This step is rather easy. I will actually follow Bryan Helmig’s assumption here that the longer the word, the harder it will be to place it. Therefore, putting the words in a list ordered by length of word could be an option and then placing it accordingly. If a word cannot be placed on the grid, because there is no good overlap, we skip it and try the next. Then we revisit the same word again.

It can also be envisioned to place the words in a dictionary, with the keys being the length of the words and the values a list with all words of each length. If this would give more comprehensive code or a faster lookup will have to be tested. In this case, it is foreseeable that we can have more variation, simply by being able to choose at random from a list of words of equal length. Something that may not be as easy when working with an order list.

2. Place the words in the grid according to specific rules

This algorithm will be the most crucial part and the one that will need most optimising. I need to subdivide this section into two parts.

1. The search for a suitable space
2. The actual placement of the word

The search for a suitable place

I have been pondering about this step for quite some time. Before, I was just brute-forcing it by going through the list of letters already placed and finding a match with a letter in the word to be placed. Unfortunately, this would always lead to the same options tested first and thus can lead into the same dead end over and over again. Additionally, you would always start at the beginning and go through all the letters. Again and again. That is not very efficient and will lead to long waiting times in calculations.

I came up with an idea that I will try for this approach. When placing a word, I will save the coordinates of each letter in a grid in a hash (python dictionary), so that it will look something like this at some point:

``` letter_coords = { 'a': [(1,0), (3,6)], 't': [(9,0), (1,4), (5,7)], ... } ```
This format will avoid that we have to go through all letters in the grid again and again and again. When we want to place a word, we just look for the letters in the word and check the coordinates given from this dictionary. The speed advantage will most likely allow us, to go through all possible positions, to find the “best” position to place the word (what the best is, we need to discuss in the next section).

Addendum:

An addition to this format is to also note down in which direction they still free to (left to right or top to bottom). Secondly, once both direction are used up for a letter, it can be removed from the list.

The actual placement of the word

I have just discussed how to find in a quick manner possible positions of overlap. The actual placement of the word requires also a little thinking. In a random placement, you can imagine that it will be easy at first, but towards the end, you will run out of suitable options very quickly. Therefore, I need to think of a smart way of placing the words.

The first thought that came to my mind is to give a score for each placement according to several factors. Here are my current thoughts:

• Start at 1
• multiply with 0 (to get 0) when an undesirable situation is found
• letter is parallel to a letter not belonging to the same word
• word is too long
• If score is ever 0, discard and go to next
• depending on how much “space” (free cells) around the letters add a score
• One free cell on either side +1
• two on one side, one on the other + 2 etc.
• +X for each additional overlap
• Choose the word with the highest score, if more than one, choose at random.

Based on this, I should get a reasonably good placement of the word and generally good variability based on the first two major steps.

3. Check the ‘quality’ of the crossword

Here, I will try to recycle an idea from before. I will try to assign a score to each crossword. The best factor here would be overlaps. Another one would be how many of the words were placed. That is right. Maybe there is a word that just cannot be placed. So rather than aborting the entire mission, give the crossword with all the words that were possible to be placed. The more words in, the better, of course. The score needs to be carefully designed, however, so that there is no chance that fewer words with more overlaps is worth more than all words placed with minimum overlaps.

4. Repeat and choose the “best” crossword

This step is self-explanatory. Based on the score of the previous step, you choose after x repeats, the best crossword.

So, based on the above waffling, I will try to write this crossword generator script. If I manage it and it looks good, I will share the code on here. If you have any additions or improvements. Feel free to mention them here, as well :).

Advertisements

# Create a simple game menu with pygame pt. 4 â€“ Connecting it to functions

Please note that I used python 2.7 for this tutorial. If you are using python3.x, this code may not work. I have adapted this tutorial to Python3 in this blog post.

Hello again :). This is the final part in my mini tutorial series on creating a simple game menu with pygame. Last time we looked at the implementation of the keyboard navigation and thus we completed the navigation section. Now we are wrapping it all up by connecting the navigation to functions, so that we can link it to our game in the making.

Follow this link here to the end of the article where the full code is.

For a change, I did not do any refactoring of the code in between articles, so there is nothing to figure out. Sorry for that by the way, but I teach myself how to write it, as much as then tell you about it ðŸ˜‰

To start us off, we shall do one very important addition to `GameMenu.__init__()`. We will add a `funcs` argument to it. This will be a dictionary of strings to functions.

```class GameMenu():
def __init__(self, screen, items, funcs, bg_color=BLACK, font=None, font_size=30,
font_color=WHITE):

...

self.funcs = funcs
```

As a consequence, we now need to define a new dictionary with respective functions in our `if __name__ == '__main__:` block. As you can see, the strings correspond to the names of our menu items and I chose to just do a simple ‘Hello World!’ print out. To avoid errors, you could use dict.keys() as the list to be passed in as menu items, but in most cases the resultant unordered list, does not give the order that you want. You could try it and see, otherwise you may need to type it out manually.

```if __name__ == "__main__":
def hello_world():
print "Hello World!"

# Creating the screen
screen = pygame.display.set_mode((640, 480), 0, 32)

funcs = {'Start': hello_world,
'Quit': sys.exit}

pygame.display.set_caption('Game Menu')
gm = GameMenu(screen, funcs.keys(), funcs)
gm.run()
```

That was all nice and easy, now let’s keep it that way and connect up the keyboard to these functions.

```                if event.type == pygame.KEYDOWN:
self.mouse_is_visible = False
self.set_keyboard_selection(event.key)
# Finally check if Enter or Space is pressed
if event.key == pygame.K_SPACE or event.key == pygame.K_RETURN:
text = self.items[self.cur_item].text
mainloop = False
self.funcs[text]()
```

The first three lines, we already know, but the rest not so much. So finally we check if either the Space Key or the Return key is pressed. If that is the case, we get the text of the menu item via its attribute, terminate the mainloop (We don’t want to have several main loops running at the same time, do we?) and eventually call the function.

Now we do the exact same for the mouse.

```                if event.type == pygame.MOUSEBUTTONDOWN:
mpos = pygame.mouse.get_pos()
for item in self.items:
if item.is_mouse_selection(mpos):
mainloop = False
self.funcs[item.text]()
```

This is essentially the same thing. We check if a mouse button was pressed (we make no distinction between left or right here. Why bother?), get the cursor coordinates and then we check if the cursor was on top of one of the menu items. If so, we again, terminate the mainloop and call the function associated to the menu item.
To avoid an extra call to `pygame.mouse.get_pos()`, you could move that call to the beginning of the mainloop as it is now used twice. If you are a purist that is. I did it in the final code, but left it in here for the sake of clarity.

And that is it! Nothing more to it and we have now successfully written a simple Game menu for any odd game. I hope it is flexible enough for you to play around with it. You can change the effect on mark up very easily and a change to the background should not be a problem either.

If you want to adjust this code and publish it, you are free to do so, but please mention me as the original source and also put a link in the comments here so that I have access to it, too. Thanks a lot, folks ðŸ™‚

NOTE: After using this class for a bit now, I have come to notice that instead of calling the function directly from the Menu, returning a fitting value (such as the text of the option) to a Main class is more advantageous and cleaner in the long run. To do that, just remove the `funcs` parameter from GameMenu and instead of calling the function on choosing just return the text itself. If you got questions feel free to comment and I will try to answer.

————————–
Here’s the full code

```#!/usr/bin/python

import sys
import pygame

pygame.init()

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

class MenuItem(pygame.font.Font):
def __init__(self, text, font=None, font_size=30,
font_color=WHITE, (pos_x, pos_y)=(0, 0)):

pygame.font.Font.__init__(self, font, font_size)
self.text = text
self.font_size = font_size
self.font_color = font_color
self.label = self.render(self.text, 1, self.font_color)
self.width = self.label.get_rect().width
self.height = self.label.get_rect().height
self.dimensions = (self.width, self.height)
self.pos_x = pos_x
self.pos_y = pos_y
self.position = pos_x, pos_y

def is_mouse_selection(self, (posx, posy)):
if (posx >= self.pos_x and posx <= self.pos_x + self.width) and \
(posy >= self.pos_y and posy <= self.pos_y + self.height):
return True
return False

def set_position(self, x, y):
self.position = (x, y)
self.pos_x = x
self.pos_y = y

def set_font_color(self, rgb_tuple):
self.font_color = rgb_tuple
self.label = self.render(self.text, 1, self.font_color)

class GameMenu():
def __init__(self, screen, items, funcs, bg_color=BLACK, font=None, font_size=30,
font_color=WHITE):
self.screen = screen
self.scr_width = self.screen.get_rect().width
self.scr_height = self.screen.get_rect().height

self.bg_color = bg_color
self.clock = pygame.time.Clock()

self.funcs = funcs
self.items = []
for index, item in enumerate(items):
menu_item = MenuItem(item, font, font_size, font_color)

# t_h: total height of text block
t_h = len(items) * menu_item.height
pos_x = (self.scr_width / 2) - (menu_item.width / 2)
# This line includes a bug fix by Ariel (Thanks!)
# Please check the comments section of pt. 2 for an explanation
pos_y = (self.scr_height / 2) â€“ (t_h / 2) + ((index*2) + index * menu_item.height)

menu_item.set_position(pos_x, pos_y)
self.items.append(menu_item)

self.mouse_is_visible = True
self.cur_item = None

def set_mouse_visibility(self):
if self.mouse_is_visible:
pygame.mouse.set_visible(True)
else:
pygame.mouse.set_visible(False)

def set_keyboard_selection(self, key):
"""
Marks the MenuItem chosen via up and down keys.
"""
for item in self.items:
# Return all to neutral
item.set_italic(False)
item.set_font_color(WHITE)

if self.cur_item is None:
self.cur_item = 0
else:
# Find the chosen item
if key == pygame.K_UP and \
self.cur_item > 0:
self.cur_item -= 1
elif key == pygame.K_UP and \
self.cur_item == 0:
self.cur_item = len(self.items) - 1
elif key == pygame.K_DOWN and \
self.cur_item < len(self.items) - 1:
self.cur_item += 1
elif key == pygame.K_DOWN and \
self.cur_item == len(self.items) - 1:
self.cur_item = 0

self.items[self.cur_item].set_italic(True)
self.items[self.cur_item].set_font_color(RED)

# Finally check if Enter or Space is pressed
if key == pygame.K_SPACE or key == pygame.K_RETURN:
text = self.items[self.cur_item].text
self.funcs[text]()

def set_mouse_selection(self, item, mpos):
"""Marks the MenuItem the mouse cursor hovers on."""
if item.is_mouse_selection(mpos):
item.set_font_color(RED)
item.set_italic(True)
else:
item.set_font_color(WHITE)
item.set_italic(False)

def run(self):
mainloop = True
while mainloop:
# Limit frame speed to 50 FPS
self.clock.tick(50)

mpos = pygame.mouse.get_pos()

for event in pygame.event.get():
if event.type == pygame.QUIT:
mainloop = False
if event.type == pygame.KEYDOWN:
self.mouse_is_visible = False
self.set_keyboard_selection(event.key)
if event.type == pygame.MOUSEBUTTONDOWN:
for item in self.items:
if item.is_mouse_selection(mpos):
self.funcs[item.text]()

if pygame.mouse.get_rel() != (0, 0):
self.mouse_is_visible = True
self.cur_item = None

self.set_mouse_visibility()

# Redraw the background
self.screen.fill(self.bg_color)

for item in self.items:
if self.mouse_is_visible:
self.set_mouse_selection(item, mpos)
self.screen.blit(item.label, item.position)

pygame.display.flip()

if __name__ == "__main__":
def hello_world():
print "Hello World!"

# Creating the screen
screen = pygame.display.set_mode((640, 480), 0, 32)

menu_items = ('Start', 'Quit')
funcs = {'Start': hello_world,
'Quit': sys.exit}

pygame.display.set_caption('Game Menu')
gm = GameMenu(screen, funcs.keys(), funcs)
gm.run()
```

# Create a simple game menu with pygame pt. 3 â€“ Recognising the keyboard

Please note that I used python 2.7 for this tutorial. If you are using python3.x, this code may not work. I have adapted this tutorial to Python3 in this blogpost.

Hello and welcome back for the third part of my little mini tutorial series where I first teach myself how to write a game menu with pygame and then live to tell the tale in little articles such as this one ðŸ˜› . Last time we looked at the mouse and how to recognise when the cursor hovers over one of our menu items. We then implemented an effect that showed us what the cursor is currently recognising.

If you are just interested in the full code after this tutorial, then follow this link.

This time round, we shall do such a navigation also for the keyboard. Again, like last time, I took the time to compartmentalise some code into methods to make it all more readable, such as the introduction of a `MenuItem` method called `is_mouse_selection()` or `GameMenu`‘s `set_mouse_selection()` method. In both cases, the code did not change, all we did was tidy up a little.

Here’s the code and try to find the sections in the code that you have so far that correspond to these snippets.

In MenuItem:

```    def is_mouse_selection(self, (posx, posy)):
if (posx >= self.pos_x and posx <= self.pos_x + self.width) and \
(posy >= self.pos_y and posy <= self.pos_y + self.height):
return True
return False
```

In GameMenu:

```    def set_mouse_selection(self, item, mpos):
"""Marks the MenuItem the mouse cursor hovers on."""
if item.is_mouse_selection(mpos):
item.set_font_color(RED)
item.set_italic(True)
else:
item.set_font_color(WHITE)
item.set_italic(False)
```

But let’s delve into this section properly. One of the first things, I thought about was trying to solve the riddle of what to do when the mouse cursor hovers over one menu item, while the user tries to navigate with the keyboard. Obviously, he doesn’t want to constantly return to the mouse selection. Thus, we need to recognise that a keyboard key was used and when that is the case we make sure the mouse stops working and disappears from sight.
So first, we make sure that the keyboard keys are recognised by adding the following line to the event loop.

```                if event.type == pygame.KEYDOWN:
```

Let’s first make the mouse cursor disappear on usage of the keyboard. For this purpose we shall introduce a new variable to the `GameMenu` init, `self.mouse_is_visible` and place it in the if clause above, and then create a method that regularly checks if the mouse should be visible or not.

```    def set_mouse_visibility(self):
if self.mouse_is_visible:
pygame.mouse.set_visible(True)
else:
pygame.mouse.set_visible(False)
```

Then call this method inside the mainloop after the `pygame.event` loop but before `self.screen.fill(self.bg_color)`. Obviously the reason for that is that all graphical operations should come last, but we still want to call this method after modifications made to the variable `self.mouse_is_visible`.

To prevent the mouse highlighting to interfere with the keyboard, we now only need to do one more thing. We need to use our previously defined variable in order to let the code only run self.set_mouse_selection() if the cursor is visible. Therefore we modify our pre-existing code like so:

```            for item in self.items:
if self.mouse_is_visible:
self.set_mouse_selection(item, mpos)
self.screen.blit(item.label, item.position)
```

This is all nice and well, the moment we touch a keyboard, our cursor will disappear. It is, however, not much use, if we can’t get it back. I figured, it is best to get it back, when we move the mouse. To recognise this, pygame provides a nice little function called `pygame.mouse.get_rel()` that gives the relative change of the mouse coordinates since the last check. In this case, we’re not interested in that, only that it “has” moved, not by how much. Therefore, a nice little check just before the call to `self.set_mouse_visibility()` in the mainloop, will do that trick.

```            if pygame.mouse.get_rel() != (0, 0):
self.mouse_is_visible = True
```

Ok, now, we press the key on the keyboard and the mouse disappears and once we move the mouse again, it re-appears. Great! Now all that is left for us to do, is get the navigation with the keyboard’s up and down arrow buttons working.
For this purpose, we need to play around with the index of `GameMenu`‘s `self.items` index. We’ll now create a new attribute in the `GameMenu.__init__`, called `self.cur_item` and set it to `None`. You will see in a second why `None` and not 0, for example.

Re-visit now our pygame event loop, in particular the section that recognises the keyboard input and add a call to a new method to it.

```                if event.type == pygame.KEYDOWN:
self.mouse_is_visible = False
self.set_keyboard_selection(event.key)
```

We shall now use this method to define our keyboard navigation. It is a couple of lines of code, but it is pretty easy. Check out the code, which is a method of the `GameMenu` class, obviously.

```    def set_keyboard_selection(self, key):
"""
Marks the MenuItem chosen via up and down keys.
"""
for item in self.items:
# Return all to neutral
item.set_italic(False)
item.set_font_color(WHITE)

if self.cur_item is None:
self.cur_item = 0
else:
# Find the chosen item
if key == pygame.K_UP and \
self.cur_item > 0:
self.cur_item -= 1
elif key == pygame.K_UP and \
self.cur_item == 0:
self.cur_item = len(self.items) - 1
elif key == pygame.K_DOWN and \
self.cur_item < len(self.items) - 1:
self.cur_item += 1
elif key == pygame.K_DOWN and \
self.cur_item == len(self.items) - 1:
self.cur_item = 0

self.items[self.cur_item].set_italic(True)
self.items[self.cur_item].set_font_color(RED)
```

Bear with me on this one and I shall go through each section with you.

```        if self.cur_item is None:
self.cur_item = 0
```

This one is the easy part. Remember, I said, I would explain why I chose `None`? If `self.cur_item` is `None`, I know that we switched from mouse to keyboard. As a consequence, I will start at index 0 and everything is peachy. No confusing mark-up. Once I use the mouse again, I will put `self.cur_item` back to `None`, just to have reliable behaviour. It’s not rocket science or particularly clever even, it just helps me keep track.

```        else:
# Find the chosen item
if key == pygame.K_UP and \
self.cur_item > 0:
self.cur_item -= 1
elif key == pygame.K_UP and \
self.cur_item == 0:
self.cur_item = len(self.items) - 1
elif key == pygame.K_DOWN and \
self.cur_item < len(self.items) - 1:
self.cur_item += 1
elif key == pygame.K_DOWN and \
self.cur_item == len(self.items) - 1:
self.cur_item = 0
```

This is the largest section, but it really is very easy. Let me write it out in words what happens here:

• If item not top item in the list and UP is pressed, move selection up one item
• If item is top item in the list and UP is pressed, select the last item on the list.
• If item not bottom item in the list and DOWN is pressed, move selection down one item
• If item is bottom item in the list and DOWN is pressed, select the first item on the list.

Simple, huh?

```        self.items[self.cur_item].set_italic(True)
self.items[self.cur_item].set_font_color(RED)
```

You have seen something similar before with the mouse selection and again it is to highlight your selection accordingly.

Finally, I have kept the first lines of code for last. That is, because I actually wrote them last ;).

```        for item in self.items:
# Return all to neutral
item.set_italic(False)
item.set_font_color(WHITE)
```

As the comment mentions, here, we are just returning all items to neutral, so that we can mark up the new selection. Nothing much to it, really.

And this is it. We have now a Game Menu in which we can navigate without much problem using either mouse or keyboard. Cool, huh? Next time, we will connect them up to functions that “may” trigger the next step in the game or such as in our case simple print functions. We have managed to do the hard part, the last part is easy in comparison.

I hope you enjoyed it. Till next time! ðŸ™‚

————————————————
Here’s the full code after this tutorial

```#!/usr/bin/python

import pygame

pygame.init()

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

class MenuItem(pygame.font.Font):
def __init__(self, text, font=None, font_size=30,
font_color=WHITE, (pos_x, pos_y)=(0, 0)):
pygame.font.Font.__init__(self, font, font_size)
self.text = text
self.font_size = font_size
self.font_color = font_color
self.label = self.render(self.text, 1, self.font_color)
self.width = self.label.get_rect().width
self.height = self.label.get_rect().height
self.dimensions = (self.width, self.height)
self.pos_x = pos_x
self.pos_y = pos_y
self.position = pos_x, pos_y
self.is_selected = False

def set_position(self, x, y):
self.position = (x, y)
self.pos_x = x
self.pos_y = y

def set_font_color(self, rgb_tuple):
self.font_color = rgb_tuple
self.label = self.render(self.text, 1, self.font_color)

def is_mouse_selection(self, (posx, posy)):
if (posx >= self.pos_x and posx <= self.pos_x + self.width) and \
(posy >= self.pos_y and posy <= self.pos_y + self.height):
return True
return False

class GameMenu():
def __init__(self, screen, items, bg_color=BLACK, font=None, font_size=30,
font_color=WHITE):
self.screen = screen
self.scr_width = self.screen.get_rect().width
self.scr_height = self.screen.get_rect().height

self.bg_color = bg_color
self.clock = pygame.time.Clock()

self.items = []
for index, item in enumerate(items):
menu_item = MenuItem(item, font, font_size, font_color)#, '/home/nebelhom/.fonts/SHOWG.TTF')

# t_h: total height of text block
t_h = len(items) * menu_item.height
pos_x = (self.scr_width / 2) - (menu_item.width / 2)
# This line includes a bug fix by Ariel (Thanks!)
# Please check the comments section of pt. 2 for an explanation
pos_y = (self.scr_height / 2) â€“ (t_h / 2) + ((index*2) + index * menu_item.height)

menu_item.set_position(pos_x, pos_y)
self.items.append(menu_item)

self.mouse_is_visible = True
self.cur_item = None

def set_mouse_visibility(self):
if self.mouse_is_visible:
pygame.mouse.set_visible(True)
else:
pygame.mouse.set_visible(False)

def set_item_selection(self, key):
"""
Marks the MenuItem chosen via up and down keys.
"""
for item in self.items:
# Return all to neutral
item.set_italic(False)
item.set_font_color(WHITE)

if self.cur_item is None:
self.cur_item = 0
else:
# Find the chosen item
if key == pygame.K_UP and \
self.cur_item > 0:
self.cur_item -= 1
elif key == pygame.K_UP and \
self.cur_item == 0:
self.cur_item = len(self.items) - 1
elif key == pygame.K_DOWN and \
self.cur_item < len(self.items) - 1:
self.cur_item += 1
elif key == pygame.K_DOWN and \
self.cur_item == len(self.items) - 1:
self.cur_item = 0

self.items[self.cur_item].set_italic(True)
self.items[self.cur_item].set_font_color(RED)

def set_mouse_selection(self, item, mpos):
"""Marks the MenuItem the mouse cursor hovers on."""
if item.is_mouse_selection(mpos):
item.set_font_color(RED)
item.set_italic(True)
else:
item.set_font_color(WHITE)
item.set_italic(False)

def run(self):
mainloop = True
while mainloop:
# Limit frame speed to 50 FPS
self.clock.tick(50)

for event in pygame.event.get():
if event.type == pygame.QUIT:
mainloop = False
if event.type == pygame.KEYDOWN:
self.mouse_is_visible = False
self.set_item_selection(event.key)

if pygame.mouse.get_rel() != (0, 0):
self.mouse_is_visible = True
self.cur_item = None

self.set_mouse_visibility()

# Redraw the background
self.screen.fill(self.bg_color)

for item in self.items:
if self.mouse_is_visible:
mpos = pygame.mouse.get_pos()
self.set_mouse_selection(item, mpos)
self.screen.blit(item.label, item.position)

pygame.display.flip()

if __name__ == "__main__":
# Creating the screen
screen = pygame.display.set_mode((640, 480), 0, 32)

menu_items = ('Start', 'Setting', 'Quit')

pygame.display.set_caption('Game Menu')
gm = GameMenu(screen, menu_items)
gm.run()
```

# Create a simple game menu with pygame pt. 2 â€“ Recognising the mouse

Please note that I used python 2.7 for this tutorial. If you are using python3.x, this code may not work. I have adapted this tutorial to Python3 in this blog post.

Ok, folks it’s been awhile since I wrote my first part of Games Menu tutorial with pygame, but serendipity didn’t kiss me since then. I am trying to make up for this with the second part of my tutorial. We will cover the recognition of mouse movement. Again, like last time, the entire code is at the end of this blog entry.

The last time, we wrote the options we wanted to the screen and centred them. We used a list of list to do this. Today, we will start off by changing this list of list for a list of objects (MenuItems). This makes the entire thing easier to handle and clearer.

So just add this piece of code in between your imports and the `GameMenu` class.

```class MenuItem(pygame.font.Font):
def __init__(self, text, font=None, font_size=30,
font_color=(255, 255, 255), (pos_x, pos_y)=(0, 0)):
pygame.font.Font.__init__(self, font, font_size)
self.text = text
self.font_size = font_size
self.font_color = font_color
self.label = self.render(self.text, 1, self.font_color)
self.width = self.label.get_rect().width
self.height = self.label.get_rect().height
self.pos_x = pos_x
self.pos_y = pos_y
self.position = pos_x, pos_y

def set_position(self, x, y):
self.position = (x, y)
self.pos_x = x
self.pos_y = y
```

and replace this section:

```        for index, item in enumerate(items):
label = self.font.render(item, 1, font_color)

width = label.get_rect().width
height = label.get_rect().height

posx = (self.scr_width / 2) - (width / 2)
# t_h: total height of text block
t_h = len(items) * height
posy = (self.scr_height / 2) - (t_h / 2) + (index * height)

self.items.append([item, label, (width, height), (posx, posy)])
```

for the following

```        for index, item in enumerate(items):
menu_item = MenuItem(item)

# t_h: total height of text block
t_h = len(items) * menu_item.height
pos_x = (self.scr_width / 2) - (menu_item.width / 2)
# This line includes a bug fix by Ariel (Thanks!)
# Please check the comments section for an explanation
pos_y = (self.scr_height / 2) - (t_h / 2) + ((index * 2) + index * menu_item.height)

menu_item.set_position(pos_x, pos_y)
self.items.append(menu_item)
```

and finally in the `while mainloop:` loop

```            for name, label, (width, height), (posx, posy) in self.items:
self.screen.blit(label, (posx, posy))
```

for

```            for item in self.items:
self.screen.blit(item.label, item.position)
```

Please have a look at what has been exchanged and you will find that it is essentially still all the same. All I did, was move all the info for the `Font` class into a separate class called `MenuItem`.
If you have questions about this change, please leave a comment with the sections, that need clarification.

The next point will be the recognition of whether the mouse pointer hovers over one of our menu items or not. To do this all we need to is figure out if the position of the mouse is within the boundaries. To this end, we will introduce a new method to our `MenuItem` class, called `is_mouse_selection()`.

```    def is_mouse_selection(self, (posx, posy)):
if (posx >= self.pos_x and posx <= self.pos_x + self.width) and \
(posy >= self.pos_y and posy <= self.pos_y + self.height):
return True
return False
```

This may look like much, but essentially we are just asking if mouse coordinates x and y are between the left and right border and the top and bottom border of `MenuItem`, respectively.

Furthermore, we obviously want something to happen, so that we know that something has been selected. This can be anything you want. I chose to change the color of the font. This is quite easy. We just need to write a short setter method and append it to the `MenuItem` class once more.

```    def set_font_color(self, rgb_tuple):
self.font_color = rgb_tuple
self.label = self.render(self.text, 1, self.font_color)
```

I hope you can see by now, why I chose to go away from a list of values to an actual object. It makes it all this little bit easier ðŸ˜‰ Now we only need to put this all together and see the great effect. I chose red as a color and for the fun of it on selection, I let the font be italic, too. This section is put into the `while mainloop` loop. I am sure you can figure out in which section (Otherwise, see below)

```            for item in self.items:
if item.is_mouse_selection(pygame.mouse.get_pos()):
item.set_font_color((255, 0, 0))
item.set_italic(True)
self.screen.blit(item.label, item.position)
```

If you have tried this out, you will have sure noticed that once you hovered over an item it will stay red and italic. That’s not really what we want, right? We obviously have to return to neutral, too.

```                else:
item.set_font_color((255, 255, 255))
item.set_italic(False)
```

And there you go! We now recognise the menu items by mouse ðŸ™‚ Simple, isn’t it.

——————————————–
The entire code:

```#!/usr/bin/python

import pygame

pygame.init()

class MenuItem(pygame.font.Font):
def __init__(self, text, font=None, font_size=30,
font_color=(255, 255, 255), (pos_x, pos_y)=(0, 0)):
pygame.font.Font.__init__(self, font, font_size)
self.text = text
self.font_size = font_size
self.font_color = font_color
self.label = self.render(self.text, 1, self.font_color)
self.width = self.label.get_rect().width
self.height = self.label.get_rect().height
self.dimensions = (self.width, self.height)
self.pos_x = pos_x
self.pos_y = pos_y
self.position = pos_x, pos_y

def set_position(self, x, y):
self.position = (x, y)
self.pos_x = x
self.pos_y = y

def set_font_color(self, rgb_tuple):
self.font_color = rgb_tuple
self.label = self.render(self.text, 1, self.font_color)

def is_mouse_selection(self, (posx, posy)):
if (posx >= self.pos_x and posx <= self.pos_x + self.width) and \
(posy >= self.pos_y and posy <= self.pos_y + self.height):
return True
return False

class GameMenu():
def __init__(self, screen, items, bg_color=(0,0,0), font=None, font_size=30,
font_color=(255, 255, 255)):
self.screen = screen
self.scr_width = self.screen.get_rect().width
self.scr_height = self.screen.get_rect().height

self.bg_color = bg_color
self.clock = pygame.time.Clock()

self.items = []
for index, item in enumerate(items):
menu_item = MenuItem(item)#, '/home/nebelhom/.fonts/SHOWG.TTF')

# t_h: total height of text block
t_h = len(items) * menu_item.height
pos_x = (self.scr_width / 2) - (menu_item.width / 2)
# This line includes a bug fix by Ariel (Thanks!)
# Please check the comments section for an explanation
pos_y = (self.scr_height / 2) - (t_h / 2) + ((index * 2) + index * menu_item.height)

menu_item.set_position(pos_x, pos_y)
self.items.append(menu_item)

def run(self):
mainloop = True
while mainloop:
# Limit frame speed to 50 FPS
self.clock.tick(50)

for event in pygame.event.get():
if event.type == pygame.QUIT:
mainloop = False

# Redraw the background
self.screen.fill(self.bg_color)

for item in self.items:
if item.is_mouse_selection(pygame.mouse.get_pos()):
item.set_font_color((255, 0, 0))
item.set_italic(True)
else:
item.set_font_color((255, 255, 255))
item.set_italic(False)
self.screen.blit(item.label, item.position)

pygame.display.flip()

if __name__ == "__main__":
# Creating the screen
screen = pygame.display.set_mode((640, 480), 0, 32)

menu_items = ('Start', 'Quit')

pygame.display.set_caption('Game Menu')
gm = GameMenu(screen, menu_items)
gm.run()
```

# Create a simple game menu with pygame pt. 1 – Writing the menu options to the screen

Please note that I used python 2.7 for this tutorial. If you are using python3.x, this code may not work. I have adapted this tutorial to Python3 in this blog here.

On my quest to write my own game using the pygame library, I noticed that there is not a single tutorial on how to write your own Game Menu interface. There are two separate modules (python-pygame-menu and KezMenu) that allow you to create a menu, but I wanted to have a learning curve and decided to write it myself.

I share my solution in an attempt to get the ball rolling again. I am aware that my solution may not be elegant in places (or in fact good code), but this is what I came up with. If you think you can do better, write your own tutorial and link it in the comments, I am more than happy to read it and learn a thing or two. This is my first tutorial of any kind, so hopefully I can give it a nice structure. Ok, enough waffling, let’s hit it!

### Tutorial

First things first. I will assume that you are familiar with python and with pygame. If not, best come back when you worked through a bunch of basic tutorials (Sorry for the link. I had to :D).

Â

For those of you who learn best by reading code, the entire code for this segment is given below.

We shall start by setting the basic scene, i.e. create a black window that doesn’t terminate due to an endless loop. You will hopefully have seen all this already in some of the pygame beginner’s tutorials.

```#!/usr/bin/python

import pygame

pygame.init()

class GameMenu():
def __init__(self, screen, bg_color=(0,0,0)):

self.screen = screen
self.bg_color = bg_color
self.clock = pygame.time.Clock()

def run(self):
mainloop = True
while mainloop:
# Limit frame speed to 50 FPS
self.clock.tick(50)

for event in pygame.event.get():
if event.type == pygame.QUIT:
mainloop = False

# Redraw the background
self.screen.fill(self.bg_color)
pygame.display.flip()

if __name__ == "__main__":
# Creating the screen
screen = pygame.display.set_mode((640, 480), 0, 32)
pygame.display.set_caption('Game Menu')
gm = GameMenu(screen)
gm.run()
```

This is our starting point, from there we need to think, what we actually need in a bog standard Game Menu. Generally, there are options such as Start, Settings and Quit. In order to do that, we will need to make them appear on the screen. For this, we shall use the pygame’s Font module.

So, we define a tuple of strings (here Start and Quit) that should be in the menu. We shall do this in the “if __name__ …” block before the definition of the gm variable. Other conceivable options could be Settings or Highscore, for example.
Of course, we shall then pass this to the GameMenu class.

```class GameMenu():
def __init__(self, screen, items, bg_color=(0,0,0)):

...
self.items = items

...
if __name__ == '__main__':
...
menu_items = ('Start', 'Quit')
...
gm = GameMenu(screen, menu_items)
```

Now that this is settled, we can finally use the pygame.font module to do what we came here for. So, let’s get to it, to add flexibility, I will give the user the option to define a font, the font colour and a font size, but set it to a default.

```class GameMenu():
def __init__(self, screen, items, bg_color=(0,0,0), font=None, font_size=30,
font_color=(255, 255, 255)):

...
self.font = pygame.font.SysFont(font, font_size)
self.font_color = font_color
```

Now let’s get to the part, where we make it appear on screen. For this, we need to make use of the font module’s `render()` method. Let’s just do this in a line below `self.font_color`.

```class GameMenu():
def __init__(self, screen, items, bg_color=(0,0,0), font=None, font_size=30,
font_color=(255, 255, 255)):

...
self.items = []
for item in items:
label = self.font.render(item, 1, font_color)
self.items.append(label)
```

Now in order to get these texts to the screen, we need the `blit()` method. Let’s try that.

```class GameMenu():
...
def run(self):
mainloop = True
while mainloop:
...
# Redraw the background
self.screen.fill(self.bg_color)

for label in self.items:
self.screen.blit(label, (100, 100))

pygame.display.flip()
```

I am sure, you have already spotted the problem. All the texts are rendered to the same spot. We do want them centred in all aspects. This requires a little maths and the dimensions of the `self.screen` and of the rendered `Font` objects. As you may have already guessed, we will make use of the `get_rect()` method to obtain both width and height. The rest, I am sure, you will figure out for yourselves.
To store all these values in place, we shall use a list of lists. I found it good practice to store general values such as name and dimensions, because I very often noticed that I needed them later, anyway. In addition, adding the string of the `Font` object is very useful for debugging.

```class GameMenu():
def __init__(self, screen, items, bg_color=(0,0,0), font=None, font_size=30,
font_color=(255, 255, 255)):
self.screen = screen
self.scr_width = self.screen.get_rect().width
self.scr_height = self.screen.get_rect().height

...

self.items = []
for index, item in enumerate(items):
label = self.font.render(item, 1, font_color)

width = label.get_rect().width
height = label.get_rect().height

posx = (self.scr_width / 2) - (width / 2)
# t_h: total height of text block
t_h = len(items) * height
posy = (self.scr_height / 2) - (t_h / 2) + (index * height)

self.items.append(item, [label, (width, height), (posx, posy)])
```

Now, before this works, we need to, of course, readjust our `blit()` method.

```class GameMenu():
...
def run(self):
mainloop = True
while mainloop:
...
for name, label, (width, height), (posx, posy) in self.items:
self.screen.blit(label, (posx, posy))
```

And now, we successfully brought our two menu options to the screen. In the next part of this tutorial series, I will implement how to recognise the mouse cursor and highlight the choice.

I hope this section was helpful. If you have any comments, suggestions or improvements, please feel free to comment below. I am always happy to hear constructive criticism.

——————————————————

Here’s the entire code:

```#!/usr/bin/python

import pygame

pygame.init()

class GameMenu():
def __init__(self, screen, items, bg_color=(0,0,0), font=None, font_size=30,
font_color=(255, 255, 255)):
self.screen = screen
self.scr_width = self.screen.get_rect().width
self.scr_height = self.screen.get_rect().height

self.bg_color = bg_color
self.clock = pygame.time.Clock()

self.items = items
self.font = pygame.font.SysFont(font, font_size)
self.font_color = font_color

self.items = []
for index, item in enumerate(items):
label = self.font.render(item, 1, font_color)

width = label.get_rect().width
height = label.get_rect().height

posx = (self.scr_width / 2) - (width / 2)
# t_h: total height of text block
t_h = len(items) * height
posy = (self.scr_height / 2) - (t_h / 2) + (index * height)

self.items.append([item, label, (width, height), (posx, posy)])

def run(self):
mainloop = True
while mainloop:
# Limit frame speed to 50 FPS
self.clock.tick(50)

for event in pygame.event.get():
if event.type == pygame.QUIT:
mainloop = False

# Redraw the background
self.screen.fill(self.bg_color)

for name, label, (width, height), (posx, posy) in self.items:
self.screen.blit(label, (posx, posy))

pygame.display.flip()

if __name__ == "__main__":
# Creating the screen
screen = pygame.display.set_mode((640, 480), 0, 32)

menu_items = ('Start', 'Quit')

pygame.display.set_caption('Game Menu')
gm = GameMenu(screen, menu_items)
gm.run()
```

# Writing a basic Vocabulary Trainer in 30 minutes with Python

(Original post from 31. May 2012)

Below is a vocabulary trainer for my effort of improving my French. It took me about 30 minutes to write and another 30 minutes with some good music on the headphones to write the relevant XML structure. I will probably try to expand this list as I read books and articles etc.

To start, you just need to call it from command line with the correct parameters. For example to test general vocabulary with English as the given language and French as the one to be tested you would need to type in (this is for linux):

```./main.py general en fr

#!usr/bin/env python
# -*- coding: iso-8859-1 -*-

import random
import string
import sys

from lxml import etree

vocab = {'chem': 'chemvocab.xml',
'general': 'general.xml'}

def load_xml2dict(fname, lang1, lang2):
"""Load xml data from file into dict depending on flag"""

d = {}
with open(fname) as xml:
tree = etree.parse(xml)
root = tree.getroot()

for elem in root:
l1 = []
l2 = []
for child in elem:
if child.tag == lang1:
l1.append(child.text)
elif child.tag == lang2:
l2.append(child.text)
d[tuple(l1)] = l2
return d

def main(fname, lang1, lang2):
d = load_xml2dict(fname, lang1, lang2)

while True:
choice = random.choice(d.keys())
print '[%s]: %s' % (lang1.upper(), ', '.join(choice))
raw_input('Press Enter for the answer')
print '[%s]: %s' % (lang2.upper(), ', '.join(d[choice]))

end = raw_input('Do you want to continue Enter/N: ')
if end == "N" or end == "n":
break

if __name__ == "__main__":
args = sys.argv
main(vocab[args[1]], args[2], args[3])
```

The XML structure is fairly straightforward and is designed with possible expansion in mind and further filtering. It looks something like this:

```<vocabulary>
<word type="verb">
<en>to agree</en>
<de>jmdm./etw. zustimmen</de>
<de>in etw. einwilligen</de>
<fr>acquiescer Ã  qn./qc.</fr>
</word>
<word type="adj">
<en>horrible</en>
<de>schrecklich</de>
<de>fÃ¼rchterlich</de>
<fr>Ã©pouvantable</fr>
<fr>terrible</fr>
</word>
<word type="noun">
<en>murmur</en>
<de gender="n">Murmeln</de>
<fr gender="m">frÃ©missement</fr>
</word>
</vocabulary>
```

Note the type attribute for . It will hopefully allow me to filter by type of word. The gender attribute is only necessary for German and French and I only really put it in for French as there are cases where it is not clear, e.g. l’Ã©mission. If I really expand on this thing, I may use it to put the gender in square brackets after the word.

Of course, this is nothing to write home about, but maybe, I will expand it a little and create a GUI for it with some filtering options or abandon python altogether and put this on my website with some jquery. We shall see. I thought it was worth sharing.

# Using Gstreamer with wxPython – Two MainLoops and the Law of Delimiter

(Original post from 19. May 2012)

Yesterday, while writing on the new version of my super duper honking RPG MusicPlayer, I came across a very interesting problem. Interesting, because it made me learn new things about Python in particular and programming in general.

Gstreamer uses the `gobject.MainLoop()` to communicate events via messages to its playbin instance. The example below is directly from the tutorial. Note the bus instance and the on_message method. This all runs via the `gobject.MainLoop()`

```        # bus is used to report messages in playtime
# Taken from tutorial, also the methods
self.bus = self.player.get_bus()
self.bus.add_signal_watch()
self.bus.enable_sync_message_emission()
self.bus.connect("message", self.on_message)

def on_message(self, bus, message):
"""
Taken from gstreamer tutorial.
http://pygstdocs.berlios.de/pygst-tutorial

Used in:
- connects to bus in class.

"""

t = message.type
if t == gst.MESSAGE_EOS: # track is finished
self.player.set_state(gst.STATE_NULL)
elif t == gst.MESSAGE_ERROR:
self.player.set_state(gst.STATE_NULL)
err, debug = message.parse_error()
print "Error: %s" % err, debug
```

So far, I had no problems not running the `gobject.MainLoop`, because the `wx.App.MainLoop()` did all the necessary things to keep my songs running. But at one point, I noticed a bug. When the song came naturally to an end, it would just stop and not play the next song. This was, of course, due to the fact, that the End of Song Message never reached the Playbin, because there was no system to relay said message

At this point, I had the uncomfortable situation of needing two MainLoops to run at the same time. Yes, I know, I should have learned to use pyGTK instead of sticking with wxPython, but I like wxPython and I was lazy. Also, that way I learned loads more funky stuff

Anyways, so how to solve that problem… Well, I used Python’s threading module to help me out here. Without threading, I was not able to start both MainLoops at the same time, because of Python’s procedural nature. Because I had no idea about threading, I had several mishaps on the way, but I came up with a minimal example such as shown at the end. I had to look for awhile, because I found most “simple” threading tutorials a bit over the top for my liking, but taking little bits and bobs from everywhere, I was able to come up with a solution.

Most of it really is just syntactic sugar. The key part about this, is the `GobjectThread` class. This class starts the `MainLoop` in a separate thread and after the `wx.App.MainLoop` is finished, the thread is stopped, too. Luckily, I only have to start and stop the `gobject.MainLoop`. I can imagine, these sort of things can very quickly become very confusing and cluttered. The only other important thing to note in this code is the close event. It is important to set the Gstreamer elements to `gst.STATE_NULL`, otherwise there are several Critical Errors thrown, when terminating the MainLoop

Also, as a little side note, while discussing this in the German Python Forum, I was told about Delimiter’s Law. I very often have things like self.player.player.get_state(), which according to Delimiter’s Law is a big “NoNo!”. Essentially, when disregarding Delimiter, too closely knit classes are a consequence. This can make it hard to debug or replace certain parts of the code, because the other classes take too much of the original architecture for granted. Knowing this now, I have a lot more work ahead of me ðŸ™‚

```#!usr/bin/python

import os
import urllib
from threading import Thread

import wx
import pygst
pygst.require("0.10")
import gst
import gobject

class MyFrame(wx.Frame):
def __init__(self, *args, **kwds):
kwds["style"] = wx.DEFAULT_FRAME_STYLE
wx.Frame.__init__(self, *args, **kwds)

###############
## Threading ##
###############
self.player = GstPlayer()

# Close Event
self.Bind(wx.EVT_CLOSE, self.on_close)

self.__set_properties()
self.__do_layout()

def on_close(self, event):
# If state not set to NULL, Critical Error occurs on gobject quit
state = self.player.get_state()
if state[1] == gst.STATE_PLAYING:
self.player.set_state(gst.STATE_NULL)
self.Destroy()

def __set_properties(self):
self.SetTitle("Test")

def __do_layout(self):
self.Layout()

class GstPlayer():
def __init__(self):
# This is almost straight out of the tutorial
p = os.path.join(os.getcwd(), "tracks", "1. Shaent Blathanna.mp3")
path = urllib.pathname2url(p)

self.player = gst.element_factory_make("playbin2", "player")
fakesink = gst.element_factory_make("fakesink", "fakesink")
self.player.set_property("video-sink", fakesink)

self.player.set_property("uri", "file:" + path)
self.player.set_state(gst.STATE_PLAYING)

def get_state(self):
return self.player.get_state()

def set_state(self, state):
self.player.set_state(state)

class GobjectThread(Thread):
def __init__(self):
Thread.__init__(self)
##############################
self.loop = gobject.MainLoop() # The mainloop to be separated from wx
##############################

def run(self): # Called on Thread.start()
self.loop.run()

def quit(self):
# Stops the gobject Mainloop
self.loop.quit()

if __name__ == "__main__":
gobject.threads_init()

t = GobjectThread()
t.start()

# wxGlade's my Friend here
# Just basics
app = wx.PySimpleApp(0)
wx.InitAllImageHandlers()
frame = MyFrame(None, -1, "")
app.SetTopWindow(frame)
frame.Show()
app.MainLoop()

t.quit() #End the gobject.MainLoop()
```