Recently I bought a new (used) camera, the Canon 80D. I used to use a Nikon D3300, but it disappeared while moving. Anyway, this new one is quite a bit nicer. The most noticeable differences for me are a far better live view mode (useful when I’m taking pictures at awkward angles) with a moveable touch screen (compared to the D3300’s static non-touch screen), more AF points when using the OVF, and a higher maximum frequency for taking photos.
This was from the first time I went on an outing specifically to take pictures with this camera. I used the lens that came with it: the Canon EF-S 18-135mm f/3.5-5.6 IS USM. It’s in Trädgårdsföreningen, Göteborg. I think I got quite lucky with the weather on this day; some of the last warm sun we’ll have this year, I would guess.
The following three images are also taken in Trädgårdsföreningen, but on the next weekend. Mainly I was playing around with fast shutter speeds to try and capture the birds doing interesting things. The main challenge was trying to get the pictures to be sharp, which was difficult since I had to increase the ISO to make up for the shutter speed.
All of these photos are taken with the same 135mmm zoom lens mentioned above.
The duck above had just dived underwater and resurfaced. It’s quite cool seeing the water run off the hydrophobic feathers.
This duck was relaxing on a protruding wooden stake sticking out of the river, although I cropped the photo quite close to see how much detail I could see. I could have got a much better quality image here if I used a shutter speed closer to, say, 1/800s. 1/2000 meant that I had to use a very high ISO, which wasn’t ideal. Not sure why I did that…
I quite like this one, but there’s still a lot to improve on for next time. Opposite to the last photo, this one should have been shot with a significantly faster shutter to reduce the blur around his wings. I would have also liked to get a bit further down to the bird’s eye level. Partly this is just to get some more separation from the background.
Here are a couple of photos from a nice forest just a few minutes from my apartment. I took these yesterday, to experiment with a second-hand lens I bought: a Canon EF 50mm f1.8 STM.
This is the first prime lens I’ve ever used – that is, it has a fixed focal length. Another thing to note is that it’s an EF lens, which means it’s for full-frame cameras. My Canon 80D is not full-frame, which means that I only “see” a section cropped out from the middle of what the lens sees. This is both a good and bad thing, depending. This 50mm lens becomes effectively 80mm for this reason, which can be good or bad.
Since lenses tend to be sharper nearer the center, in theory I should get sharper results with this than using it on a full-frame camera. On the other hand, if the lens was just sharp enough to produce a sharp image on a full-frame sensor, then the fact that I’m zoomed in could reveal softness.
I was quite happy with this photo. Usually when I take photos of trees in scenes like this, the composition isn’t great and the picture looks boring. Here, the clearing between the foreground bushes and the background forest makes it a bit more interesting.
This is part of a hiking trail through the same woods as the previous photo. Everything looked very yellow here because it’s Autumn, and this particular type of long grass was everywhere in this boggy area of the route.
These wooden planks were for getting over those boggy areas, and in one part they have a long long path made of them which crosses a big reedy pond.
I’m not sure exactly what I think of this lens. In these two photos it was fine, but when I had the aperture very open (1.8-2.0) and had bright highlights, the lens was very prone to pink-coloured haze around these objects. This is something I can work around though, and I got the lens for a pretty good price, so I can’t complain :)
]]>I’m not sure where the game came from originally – probably it was based on some other game, but we added several of our own rules to it over time. I think it’s a little like Uno, conceptually, although I’ve never played Uno.
The aim of the game is to be the first to get rid of all of your cards.
In one turn you may play some cards according to the rules listed below. In a turn you can play a potentially large number of cards, and can also do things that cause other players to pick up new cards.
Each player is dealt cards from a shuffled deck, until there are no cards left.
Like most card games, the players should sit in a circle-like formation around a table.
An arbitrary player goes first. It doesn’t matter at all, but it’s common to pick whoever is to the left hand side of the dealer.
To begin with, turns proceed clockwise around the circle. Note that this direction can change later in the game.
At the start of your turn, first consider whether the last player’s turn caused you to pick up some cards. This can be the case if they ended their turn by playing a pick-up card (a 2 or a Jack). If you don’t, simply skip this step.
If you do have to pick up some cards, you can play an Ace to cancel this, thereafter playing your turn as usual as if starting normally with this Ace. Alternatively, you can play one or more other pick-up cards (following the normal rules of playing cards) to prevent picking up anything yourself, but adding to the amount of cards to pick up for the next player.
Failing either of these, you must pick up the correct number of cards. Your turn ends immediately after doing so.
This subsection describes the basic rules of playing cards. It ignores most special cases caused by playing power cards, which are described later.
To win the game, you have to get rid of all your cards so that you have an empty hand.
You cannot win by playing a power card as your final card. In this case, you have to pick up one new card.
Some cards act differently when played. They’re known as Power Cards. They are: Ace, 2, 3, 8, J, Q, K.
For each Power Card, the corresponding operation occurs at the moment that it’s played (during a turn). Some Power Cards have additional rules about when they may be played.
3h Ah Ac
as a turn.At the start of the game, there is no deck from which to draw new cards, since all of the cards are in the players’ hands. Of course, at some point, such a deck will be necessary, so that players can pick up cards when they are required to.
To facilitate this, it’s necessary to occasionally remove all but the top card of the play pile and shuffle it into the deck.
Still, there could be a situation where a player must pick up more cards than are in the deck and that are available to move into the deck from the play pile. In this case, you can either:
I can’t remember which option we used when we played. Probably 1, since 2 sounds like a hassle…
If I’m playing first in a game (i.e. the play pile is empty), then here are some simple turns which do not result in the player having to pick up any extra cards themselves.
Example 1. 9h (9 of hearts)
Example 2. 9h 9c 4c
Example 3. 9h 9c 3c 4c
Example 4. Js Jc Jh
And here are some examples which, due to not “capping off” the turn, the player must pick up one card from the deck after playing.
Example 5. ø (no cards played)
Example 6. 9h 9c
Here are some moves which utilise power cards, showing how different ones interact with
prior pick-up cards. In the following set of examples, the previous turn was 9c 9h Jh
,
hence three cards are to be picked up, and Jh
is at the top of discard
.
Example 7. ø <pick up three cards from deck>
Example 8. Ac
Example 9. Jc
Here’s an example of a particularly long turn.
Example 10. Ks Kc 6c 6h 6d 6s Qs 8h 8d 3d 4d 4h As Ac Ad Ah Jh Jd Jc Js
To clarify some points about example 10:
There are quite a few approaches for generating mazes algorithmically. I particularly like the graph based approaches, since they seem most adaptable. They are:
Maybe there are even more graph-based maze generation methods, but I don’t know about them. There are of course some non-graph-based methods, like iteratively splitting a space into randomised chunks and cutting holes in the new walls^{1}, or even using cellular automata^{2}, which are also interesting.
The reason I say that graph based approaches are most adaptable is because of their independence on any particular shape or structure. You’ll see what I mean by this later on.
First it might be a good idea to define what a maze is and isn’t. For example, consider this:
Imagine that the black lines are passageways that you can walk through. This definitely seems like a maze. Here are some properties of this specific maze:
The last of these is the most controversial of the three, since it’s very difficult to quantify how difficult a maze is. However, here are some features of good mazes that probably help:
Probably none of these features are necessary for something to be a maze, though. Loops are definitely possible in mazes, there’s no reason why not, and the only reason they’re not present in the above maze is because it is specifically a spanning tree of a graph. Mazes may in theory have disconnected sections, I suppose, but in that case it would really just be two (or more) mazes next to each other. Also, mazes don’t need to have a non-obvious solution – take the kids mazes on the backs of some ceral boxes, for example.
In fact, mazes don’t even need to have branches. Some hedge mazes^{3}, for instance, are just one long twisting path from start to finish. And should all mazes have a start and a finish? The maze presented above doesn’t have a specific start or finish, but the nature of it means that any two points on it can reasonably be chosen for these. I would say that a maze has to have a defined start and finish, or be constructed such that they can be chosen arbitrarily.
I think a reasonable definition for a maze is just “A passageway (or collection of passageways) connecting a start to a finish”. Then if our maze has starts and finishes that can be chosen arbitrarily, we basically have a set of mazes with the same construction but with different start and finish points. Anyway, this doesn’t matter.
The maze-generation algorithm I’m going to talk about now is depth-first search (DFS). This algorithm is used for many more useful purposes than generating mazes, but this is what I’ll use it for.
DFS takes a graph (a collection of nodes and edges between them) and a starting node, and, in a certain order, examines each of these. The reason it’s called “depth-first” is that it starts by traversing one path for as long as possible before going back to try another one. This is in contrast to breadth-first searching which, before examining any node which is n nodes away from the starting node, examines all those which are up to n-1 away.
This post isn’t meant to be a detailed depth-first search tutorial – you can easily find those anywhere on the internet. Even still, here’s some rough pseudocode for one iteration of the algorithm, as I implemented it for this purpose:
PROCEDURE dfs_step
INPUTS:
G: The graph to search
S: A stack data structure.
WHILE S is not empty
next = S.pop()
IF `next` has not yet been visited:
Visit `next`
FOR EACH edge IN `next`'s neighbours:
S.push(`edge`)
RETURN
This is slightly different to standard iterative DFS implementations, in that the procedure only executes one step, by which I mean it runs until it either exhausts the stack or a new node is visited. Normal implementations run until the entire graph has been visited.
The reason for this difference is that I wanted to display a realtime animation of the algorithm running, and this implementation allows me to periodically run a step (say, every half a second) and update the graphical representation accordingly, without the algorithm itself needing to know anything about this.
To summarise the pseudocode, we repeatedly pop nodes from the stack until we find one that we haven’t visited yet. Then, we “visit” it, push all of its neighbours to the stack, and return, i.e. end the procedure. A traditional DFS implementation won’t return at this point, as I mentioned earlier, and instead will repeat until there’s nothing left on the stack.
The meaning of “visiting” a node depends on what the DFS is meant to achieve. For example, another use of DFS is finding connected components within a graph. To do this, we can just begin a DFS at an arbitrary node, and efficiently find the connected component that contains it, then repeating the process on an unclassified node. In such a case, “visiting” a node would be adding it to a list of nodes in some structure representing the connected components of a graph.
What about generating a maze, though? If we run DFS on any graph and make a note of the order in which nodes are visited, we can construct a tree containing every node. Let’s run through a quick example.
The first image shows the plain graph which we’ll operate on. I generated this graph by randomly placing 20 nodes in a 500×500 unit space, and mutually connecting any two nodes which are closer than (or exactly) 150 units apart. The second image visualises the very first iteration of my DFS step procedure. It’s starting at the top-left node, where the orange and green lines are protruding from, which represent all of the node under consideration’s neighbours. The actual implementation pushes the edges such that the closest edge is at the top of the stack.
In the third image, in bold, the resulting spanning tree is shown. It may not look much like a maze at this point, but the point is we can run this on any graph, and certain graphs will yield better mazes. In fact, the big square maze presented earlier in this post was generated in the exact same way as this tree. The primary difference between these two, and all the other mazes I’ll make, are in the way the graph is generated initially, although I make a couple of extra modifications to the algorithm as well, for some.
A very standard type of maze is square-shaped, with horizontal and vertical passageways. I can very easily write a function to place nodes in a square grid, and join them to their correct neighbours. Then I can just feed this graph into the DFS algorithm, and…
Oh, it’s not a very good maze. Going back to my thoughts earlier about what makes a (good) maze,
we can see that this one has no cycles and no disconnected sections, like the earlier maze, but,
it’s very easy to solve this maze from any point A to any point B. In fact it’s trivial, because
this maze has no branches at all – it’s topologically equivalent to a straight line. Starting from
A, you can always get to B, regardless of where B is, by just trying each of the two opposite directions.
In fact this maze is even worse than just the general case of mazes topologically equivalent to
straight lines, because it has a consistent repeating zig-zag pattern going downwards, so if you
know the positions of A and B you can immediately know whether you have to travel up or down in space,
and hence work out if you need to start moving left or right. In other words, with this maze, it
would be possible to implement a function Node next_node(Node current_node, Node to_find)
that
runs in O(1) time, given that we can view the structure of the maze from above.
The reason that our algorithm generates a zig-zag maze here is just because we don’t involve any randomness yet. The procedural method by which we generated our graph appends neighbouring nodes to a list contained within each node, and this list is iterated in order when pushing to the stack in the DFS algorithm. The way that this list is generated means that neighbours are pushed in the order (up, down, left, right), and so if a right-facing neighbour is present, this will always be preferred (because it will be at the top of the stack at the start of the next iteration). This explains the intial long-as-possible right-facing path. It only stops moving right when it can’t anymore, because that neighbour is then not pushed to the stack.
The solution is simple though, we can just shuffle each node’s neighbour list at initialisation time. And this pattern has the added benefit that it’s adaptable to different patterns that we might want. For example, remember what I mentioned earlier about picking the neighbour closest to the current node, when we saw the DFS algorithm running on a more freeform graph layout? Well that behaviour doesn’t have to be impemented within DFS at all, keeping it more generalised. Instead we implement that in the same way as this neighbour shuffling, by sorting each node’s neighbours list by distance, specifically for graphs where we want this shortest-first behaviour.
Anyway, if we implement this neighbour shuffling, we get this:
This is significantly better. Now, we have lots of branching – this occurs when a search path gets to a point where it cannot go any deeper, so it pushes no neighbours for the next iteration and instead some neighbours that were pushed by an earlier iteration are taken instead.
This maze still isn’t ideal though. The branches, although many, are not, on average, very deep, which makes it easy to quickly disregard many of them when solving the maze. I think this is just because this particular maze is fairly small. If I generate a larger one, the branches become far longer.
It can be fun to fiddle with the code a bit to get some different interesting mazes. With our graph-based maze approach, there are a lot of options here, because we simply apply our algorithm to any graph.
First, let’s look at different ways we can modify our existing grid maze.
The only change needed to generate these three mazes is to change which nodes count as neighbours of other nodes. Before, a node only neighboured adjacent nodes cardinally north, east, south, and west of it, but this can easily be changed when generating the graph.
For the first of these three examples, the neighbourhood includes all eight adjacent nodes, including diagonals. This produces maybe a more “organic” looking design. It also kind of reminds me of runes in some fantasy game?
In the second example, the four cardinal directions are included, as well as north-west and south-east neighbours. This creates angles paths, and almost looks like a normal maze has just been skewed.
The third example is similar, except depending on the node’s position on the y-axis the “skew” direction is either left or right.
As shown earlier, we can generate a maze on top of any graph, not only rigid grids. For these next tests, I place 1000 nodes randomly in a 800x800px world.
To determine the neighbours, the first of these two examples finds all other nodes which are within a certain threshold distance (in this case 100px), and uses this set as its neighbourhood. The ordering of these neighbours (which determines how DFS will traverse the graph – remember how we randomised the ordering of neighbours for the rigid grid earlier) is simply their distance. The shortest node comes first in the neighbour order.
This means that we get lots of winding, intricate paths, since it’s biased towards picking out small details.
In the second example, the set of neighbours is generated identically (though with a different random seed). The only difference is that instead of ordering the neighbours by their distance, they’re just shuffled (exactly like the earlier rigid grid examples). Since here we have a combination of a fairly high threshold and densely packed nodes, we get a bit of a mess here. I think it looks like the creases of scrunched up tin foil.
If you experiment with this yourself, it’s fun to play with the density and threshold parameters for the loose graph. If the nodes are too sparse, though, there is a chance that you’ll encounter disconnected regions, meaning that the whole graph will not be part of the maze.
Some nice things to do to extend this would be:
Aside on overlapping passages: When I first ran a version of this “loose maze” generator, sometimes passages would overlap. This was of course because the neighbourhood generation didn’t take this into account, and the DFS algorithm itself didn’t check for overlaps either.
I had the option of either ensuring no overlaps when generating the ‘substrate’ graph, or making a DFS which is aware of this. I decided on the latter, since whether an edge may exist without overlapping only depends on previous edges that have been visited.
The current state of the program supports grid mazes and loose mazes, and some code to try and generate a labyrinth-like maze (where nodes lie on concentric circles, with a few edges between them). The labyrinth generator isn’t working that well at the moment – ideally, I want fully the concentric circles to have long unbroken sections, with far fewer inter-ring connectors.
Below, my radial graph is on the left, and on the right is something that I would like mine to look like! One major difference here is that the target image uses lines as walls, whereas mine uses lines as passages. I think that DFS might not be the correct algorithm to use to generate this sort of maze, anyway.
If you’re interested in this, you should definitely have a go at writing your own code to generate graphs. Here are some ideas:
You can find the source code on GitHub!
Depth-first search on a graph can generate some quite nice custom mazes. Since it’s “depth-first”, though, there is some bias towards long paths, which may or may not be desirable. Other algorithms (such as a greedy MST algorithm or a breadth-first search) will have different characteristics in this way, which might be better for some applications.
Hedge mazes in particular always have the other kind of branch, though. ↩
I plan on posting about anything I happen to find interesting, which will hopefully in the near future consist of working out the design for a kernel I’m going to make. I also have a firefox bookmark folder full of some interesting and cool papers I found, which I plan to write a bit about.
Hopefully this website will be an enjoyable experience.
]]>