While none of the levels are going to be amazing, or inspired, or beautiful, the fact that they're playable at all goes to show how versatile a game N is. Anyway, here's the Python 2.5 code and a bunch of sample levels.
Generate Now
(Refresh the page for more levels)
Code: Select all
import random as r;n,c=range,r.choice;t=[c('001'*12+'2345') for i in n(713)]+['|5^396,300']+['!%s^%s,%s'%(c([12,0,0]),c(n(1,32))*24,c(n(1,24))*24) for i in n(63)];t[356]='0';print ''.join(t)
THE TECHNICAL DESCRIPTION
-----
Code: Select all
import random as r;
n, c = range, r.choice;
t = [c('001'*12 + '2345') for i in n(713)] + \
['|5^396,300'] + \
['!%s^%s,%s' % (c([12,0,0]), c(n(1,32))*24, c(n(1,24))*24) for i in n(63)]
t[356] = '0'
print ''.join(t)
Code: Select all
import random as r;
n, c = range, r.choice;
Code: Select all
t = [c('001'*12 + '2345') for i in n(713)] + \
t = []
for i in range(713):
. . t.append(c('001' * 12 + '2345'))
Er, and for even *further* clarity, that up there is a loop that runs 713 times, and each time appends a certain object to the end of the list t. That object happens to be an N tile, but let's look at how it's chosen.
Code: Select all
c('001'*12 + '2345')
Code: Select all
['|5^396,300'] + \
Code: Select all
['!%s^%s,%s' % (c([12,0,0]), c(n(1,32))*24, c(n(1,24))*24) for i in n(63)]
First of all, this creates the N objects. You already know list comprehensions a bit from earlier, so you'll see that this loops 63 times to create 63 objects. This number was derived from the Legacy stats to give about 42 gold and 21 mines (some of which will be lost under tiles).
Code: Select all
'!%s^%s,%s' % (c([12,0,0]), c(n(1,32))*24, c(n(1,24))*24)
The next two placeholders are the x- and y-coordinates. The functions that fill them are a bit complicated. First, what it does as is: choice(range(number))*24. The range in the middle creates a list of numbers from 1 to 31 for width and 1 to 23 for height to choose from, and then the choice function picks one of each to form the position of the gold or mine. Now, 31x23 is the tileset dimensions, so we then multiply the number by 24 to convert from tileset coordinates to object coordinates. Beautiful. These objects are always full-snapped and on the edges of tiles, mostly to get mines at the sides of chimneys to make levels more playable.
Some technical things I did and didn't do to save space: First, I know what you're thinking. "But LV, '!'+x+'^'+y+','+z is two characters shorter than '!%s^%s,%s'%(x,y,z)," to which I reply "NO. COULD NOT CONCAT INT WITH STRING." You can't add an integer to a string in Python, but the formatted string automatically converts integer inputs to strings. This saved me from several str() operations. Second, choice(range(number)) is a strange way to get a random integer within an interval. In fact, the random module has randrange() and even randint() functions, but I went this route to avoid importing them. I already spent an annoying amount of characters just importing the one function, let alone two or three. Third, the range function (n() to us) has support for jumping over intervals, so I shouldn't have to generate small numbers and multiply them by 24. I could use n(24,744,24) to get a list [24,48,72, ... ,744] and have the same randomization as I have now. But notice that 24 and 744 are each one digit longer than 1 and 31! I saved 4 characters by choosing from small numbers and multiplying after.
Code: Select all
t[356] = '0'
Code: Select all
print ''.join(t)