Skip to content

[V3] Annalyn's Infiltration: fix everything around this exercise #1020

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 14 commits into from
Mar 2, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions concepts/booleans/about.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,11 @@

JavaScript uses `true` and `false` to represent the two truth values of logic.

In JavaScript, for each of the three logical operations (AND, OR and NOT) there is a corresponding operator: `&&`, `||` and `!`. In general, there are rules regarding the order of the operations and, in this case, `!` (negation) is applied first, and then `&&` (conjunction) and then `||` (disjunction).
In JavaScript, for each of the three logical operations (AND, OR and NOT) there is a corresponding operator: `&&`, `||` and `!`.
In general, there are rules regarding the order of the operations and, in this case, `!` (negation) is applied first, and then `&&` (conjunction) and then `||` (disjunction).

The order of operations between the operators can be overcome by using an operator with an even higher precedence: `( )`, named the 'Grouping operator' or simply said 'parentheses'. As a matter of fact the `( )` operator has the highest precedence of all JavaScript operators. More information about operators precedence [here].
The order of operations between the operators can be overcome by using an operator with an even higher precedence: `( )`, named the 'Grouping operator' or simply said 'parentheses'.
As a matter of fact, the `( )` operator has the highest precedence of all JavaScript operators.
More information about operators precedence found [here].

[here]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Operator_Precedence
3 changes: 2 additions & 1 deletion concepts/booleans/introduction.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# Introduction

A boolean represents one of two values: `true` or `false`. Logical operators (`!`, `&&`, `||`) are typically used with boolean values and they return a boolean value.
A boolean represents one of two values: `true` or `false`.
Logical operators (`!`, `&&`, `||`) are typically used with boolean values and they return a boolean value.
2 changes: 1 addition & 1 deletion concepts/booleans/links.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[
{
"url": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Operator_Precedence",
"description": "here"
"description": "MDN: Operator precedence"
}
]
5 changes: 3 additions & 2 deletions config.json
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,8 @@
"status": "active"
},
{
"slug": "booleans",
"slug": "annalyns-infiltration",
"name": "Annalyn's Infiltration",
"uuid": "5acafcbb-20a0-45b9-b276-3d167e0de313",
"concepts": ["booleans"],
"prerequisites": ["basics"],
Expand Down Expand Up @@ -1517,7 +1518,7 @@
"uuid": "791d215c-6813-479a-a126-d9ad9cdc49a9",
"slug": "booleans",
"name": "Booleans",
"blurb": "TODO: add blurb for booleans concept"
"blurb": "A boolean represents one of two values. JavaScript has various logical operators that return a boolean value."
},
{
"uuid": "fba5ca5c-849c-44ee-91be-3d6c81a3cf4e",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
## 2. Check if the 'Approach and Spy' action is possible

- Logical expressions are evaluated from left to right and are tested for possible 'short-circuits'.
- For a more complete understanding of the left-to-right mechanic, you can take a look at [this article](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Operator_Precedence)!
- For a more complete understanding of the left-to-right mechanic, take a look at [this article](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Operator_Precedence)!

## 3. Check if the 'Signal Prisoner' action is possible

Expand Down
78 changes: 78 additions & 0 deletions exercises/concept/annalyns-infiltration/.docs/instructions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
# Instructions

In this exercise, you'll be implementing the quest logic for a new RPG game a friend is developing.
The game's main character is Annalyn, a brave girl with a fierce and loyal pet dog.
Unfortunately, disaster strikes, as her best friend was kidnapped while searching for berries in the forest.
Annalyn will try to find and free her best friend, optionally taking her dog with her on this quest.

After some time spent following her best friend's trail, she finds the camp in which her best friend is imprisoned.
It turns out there are two kidnappers: a mighty knight and a cunning archer.

Having found the kidnappers, Annalyn considers which of the following actions she can engage in:

- _Fast attack_: a fast attack can be made if the **knight** is **_sleeping_**, as it takes time for him to get his armor on, so he will be vulnerable.
- _Spy_: the group can be spied upon if **at least one** of them is **_awake_**. Otherwise, spying is a waste of time.
- _Signal prisoner_: the prisoner can be signalled using bird sounds if the **prisoner** is **_awake_** and the **archer** is **_sleeping_**, as archers are trained in bird signaling so they could intercept the message.
- _Free prisoner_: Annalyn can try sneaking into the camp to free the prisoner, but this tactic will only work if the **prisoner** is **_awake_** and the **other two characters** are **_sleeping_**.
If the **prisoner** is **_sleeping_**, they'll be startled by Annalyn's sudden appearance and will awaken the other two characters.
The prisoner can also be freed if the **archer** is **_sleeping_** and Annalyn has her **pet dog** **_with her_**, as the knight will be scared by the dog and will withdraw, and the archer can't equip his bow fast enough to prevent the prisoner from being freed.

You have four tasks: to implement the logic for determining if the above actions are available based on the state of the three characters found in the forest and whether Annalyn's pet dog is present or not.

## Tasks

## 1. Check if the 'Fast Attack' action is possible

Implement a function named `canExecuteFastAttack` that takes a boolean value which indicates if the knight is awake.
This function returns `true` if the 'Fast Attack' action is available based on the state of the character.
Otherwise, returns `false`:

```javascript
const knightIsAwake = true;
canExecuteFastAttack(knightIsAwake);
// => false
```

## 2. Check if the 'Spy' action is possible

Implement a function named `canSpy` that takes three boolean values, indicating if the knight, archer and the prisoner, respectively, are awake.
The function returns `true` if the 'Spy' action is available based on the state of the characters.
Otherwise, returns `false`:

```javascript
const knightIsAwake = false;
const archerIsAwake = true;
const prisonerIsAwake = false;
canSpy(knightIsAwake, archerIsAwake, prisonerIsAwake);
// => true
```

## 3. Check if the 'Signal Prisoner' action is possible

Implement a function named `canSignalPrisoner` that takes two boolean values, indicating if the archer and the prisoner, respectively, are awake.
The function returns `true` if the 'Signal Prisoner' action is available based on the state of the characters.
Otherwise, returns `false`:

```javascript
const archerIsAwake = false;
const prisonerIsAwake = true;
canSignalPrisoner(archerIsAwake, prisonerIsAwake);
// => true
```

## 4. Check if the 'Free Prisoner' action is possible

Implement a function named `canFreePrisoner` that takes four boolean values.
The first three parameters indicate if the knight, archer and the prisoner, respectively, are awake.
The last parameter indicates if Annalyn's pet dog is present.
The function returns `true` if the 'Free Prisoner' action is available based on the state of the characters and Annalyn's pet dog presence.
Otherwise, it returns `false`:

```javascript
const knightIsAwake = false;
const archerIsAwake = true;
const prisonerIsAwake = false;
const petDogIsPresent = false;
canFreePrisoner(knightIsAwake, archerIsAwake, prisonerIsAwake, petDogIsPresent);
// => false
```
4 changes: 4 additions & 0 deletions exercises/concept/annalyns-infiltration/.docs/introduction.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# Introduction

A boolean represents one of two values: `true` or `false`.
Logical operators (`!`, `&&`, `||`) are typically used with boolean values and they return a boolean value.
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@
}
],
"files": {
"solution": ["booleans.js"],
"test": ["booleans.spec.js"],
"solution": ["annalyns-infiltration.js"],
"test": ["annalyns-infiltration.spec.js"],
"exemplar": [".meta/exemplar.js"]
},
"forked_from": []
Expand Down
35 changes: 35 additions & 0 deletions exercises/concept/annalyns-infiltration/.meta/design.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# Design

