====== Scripts > Wang tiles ====== ^ Description | This script generates a plane of Wang Tile indicies using the size of the design map. | ^ Author | David Walters | ^ Created | 2009 / 05 / 30 | ^ Updated | 2013 / 05 / 21 | ^ Requires | L3DT v2.9 or later | ^ Download | {{:scripts:wangtiles_may2013.zs|WangTiles_May2013.zs}} | ^ Forum thread | [[http://www.bundysoft.com/phpBB2/viewtopic.php?f=11&t=1156]] | ===== Script contents ===== // // Wang Tiling Generator // // by David Walters // // Requires L3DT v2.9 (or later). // // Based on: http://research.microsoft.com/en-us/um/people/cohen/WangFinal.pdf // // This script generates a plane of Wang Tile indicies using the size of the design map. // It is based around a set of 8 tiles, as per. figure 1a // // In the above paper the tile edges are coloured. This colouring of north/south // and east/west edges uses four colours - but this can actually be reduced to two // colours as only opposite edges are ever compared. This lets us create a set of // binary codes for each tile: // // RED or BLUE = 0; GREEN or YELLOW = 1 // // NS:EW // 0: WANG_A => [01:10] // 1: WANG_B => [11:00] // 2: WANG_C => [00:11] // 3: WANG_D => [10:01] // 4: WANG_E => [01:01] // 5: WANG_F => [11:11] // 6: WANG_G => [00:00] // 7: WANG_H => [10:10] // // // Changes: // // 21st May 2013 // // * Updated to support new ZeoScript syntax in L3DT v2.9 and later (by A.T.) // // 6th May 2009 // // * Update to new variable declaration style // * Update to use new 'SetValue2' when building tables // * Add a call to the EditUI function to allow manual adjustment of size. // //============================================================================== // Configure //============================================================================== // Create settings list 'ls' varlist ls uint ls.size_x uint ls.size_y // Use the design map size as default hvar hDM set hDM set ls.size_x set ls.size_y // edit settings list assert "Calculation aborted!" //============================================================================== // Initialisation //============================================================================== int x int y int value int index int current int random byte b int row_base int above_base int is_west_one int is_north_one // Starting up echo "Initialising ..." // // Populate 'is_east_one' array // // This array is a simple lookup table storing the value of the east edge. // hvar is_east_one set is_east_one assert "Allocation failure." // Does a tile have an 'east' value of one? assert "Cannot set buffer value." assert "Cannot set buffer value." assert "Cannot set buffer value." assert "Cannot set buffer value." assert "Cannot set buffer value." assert "Cannot set buffer value." assert "Cannot set buffer value." assert "Cannot set buffer value." // // Populate 'is_south_one' array // // This array is a simple lookup table storing the value of the south edge. // hvar is_south_one set is_south_one assert "Allocation failure." // Does a tile have a 'south' value of one? assert "Cannot set buffer value." assert "Cannot set buffer value." assert "Cannot set buffer value." assert "Cannot set buffer value." assert "Cannot set buffer value." assert "Cannot set buffer value." assert "Cannot set buffer value." assert "Cannot set buffer value." // // Populate 'west' array // // This is an array of tiles, two groups of four, that are the tiles // that can be matched with east values of zero and one respectively. // hvar west set west assert "Allocation failure." // EAST: 0 => WEST: 0 (abgh) assert "Cannot set buffer value." // WANG_A assert "Cannot set buffer value." // WANG_B assert "Cannot set buffer value." // WANG_G assert "Cannot set buffer value." // WANG_H // EAST: 1 => WEST: 1 (cdef) assert "Cannot set buffer value." // WANG_C assert "Cannot set buffer value." // WANG_D assert "Cannot set buffer value." // WANG_E assert "Cannot set buffer value." // WANG_F // // Populate 'north' array // // This is an array of tiles, two groups of four, that are the tiles // that can be matched with south values of zero and one respectively. // hvar north set north assert "Allocation failure." // SOUTH: 0 => NORTH: 0 (aceg) assert "Cannot set buffer value." // WANG_A assert "Cannot set buffer value." // WANG_C assert "Cannot set buffer value." // WANG_E assert "Cannot set buffer value." // WANG_G // SOUTH: 1 => NORTH: 1 (bdfh) assert "Cannot set buffer value." // WANG_B assert "Cannot set buffer value." // WANG_D assert "Cannot set buffer value." // WANG_F assert "Cannot set buffer value." // WANG_H // // Populate 'wang_table' array // // This is an array of tiles that resolves the two constraints of // main body tiles. Each combination of constraints has two choices // picked at random. // hvar wang_table set wang_table assert "Allocation failure." // ====== WEST:0 // === NORTH:0 assert "Cannot set buffer value." // WANG_A assert "Cannot set buffer value." // WANG_G // == NORTH:1 assert "Cannot set buffer value." // WANG_B assert "Cannot set buffer value." // WANG_H // ====== WEST:1 // === NORTH:0 assert "Cannot set buffer value." // WANG_C assert "Cannot set buffer value." // WANG_E // === NORTH:1 assert "Cannot set buffer value." // WANG_D assert "Cannot set buffer value." // WANG_F // Prepare a buffer for all tiles hvar tiles set tiles assert int > "Allocation failure." //============================================================================== // Generate Tiles //============================================================================== // // Say Hello // string hello set hello "Generating Wang Tiles ( " set hello set hello set hello set hello echo hello // // Generate First Tile - pick any tile // // current = rand() % 8 set current 8 > // [0-7] // tiles[ 0 ] = current assert "Cannot set buffer value." // // Tile the First Row // // For each tile in this row the east/west "colour" should match. We use the // 'is_east_one' lookup table to first see what our constraint is, then pick one // of the four possible tiles at random from the 'west' array. // set x 1 do // value = is_east_one[ current ] assert "Cannot get buffer value." // current = west[ value ][ random ] set random 4 > // [0-3] set index random > assert "Cannot get buffer value." // Store 'current' as new tile assert "Cannot set buffer value." set x while // // For each remaining row... // set y 1 do // First: Compute index of the first element of the row, and the one above. set row_base set above_base ls.size_x > // // Pick Row Start // // The first tile of a row must match with the south edge of the tile above. // We use the 'is_south_one' this time to identify our constraint and then pick // randomly from one of the four tiles in the 'north' array. // // value = is_south_one[ tiles[ above_base ] ] assert "Cannot get buffer value." assert "Cannot get buffer value." // current = north[ value ][ random ] set random 4 > // [0-3] set index random > assert "Cannot get buffer value." // Store 'current' as new tile of this row assert "Cannot set buffer value." // // Complete the Row // // Additional tiles of these rows must now conform to two constraints. // One from the north, and another from the west. // set x 1 do // What is the 'colour' of the edge to the west of this tile? // (the value of the tile to the west is stored in 'current') assert "Cannot get buffer value." // What is the 'colour' of the edge to the north of this tile? set index assert "Cannot get buffer value." assert "Cannot set buffer value." // We have two choices for each tile ... set random 2 > // current = wang_table[ is_west_one ][ is_north_one ][ random ] set index set index > set index assert "Cannot get buffer value." // Store 'current' in our row in the tiles array set index assert "Cannot set buffer value." set x while set y while echo " ...generation complete." //============================================================================== // Write Data //============================================================================== string FileName set FileName if > return 0 endif voidptr fp set fp assert fp "Cannot open file!" set y 0 do set x 0 do // Get the tile value set index x > assert "Cannot get buffer value." // Cast to a byte, and write 8-bits set b current fwrite fp b set x while set y while fclose fp echo "done." // [EOF]