Skip to content

Commit

Permalink
[queen-attack] Implementation (#615)
Browse files Browse the repository at this point in the history
  • Loading branch information
habere-et-dispertire committed May 15, 2023
1 parent d252c20 commit d58d736
Show file tree
Hide file tree
Showing 9 changed files with 283 additions and 0 deletions.
9 changes: 9 additions & 0 deletions config.json
Original file line number Diff line number Diff line change
Expand Up @@ -463,6 +463,15 @@
"prerequisites": [],
"difficulty": 1,
"topics": []
},
{
"slug": "queen-attack",
"name": "Queen Attack",
"uuid": "0ce48cac-a3ad-42d5-8903-d1e062287802",
"practices": [],
"prerequisites": [],
"difficulty": 1,
"topics": []
}
]
},
Expand Down
25 changes: 25 additions & 0 deletions exercises/practice/queen-attack/.docs/instructions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Instructions

Given the position of two queens on a chess board, indicate whether or not they are positioned so that they can attack each other.

In the game of chess, a queen can attack pieces which are on the same row, column, or diagonal.

A chessboard can be represented by an 8 by 8 array.

So if you are told the white queen is at `c5` (zero-indexed at column 2, row 3) and the black queen at `f2` (zero-indexed at column 5, row 6), then you know that the set-up is like so:

```text
a b c d e f g h
8 _ _ _ _ _ _ _ _ 8
7 _ _ _ _ _ _ _ _ 7
6 _ _ _ _ _ _ _ _ 6
5 _ _ W _ _ _ _ _ 5
4 _ _ _ _ _ _ _ _ 4
3 _ _ _ _ _ _ _ _ 3
2 _ _ _ _ _ B _ _ 2
1 _ _ _ _ _ _ _ _ 1
a b c d e f g h
```

You are also able to answer whether the queens can attack each other.
In this case, that answer would be yes, they can, because both pieces share a diagonal.
19 changes: 19 additions & 0 deletions exercises/practice/queen-attack/.meta/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"authors": [
"habere-et-dispertire"
],
"files": {
"solution": [
"Queen.rakumod"
],
"test": [
"queen-attack.rakutest"
],
"example": [
".meta/solutions/Queen.rakumod"
]
},
"blurb": "Given the position of two queens on a chess board, indicate whether or not they are positioned so that they can attack each other.",
"source": "J Dalbey's Programming Practice problems",
"source_url": "https://users.csc.calpoly.edu/~jdalbey/103/Projects/ProgrammingPractice.html"
}
13 changes: 13 additions & 0 deletions exercises/practice/queen-attack/.meta/solutions/Queen.rakumod
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
unit class Queen;

has Int() ($.row where 0..7, $.column where 0..7);

method can-attack (:$row, :$column --> Bool() ) {
with cache map { .head, .tail }, ($.row, $.column), ($row, $column) {
when [eqv] .list { fail } # Same square
when [==] map *.head, .list # Same file
or [==] map *.tail, .list # Same rank
or [==] map *.abs , [Z-] .list { True } # Same diagonal
default { False }
}
}
55 changes: 55 additions & 0 deletions exercises/practice/queen-attack/.meta/template-data.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package: Queen
methods: can-attack
properties:
create:
test: |-
if %case<expected><error>:exists {
sprintf(q:to/END/, (%case<input><queen><position><row>, %case<input><queen><position><column>, %case<expected><error>, %case<description>).map(*.raku));
throws-like(
{ Queen.new( :row(%s), :column(%s) ) },
Exception,
message => /:i
%s
|| "type check failed"
/,
%s,
);
END
} else {
sprintf(q:to/END/, (%case<input><queen><position><row>, %case<input><queen><position><column>, %case<description>).map(*.raku));
try {
my $QA = Queen.new( :row(%s), :column(%s) );
} // fail %s;
END
}
canAttack:
test: |-
sprintf(q:to/END/, (%case<input><white_queen><position><row>, %case<input><white_queen><position><column>, %case<input><black_queen><position><row>, %case<input><black_queen><position><column>).map(*.raku), %case<expected>, %case<description>.map(*.raku));
cmp-ok(
Queen.new( :row(%s), :column(%s) ).can-attack( :row(%s), :column(%s) ),
&infix:<eqv>,
%s,
%s,
);
END
unit: class
example: |-
has Int() ($.row where 0..7, $.column where 0..7);
method can-attack (:$row, :$column --> Bool() ) {
with cache map { .head, .tail }, ($.row, $.column), ($row, $column) {
when [eqv] .list { fail } # Same square
when [==] map *.head, .list # Same file
or [==] map *.tail, .list # Same rank
or [==] map *.abs , [Z-] .list { True } # Same diagonal
default { False }
}
}
stub: |-
has ($.row, $.column);
method can-attack (:$row, :$column) {
}
49 changes: 49 additions & 0 deletions exercises/practice/queen-attack/.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.