## Learning objectives

- Know of the existence of the `boolean` type.
- Know about boolean operators and how to build logical expressions with them.
- Know of the boolean operator precedence rules.
- Know where it's documented, or at least how to search for it.

## Out of scope

- Binary operators

## Concepts

- `booleans`: Know of the existence of the `boolean` type.
Know about boolean operators and how to build logical expressions with them.
Know of the boolean operator precedence rules.
Know where it's documented, or at least how to search for it.

## Prerequisites

- `basics`

## Analyzer

This exercise could benefit from the following rules added to the the [analyzer][analyzer]:

- Verify that the `canExecuteFastAttack` function is as simple as possible (single negation `!`).
- Verify that the `canSpy` function is as simple as possible (double OR `||`).
- Verify that the `canSignalPrisoner` function is as simple as possible (single OR `||` and single negation `!`)
- Verify that the `canFreePrisoner` function is not overly complex.
Helper variables may be used, but those should result in a suggestion about combining them (informational, non-essential).

[analyzer]: https://github.com/exercism/javascript-analyzer
78 changes: 78 additions & 0 deletions exercises/concept/annalyns-infiltration/.meta/exemplar.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
// @ts-check
//
// ☝🏽 The line above enables type checking for this file. Various IDEs interpret
// the @ts-check directive. It will give you helpful autocompletion on the web
// and supported IDEs when implementing this exercise. You don't need to
// understand types, JSDoc, or TypeScript in order to complete this JavaScript
// exercise, and can completely ignore this comment block and directive.

// 👋🏽 Hi again!
//
// A quick reminder about exercise stubs:
//
// 💡 You're allowed to completely clear any stub before you get started. Often
// we recommend using the stub, because they are already set-up correctly to
// work with the tests, which you can find in ./annalyns-infiltration.spec.js.
//
// 💡 You don't need to write JSDoc comment blocks yourself; it is not expected
// in idiomatic JavaScript, but some companies and style-guides do enforce them.
//
// Now help Annalyn free her best friend!

