# A small view of a tunnel is shown as 100 x 100 # section of the larger canvas. This view is then # expanded to show how much more space and depth is # available with the 200 x 200 canvas. import math def sqr(x): return x*x def mod(num, den): return (num-int(num/den)*den) objectTag = 123 pointTag = 234 pixelTag = 345 bitmapTag = 456 def makeObject(newTag): data = [] data.append(objectTag) data.append(newTag) return data def checkObject(object): if object[0] != objectTag: print "error: not an object" def getObjectTag(object): checkObject(object) return object[1] def makePoint(x, y): data = [] data.append(makeObject(pointTag)) data.append(x) data.append(y) return data def checkPoint(p): if getObjectTag(p[0]) != pointTag: print "error: not a point" def getPointX(p): checkPoint(p) return p[1] def getPointY(p): checkPoint(p) return p[2] def makePixel(color): data = [] data.append(makeObject(pixelTag)) data.append(color) return data def checkPixel(pix): if getObjectTag(pix[0]) != pixelTag: print "error: not a pixel" def getPixelColor(pix): checkPixel(pix) return pix[1] def makeBitmap(width, height, backColor): bm = [] bm.append(makeObject(bitmapTag)) bm.append(int(width)) bm.append(int(height)) for y in range(0, int(height)): for x in range(0, int(width)): bm.append(makePixel(backColor)) return bm def checkBitmap(bm): if getObjectTag(bm[0]) != bitmapTag: print "error: not a bitmap" def getBitmapWidth(bm): checkBitmap(bm) return bm[1] def getBitmapHeight(bm): checkBitmap(bm) return bm[2] def getBitmapPixel(bm, p): checkBitmap(bm) return bm[3+int(getPointY(p))*getBitmapWidth(bm)+int(getPointX(p))] def setBitmapPixel(bm, p, pix): checkBitmap(bm) bm[3+(int(getPointY(p))*getBitmapWidth(bm))+int(getPointX(p))] = pix def drawBitmapOnBitmap(destBm, p, srcBm): for y in range(0, getBitmapWidth(srcBm)): for x in range(0, getBitmapHeight(srcBm)): setBitmapPixel(destBm, makePoint(x+getPointX(p), y+getPointY(p)), getBitmapPixel(srcBm, makePixel(x, y))) def drawPixel(pix, destP): g.setPixel(int(getPointX(destP)), int(getPointY(destP)), int(getPixelColor(pix))) def drawBitmap(bm, destP): for y in range(0, getBitmapHeight(bm)): for x in range(0, getBitmapWidth(bm)): drawPixelField(getBitmapPixel(bm, makePoint(x, y)), makePoint(x+getPointX(destP), y+getPointY(destP))) def drawBitmapSprite(bm, destP, transKey): for y in range(0, getBitmapHeight(bm)): for x in range(0, getBitmapWidth(bm)): pix = getBitmapPixel(bm, makePoint(x, y)) if getPixelColor(pix) != transKey: drawPixel(pix, makePoint(x+getPointX(destP), y+getPointY(destP))) def drawPixelField(pix, p1, p2): g.field(int(getPointX(p1)), int(getPointY(p1)), int(getPointX(p2)), int(getPointY(p2)), int(getPixelColor(pix))) def drawBitmapScaledBig(bm, destP, horizScale, vertScale): for y in range(0, getBitmapHeight(bm)): for x in range(0, getBitmapWidth(bm)): drawPixelField(getBitmapPixel(bm, makePoint(x, y)), makePoint((x*horizScale)+getPointX(destP), (y*vertScale)+getPointY(destP)), makePoint((x*horizScale)+getPointX(destP)+horizScale, (y*vertScale)+getPointY(destP)+vertScale)) def drawBitmapScaledSmall(bm, destP, horizScale, vertScale): for y in range(0, getBitmapHeight(bm)): for x in range(0, getBitmapWidth(bm)): drawPixelField(getBitmapPixel(bm, makePoint(x, y)), makePoint((x*horizScale)+getPointX(destP), (y*vertScale)+getPointY(destP)), makePoint((x*horizScale)+getPointX(destP)+horizScale, (y*vertScale)+getPointY(destP)+vertScale)) def drawBitmapScaled(bm, destP, horizScale, vertScale): if horizScale+vertScale > 2: drawBitmapScaledBig(bm, destP, horizScale, vertScale) else: drawBitmapScaledSmall(bm, destP, horizScale, vertScale) def drawBitmapSpriteScaledSmall(bm, destP, transKey, horizScale, vertScale): oxi = -1 oyi = -1 for y in range(0, getBitmapHeight(bm)): for x in range(0, getBitmapWidth(bm)): pix = getBitmapPixel(bm, makePoint(x, y)) if getPixelColor(pix) != transKey: xi = x * horizScale yi = y * vertScale if oxi != xi or oyi != yi: drawPixel(getBitmapPixel(bm, makePoint(x, y)), makePoint(xi+getPointX(destP), yi+getPointY(destP))) oxi = xi*horizScale oyi = yi*vertScale def drawBitmapSpriteScaledBig(bm, destP, transKey, horizScale, vertScale): for y in range(0, getBitmapHeight(bm)): for x in range(0, getBitmapWidth(bm)): pix = getBitmapPixel(bm, makePoint(x, y)) if getPixelColor(pix) != transKey: drawPixelField(getBitmapPixel(bm, makePoint(x, y)), makePoint((x*horizScale)+getPointX(destP), (y*vertScale)+getPointY(destP)), makePoint((x*horizScale)+getPointX(destP)+horizScale, (y*vertScale)+getPointY(destP)+vertScale)) def drawBitmapSpriteScaled(bm, destP, transKey, horizScale, vertScale): if horizScale+vertScale > 2: drawBitmapSpriteScaledBig(bm, destP, transKey, horizScale, vertScale) else: drawBitmapSpriteScaledSmall(bm, destP, transKey, horizScale, vertScale) def drawBitmapWallSprite(bm, destP1, h1, destP2, h2, transKey): p1x = getPointX(destP1) p1y = getPointY(destP1) p2x = getPointX(destP2) p2y = getPointY(destP2) w = p2x - p1x + 1 hd = h2 - h1 y1d = p2y - p1y bmw = getBitmapWidth(bm) bmh = getBitmapHeight(bm) for x in range(int(p1x), int(p2x)+1): xoff = x - p1x xy1 = p1y+xoff*y1d/w xh = h1+xoff*hd/w xi = xoff*bmw/w for y in range(int(xy1), int(xy1+xh)): yi = (y-xy1)*bmh/xh drawPixel(getBitmapPixel(bm, makePoint(xi, yi)), makePoint(x, y)) def drawBitmapLevelSprite(bm, destP1, w1, destP2, w2, transKey): p1x = getPointX(destP1) p1y = getPointY(destP1) p2x = getPointX(destP2) p2y = getPointY(destP2) h = p2y - p1y wd = w2 - w1 x1d = p2x - p1x bmw = getBitmapWidth(bm) bmh = getBitmapHeight(bm) for y in range(int(p1y), int(p2y)): yoff = y - p1y yx1 = p1x+yoff*x1d/h yw = w1+yoff*wd/h+3 yi = yoff*bmh/h for x in range(int(yx1), int(yx1+yw)): xi = (x-yx1)*bmw/(yw+1) drawPixel(getBitmapPixel(bm, makePoint(xi, yi)), makePoint(x, y)) def drawBitmapFlatSprite(bm, p1, p2, transKey): p1x = getPointX(p1) p1y = getPointY(p1) p2x = getPointX(p2) p2y = getPointY(p2) w = p2x - p1x + 1 h = p2y - p1y + 1 bmw = getBitmapWidth(bm) bmh = getBitmapHeight(bm) horizScale = 1.0*w/bmw vertScale = 1.0*h/bmh drawBitmapSpriteScaled(bm, p1, -1, horizScale, vertScale) #for y in range(p1y, p2y+1): # yi = (y-p1y)*bmh/h # for x in range(p1x, p2x+1): # xi = (x-p1x)*bmw/w # drawPixel(getBitmapPixel(bm, makePoint(xi, yi)), makePoint(x, y)) def renderBrickSurface(bm): w = getBitmapWidth(bm) h = getBitmapHeight(bm) for x in range(0, w): for y in range(0, h): color = 50 + mod(sqr(sqr(x+y)), 10) + mod(sqr(y), 10) setBitmapPixel(bm, makePoint(x, y), makePixel(color)) for yi in range(0, 5): for x in range(0, w): if yi == 0: color = 75 - mod(sqr(x+sqr(yi)), 10) else: color = 100 - mod(sqr(x+sqr(yi)), 10) setBitmapPixel(bm, makePoint(x, h-1-yi*h/5), makePixel(color)) for xi in range(0, 5): for y in range(yi*h/5, (yi+1)*h/5): if yi == 0: color = 90 + (y-yi*h/5)*10/((yi+1)*h/5-yi*h/5) - mod(sqr(x+y), 10) else: color = 100 - mod(sqr(x+y), 10) setBitmapPixel(bm, makePoint((xi*w+mod(yi,2)*w/2)/5, h-1-y), makePixel(color)) def renderFloorSurface(bm): w = getBitmapWidth(bm) h = getBitmapHeight(bm) for x in range(0, w): for y in range(0, h): color = 50 + mod(sqr(x+sqr(y)), 7)*4 + mod(sqr(y-sqr(x)), 13)*4 setBitmapPixel(bm, makePoint(x, y), makePixel(color)) def renderCeilingSurface(bm): w = getBitmapWidth(bm) h = getBitmapHeight(bm) for x in range(0, w): for y in range(0, h): color = 50 + mod(sqr(x+sqr(y)), 13) + mod(sqr(y), 7) setBitmapPixel(bm, makePoint(x, y), makePixel(color)) def drawRightWall(brickWall, p1, p2): p1x = getPointX(p1) p1y = getPointY(p1)-0.5 p2x = getPointX(p2) p2y = getPointY(p2) w = p2x - p1x h = p2y - p1y drawBitmapWallSprite(brickWall, makePoint((p1x+p2x*3+2)/4,(p1x*3+p2x+2)/4), w/2, makePoint(p2x,p1y), w, -1) def drawLeftWall(brickWall, p1, p2): p1x = getPointX(p1) p1y = getPointY(p1) p2x = getPointX(p2) p2y = getPointY(p2) w = p2x - p1x h = p2y - p1y drawBitmapWallSprite(brickWall, p1, w+1, makePoint((p1x*3+p2x)/4,(p1y*3+p2y)/4), w/2, -1) def drawFrontWall(brickWall, p1, p2): p1x = getPointX(p1) p1y = getPointY(p1) p2x = getPointX(p2) p2y = getPointY(p2) w = p2x - p1x h = p2y - p1y drawBitmapFlatSprite(brickWall, makePoint((p1x*3+p2x)/4,(p1y*3+p2y)/4), makePoint((p1x+p2x*3)/4,(p1y+p2y*3)/4), -1) def drawCeiling(ceiling, p1, p2): p1x = getPointX(p1) p1y = getPointY(p1) p2x = getPointX(p2) p2y = getPointY(p2) w = p2x - p1x h = p2y - p1y drawBitmapLevelSprite(ceiling, makePoint((p1x*3+p2x)/4,(p1x+p2x*3)/4), w/2+1, makePoint(p1x, p2y), w+1, -1) def drawFloor(floor, p1, p2): p1x = getPointX(p1) p1y = getPointY(p1) p2x = getPointX(p2) p2y = getPointY(p2) w = p2x - p1x h = p2y - p1y drawBitmapLevelSprite(floor, p1, w-1, makePoint((p1x*3+p2x)/4, (p1y*3+p2y)/4), (w-3)/2, -1) def drawPassage(brickWall, ceiling, floor, p1, p2): p1x = getPointX(p1) p1y = getPointY(p1) p2x = getPointX(p2) p2y = getPointY(p2) w = p2x - p1x h = p2y - p1y drawFloor(floor, p1, p2) drawCeiling(ceiling, p1, p2) drawLeftWall(brickWall, p1, p2) drawRightWall(brickWall, p1, p2) def drawDeadEnd(brickWall, ceiling, floor, p1, p2): p1x = getPointX(p1) p1y = getPointY(p1) p2x = getPointX(p2) p2y = getPointY(p2) w = p2x - p1x h = p2y - p1y drawFrontWall(brickWall, p1, p2) drawPassage(brickWall, ceiling, floor, p1, p2) def drawTunnel(brickWall, ceiling, floor, p1, p2, length): p1x = getPointX(p1) p1y = getPointY(p1) p2x = getPointX(p2) p2y = getPointY(p2) if length > 1: drawTunnel(brickWall, ceiling, floor, makePoint((p1x*3+p2x)/4, (p1y*3+p2y)/4), makePoint((p1x+p2x*3)/4, (p1y+p2y*3)/4), length-1) drawPassage(brickWall, ceiling, floor, p1, p2) else: if length == 1: drawDeadEnd(brickWall, ceiling, floor, p1, p2) xRes = 25 yRes = 25 brickWall = makeBitmap(xRes, yRes, -1) ceiling = makeBitmap(xRes, yRes, -1) floor = makeBitmap(xRes, yRes, -1) renderBrickSurface(brickWall) renderCeilingSurface(ceiling) renderFloorSurface(floor) g.paper(0) drawTunnel(brickWall, ceiling, floor, makePoint(0,0), makePoint(201,201), 2)