Jump to content

The mason's puzzle


Demonic God
 Share

Recommended Posts

Just recently, I passed by the Tempest Fort, and noticed a worrying issue. Moss! Some strange moss had invaded the walls. Its root penetrated the solid stone, and weakened its integrity! Unacceptable!

However, it seems that the stones available to patch up the walls is in short supply, and on top of that, they naturally form in difficult shapes. Thus, I'd like to employ your help, to find a way, to most efficiently replace the damaged walls.

The wall to be replaced could be modeled as a solid slate, of dimensions 8x8x3. There are various types of stones available:

  • Z, T and L shaped stones (volume of 4)
  • I shaped stones (volume of 2, or 1x2)
  • Singular, dot/square ( . ) shape stones, volume of 1

Your goal is to find a way to assemble the 8x8x3 walls using these materials. In general, based on scarcity of materials, I've assigned the tiles the following points:

  • Z shape: 4 points
  • T and L: 3 points
  • I: 1 points
  • dot: 0 points

The winning designs shall be rewarded handsomely. In particular:

  • The design with the highest score shall win 3 gold coins, and an anni creature
  • The second place, would be 2 gold coins, along with an anni creature
  • The third place, would be receiving 1 gold coin, and an anni creature

However, there's more!

I look not only for the design that has high point values. There's more to this challenge, than simply finding a single solution with a good point value. Artistry and beauty is a major aspect of masonry. I look also for designs that amazes me, regardless of how well they perform in the actual competition. In particular:

  • Designs with a certain mathematical "beauty" - whenever that be an absolute order, scalability, or an extremely chaotic, complex yet efficient pattern
  • Designs with fantastic demonstration and illustration, demonstrating a huge amount of effort & care
  • Etc.

In general, anything that amazes me greatly, would be rewarded with 1 WP. Your design does not need to achieve a high score to a WP, but a high score itself could certainly amazes me. There's no limited to how many winners, but there's no guarantee that there would be a winner as well.

Deadlines and submission guidelines:

Deadline:

  • You have until the end of anniversary (29th) to submit your design

Submission guideline:

  • You can submit your design in any manner that you like. Rather, coming up with a unique design AND presentation is part of the quest, at least for the WP portion
  • For clarity, I'd ask that you make three 8x8 squares and fill it with numbers. Squares with the same number should be occupied by the same "stone". You may also submit just this three squares as your submission.

Below are the shapes, in image form (with a thickness of 1), as I've been notified that there are confusions to the shapes. They're somewhat similar to tetris shape, as you can tell.

pieces.png

Edited by Demonic God
Link to comment
Share on other sites

  • 2 weeks later...

A bit late... o well. I'm not even sure why I made this, since most contestant drew their own thing xD. This is a tool to visualize what you made, and the scores you get... provided that it doesn't throw an error.

For those that likes tinkering around, this might be fun for you to poke around with :D

from graphics import *

BORDER_THICKNESS = 3
SQUARE_THICKNESS = 50

SHAPES = {
	'T_SHAPE':{
				frozenset({(0,0,0),(0,1,0),(0,2,0),(0,1,1)}),
				frozenset({(0,0,0),(0,0,1),(0,0,2),(0,1,1)}),
				frozenset({(0,0,1),(0,1,1),(0,2,1),(0,1,0)}),
				frozenset({(0,1,0),(0,1,1),(0,1,2),(0,0,1)})
			},
	'L_SHAPE':{
				frozenset({(0,0,0),(0,1,0),(0,2,0),(0,0,1)}),
				frozenset({(0,0,0),(0,1,0),(0,2,0),(0,2,1)}),
				frozenset({(0,0,0),(0,0,1),(0,0,2),(0,1,0)}),
				frozenset({(0,0,0),(0,0,1),(0,0,2),(0,1,2)}),
				frozenset({(0,0,1),(0,1,1),(0,2,1),(0,0,0)}),
				frozenset({(0,0,1),(0,1,1),(0,2,1),(0,2,0)}),
				frozenset({(0,1,0),(0,1,1),(0,1,2),(0,0,0)}),
				frozenset({(0,1,0),(0,1,1),(0,1,2),(0,0,2)})
			},
	'Z_SHAPE':{
				frozenset({(0,0,0),(0,1,0),(0,1,1),(0,2,1)}),
				frozenset({(0,0,1),(0,1,1),(0,1,0),(0,2,0)}),
				frozenset({(0,0,0),(0,0,1),(0,1,1),(0,1,2)}),
				frozenset({(0,1,0),(0,1,1),(0,0,1),(0,0,2)})
			},
	'I_SHAPE':{
				frozenset({(0,0,0),(0,1,0)}),
				frozenset({(0,0,0),(0,0,1)})
			},
	'DOT_SHAPE':{
				frozenset({(0,0,0)})
			}
}

POINTS = {
	'Z_SHAPE': 4,
	'T_SHAPE': 3,
	'L_SHAPE': 3,
	'I_SHAPE': 1,
	'DOT_SHAPE': 0
}