[3ac4f735-d36c-44c4-a3e2-316f79704203]
description = "Test creation of Queens with valid and invalid positions -> queen with a valid position"

[4e812d5d-b974-4e38-9a6b-8e0492bfa7be]
description = "Test creation of Queens with valid and invalid positions -> queen must have positive row"

[f07b7536-b66b-4f08-beb9-4d70d891d5c8]
description = "Test creation of Queens with valid and invalid positions -> queen must have row on board"

[15a10794-36d9-4907-ae6b-e5a0d4c54ebe]
description = "Test creation of Queens with valid and invalid positions -> queen must have positive column"

[6907762d-0e8a-4c38-87fb-12f2f65f0ce4]
description = "Test creation of Queens with valid and invalid positions -> queen must have column on board"

[33ae4113-d237-42ee-bac1-e1e699c0c007]
description = "Test the ability of one queen to attack another -> cannot attack"

[eaa65540-ea7c-4152-8c21-003c7a68c914]
description = "Test the ability of one queen to attack another -> can attack on same row"

[bae6f609-2c0e-4154-af71-af82b7c31cea]
description = "Test the ability of one queen to attack another -> can attack on same column"

[0e1b4139-b90d-4562-bd58-dfa04f1746c7]
description = "Test the ability of one queen to attack another -> can attack on first diagonal"

[ff9b7ed4-e4b6-401b-8d16-bc894d6d3dcd]
description = "Test the ability of one queen to attack another -> can attack on second diagonal"

[0a71e605-6e28-4cc2-aa47-d20a2e71037a]
description = "Test the ability of one queen to attack another -> can attack on third diagonal"

[0790b588-ae73-4f1f-a968-dd0b34f45f86]
description = "Test the ability of one queen to attack another -> can attack on fourth diagonal"

[543f8fd4-2597-4aad-8d77-cbdab63619f8]
description = "Test the ability of one queen to attack another -> cannot attack if falling diagonals are only the same when reflected across the longest falling diagonal"
6 changes: 6 additions & 0 deletions exercises/practice/queen-attack/Queen.rakumod
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
unit class Queen;

has ($.row, $.column);

method can-attack (:$row, :$column) {
}
106 changes: 106 additions & 0 deletions exercises/practice/queen-attack/queen-attack.rakutest
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
#!/usr/bin/env raku
use Test;
use lib $?FILE.IO.dirname;
use Queen;

try { # begin: 3ac4f735-d36c-44c4-a3e2-316f79704203
my $QA = Queen.new( :row(2), :column(2) );
} // fail "Test creation of Queens with valid and invalid positions: queen with a valid position"; # end: 3ac4f735-d36c-44c4-a3e2-316f79704203

throws-like( # begin: 4e812d5d-b974-4e38-9a6b-8e0492bfa7be
{ Queen.new( :row(-2), :column(2) ) },
Exception,
message => /:i
"row not positive"
|| "type check failed"
/,
"Test creation of Queens with valid and invalid positions: queen must have positive row",
); # end: 4e812d5d-b974-4e38-9a6b-8e0492bfa7be

