> **Disclaimer**:
I will slip into C# syntax from time to time, as I have little direct typescript experience. I'm focusing on the principle more than the actual syntax.
----
Class abuse
--
This is something that you've peppered through your codebase:
class Demon extends EnemyUnit {
constructor(hand, deck) {
super(10, 100, 10, "#DFB720", "Demon", 7, hand, deck);
};
};
class HellHound extends EnemyUnit {
constructor(hand, deck) {
super(5, 60, 5, "#C0C0C0", "Hell Hound", 4, hand, deck);
};
};
These inherited classes are not actually different from their `EnemyUnit` base class. They should not be classes in and of themselves.
This is the equivalent of doing things like:
public class Number
{
public int Value;
public Number(int value)
{
this.Value = value;
}
}
public class Five
{
public Five() : base(5)
{ }
}
public class Twenty
{
public Twenty() : base(20)
{ }
}
var myAge = new Twenty();
var fingersOnMyLeftHand = new Five();
My example is more blatant, but it's the same principle.
You shouldn't create new _classes_ when you want to change _values_. The point of having a class is to have a _single reusable type_ that can contain different values.
Just like my example should be rewritten to:
Number myAge = 20;
Number fingersOnMyLeftHand = 5;
Your code should be rewritten to:
public EnemyUnit CreateDemon(hand, deck) {
return new EnemyUnit(10, 100, 10, "#DFB720", "Demon", 7, hand, deck);
}
public EnemyUnit CreateHellHound(hand, deck) {
return new EnemyUnit(5, 60, 5, "#C0C0C0", "Hell Hound", 4, hand, deck);
}
Don't use inheritance as a way to create some preset values. That is not what inheritance is for.
Only inherit if you wish to create a new unit whose **behavior** is different to that of the existing `EnemyUnit` type. (e.g. attack is always equal to health, or a "hero" unit type).
For game design specifically, you'll see that most games tend to not inherit for different unit types, but rather to have a single unit type with omittable properties.
For example, if you have both physical armor and magical armor, you don't need to create separate classes for these. Just give `EnemyUnit` both `PhysicalArmor` and `MagicalArmor` properties, and simply set them to 0 in the current enemy doesn't have that particular type of armor.
-----
_A very minor comment, it's **Cthulhu**, not Cuthulu. It is phonetically pronounced "Cuthulu" though._
----
class TurnManager {
constructor() {
this.turnNumber = -1;
};
nextTurn() {
this.turnNumber++;
};
};
This isn't necessarily wrong, but why is turnNumber set to -1?
I suspect that you're thinking in a zero-indexed environment, and that you're relying on calling `nextTurn()` at the start of the game. But I think there are more intuitive approaches here:
* Card games start at turn 1, not 0. Don't mix code-behind indexes and user interface numbers.
* To that end, I would suggest a strict naming convention: **Numbers** are 1-indexed, **indexes** are 0-indexed. Which means you need to either rename your field to `turnIndex`, or rework it to start from 1.
* I wouldn't call `nextTurn()` at the start of a game (and at the start of a turn), but rather _after_ a turn has completed. This makes more sense semantically (and logically). As a simple example: a `for` loop doesn't let its index start at -1 and then autoincrements it before iterating the first time. It's counterintuitive behavior.
------