Skip to content

Commit

Permalink
Add darts exercise (#139)
Browse files Browse the repository at this point in the history
  • Loading branch information
keiravillekode authored Jan 6, 2025
1 parent 5a87770 commit 0a51bb8
Show file tree
Hide file tree
Showing 12 changed files with 3,589 additions and 0 deletions.
8 changes: 8 additions & 0 deletions config.json
Original file line number Diff line number Diff line change
Expand Up @@ -354,6 +354,14 @@
"prerequisites": [],
"difficulty": 5
},
{
"slug": "darts",
"name": "Darts",
"uuid": "4ca6a71e-e422-4158-8968-b11ac98a90ee",
"practices": [],
"prerequisites": [],
"difficulty": 5
},
{
"slug": "diamond",
"name": "Diamond",
Expand Down
31 changes: 31 additions & 0 deletions exercises/practice/darts/.docs/instructions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# Instructions

Calculate the points scored in a single toss of a Darts game.

[Darts][darts] is a game where players throw darts at a [target][darts-target].

In our particular instance of the game, the target rewards 4 different amounts of points, depending on where the dart lands:

![Our dart scoreboard with values from a complete miss to a bullseye](https://assets.exercism.org/images/exercises/darts/darts-scoreboard.svg)

- If the dart lands outside the target, player earns no points (0 points).
- If the dart lands in the outer circle of the target, player earns 1 point.
- If the dart lands in the middle circle of the target, player earns 5 points.
- If the dart lands in the inner circle of the target, player earns 10 points.

The outer circle has a radius of 10 units (this is equivalent to the total radius for the entire target), the middle circle a radius of 5 units, and the inner circle a radius of 1.
Of course, they are all centered at the same point — that is, the circles are [concentric][] defined by the coordinates (0, 0).

Given a point in the target (defined by its [Cartesian coordinates][cartesian-coordinates] `x` and `y`, where `x` and `y` are [real][real-numbers]), calculate the correct score earned by a dart landing at that point.

## Credit

The scoreboard image was created by [habere-et-dispertire][habere-et-dispertire] using [Inkscape][inkscape].

[darts]: https://en.wikipedia.org/wiki/Darts
[darts-target]: https://en.wikipedia.org/wiki/Darts#/media/File:Darts_in_a_dartboard.jpg
[concentric]: https://mathworld.wolfram.com/ConcentricCircles.html
[cartesian-coordinates]: https://www.mathsisfun.com/data/cartesian-coordinates.html
[real-numbers]: https://www.mathsisfun.com/numbers/real-numbers.html
[habere-et-dispertire]: https://exercism.org/profiles/habere-et-dispertire
[inkscape]: https://en.wikipedia.org/wiki/Inkscape
18 changes: 18 additions & 0 deletions exercises/practice/darts/.meta/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"authors": [
"keiravillekode"
],
"files": {
"solution": [
"darts.s"
],
"test": [
"darts_test.c"
],
"example": [
".meta/example.s"
]
},
"blurb": "Calculate the points scored in a single toss of a Darts game.",
"source": "Inspired by an exercise created by a professor Della Paolera in Argentina"
}
38 changes: 38 additions & 0 deletions exercises/practice/darts/.meta/example.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
.text
.globl score

/* extern int score(double x, double y); */
score:
fmul d0, d0, d0 /* x * x */
fmadd d0, d1, d1, d0 /* y * y + x * x */

mov w9, #100
ucvtf d2, w9
fcmpe d0, d2
bgt .zero

mov w9, #25
ucvtf d2, w9
fcmpe d0, d2
bgt .one

mov w9, #1
ucvtf d2, w9
fcmpe d0, d2
bgt .five

.ten:
mov x0, #10
ret

.five:
mov x0, #5
ret

.one:
mov x0, #1
ret

.zero:
mov x0, #0
ret
49 changes: 49 additions & 0 deletions exercises/practice/darts/.meta/tests.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# This is an auto-generated file.
#
# Regenerating this file via `configlet sync` will:
# - Recreate every `description` key/value pair
# - Recreate every `reimplements` key/value pair, where they exist in problem-specifications
# - Remove any `include = true` key/value pair (an omitted `include` key implies inclusion)
# - Preserve any other key/value pair
#
# As user-added comments (using the # character) will be removed when this file
# is regenerated, comments can be added via a `comment` key.

[9033f731-0a3a-4d9c-b1c0-34a1c8362afb]
description = "Missed target"

[4c9f6ff4-c489-45fd-be8a-1fcb08b4d0ba]
description = "On the outer circle"

[14378687-ee58-4c9b-a323-b089d5274be8]
description = "On the middle circle"

[849e2e63-85bd-4fed-bc3b-781ae962e2c9]
description = "On the inner circle"

[1c5ffd9f-ea66-462f-9f06-a1303de5a226]
description = "Exactly on center"

[b65abce3-a679-4550-8115-4b74bda06088]
description = "Near the center"

[66c29c1d-44f5-40cf-9927-e09a1305b399]
description = "Just within the inner circle"

[d1012f63-c97c-4394-b944-7beb3d0b141a]
description = "Just outside the inner circle"

[ab2b5666-b0b4-49c3-9b27-205e790ed945]
description = "Just within the middle circle"

[70f1424e-d690-4860-8caf-9740a52c0161]
description = "Just outside the middle circle"

[a7dbf8db-419c-4712-8a7f-67602b69b293]
description = "Just within the outer circle"

[e0f39315-9f9a-4546-96e4-a9475b885aa7]
description = "Just outside the outer circle"

[045d7d18-d863-4229-818e-b50828c75d19]
description = "Asymmetric position between the inner and middle circles"
36 changes: 36 additions & 0 deletions exercises/practice/darts/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
AS = aarch64-linux-gnu-as
CC = aarch64-linux-gnu-gcc

CFLAGS = -g -Wall -Wextra -pedantic -Werror
LDFLAGS =

ALL_LDFLAGS = -pie -Wl,--fatal-warnings

ALL_CFLAGS = -std=c99 -fPIE $(CFLAGS)
ALL_LDFLAGS += $(LDFLAGS)

C_OBJS = $(patsubst %.c,%.o,$(wildcard *.c))
AS_OBJS = $(patsubst %.s,%.o,$(wildcard *.s))
ALL_OBJS = $(filter-out example.o,$(C_OBJS) $(AS_OBJS) vendor/unity.o)

CC_CMD = $(CC) $(ALL_CFLAGS) -c -o $@ $<

all: tests
qemu-aarch64 -L /usr/aarch64-linux-gnu ./$<

tests: $(ALL_OBJS)
@$(CC) $(ALL_CFLAGS) $(ALL_LDFLAGS) -o $@ $(ALL_OBJS)

%.o: %.s
@$(AS) -o $@ $<

%.o: %.c
@$(CC_CMD)

vendor/unity.o: vendor/unity.c vendor/unity.h vendor/unity_internals.h
@$(CC_CMD)

clean:
@rm -f *.o vendor/*.o tests

.PHONY: all clean
5 changes: 5 additions & 0 deletions exercises/practice/darts/darts.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
.text
.globl score

score:
ret
91 changes: 91 additions & 0 deletions exercises/practice/darts/darts_test.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
#include "vendor/unity.h"

extern int score(double x, double y);

void setUp(void) {
}

void tearDown(void) {
}

void test_missed_target(void) {
TEST_ASSERT_EQUAL_INT(0, score(-9, 9));
}

void test_on_the_outer_circle(void) {
TEST_IGNORE();
TEST_ASSERT_EQUAL_INT(1, score(0, 10));
}

void test_on_the_middle_circle(void) {
TEST_IGNORE();
TEST_ASSERT_EQUAL_INT(5, score(-5, 0));
}

void test_on_the_inner_circle(void) {
TEST_IGNORE();
TEST_ASSERT_EQUAL_INT(10, score(0, -1));
}

void test_exactly_on_center(void) {
TEST_IGNORE();
TEST_ASSERT_EQUAL_INT(10, score(0, 0));
}

void test_near_the_center(void) {
TEST_IGNORE();
TEST_ASSERT_EQUAL_INT(10, score(-0.1, -0.1));
}

void test_just_within_the_inner_circle(void) {
TEST_IGNORE();
TEST_ASSERT_EQUAL_INT(10, score(0.7, 0.7));
}

void test_just_outside_the_inner_circle(void) {
TEST_IGNORE();
TEST_ASSERT_EQUAL_INT(5, score(0.8, -0.8));
}

void test_just_within_the_middle_circle(void) {
TEST_IGNORE();
TEST_ASSERT_EQUAL_INT(5, score(-3.5, 3.5));
}

void test_just_outside_the_middle_circle(void) {
TEST_IGNORE();
TEST_ASSERT_EQUAL_INT(1, score(-3.6, -3.6));
}

void test_just_within_the_outer_circle(void) {
TEST_IGNORE();
TEST_ASSERT_EQUAL_INT(1, score(-7.0, 7.0));
}

void test_just_outside_the_outer_circle(void) {
TEST_IGNORE();
TEST_ASSERT_EQUAL_INT(0, score(7.1, -7.1));
}

void test_asymmetric_position_between_the_inner_and_middle_circles(void) {
TEST_IGNORE();
TEST_ASSERT_EQUAL_INT(5, score(0.5, -4));
}

int main(void) {
UNITY_BEGIN();
RUN_TEST(test_missed_target);
RUN_TEST(test_on_the_outer_circle);
RUN_TEST(test_on_the_middle_circle);
RUN_TEST(test_on_the_inner_circle);
RUN_TEST(test_exactly_on_center);
RUN_TEST(test_near_the_center);
RUN_TEST(test_just_within_the_inner_circle);
RUN_TEST(test_just_outside_the_inner_circle);
RUN_TEST(test_just_within_the_middle_circle);
RUN_TEST(test_just_outside_the_middle_circle);
RUN_TEST(test_just_within_the_outer_circle);
RUN_TEST(test_just_outside_the_outer_circle);
RUN_TEST(test_asymmetric_position_between_the_inner_and_middle_circles);
return UNITY_END();
}
Loading

0 comments on commit 0a51bb8

Please sign in to comment.