COLORS = {
	'Z_SHAPE': 'red',
	'T_SHAPE': 'green',
	'L_SHAPE': 'blue',
	'I_SHAPE': 'purple',
	'DOT_SHAPE': 'yellow',
	'BORDER': 'black'
}

def rotateFlat(shape):
	o = []	#re-order
	detect = [max(x) for x in [*zip(*shape)]]
	if detect[0] == 0:
		return shape # already flat
	elif detect[1] == 0:
		o = [1,0,2]
	elif detect[2] == 0:
		o = [2,1,0]
	else:
		raise Exception('Nonrotatable shape')

	return {(x[o[0]],x[o[1]],x[o[2]]) for x in shape}

def getSimplifiedShape(index, matrix):
	tiles = []
	for x,surface in enumerate(matrix):
		for y,line in enumerate(surface):
			for z,point in enumerate(line):
				if point == index:
					tiles.append([x,y,z])

	simplifier = [min(x) for x in [*zip(*tiles)]]	#Transpose to find min x y z
	simplified_shape = {(tile[0] - simplifier[0], tile[1] - simplifier[1], tile[2] - simplifier[2]) for tile in tiles}
	simplified_shape = rotateFlat(simplified_shape)

	return simplified_shape

def getShape(index, matrix):
	simplified_shape = getSimplifiedShape(index, matrix)
	for SHAPE in SHAPES:
		if simplified_shape in SHAPES[SHAPE]:
			return SHAPE
	else:
		print(f'Cannot find shape {simplified_shape}')
		raise Exception()

def getColor(matrix, layer, x, y):
	if isBorder(x,y):
		return COLORS['BORDER']
	elif isInnerBorder(x,y):
		if _isInnerBorder(x) and not _isInnerBorder(y):
			x, y = getIndex(x,y)
			index_1 = matrix[layer][y][x-1]
			index_2 = matrix[layer][y][x]
		elif _isInnerBorder(y) and not _isInnerBorder(x):
			x, y = getIndex(x,y)
			index_1 = matrix[layer][y-1][x]
			index_2 = matrix[layer][y][x]
		else:
			return COLORS['BORDER']

		if index_1 == index_2:
			shape = getShape(index_1, matrix)
			return COLORS[shape]
		else:
			return COLORS['BORDER']
	else:
		x, y = getIndex(x,y)
		index = matrix[layer][y][x]
		shape = getShape(index, matrix)
		return COLORS[shape]

def draw(matrix, offset_x = 30, offset_y = 30):
	size = BORDER_THICKNESS * 9 + SQUARE_THICKNESS * 8
	window = GraphWin(width = size * 3  + offset_x * 4, height = size + offset_y * 2 + 40)

	indexSet = set()
	score = 0
	for surface in matrix:
		for line in surface:
			for index in line:
				if index in indexSet:
					continue
				else:
					indexSet.add(index)
					score += POINTS[getShape(index, matrix)]

	message = Text(Point(window.getWidth() / 2 - 50, window.getHeight() - 40), f'Score: {score}')
	message.setTextColor('black')
	message.setSize(20)
	message.draw(window)

	for layer in range(3):
		for y in range(size):
			x = 0
			while x < size:
				color = getColor(matrix, layer, x, y)
				point_a = Point(x + offset_x * (layer + 1) + layer * size, y + offset_y)

				if color != COLORS['BORDER']:
					if _isInnerBorder(x):
						length = BORDER_THICKNESS
					else:
						length = SQUARE_THICKNESS
				elif _isBorder(y):
					length = size
				elif _isInnerBorder(x) or _isBorder(x):
					length = BORDER_THICKNESS
				else:
					length = SQUARE_THICKNESS

				point_b = Point(point_a.getX() + length	, point_a.getY())
				x += length
				line = Line(point_a, point_b)
				line.setFill(color)
				line.draw(window)


def _isBorder(x):
	return x < BORDER_THICKNESS or x >= ((BORDER_THICKNESS + SQUARE_THICKNESS) * 8)

def isBorder(x, y):
	return _isBorder(x) or _isBorder(y)

def _isInnerBorder(x):
	if _isBorder(x):
		return False

	while x >= BORDER_THICKNESS + SQUARE_THICKNESS:
		x -= BORDER_THICKNESS + SQUARE_THICKNESS
		if _isBorder(x):
			return True

	return False

def isInnerBorder(x,y):
	if isBorder(x,y):
		return False

	return _isInnerBorder(x) or _isInnerBorder(y)

