Wave function collapse: Difference between revisions

From Rosetta Code
Content added Content deleted
(→‎{{header|J}}: use local names for intermediate results in wfc)
(→‎{{header|J}}: add documentation)
Line 9: Line 9:
Implementation:<lang J>tiles=: 0,(|.@|:)^:(i.4)0,1 1 1,:0 1 0
Implementation:<lang J>tiles=: 0,(|.@|:)^:(i.4)0,1 1 1,:0 1 0
wfc=: {{
wfc=: {{
M=. #.,"2 tiles
opts=. (<each, <@<)M
adj=. y#.y|"1(y#:,i.y)+"1/0,<:3 3#:1 3 5 7
adj=. y#.y|"1(y#:,i.y)+"1/0,<:3 3#:1 3 5 7
horz=. ({."1 -:"1/ {:"1) m
horz=. ({."1 -:"1/ {:"1) m NB. horizontal tile pairs
vert=. ({."2 -:"1/ {:"2) m
vert=. ({."2 -:"1/ {:"2) m NB. vertical tile pairs
id=. <@I.(=i.#tiles),1 NB. identity constraint
id=. <@I.(=i.#tiles),1 NB. identity constraint
north=. <@I.vert,1 NB. adj 1 constraint
north=. <@I.vert,1 NB. adj 1 constraint
Line 31: Line 29:
,/"2,/0 2 1 3|:(y$i){m
,/"2,/0 2 1 3|:(y$i){m
}}</lang>
}}</lang>

Here, <code>m</code> is the list of tiles, and <code>i</code> represents an 8x8 list of indexes into that list, with <code>_1</code> being a placeholder for the case where the index hasn't been choosen -- initially, we pick a random location in i and assign an arbitrarily picked tile to that location.

<code>adj</code> indexes into <code>i</code> -- for each item in <code>i</code>, <code>adj</code> selects that item, the item "above" it, the item to the "left" of it, the item to the "right" of it and the item "below" it (with scare quotes because the tile represented by <code>i</code> "wraps around" on all sides). And, <code>allow</code> lists the allowable tiles corresponding to each of those <code>adj</code> constraints.

To build <code>allow</code> we first matched the left side of each tile with the right side of each tile (cartesian product) forming <code>horz</code> and similarly matched the tops and bottoms of the tiles forming <code>vert</code>. Then we built <code>id</code> which selects only the tile itself (or all tiles, for <code>i=_1</code>), <code>north</code> which limits tiles based on the tile above it, and so on for <code>west</code>, <code>east</code>, and <code>south</code>.

Once we're set up, we drop into a loop: <code>todo</todo> selects the unchosen tile locations, <code>wave</code>lists for each location the eligible tiles, and <code>entropy</code> counts how many are eligible for each location -- <code>E</code> is the entropy for the unchosen locations, and <code>min</code> is the smallest value in <code>E</code>. <code>ndx</code> is a randomly picked index into <code>i</code> with minimal entropy and for that location we randomly pick one of the options and update i with it. (When there's only one option remaining "randomly pick" here means we pick that option.)

Once we've assigned a tile to every location in i, we use those indices to assemble the result.

For task purposes here, we will use space to represent a white pixel and "#" to represent a black pixel. Also, because characters are narrow, we will insert a space between each of these "pixels" to better approximate a square aspect ratio.


Task example (the initial tiles and two runs of wave function collapse (two, to illustrate randomness):<lang J> (<"2) 1j1#"1 ' #'{~ tiles
Task example (the initial tiles and two runs of wave function collapse (two, to illustrate randomness):<lang J> (<"2) 1j1#"1 ' #'{~ tiles

Revision as of 10:25, 10 July 2022

Wave function collapse is a draft programming task. It is not yet considered ready to be promoted as a complete task, for reasons that should be found in its talk page.
This task has been flagged for clarification. Code on this page in its current state may be flagged incorrect once this task has been clarified. See this page's Talk page for discussion.

Write the solution for Wave Function Collapse based on the Coding Challenge 171: Wave Function Collapse and create new map 8x8 tiles with fourth T-blocks with variously directions (┤ ┴ ┬ ├) or blank tiles (space).

Reference WFC explained and another WFC explained

J

Implementation:<lang J>tiles=: 0,(|.@|:)^:(i.4)0,1 1 1,:0 1 0 wfc=: Template:Adj=. y</lang>

Here, m is the list of tiles, and i represents an 8x8 list of indexes into that list, with _1 being a placeholder for the case where the index hasn't been choosen -- initially, we pick a random location in i and assign an arbitrarily picked tile to that location.

adj indexes into i -- for each item in i, adj selects that item, the item "above" it, the item to the "left" of it, the item to the "right" of it and the item "below" it (with scare quotes because the tile represented by i "wraps around" on all sides). And, allow lists the allowable tiles corresponding to each of those adj constraints.

To build allow we first matched the left side of each tile with the right side of each tile (cartesian product) forming horz and similarly matched the tops and bottoms of the tiles forming vert. Then we built id which selects only the tile itself (or all tiles, for i=_1), north which limits tiles based on the tile above it, and so on for west, east, and south.

Once we're set up, we drop into a loop: todo</todo> selects the unchosen tile locations, wavelists for each location the eligible tiles, and entropy counts how many are eligible for each location -- E is the entropy for the unchosen locations, and min is the smallest value in E. ndx is a randomly picked index into i with minimal entropy and for that location we randomly pick one of the options and update i with it. (When there's only one option remaining "randomly pick" here means we pick that option.)

Once we've assigned a tile to every location in i, we use those indices to assemble the result.

For task purposes here, we will use space to represent a white pixel and "#" to represent a black pixel. Also, because characters are narrow, we will insert a space between each of these "pixels" to better approximate a square aspect ratio.

Task example (the initial tiles and two runs of wave function collapse (two, to illustrate randomness):<lang J> (<"2) 1j1#"1 ' #'{~ tiles ┌──────┬──────┬──────┬──────┬──────┐ │ │ │ # │ # │ # │ │ │# # # │ # # │# # # │# # │ │ │ # │ # │ │ # │ └──────┴──────┴──────┴──────┴──────┘

  1j1#"1 ' #'{~ tiles wfc 8 8
       #           #     #                 #   
     # #   # # #   # # # #   # # # # # #   # # 
       #     #     #     #     #     #     #   
 #           #                 #     #         
  1. # # # # # # # # # # # # # # # # # # # # # # #
       #           #     #                 #   
 #           #     #     #                 #   
 # #       # #   # # # # # # # # # # # # # # # 
 #           #                 #     #         
 #     #     #     #           #     #     #   
  1. # # # # # # # # # # # # # # # # # # #
 #           #     #     #                 #   
       #     #     #           #     #     #   
  1. # # # # # # # # # # # # # #
 #     #     #     #           #     #     #   
 #                       #     #     #         
  1. # # # # # # # # # # # # # # # # # # # # #
       #     #     #           #     #     #   
 #     #     #     #     #     #     #         
  1. # # # # # # # # # # # # # # # #
 #                       #     #     #         
       #     #     #     #     #     #     #   
  1. # # # # # # # # # # # # # # # # #
 #     #     #     #     #     #     #         
  1j1#"1 ' #'{~ tiles wfc 8 8
 #     #                       #           #   
  1. # # # # # # # # # # # # # # # # # #
             #     #     #     #           #   
 #     #     #     #     #           #         
 # # # #   # # # # # # # # # # # # # # # # # # 
 #     #                       #           #   
 #     #     #     #     #     #     #         
  1. # # # # # # # # # # # # # #
 #     #     #     #     #           #         
 #     #                       #     #     #   
 # # # #   # # # # # # # # #   # # # #   # # # 
 #     #     #     #     #     #     #         
 #     #                       #           #   
  1. # # # # # # # # # #
 #     #                       #     #     #   
 #     #     #     #     #           #         
 # # # #   # # # # # # # # # # # # # # # # # # 
 #     #                       #           #   
             #     #     #           #     #   
  1. # # # # # # # # # # # # # # # #
 #     #     #     #     #           #         
             #     #     #     #           #   
           # #     # # # #   # # # # # #   # # 
             #     #     #           #     #   </lang>