Skip to content

Commit 4308bc2

Browse files
flower-field replaces minesweeper (#278)
1 parent 93d9d83 commit 4308bc2

File tree

12 files changed

+3817
-1
lines changed

12 files changed

+3817
-1
lines changed

config.json

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -564,13 +564,22 @@
564564
"prerequisites": [],
565565
"difficulty": 7
566566
},
567+
{
568+
"slug": "flower-field",
569+
"name": "Flower Field",
570+
"uuid": "bb250fb5-0d8a-49d2-bcce-6fd107117c16",
571+
"practices": [],
572+
"prerequisites": [],
573+
"difficulty": 7
574+
},
567575
{
568576
"slug": "minesweeper",
569577
"name": "Minesweeper",
570578
"uuid": "5f717115-0688-424d-959f-33f5c83e44cb",
571579
"practices": [],
572580
"prerequisites": [],
573-
"difficulty": 7
581+
"difficulty": 7,
582+
"status": "deprecated"
574583
},
575584
{
576585
"slug": "state-of-tic-tac-toe",
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
# Instructions
2+
3+
Your task is to add flower counts to empty squares in a completed Flower Field garden.
4+
The garden itself is a rectangle board composed of squares that are either empty (`' '`) or a flower (`'*'`).
5+
6+
For each empty square, count the number of flowers adjacent to it (horizontally, vertically, diagonally).
7+
If the empty square has no adjacent flowers, leave it empty.
8+
Otherwise replace it with the count of adjacent flowers.
9+
10+
For example, you may receive a 5 x 4 board like this (empty spaces are represented here with the '·' character for display on screen):
11+
12+
```text
13+
·*·*·
14+
··*··
15+
··*··
16+
·····
17+
```
18+
19+
Which your code should transform into this:
20+
21+
```text
22+
1*3*1
23+
13*31
24+
·2*2·
25+
·111·
26+
```
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# Introduction
2+
3+
[Flower Field][history] is a compassionate reimagining of the popular game Minesweeper.
4+
The object of the game is to find all the flowers in the garden using numeric hints that indicate how many flowers are directly adjacent (horizontally, vertically, diagonally) to a square.
5+
"Flower Field" shipped in regional versions of Microsoft Windows in Italy, Germany, South Korea, Japan and Taiwan.
6+
7+
[history]: https://web.archive.org/web/20020409051321fw_/http://rcm.usr.dsi.unimi.it/rcmweb/fnm/
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
{
2+
"authors": [
3+
"keiravillekode"
4+
],
5+
"files": {
6+
"solution": [
7+
"flower_field.asm"
8+
],
9+
"test": [
10+
"flower_field_test.c"
11+
],
12+
"example": [
13+
".meta/example.asm"
14+
]
15+
},
16+
"blurb": "Mark all the flowers in a garden."
17+
}
Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
section .text
2+
global annotate
3+
4+
; | Register | Usage | Type | Description |
5+
; | -------- | ------------ | ------- | --------------------------------------------- |
6+
; | `rdi` | input/output | address | null-terminated output string |
7+
; | `rsi` | input | address | null-terminated input string |
8+
; | `al` | temporary | byte | input character |
9+
; | `rbx` | temporary | address | pointer into input |
10+
; | `rcx` | temporary | integer | number of adjacent flowers |
11+
; | `rdx` | temporary | address | line length (including newline character) |
12+
; | `rbp` | temporary | address | location of input's null terminator |
13+
; | `r8` | temporary | address | previous row (or current for first row) |
14+
; | `r9` | temporary | address | current row |
15+
; | `r10` | temporary | address | next row (or current for last row) |
16+
; | `r11` | temporary | address | row of adjacent square |
17+
; | `r12` | temporary | integer | previous column (or current for first column) |
18+
; | `r13` | temporary | integer | current column |
19+
; | `r14` | temporary | integer | next column (or current for last column) |
20+
; | `r15` | temporary | integer | column of adjacent square |
21+
22+
; extern void annotate(char *buffer, const char *garden);
23+
annotate:
24+
push rbx
25+
push rbp
26+
push r12
27+
push r13
28+
push r14
29+
push r15
30+
cld
31+
mov rbx, rsi
32+
mov al, [rbx] ; read first byte of garden
33+
test al, al
34+
jz .return
35+
36+
.find_newline:
37+
lodsb
38+
cmp al, 0x0a
39+
jne .find_newline
40+
41+
mov rdx, rsi
42+
mov rsi, rbx
43+
sub rdx, rbx ; line length (including newline character)
44+
45+
.find_null:
46+
add rbx, rdx ; jump ahead by line length
47+
mov al, [rbx]
48+
test al, al
49+
jnz .find_null
50+
51+
mov rbp, rbx ; location of input's null terminator
52+
mov r9, rsi
53+
mov r10, rsi ; start of first row
54+
55+
.next_row:
56+
xor r13, r13 ; first column
57+
xor r14, r14
58+
mov r8, r9 ; current row becomes previous row
59+
mov r9, r10 ; next row becomes current row
60+
61+
mov r10, r9
62+
add r10, rdx ; next row
63+
cmp r10, rbp
64+
jne .first_column
65+
66+
mov r10, r9 ; last row
67+
68+
.first_column:
69+
cmp rdx, 1
70+
je .write_newline ; jump ahead if rows contain no squares
71+
72+
.next_column:
73+
mov r12, r13 ; current column becomes previous column
74+
mov r13, r14 ; next column becomes current column
75+
mov rax, r13
76+
add r14, 2
77+
cmp r14, rdx
78+
je .update_next_column ; no more columns?
79+
80+
inc rax
81+
82+
.update_next_column:
83+
mov r14, rax ; next column
84+
mov al, [r9 + r13] ; garden square
85+
cmp al, '*'
86+
je .write_square ; jump ahead if we have reached a flower
87+
88+
xor rcx, rcx ; number of adjacent flowers
89+
mov r11, r8
90+
sub r11, rdx
91+
92+
.adjacent_row:
93+
add r11, rdx
94+
mov r15, r12
95+
dec r15
96+
97+
.adjacent_column:
98+
inc r15
99+
mov al, [r11 + r15] ; adjacent square
100+
cmp al, '*'
101+
jne .next_adjacent
102+
103+
inc rcx ; update flower count
104+
105+
.next_adjacent:
106+
cmp r15, r14
107+
jne .adjacent_column
108+
109+
cmp r11, r10
110+
jne .adjacent_row
111+
112+
mov al, ' '
113+
test rcx, rcx
114+
jz .write_square
115+
mov al, '0'
116+
add al, cl ; flower count, as ASCII digit
117+
118+
.write_square:
119+
stosb
120+
cmp r13, r14
121+
jne .next_column
122+
123+
.write_newline:
124+
mov al, 0x0a
125+
stosb ; write '\n'
126+
cmp r9, r10
127+
jne .next_row
128+
129+
.return:
130+
xor al, al
131+
stosb ; null terminator
132+
pop r15
133+
pop r14
134+
pop r13
135+
pop r12
136+
pop rbp
137+
pop rbx
138+
ret
139+
140+
%ifidn __OUTPUT_FORMAT__,elf64
141+
section .note.GNU-stack noalloc noexec nowrite progbits
142+
%endif
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
# This is an auto-generated file.
2+
#
3+
# Regenerating this file via `configlet sync` will:
4+
# - Recreate every `description` key/value pair
5+
# - Recreate every `reimplements` key/value pair, where they exist in problem-specifications
6+
# - Remove any `include = true` key/value pair (an omitted `include` key implies inclusion)
7+
# - Preserve any other key/value pair
8+
#
9+
# As user-added comments (using the # character) will be removed when this file
10+
# is regenerated, comments can be added via a `comment` key.
11+
12+
[237ff487-467a-47e1-9b01-8a891844f86c]
13+
description = "no rows"
14+
15+
[4b4134ec-e20f-439c-a295-664c38950ba1]
16+
description = "no columns"
17+
18+
[d774d054-bbad-4867-88ae-069cbd1c4f92]
19+
description = "no flowers"
20+
21+
[225176a0-725e-43cd-aa13-9dced501f16e]
22+
description = "garden full of flowers"
23+
24+
[3f345495-f1a5-4132-8411-74bd7ca08c49]
25+
description = "flower surrounded by spaces"
26+
27+
[6cb04070-4199-4ef7-a6fa-92f68c660fca]
28+
description = "space surrounded by flowers"
29+
30+
[272d2306-9f62-44fe-8ab5-6b0f43a26338]
31+
description = "horizontal line"
32+
33+
[c6f0a4b2-58d0-4bf6-ad8d-ccf4144f1f8e]
34+
description = "horizontal line, flowers at edges"
35+
36+
[a54e84b7-3b25-44a8-b8cf-1753c8bb4cf5]
37+
description = "vertical line"
38+
39+
[b40f42f5-dec5-4abc-b167-3f08195189c1]
40+
description = "vertical line, flowers at edges"
41+
42+
[58674965-7b42-4818-b930-0215062d543c]
43+
description = "cross"
44+
45+
[dd9d4ca8-9e68-4f78-a677-a2a70fd7a7b8]
46+
description = "large garden"
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
AS = nasm
2+
3+
CFLAGS = -g -Wall -Wextra -pedantic -Werror
4+
LDFLAGS =
5+
ASFLAGS = -g -F dwarf -Werror
6+
7+
ifeq ($(shell uname -s),Darwin)
8+
ifeq ($(shell sysctl -n hw.optional.arm64 2>/dev/null),1)
9+
ALL_CFLAGS = -target x86_64-apple-darwin
10+
endif
11+
ALL_LDFLAGS = -Wl,-pie
12+
ALL_ASFLAGS = -f macho64 --prefix _
13+
else
14+
ALL_LDFLAGS = -pie -Wl,--fatal-warnings
15+
ALL_ASFLAGS = -f elf64
16+
endif
17+
18+
ALL_CFLAGS += -std=c99 -fPIE -m64 $(CFLAGS)
19+
ALL_LDFLAGS += $(LDFLAGS)
20+
ALL_ASFLAGS += $(ASFLAGS)
21+
22+
C_OBJS = $(patsubst %.c,%.o,$(wildcard *.c))
23+
AS_OBJS = $(patsubst %.asm,%.o,$(wildcard *.asm))
24+
ALL_OBJS = $(filter-out example.o,$(C_OBJS) $(AS_OBJS) vendor/unity.o)
25+
26+
CC_CMD = $(CC) $(ALL_CFLAGS) -c -o $@ $<
27+
28+
all: tests
29+
@./$<
30+
31+
tests: $(ALL_OBJS)
32+
@$(CC) $(ALL_CFLAGS) $(ALL_LDFLAGS) -o $@ $(ALL_OBJS)
33+
34+
%.o: %.asm
35+
@$(AS) $(ALL_ASFLAGS) -o $@ $<
36+
37+
%.o: %.c
38+
@$(CC_CMD)
39+
40+
vendor/unity.o: vendor/unity.c vendor/unity.h vendor/unity_internals.h
41+
@$(CC_CMD)
42+
43+
clean:
44+
@rm -f *.o vendor/*.o tests
45+
46+
.PHONY: all clean
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
.text
2+
.globl annotate
3+
4+
annotate:
5+
ret

0 commit comments

Comments
 (0)