def getIndex(x,y):
	return (x//(BORDER_THICKNESS + SQUARE_THICKNESS), y//(BORDER_THICKNESS + SQUARE_THICKNESS))

testArr = [
			[
				[0, 0, 1, 1, 1, 2, 2, 2],
				[3, 0, 0, 1, 4, 13, 14, 2],
				[3, 17, 18, 4, 4, 21, 22, 23],
				[24, 25, 26, 27, 4, 29, 30, 31],
				[32, 33, 34, 35, 36, 37, 38, 39],
				[40, 41, 42, 43, 44, 45, 46, 47],
				[48, 49, 50, 51, 52, 53, 54, 55],
				[56, 57, 58, 59, 60, 61, 62, 63]
			],
			[
				[64, 65, 66, 67, 68, 69, 70, 71],
				[72, 73, 74, 75, 76, 77, 78, 79],
				[80, 81, 82, 83, 84, 85, 86, 87],
				[88, 89, 90, 91, 92, 93, 94, 95],
				[96, 97, 98, 99, 100, 101, 102, 103],
				[104, 105, 106, 107, 108, 109, 110, 111],
				[112, 113, 114, 115, 116, 117, 118, 119],
				[120, 121, 122, 123, 124, 125, 126, 127]
			],
			[
				[128, 129, 130, 131, 132, 133, 134, 135],
				[136, 137, 138, 139, 140, 141, 142, 143],
				[144, 145, 146, 147, 148, 149, 150, 151],
				[152, 153, 154, 155, 156, 157, 158, 159],
				[160, 161, 162, 163, 164, 165, 166, 167],
				[168, 169, 170, 171, 172, 173, 174, 175],
				[176, 177, 178, 179, 180, 181, 182, 183],
				[184, 185, 186, 187, 188, 189, 190, 191]
			]
		]

# draw(testArr)
f = open("blocks.txt", "r", encoding="utf-8")
matrix = []
layer = []
for line in f:
	line.replace(';',' ').replace(',',' ')
	data = [int(x) for x in line.split()]
	if len(data) == 0:
		continue
	assert len(data) == 8
	layer.append(data)
	if len(layer) == 8:
		matrix.append(layer)
		layer = []

f.close()

draw(matrix)
input("Enter any key to quit.")

You'd need to have python + graphics.py installed. Make a text file, name it "blocks.txt", and it *should* work.

Here's an example of how "blocks.txt" should look like :D

0 0 1 1 1 2 2 2
3 0 0 1 4 13 14 2
3 17 18 4 4 21 22 23
24 25 26 27 4 29 30 31
32 33 34 35 36 37 38 39
40 41 42 43 44 45 46 47
48 49 50 51 52 53 54 55
56 57 58 59 60 61 62 63

64 65 66 67 68 69 70 71
72 73 74 75 76 77 78 79
80 81 82 83 84 85 86 87
88 89 90 91 92 93 94 95
96 97 98 99 100 101 102 103
104 105 106 107 108 109 110 111
112 113 114 115 116 117 118 119
120 121 122 123 124 125 126 127

128 129 130 131 132 133 134 135
136 137 138 139 140 141 142 143
144 145 146 147 148 149 150 151
152 153 154 155 156 157 158 159
160 161 162 163 164 165 166 167
168 169 170 171 172 173 174 175
176 177 178 179 180 181 182 183
184 185 186 187 188 189 190 191

If you don't get any of this... well, it's just a tool ~~that I made after Yoshi submitted numbers~~ that is kinda used to grade stuff.

I'll be making the grading script for the rock-paper-scissor game later, for those who wants to poke around with that too :D

Link to comment
Share on other sites

Here's a the results!

  1. @Aia del Mana - 188
  2. @Fyrd Argentus - 184
  3. @Yoshi - 181
  4. @Kaya - 181 (Yoshi submitted earlier)
  5. @Nepgear- 177
  6. @Jubaris - 174
  7. @Dracoloth - 165
  8. @Pipstickz - 164
  9. @Aelis - 160
  10. @Ungod - 116

Congratulations to the top masons!

In addition, @Aia del Manaand @Fyrd Argentusboth presented solutions that are quite fascinating. They both won a WP each! Congratulations!

Below are each player's submission, in order:

Edited by Demonic God
Link to comment
Share on other sites

3. Yoshi

submission.thumb.png.a94126cf79a36d5bcd846dd310cf62d0.png

The first submission (and so far... the only submission that used my suggestion of a numbering format. With multiple revisions. He himself was the reason why I made the python script for visualization and scoring xD.

(Note to Yoshi - you could've gotten 184 - and the second prize, as you did submit before Fyrd)

sub.thumb.png.402537d6cb0bac0991d84a638380e907.png

Link to comment
Share on other sites

10. Ungod

submission.png.04bb2ddcc93eb968e6a51c305bc62ef9.png

I'll... just assume I understand his schematics. It also seems that he's missing 6 empty spaces unaccounted for, if I'm reading his material summary correctly xD

Regardless, a very creative approach, that comes with some actual masonry reasoning! - had it come with some actual rocks and such, or a small scale physical model with some stones, I'd have awarded a wp :P

Link to comment
Share on other sites

1 hour ago, Demonic God said:

It also seems that he's missing 6 empty spaces unaccounted for

you're right, my description of the z stones is somewhat wrong (well, it works if I change the design for the middle sections, but...what I described and what I drew are different indeed)

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
 Share

  • Forum Statistics

    16.8k
    Total Topics
    180k
    Total Posts
×
×
  • Create New...