/**
* The fast attack is available when the knight is sleeping
*
* @param {boolean} knightIsAwake
*
* @return {boolean} Whether or not you can execute a fast attack.
*/
export function canExecuteFastAttack(knightIsAwake) {
return !knightIsAwake;
}

/**
* A useful spy captures information, which they can't do if everyone's asleep.
*
* @param {boolean} knightIsAwake
* @param {boolean} archerIsAwake
* @param {boolean} prisonerIsAwake
*
* @returns {boolean} Whether or not you can spy on someone.
*/
export function canSpy(knightIsAwake, archerIsAwake, prisonerIsAwake) {
return knightIsAwake || archerIsAwake || prisonerIsAwake;
}

/**
* You'll get caught by the archer if you signal while they're awake.
*
* @param {boolean} archerIsAwake
* @param {boolean} prisonerIsAwake
*
* @returns {boolean} Whether or not you can send a signal to the prisoner.
*/
export function canSignalPrisoner(archerIsAwake, prisonerIsAwake) {
return prisonerIsAwake && !archerIsAwake;
}

/**
* The final stage in the plan: freeing Annalyn's best friend.
*
* @param {boolean} knightIsAwake
* @param {boolean} archerIsAwake
* @param {boolean} prisonerIsAwake
* @param {boolean} petDogIsPresent
*
* @returns {boolean} Whether or not you can free Annalyn's friend.
*/
export function canFreePrisoner(
knightIsAwake,
archerIsAwake,
prisonerIsAwake,
petDogIsPresent
) {
return (
(!knightIsAwake && !archerIsAwake && prisonerIsAwake) ||
(petDogIsPresent && !archerIsAwake)
);
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,23 @@
// @ts-check
//
// The line above enables type checking for this file. Various IDEs interpret
// the @ts-check directive. It will give you helpful autocompletion when
// implementing this exercise.
// ☝🏽 The line above enables type checking for this file. Various IDEs interpret
// the @ts-check directive. It will give you helpful autocompletion on the web
// and supported IDEs when implementing this exercise. You don't need to
// understand types, JSDoc, or TypeScript in order to complete this JavaScript
// exercise, and can completely ignore this comment block and directive.

// 👋🏽 Hi again!
//
// A quick reminder about exercise stubs:
//
// 💡 You're allowed to completely clear any stub before you get started. Often
// we recommend using the stub, because they are already set-up correctly to
// work with the tests, which you can find in ./annalyns-infiltration.spec.js.
//
// 💡 You don't need to write JSDoc comment blocks yourself; it is not expected
// in idiomatic JavaScript, but some companies and style-guides do enforce them.
//
// Now help Annalyn free her best friend!

/**
* The fast attack is available when the knight is sleeping
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,24 +3,26 @@ import {
canSpy,
canSignalPrisoner,
canFreePrisoner,
} from './booleans';
} from './annalyns-infiltration';

describe("Annalyn's infiltration", () => {
describe('can execute fast attack', () => {
test(`when the knight is awake`, () => {
const knightIsAwake = true;
const expected = false;

describe('booleans', () => {
describe('canExecuteFastAttack', () => {
let knightIsAwake = true;
let expected = false;
test(`canExecuteFastAttack(${knightIsAwake})`, () => {
expect(canExecuteFastAttack(knightIsAwake)).toBe(expected);
});

knightIsAwake = false;
expected = true;
test(`canExecuteFastAttack(${knightIsAwake})`, () => {
test(`when the knight is asleep`, () => {
const knightIsAwake = false;
const expected = true;

expect(canExecuteFastAttack(knightIsAwake)).toBe(expected);
});
});

describe('canSpy', () => {
describe('can spy', () => {
const CHARACTERS_STATE_COMBINATIONS = [
[false, false, false, false],
[false, false, true, true],
Expand All @@ -42,7 +44,7 @@ describe('booleans', () => {
);
});

describe('canSignalPrisoner', () => {
describe('can signal prisoner', () => {
const CHARACTERS_STATE_COMBINATIONS = [
[false, false, false],
[false, true, true],
Expand All @@ -61,7 +63,7 @@ describe('booleans', () => {
);
});

describe('canFreePrisoner', () => {
describe('can free prisoner', () => {
const CHARACTERS_STATE_COMBINATIONS = [
[false, false, false, false, false],
[false, false, false, true, true],
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
{
"name": "@exercism/javascript-concept-booleans",
"name": "@exercism/javascript-annalyns-infiltration",
"description": "Exercism concept exercise on booleans",
"author": "Ovidiu Miu",
"contributors": [
"Derk-Jan Karrenbeld <derk-jan+git@karrenbeld.info> (https://derk-jan.com)"
],
"private": true,
"repository": {
"type": "git",
"url": "https://github.com/exercism/javascript",
"directory": "languages/javascript/exercises/concept/booleans"
"directory": "exercises/concept/annalyns-infiltration"
},
"devDependencies": {
"@babel/cli": "^7.13.0",
Expand Down
Loading