Skip to content

Commit 3c73508

Browse files
Reformat concept exercise Wizards and Warriors (#2729)
* Reformat concept exercise Wizards and Warriors Adding two new tasks so the user has to implement the classes and inheritance concept instead of being given Updating hints, instructions and introduction acordingly to the updated Adding new tests for the new tasks, and update the code given to the student * Update exercises/concept/wizards-and-warriors/.docs/hints.md Co-authored-by: Sander Ploegsma <[email protected]> * Applying suggestions * Modifying the order of the tasks Updating Fighter class to not be abstract Updating instructions and hints Updating tests accordingly * Implementing Reflection proxy for wizard and warriors exercise * Finish tests using reflection proxy * Merging preparespell and isvulnerable tasks for wizard into one task * Update test method names and descriptions * Update the exercise instructions to be less verbose * Clean up reference solution * Add if-else-statements as prerequisite, clean up design.md * Add test to check that prepareSpell is not added to base class * Add TODOs to stub --------- Co-authored-by: Sander Ploegsma <[email protected]>
1 parent b6f79bc commit 3c73508

File tree

13 files changed

+833
-159
lines changed

13 files changed

+833
-159
lines changed

concepts/inheritance/introduction.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,19 @@ Consider an animal named `Lion`, having a class like,
2525
//Lion class is a child class of Animal.
2626
public class Lion extends Animal {
2727

28+
@Override
2829
public void bark() {
2930
System.out.println("Lion here!!");
3031
}
3132

3233
}
3334
```
3435

36+
~~~~exercism/note
37+
The `Override` annotation is used to indicate that a method in a subclass is overriding a method of its superclass.
38+
It's not strictly necessary but it's a best practice to use it.
39+
~~~~
40+
3541
Now whenever we do,
3642

3743
```java

config.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,7 @@
217217
"prerequisites": [
218218
"classes",
219219
"strings",
220-
"booleans"
220+
"if-else-statements"
221221
],
222222
"status": "active"
223223
},

exercises/concept/wizards-and-warriors/.docs/hints.md

Lines changed: 33 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2,41 +2,56 @@
22

33
## General
44

5-
Detailed explanation of inheritance can be found at [Inheritance][inheritance-main].
5+
Detailed explanation of inheritance can be found at [Inheritance][inheritance-concept].
66
The whole inheritance concept has a lot to do with the concepts around [overriding][java-overriding].
77