throws-like( # begin: f07b7536-b66b-4f08-beb9-4d70d891d5c8
{ Queen.new( :row(8), :column(4) ) },
Exception,
message => /:i
"row not on board"
|| "type check failed"
/,
"Test creation of Queens with valid and invalid positions: queen must have row on board",
); # end: f07b7536-b66b-4f08-beb9-4d70d891d5c8

throws-like( # begin: 15a10794-36d9-4907-ae6b-e5a0d4c54ebe
{ Queen.new( :row(2), :column(-2) ) },
Exception,
message => /:i
"column not positive"
|| "type check failed"
/,
"Test creation of Queens with valid and invalid positions: queen must have positive column",
); # end: 15a10794-36d9-4907-ae6b-e5a0d4c54ebe

throws-like( # begin: 6907762d-0e8a-4c38-87fb-12f2f65f0ce4
{ Queen.new( :row(4), :column(8) ) },
Exception,
message => /:i
"column not on board"
|| "type check failed"
/,
"Test creation of Queens with valid and invalid positions: queen must have column on board",
); # end: 6907762d-0e8a-4c38-87fb-12f2f65f0ce4

cmp-ok( # begin: 33ae4113-d237-42ee-bac1-e1e699c0c007
Queen.new( :row(2), :column(4) ).can-attack( :row(6), :column(6) ),
&infix:<eqv>,
False,
"Test the ability of one queen to attack another: cannot attack",
); # end: 33ae4113-d237-42ee-bac1-e1e699c0c007

cmp-ok( # begin: eaa65540-ea7c-4152-8c21-003c7a68c914
Queen.new( :row(2), :column(4) ).can-attack( :row(2), :column(6) ),
&infix:<eqv>,
True,
"Test the ability of one queen to attack another: can attack on same row",
); # end: eaa65540-ea7c-4152-8c21-003c7a68c914

cmp-ok( # begin: bae6f609-2c0e-4154-af71-af82b7c31cea
Queen.new( :row(4), :column(5) ).can-attack( :row(2), :column(5) ),
&infix:<eqv>,
True,
"Test the ability of one queen to attack another: can attack on same column",
); # end: bae6f609-2c0e-4154-af71-af82b7c31cea

cmp-ok( # begin: 0e1b4139-b90d-4562-bd58-dfa04f1746c7
Queen.new( :row(2), :column(2) ).can-attack( :row(0), :column(4) ),
&infix:<eqv>,
True,
"Test the ability of one queen to attack another: can attack on first diagonal",
); # end: 0e1b4139-b90d-4562-bd58-dfa04f1746c7

cmp-ok( # begin: ff9b7ed4-e4b6-401b-8d16-bc894d6d3dcd
Queen.new( :row(2), :column(2) ).can-attack( :row(3), :column(1) ),
&infix:<eqv>,
True,
"Test the ability of one queen to attack another: can attack on second diagonal",
); # end: ff9b7ed4-e4b6-401b-8d16-bc894d6d3dcd

cmp-ok( # begin: 0a71e605-6e28-4cc2-aa47-d20a2e71037a
Queen.new( :row(2), :column(2) ).can-attack( :row(1), :column(1) ),
&infix:<eqv>,
True,
"Test the ability of one queen to attack another: can attack on third diagonal",
); # end: 0a71e605-6e28-4cc2-aa47-d20a2e71037a

cmp-ok( # begin: 0790b588-ae73-4f1f-a968-dd0b34f45f86
Queen.new( :row(1), :column(7) ).can-attack( :row(0), :column(6) ),
&infix:<eqv>,
True,
"Test the ability of one queen to attack another: can attack on fourth diagonal",
); # end: 0790b588-ae73-4f1f-a968-dd0b34f45f86

cmp-ok( # begin: 543f8fd4-2597-4aad-8d77-cbdab63619f8
Queen.new( :row(4), :column(1) ).can-attack( :row(2), :column(5) ),
&infix:<eqv>,
False,
"Test the ability of one queen to attack another: cannot attack if falling diagonals are only the same when reflected across the longest falling diagonal",
); # end: 543f8fd4-2597-4aad-8d77-cbdab63619f8

done-testing;

0 comments on commit d58d736

Please sign in to comment.