To add railway track we need to have some normal rail and some powered rail. Next to every section of powered rail we need to provide a redstone torch.

First we define the items which are not defined in mcpi.block yet

RAIL = block.Block(66)
RAIL_POWERED = block.Block(27)
TORCH_REDSTONE = block.Block(76)

We are already placing a plain torch every 4 blocks. Now we want to place a redstone torch every 4 blocks but offset by 2. Next to the redstone torch we want two pieces of powered rail, at positions 1 and 2. The rest of the rail is normal rail. This code goes in the second loop where the full tunnel profile is created.

if x % 4 == 2:
mc.setBlock(x,y+1,z+1,TORCH_REDSTONE.id,5)
if x % 4 == 1 or x % 4 == 2:
mc.setBlock(x,y+1,z,RAIL_POWERED)
else:
mc.setBlock(x,y+1,z,RAIL)

Here is a screenshot showing the railway track in the tunnel.

Here is the full code.

import mcpi.minecraft as minecraft
import mcpi.block as block
mc=minecraft.Minecraft.create()
XMIN = -400 # x value at one end of tunnel.
XMAX = -200 # x value at other end of tunnel. Must be greater than XMIN
GROUND = 72 # y position of tunnel at each end
FLOOR = 10 # minimum value of y at bottom of tunnel
ZPOS = -244 # z position for full length of tunnel
TAIL = 10 # length of horizontal at each end of tunnel
# Define blocks currently missing from mcpi.block
STAIRS_STONE = block.Block(109)
RAIL = block.Block(66)
RAIL_POWERED = block.Block(27)
TORCH_REDSTONE = block.Block(76)
# constants for tunnelvertical function
kx = (XMAX + XMIN) / 2
ky = GROUND + TAIL - (XMAX - XMIN) / 2
# tunnelvertical returns a vertical position of the tunnel
# for each value of the x position (eastposition)
def tunnelvertical(eastposition):
y = abs(eastposition - kx) + ky
if y < FLOOR:
return FLOOR
if y > GROUND:
return GROUND
return y
# set the z coordinate for the tunnel which doesn't change for the full length
z = ZPOS
# Initial loop to create a route made of solid glass with a stone base
for x in range(XMIN,XMAX+1):
y = tunnelvertical(x)
mc.setBlocks(x,y,z-2,x,y+6,z+2,block.GLASS)
mc.setBlocks(x,y,z-1,x,y,z+1,block.STONE)
# Initialise previous value of y so can determine if stairs going up or down
yprev = tunnelvertical(XMIN)
# Second loop to convert solid glass into a tunnel
for x in range(XMIN+1,XMAX):
y = tunnelvertical(x)
# replace centre glass with air to make it a tunnel
mc.setBlocks(x,y+1,z-1,x,y+5,z+1,block.AIR)
# place a torch every 4 positions to light the tunnel
# variation 5 = torch facing up
# every 4 blocks
# pos 0: rail and normal torch
# pos 1: powered rail
# pos 2: powered rail and redstone torch
# pos 3: rail
if x % 4 == 0:
mc.setBlock(x,y+1,z+1,block.TORCH.id,5)
if x % 4 == 2:
mc.setBlock(x,y+1,z+1,TORCH_REDSTONE.id,5)
if x % 4 == 1 or x % 4 == 2:
mc.setBlock(x,y+1,z,RAIL_POWERED)
else:
mc.setBlock(x,y+1,z,RAIL)
# check if stairs are going up or down
if y > yprev:
# variation 0 = stairs ascending to the east
mc.setBlock(x,y,z-1,STAIRS_STONE.id,0)
if y < yprev:
# variation 1 = stairs ascending to the west
mc.setBlock(x-1,yprev,z-1,STAIRS_STONE.id,1)
yprev=y