8-
## 1. Describe a Fighter
8+
## 1. Create the Warrior class
9+
10+
- Review the [concept:java/classes](https://github.com/exercism/java/tree/main/concepts/classes) concept.
11+
- Review the [inheritance][inheritance-concept] concept.
12+
13+
## 2. Describe a Warrior
914

1015
- In Java, the `toString()` method is actually present inside the `Object` class (which is a superclass to all the classes in Java).
1116
You can read more about it [here][object-class-java].
1217
- To override this method inside your implementation class, you should have a method with same name i.e. `toString()` and same return type i.e. `String`.
18+
- The `toString()` method must be `public`.
1319

14-
## 2. Making Fighters not vulnerable by default
20+
## 3. Make Warriors invulnerable
1521

16-
- Consider having a method `isVulnerable()` inside the `Fighter` class which states vulnerability of the fighter, return `false` to make it non-vulnerable by default.
17-
- This can than be overridden by any child class(the class extending `Fighter`), according to its requirements.
18-
- Again the [overriding][java-overriding] concept will come handy.
22+
- Override the `isVulnerable()` method in the `Warrior` class to make Warriors always invulnerable.
1923

20-
## 3. Allowing wizards to prepare a spell
24+
## 4. Calculate the damage points for a Warrior
2125

22-
- Preparing a spell can only be done by a wizard.
23-
So, it makes sense to have this property defined inside the `Wizard` class.
24-
- Create `prepareSpell()` method inside `Wizard` class.
25-
- Remember: Parent class (here `Fighter`) has no access to the properties of the child class (for example, `Wizard`)
26+
- Override the `getDamagePoints(Fighter)` method in the `Warrior` class.
27+
- Use a [conditional statement][if-else] to return the damage points, taking into account the vulnerability of the target.
2628

27-
## 4. Make Wizards vulnerable when not having prepared a spell
29+
## 5. Create the Wizard class
2830

29-
- Override the `isVulnerable()` method in the `Wizard` class to make Wizards vulnerable if they haven't prepared a spell.
31+
- Review the [concept:java/classes](https://github.com/exercism/java/tree/main/concepts/classes) concept.
32+
- Review the [inheritance][inheritance-concept] concept.
3033

31-
## 5. Calculate the damage points for a Wizard
34+
## 6. Describe a Wizard
3235

33-
- Use a [conditional statement][if-else] to return the damage points, taking into account the value of the prepare spell field.
36+
- In Java, the `toString()` method is actually present inside the `Object` class (which is a superclass to all the classes in Java).
37+
You can read more about it [here][object-class-java].
38+
- To override this method inside your implementation class, you should have a method with same name i.e. `toString()` and same return type i.e. `String`.
39+
- The `toString()` method must be `public`.
3440

35-
## 6. Calculate the damage points for a Warrior
41+
## 7. Allow Wizards to prepare a spell and make them vulnerable when not having prepared a spell
3642

37-
- Use a [conditional statement][if-else] to return the damage points, taking into account the vulnerability of the target.
43+
- Preparing a spell can only be done by a wizard. So, it makes sense to have this property defined inside the `Wizard` class.
44+
- Create `prepareSpell()` method inside `Wizard` class.
45+
- Remember: Parent class (here `Fighter`) has no access to the properties of the child class (for example, `Wizard`)
46+
- Remember: As the method does not have a return type you should use `void` instead.
47+
- Override the `isVulnerable()` method in the `Wizard` class to make Wizards vulnerable if they haven't prepared a spell.
48+
49+
## 8. Calculate the damage points for a Wizard
50+
51+
- Override the `getDamagePoints(Fighter)` method in the `Wizard` class.
52+
- Use a [conditional statement][if-else] to return the damage points, taking into account the value of the prepare spell field.
3853

39-
[inheritance-main]: https://www.geeksforgeeks.org/inheritance-in-java/
54+
[inheritance-concept]: https://www.geeksforgeeks.org/inheritance-in-java/
4055
[object-class-java]: https://docs.oracle.com/javase/7/docs/api/java/lang/Object.html
4156
[java-overriding]: https://docs.oracle.com/javase/tutorial/java/IandI/override.html
4257
[if-else]: https://docs.oracle.com/javase/tutorial/java/nutsandbolts/if.html
Lines changed: 48 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,83 +1,97 @@
11
# Instructions
22

3-
In this exercise you're playing a role-playing game named "Wizards and Warriors," which allows you to play as either a Wizard or a Warrior.
4-
5-
There are different rules for Warriors and Wizards to determine how much damage points they deal.
3+
In this exercise you're playing a role-playing game where different types of fighters can combat each other.
4+
The game has different rules for each type of fighter.
5+
We are going to focus on two specific types: Wizards and Warriors.
66

77
For a Warrior, these are the rules:
88

9-
- Deal 6 points of damage if the fighter they are attacking is not vulnerable
10-
- Deal 10 points of damage if the fighter they are attacking is vulnerable
9+
- A Warrior is never vulnerable.
10+
- A Warrior deals `6` points of damage if the fighter they are attacking is not vulnerable.
11+
- A Warrior deals `10` points of damage if the fighter they are attacking is vulnerable.
1112

1213
For a Wizard, these are the rules:
1314

14-
- Deal 12 points of damage if the Wizard prepared a spell in advance
15-
- Deal 3 points of damage if the Wizard did not prepare a spell in advance
15+
- A Wizard can prepare a spell in advance.
16+
- A Wizard is vulnerable unless they have prepared a spell in advance.
17+
- A Wizard deals `12` points of damage if they prepared a spell in advance.
18+
- A Wizard deals `3` points of damage if they did not prepare a spell in advance.
1619

17-
In general, fighters are never vulnerable. However, Wizards _are_ vulnerable if they haven't prepared a spell.
20+
## 1. Create the Warrior class
1821

19-
You have six tasks that work with Warriors and Wizard fighters.
22+
Create a new class called `Warrior`.
23+
This class should inherit from the existing `Fighter` class.
2024

21-
## 1. Describe a fighter
25+
## 2. Describe a Warrior
2226

23-
Override the `toString()` method on the `Fighter` class to return a description of the fighter, formatted as `"Fighter is a <FIGHTER_TYPE>"`.
27+
Update the `Warrior` class so that its `toString()` method describes what kind of fighter they are.
28+
The method should return the string `"Fighter is a Warrior"`.
2429

2530
```java
26-
Fighter warrior = new Warrior();
31+
Warrior warrior = new Warrior();
2732
warrior.toString();
2833
// => "Fighter is a Warrior"
2934
```
3035

31-
## 2. Make fighters not vulnerable by default
36+
## 3. Make Warriors invulnerable
3237

33-
Ensure that the `Fighter.isVulnerable()` method always returns `false`.
38+
Update the `Warrior` class so that its `isVulnerable()` method always returns `false`.
3439

3540
```java
36-
Fighter warrior = new Warrior();
41+
Warrior warrior = new Warrior();
3742
warrior.isVulnerable();
3843
// => false
3944
```
4045

41-
## 3. Allow Wizards to prepare a spell
46+
## 4. Calculate the damage points for a Warrior
4247

43-
Implement the `Wizard.prepareSpell()` method to allow a Wizard to prepare a spell in advance.
48+
Update the `Warrior` class so that its `getDamagePoints(Fighter)` method calculates the damage dealt by a Warrior according to the rules above.
4449

4550
```java
51+
Warrior warrior = new Warrior();
4652
Wizard wizard = new Wizard();
47-
wizard.prepareSpell();
53+
54+
warrior.getDamagePoints(wizard);
55+
// => 10
4856
```
4957

50-
## 4. Make Wizards vulnerable when not having prepared a spell
58+
## 5. Create the Wizard class
59+
60+
Create another new class called `Wizard`.
61+
This class should also inherit from the existing `Fighter` class.
62+
63+
## 6. Describe a Wizard
5164

52-
Ensure that the `isVulnerable()` method returns `true` if the wizard did not prepare a spell; otherwise, return `false`.
65+
Update the `Wizard` class so that its `toString()` method describes what kind of fighter they are.
66+
The method should return the string `"Fighter is a Wizard"`.
5367

5468
```java
55-
Fighter wizard = new Wizard();
56-
wizard.isVulnerable();
57-
// => true
69+
Wizard wizard = new Wizard();
70+
wizard.toString();
71+
// => "Fighter is a Wizard"
5872
```
5973

60-
## 5. Calculate the damage points for a Wizard
74+
## 7. Allow Wizards to prepare a spell and make them vulnerable when not having prepared a spell
6175

62-
Implement the `Wizard.damagePoints()` method to return the damage points dealt: 12 damage points when a spell has been prepared, 3 damage points when not.
76+
Update the `Wizard` class to add a method called `prepareSpell()`.
77+
The class should remember when this method is called, and make sure that its `isVulnerable()` method returns `false` only when a spell is prepared.
6378

6479
```java
6580
Wizard wizard = new Wizard();
66-
Warrior warrior = new Warrior();
67-
6881
wizard.prepareSpell();
69-
wizard.damagePoints(warrior);
70-
// => 12
82+
wizard.isVulnerable();
83+
// => false
7184
```
7285

73-
## 6. Calculate the damage points for a Warrior
86+
## 8. Calculate the damage points for a Wizard
7487

75-
Implement the `Warrior.damagePoints()` method to return the damage points dealt: 10 damage points when the target is vulnerable, 6 damage points when not.
88+
Update the `Wizard` class so that its `getDamagePoints(Fighter)` method calculates the damage dealt by a Wizard according to the rules above.
7689

7790
```java
78-
Warrior warrior = new Warrior();
7991
Wizard wizard = new Wizard();
92+
Warrior warrior = new Warrior();
8093

81-
warrior.damagePoints(wizard);
82-
// => 10
94+
wizard.prepareSpell();
95+
wizard.getDamagePoints(warrior);
96+
// => 12
8397
```

exercises/concept/wizards-and-warriors/.docs/introduction.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,19 @@ Consider an animal named `Lion`, having a class like,
2727
//Lion class is a child class of Animal.
2828
public class Lion extends Animal {
2929

30+
@Override
3031
public void bark() {
3132
System.out.println("Lion here!!");
3233
}
3334

3435
}
3536
```
3637

38+
~~~~exercism/note
39+
The `Override` annotation is used to indicate that a method in a subclass is overriding a method of its superclass.
40+
It's not strictly necessary but it's a best practice to use it.
41+
~~~~
42+
3743
Now whenever we do,
3844

3945
```java

exercises/concept/wizards-and-warriors/.meta/config.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@
22
"authors": [
33
"himanshugoyal1065"
44
],
5+
"contributors": [
6+
"manumafe98",
7+
"sanderploegsma"
8+
],
59
"files": {
610
"solution": [
711
"src/main/java/Fighter.java"

exercises/concept/wizards-and-warriors/.meta/design.md

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,25 +9,24 @@ The goal of this exercise is to teach the student the basics of the Concept of `
99
- Know what inheritance is.
1010
- Know how to inherit from a class.
1111
- Know that all types inherit from object.
12+
- Know what the override annotation means.
1213

1314
## Out of scope
1415

1516
- Inheritance from interfaces
17+
- Abstract classes
1618

1719
## Concepts
1820

19-
- `inheritence`
20-
- `objects`
21+
- `inheritance`
2122

2223
## Prerequisites
2324

2425
This exercise's prerequisites Concepts are:
2526

2627
- `classes`
27-
- `abstract`
28-
- `functions`
2928
- `strings`
30-
- `boolean`
29+
- `if-else-statements`
3130

3231
## Representer
3332

Lines changed: 15 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,12 @@
1-
abstract class Fighter {
1+
class Fighter {
22

3-
/**
4-
* this method sets the default vulnerability to false for all the child classes.
5-
*
6-
* @return the vulnerability i.e. false.
7-
*/
83
boolean isVulnerable() {
9-
return false;
4+
return true;
105
}
116

12-
abstract int damagePoints(Fighter fighter);
13-
7+
int getDamagePoints(Fighter fighter) {
8+
return 1;
9+
}
1410
}
1511

1612
class Warrior extends Fighter {
@@ -21,12 +17,13 @@ public String toString() {
2117
}
2218

2319
@Override
24-
int damagePoints(Fighter wizard) {
25-
if (wizard.isVulnerable()) {
26-
return 10;
27-
} else {
28-
return 6;
29-
}
20+
public boolean isVulnerable() {
21+
return false;
22+
}
23+
24+
@Override
25+
int getDamagePoints(Fighter target) {
26+
return target.isVulnerable() ? 10 : 6;
3027
}
3128
}
3229

@@ -41,23 +38,15 @@ public String toString() {
4138

4239
@Override
4340
boolean isVulnerable() {
44-
if (isSpellPrepared == false) {
45-
return true;
46-
}
47-
return false;
41+
return !isSpellPrepared;
4842
}
4943

5044
@Override
51-
int damagePoints(Fighter warrior) {
52-
if (isSpellPrepared) {
53-
return 12;
54-
} else {
55-
return 3;
56-
}
45+
int getDamagePoints(Fighter target) {
46+
return isSpellPrepared ? 12 : 3;
5747
}
5848

5949
void prepareSpell() {
6050
isSpellPrepared = true;
6151
}
62-
6352
}

0 commit comments

Comments
 (0)