diff --git a/index.html b/index.html
index 26d3120..9ba6862 100644
--- a/index.html
+++ b/index.html
@@ -8,6 +8,8 @@
+
+
diff --git a/src/Animals/Predator.ts b/src/Animals/Predator.ts
new file mode 100644
index 0000000..49eed2f
--- /dev/null
+++ b/src/Animals/Predator.ts
@@ -0,0 +1,37 @@
+import { AnimalNames } from '../Enums/AnimalNamesEnum';
+import { AnimalRoles } from '../Enums/AnimalRolesEnum';
+import { AttackHerdInterface } from '../Interfaces/AttackHerdInterface';
+import { Animal } from './Animal';
+
+export class Predator extends Animal implements AttackHerdInterface {
+ protected _kills: AnimalNames[];
+ protected _isChasedAwayBy: AnimalNames;
+ protected _exclamation: string;
+ constructor(
+ name: AnimalNames,
+ imagePath: string,
+ roles: AnimalRoles = AnimalRoles.PREDATOR,
+ kills: AnimalNames[],
+ isChasedAwayBy: AnimalNames,
+ exclamation: string,
+ ) {
+ super(name, imagePath, undefined, roles);
+ this._kills = kills;
+ this._isChasedAwayBy = isChasedAwayBy;
+ this._exclamation = exclamation;
+ }
+
+ get kills(): AnimalNames[] {
+ return this._kills;
+ }
+ get isChasedAwayBy(): AnimalNames {
+ return this._isChasedAwayBy;
+ }
+ get exclamation(): string {
+ return this._exclamation;
+ }
+
+ attackHerd(): string {
+ return this._exclamation;
+ }
+}
diff --git a/src/Animals/Protector.ts b/src/Animals/Protector.ts
new file mode 100644
index 0000000..61280fe
--- /dev/null
+++ b/src/Animals/Protector.ts
@@ -0,0 +1,37 @@
+import { AnimalNames } from '../Enums/AnimalNamesEnum';
+import { AnimalRoles } from '../Enums/AnimalRolesEnum';
+import { ProtectHerdInterface } from '../Interfaces/ProtectHerdInterface';
+import { Animal, Value } from './Animal';
+
+export class Protector
+ extends Animal
+ implements ProtectHerdInterface {
+ protected _chasesAway: AnimalNames;
+ protected _exclamation: string;
+ constructor(
+ name: AnimalNames,
+ imagePath: string,
+ role: AnimalRoles = AnimalRoles.PREDATOR,
+ value: Value,
+ chasesAway: AnimalNames,
+ exclamation: string,
+ ) {
+ super(name, imagePath, value, role);
+ this._chasesAway = chasesAway;
+ this._exclamation = exclamation;
+ }
+
+ get chasesAway(): AnimalNames {
+ if (!this._chasesAway) throw new Error('nothing to chase away');
+ return this._chasesAway;
+ }
+ get exclamation(): string {
+ if (!this._exclamation) return '';
+ return this._exclamation;
+ }
+
+ protectHerd(): string {
+ if (!this._exclamation) return '';
+ return this._exclamation;
+ }
+}
diff --git a/src/Interfaces/AttackHerdInterface.ts b/src/Interfaces/AttackHerdInterface.ts
index 4ac3c53..40a283c 100644
--- a/src/Interfaces/AttackHerdInterface.ts
+++ b/src/Interfaces/AttackHerdInterface.ts
@@ -1,4 +1,4 @@
export interface AttackHerdInterface {
- // TODO: tweak when herd is ready
+ // TODO: DEFINE THE ACTION FOR ATTACK
attackHerd(): string;
}
diff --git a/src/Interfaces/GameConfigInterface.ts b/src/Interfaces/GameConfigInterface.ts
index f124104..e56a7b9 100644
--- a/src/Interfaces/GameConfigInterface.ts
+++ b/src/Interfaces/GameConfigInterface.ts
@@ -1,5 +1,6 @@
import { GameModes } from '../Enums/GameModeEnums';
import { LivestockConfigInterface } from './LivestockConfigInterface';
+import { PlayerDTO } from './PlayerDTOInterface';
import { PredatorsConfigInterface } from './PredatorsConfigInterface';
import { ProtectorsConfigInterface } from './ProtectorsConfigInterface';
@@ -7,7 +8,7 @@ export interface GameConfigInterface {
mode: GameModes;
roundTimeInSeconds: number;
totalGameTimeInSeconds?: number;
- playersConfig: { name: string; path: string; color: string }[];
+ playersConfig: PlayerDTO[];
livestockConfig: LivestockConfigInterface[];
protectorsConfig: ProtectorsConfigInterface[];
predatorsConfig: PredatorsConfigInterface[];
diff --git a/src/Interfaces/HerdConfigInterface.ts b/src/Interfaces/HerdConfigInterface.ts
index 4939e12..0305541 100644
--- a/src/Interfaces/HerdConfigInterface.ts
+++ b/src/Interfaces/HerdConfigInterface.ts
@@ -9,4 +9,5 @@ export interface HerdConfigInterface {
path: string;
inStock: number;
chasesAway?: AnimalNames;
+ exclamation?: string;
}
diff --git a/src/Interfaces/PredatorsConfigInterface.ts b/src/Interfaces/PredatorsConfigInterface.ts
index a5ef595..e362d54 100644
--- a/src/Interfaces/PredatorsConfigInterface.ts
+++ b/src/Interfaces/PredatorsConfigInterface.ts
@@ -1,9 +1,12 @@
+import { AnimalRoles } from '../Enums/AnimalRolesEnum';
import { AnimalNames } from '../Enums/AnimalNamesEnum';
export interface PredatorsConfigInterface {
name: AnimalNames;
path: string;
+ roles: AnimalRoles;
kills: AnimalNames[];
- isChasedAwayBy: AnimalNames[];
+ isChasedAwayBy: AnimalNames;
+ exclamation: string;
dice?: { diceNumber: number; probability: number }[];
}
diff --git a/src/Interfaces/ProtectorsConfigInterface.ts b/src/Interfaces/ProtectorsConfigInterface.ts
index ec7d913..232cebe 100644
--- a/src/Interfaces/ProtectorsConfigInterface.ts
+++ b/src/Interfaces/ProtectorsConfigInterface.ts
@@ -4,4 +4,5 @@ import { LivestockConfigInterface } from './LivestockConfigInterface';
export interface ProtectorsConfigInterface
extends LivestockConfigInterface {
chasesAway: AnimalNames;
+ exclamation: string;
}
diff --git a/src/Interfaces/DiceInterface.ts b/src/Interfaces/RandomAnimalInterface.ts
similarity index 69%
rename from src/Interfaces/DiceInterface.ts
rename to src/Interfaces/RandomAnimalInterface.ts
index 5efe9e1..55e0baa 100644
--- a/src/Interfaces/DiceInterface.ts
+++ b/src/Interfaces/RandomAnimalInterface.ts
@@ -1,5 +1,5 @@
import { AnimalNames } from '../Enums/AnimalNamesEnum';
-export interface GetRandomValue {
+export interface RandomAnimalInterface {
getRandomValue(): AnimalNames;
}
diff --git a/src/Player.ts b/src/Player.ts
index 3948423..c5ad28a 100644
--- a/src/Player.ts
+++ b/src/Player.ts
@@ -1,5 +1,6 @@
+import { defaultPlayerHerdConfig } from './app/logic/defaultHerdConfig';
import { Herd } from './app/logic/Herd';
-import { mockHerdConfig } from './app/logic/mockHerdConfig';
+// import { mockHerdConfig } from './app/logic/defaultHerdConfig';
import { HerdConfigInterface } from './Interfaces/HerdConfigInterface';
export class Player {
@@ -8,12 +9,11 @@ export class Player {
protected herd: Herd;
protected color: string;
- // TODO: set path to default avatar when it's available
constructor(
name: string,
avatar = 'path to default avatar',
color = 'green',
- herdConfig: HerdConfigInterface[] = mockHerdConfig,
+ herdConfig: HerdConfigInterface[] = defaultPlayerHerdConfig,
) {
this.name = name;
this.herd = new Herd(herdConfig);
diff --git a/src/app/BreedProcessor.ts b/src/app/BreedProcessor.ts
index 3cd4088..9d8b191 100644
--- a/src/app/BreedProcessor.ts
+++ b/src/app/BreedProcessor.ts
@@ -1,15 +1,12 @@
-import { GetRandomValue } from '../Interfaces/DiceInterface';
-import { FirstDice } from './FirstDice';
-import { SecondDice } from './SecondDice';
+import { RandomAnimalInterface } from '../Interfaces/RandomAnimalInterface';
import { Player } from '../Player';
import { AnimalNames } from '../Enums/AnimalNamesEnum';
-import { Fox } from '../Animals/Fox';
-import { Wolf } from '../Animals/Wolf';
import { Herd } from './logic/Herd';
-import { add, divide, floor, min } from 'lodash';
-import { AnimalRoles } from '../Enums/AnimalRolesEnum';
+import { add, divide, floor, min, remove } from 'lodash';
import { Bank } from './logic/Bank';
-import { ConvertAnimalName } from './utils/ConvertAnimalName';
+import { PredatorsConfigInterface } from '../Interfaces/PredatorsConfigInterface';
+import { GameModes } from '../Enums/GameModeEnums';
+import { Predator } from '../../src/Animals/Predator';
export type RollResult = {
rollResult: AnimalNames[];
@@ -17,48 +14,70 @@ export type RollResult = {
};
export class BreedProcessor {
- randomResultInterfaceWolf: GetRandomValue;
- randomResultInterfaceFox: GetRandomValue;
+ predators: Predator[];
- constructor(private bank: Bank) {
- this.randomResultInterfaceWolf = new SecondDice();
- this.randomResultInterfaceFox = new FirstDice();
+ constructor(
+ private bank: Bank,
+ private firstDice: RandomAnimalInterface,
+ private secondDice: RandomAnimalInterface,
+ predatorConfig: PredatorsConfigInterface[],
+ private mode: GameModes,
+ ) {
+ this.predators = predatorConfig.map(
+ ({ name, path, roles, kills, isChasedAwayBy, exclamation }) => {
+ return new Predator(
+ name,
+ path,
+ roles,
+ kills,
+ isChasedAwayBy,
+ exclamation,
+ );
+ },
+ );
+ }
+
+ getPredatorByName(predatorName: AnimalNames): Predator {
+ const attackingPredator = this.predators.find(
+ (predator) => predator.theName === predatorName,
+ );
+ if (!attackingPredator) throw new Error('No such predator');
+ return attackingPredator;
}
processBreedPhase({ theHerd }: Player): RollResult {
- const wolfDiceResult = this.randomResultInterfaceWolf.getRandomValue();
- const foxDiceResult = this.randomResultInterfaceFox.getRandomValue();
- const equalResult = foxDiceResult === wolfDiceResult;
- const roll = [wolfDiceResult, foxDiceResult];
- if (equalResult) {
- const count = this.breedAnimals(foxDiceResult, theHerd, true);
- return { rollResult: roll, gain: [[foxDiceResult, count]] };
+ const roll = [
+ this.firstDice.getRandomValue(),
+ this.secondDice.getRandomValue(),
+ ];
+ const [firstDice, secondDice] = roll;
+ if (firstDice === secondDice) {
+ const count = this.breedAnimals(firstDice, theHerd, true);
+ return {
+ rollResult: roll,
+ gain: count ? [[firstDice, count]] : [],
+ };
}
const gain: [AnimalNames, number][] = [];
- if (foxDiceResult === AnimalNames.FOX) {
- const fox: Fox = ConvertAnimalName.toAnimalObject(
- foxDiceResult,
- ) as Fox;
- this.returnToBank(fox, theHerd);
- theHerd.cullAnimals(fox);
- } else {
- gain.push([
- foxDiceResult,
- this.breedAnimals(foxDiceResult, theHerd),
- ]);
- }
- if (wolfDiceResult === AnimalNames.WOLF) {
- const wolf = ConvertAnimalName.toAnimalObject(
- wolfDiceResult,
- ) as Wolf;
- this.returnToBank(wolf, theHerd);
- theHerd.cullAnimals(wolf);
- } else {
- gain.push([
- wolfDiceResult,
- this.breedAnimals(wolfDiceResult, theHerd),
- ]);
- }
+ roll
+ .filter((animal) => !this.isPredator(animal))
+ .forEach((animal) => {
+ const grow = this.breedAnimals(animal, theHerd);
+ if (grow) {
+ gain.push([animal, grow]);
+ }
+ });
+ roll
+ .filter((animal) => this.isPredator(animal))
+ .forEach((animal) => {
+ const predator = this.getPredatorByName(animal);
+ const isHerdCulled = this.returnToBank(predator, theHerd);
+ if (isHerdCulled && gain.length > 0) {
+ this.reduceGain(predator, gain);
+ }
+ predator.attackHerd();
+ theHerd.cullAnimals(predator, this.mode);
+ });
return { rollResult: roll, gain: gain };
}
@@ -83,28 +102,24 @@ export class BreedProcessor {
return herdGrow;
}
- private returnToBank(predator: Wolf | Fox, herd: Herd): void {
- if (predator instanceof Fox) {
- if (herd.getAnimalNumber(AnimalNames.SMALL_DOG) > 0) {
- this.bank.theHerd.addAnimalsToHerd(AnimalNames.SMALL_DOG, 1);
- return;
- }
- const quantity = herd.getAnimalNumber(AnimalNames.RABBIT);
- this.bank.theHerd.addAnimalsToHerd(
- AnimalNames.RABBIT,
- quantity,
- );
- return;
- }
- if (herd.getAnimalNumber(AnimalNames.BIG_DOG) > 0) {
- this.bank.theHerd.addAnimalsToHerd(AnimalNames.BIG_DOG, 1);
- return;
+ private isPredator(animal: AnimalNames): boolean {
+ return this.predators.some(({ theName }) => theName === animal);
+ }
+
+ private returnToBank(predator: Predator, herd: Herd): boolean {
+ const animalsToCull = predator.kills;
+ const protector = predator.isChasedAwayBy;
+ const hasProtector = herd.getAnimalNumber(protector);
+ const isDynamicMode = this.mode === GameModes.DYNAMIC;
+ const killsRabbits = animalsToCull.includes(AnimalNames.RABBIT);
+ if (hasProtector) {
+ this.bank.theHerd.addAnimalsToHerd(protector, 1);
+ return false;
}
+
herd.theAnimals
- .filter(
- ([animal]) =>
- animal.hasRole(AnimalRoles.LIVESTOCK) &&
- animal.theName !== AnimalNames.HORSE,
+ .filter(([animal]) =>
+ animalsToCull.includes(animal.theName as AnimalNames),
)
.forEach(([animal, count]) =>
this.bank.theHerd.addAnimalsToHerd(
@@ -112,6 +127,10 @@ export class BreedProcessor {
count,
),
);
+ if (isDynamicMode && killsRabbits) {
+ this.bank.theHerd.removeAnimalsFromHerd(AnimalNames.RABBIT, 1);
+ }
+ return true;
}
private calculateHerdGrow(
@@ -130,4 +149,13 @@ export class BreedProcessor {
);
return min([herdMaxGrow, bankContains]) as number;
}
+
+ private reduceGain(
+ predator: Predator,
+ animalsGain: [AnimalNames, number][],
+ ): void {
+ remove(animalsGain, ([animal]) => {
+ return predator.kills.includes(animal);
+ });
+ }
}
diff --git a/src/app/Dice.ts b/src/app/Dice.ts
index 039501f..91418d0 100644
--- a/src/app/Dice.ts
+++ b/src/app/Dice.ts
@@ -1,10 +1,28 @@
-import { GetRandomValue } from '../Interfaces/DiceInterface';
+import { RandomAnimalInterface } from '../Interfaces/RandomAnimalInterface';
import { AnimalNames } from '../Enums/AnimalNamesEnum';
-import { sample } from 'lodash';
+import { sample, shuffle } from 'lodash';
-export class Dice implements GetRandomValue {
- constructor(private diceSides: AnimalNames[]) {}
+export class Dice implements RandomAnimalInterface {
+ private dice: AnimalNames[] = [];
+
+ /**
+ * adds animals names to dice sides in quantity of probability
+ * @param animal accepts AnimalNames with desired animal on side
+ * @param probability accepts number with number of sides with this animal
+ */
+ addSide(animal: AnimalNames, probability: number): void {
+ if (probability === 0) {
+ return;
+ }
+ this.dice.push(animal);
+ this.addSide(animal, probability - 1);
+ }
+
+ /**
+ * Returns random animal
+ */
getRandomValue(): AnimalNames {
- return sample(this.diceSides) as AnimalNames;
+ this.dice = shuffle(this.dice);
+ return sample(this.dice) as AnimalNames;
}
}
diff --git a/src/app/DiceBuilder.ts b/src/app/DiceBuilder.ts
new file mode 100644
index 0000000..26e022a
--- /dev/null
+++ b/src/app/DiceBuilder.ts
@@ -0,0 +1,41 @@
+import { LivestockConfigInterface } from '../Interfaces/LivestockConfigInterface';
+import { PredatorsConfigInterface } from '../Interfaces/PredatorsConfigInterface';
+import { ProtectorsConfigInterface } from '../Interfaces/ProtectorsConfigInterface';
+import { Dice } from './Dice';
+
+/**
+ * Builds two dice, depends on configuration.
+ * Usage: DiceBuilder.build()
+ */
+export class DiceBuilder {
+ static build(
+ livestockConfig: LivestockConfigInterface[],
+ predatorsConfig: PredatorsConfigInterface[],
+ protectorsConfig: ProtectorsConfigInterface[],
+ ): Dice[] {
+ const firstDice = new Dice();
+ const secondDice = new Dice();
+ for (const animal of [
+ ...livestockConfig,
+ ...predatorsConfig,
+ ...protectorsConfig,
+ ]) {
+ if (!animal.dice) {
+ continue;
+ }
+ animal.dice.forEach(({ diceNumber, probability }) => {
+ switch (diceNumber) {
+ case 1:
+ firstDice.addSide(animal.name, probability);
+ break;
+ case 2:
+ secondDice.addSide(animal.name, probability);
+ break;
+ default:
+ throw Error(`Error: Unknown dice number: ${diceNumber}`);
+ }
+ });
+ }
+ return [firstDice, secondDice];
+ }
+}
diff --git a/src/app/FirstDice.ts b/src/app/FirstDice.ts
deleted file mode 100644
index c8b5a1a..0000000
--- a/src/app/FirstDice.ts
+++ /dev/null
@@ -1,21 +0,0 @@
-import { Dice } from './Dice';
-import { AnimalNames } from '../Enums/AnimalNamesEnum';
-
-export class FirstDice extends Dice {
- constructor() {
- super([
- AnimalNames.RABBIT,
- AnimalNames.RABBIT,
- AnimalNames.RABBIT,
- AnimalNames.RABBIT,
- AnimalNames.RABBIT,
- AnimalNames.RABBIT,
- AnimalNames.SHEEP,
- AnimalNames.SHEEP,
- AnimalNames.PIG,
- AnimalNames.PIG,
- AnimalNames.HORSE,
- AnimalNames.FOX,
- ]);
- }
-}
diff --git a/src/app/GameController.ts b/src/app/GameController.ts
index 985441e..55f8f81 100644
--- a/src/app/GameController.ts
+++ b/src/app/GameController.ts
@@ -1,15 +1,15 @@
import { GameProcessor } from './logic/GameProcessor';
import { ViewController } from './ViewController';
import { Game } from './logic/Game';
-import { defaultGameConfiguration } from './logic/defaultGameConfiguration';
import { Bank } from './logic/Bank';
+import { Configuration } from './logic/Configuration';
export class GameController {
private game: Game;
private gameProcessor: GameProcessor;
constructor(
private view: ViewController,
- private config = defaultGameConfiguration,
+ private config: Configuration,
) {
this.game = new Game(config);
this.gameProcessor = new GameProcessor(this.game, this);
@@ -42,7 +42,6 @@ export class GameController {
private isGameWon(): void {
if (this.gameProcessor.checkWin()) {
- this.gameProcessor.stopTurn();
this.view.displayWinModal(this.game.theCurrentPlayer);
}
}
diff --git a/src/app/GameView.ts b/src/app/GameView.ts
index 5360178..cbe1076 100644
--- a/src/app/GameView.ts
+++ b/src/app/GameView.ts
@@ -9,7 +9,7 @@ import { ViewController } from './ViewController';
export class GameView {
private playerPanel: PlayerPanel;
-
+ // TODO: FIND OUT WHY THIS CREATES INSTANCE OF PLAYER PANEL IN CONTRUCTOR
constructor(private view: ViewController) {
this.playerPanel = new PlayerPanel(this);
}
diff --git a/src/app/MenuView.ts b/src/app/MenuView.ts
index b76d120..040ce4e 100644
--- a/src/app/MenuView.ts
+++ b/src/app/MenuView.ts
@@ -6,107 +6,74 @@ import { ViewController } from './ViewController';
export class MenuView extends EmptyView {
private modeModal: ModeView;
+ private menuViewContent: HTMLElement;
constructor(private viewController: ViewController) {
super(false);
const backCallback = () => this.show();
const submitCallback = (
isDynamic: boolean,
players: PlayerDTO[],
- ) => this.viewController.launchGame(players);
+ ) => {
+ Render.removeAllChildren('#sf-app');
+ this.viewController.launchGame(players, isDynamic);
+ };
this.modeModal = new ModeView(backCallback, submitCallback);
- Render.render('body', this.modeModal.theModeView);
+ this.menuViewContent = Render.elementFactory(
+ 'div',
+ { className: 'menu-window' },
+ this.createHeading(),
+ this.createPageContent(),
+ this.createStartButton(),
+ this.createFooter(),
+ );
+ this.viewContainer.appendChild(this.menuViewContent);
}
displayMenu(): void {
Render.removeAllChildren('#sf-app');
- Render.childrenInjector(
- this.viewContainer,
- this.createLandingPage(),
- this.createFooter(),
- );
+ this.show();
Render.render('#sf-app', this.view);
}
- private createLandingPage(): HTMLElement {
- return Render.elementFactory(
- 'div',
- {
- className: 'page__container menu-window',
- },
- this.createHeading(),
- this.createPageContent(),
- );
- }
-
private createHeading(): HTMLElement {
return Render.elementFactory(
- 'header',
+ 'h1',
{ className: 'menu-window__header' },
- Render.elementFactory(
- 'h1',
- { className: 'menu-window__heading heading' },
- 'FARM TYCOON',
- ),
- Render.elementFactory(
- 'h2',
- { className: 'menu-window__description text' },
- 'Breed animals, Do your math, Be quick, Plan ahead, Protect your herd, Predators are there to get your animals! Become a farmer and be the first to gather all the animals!',
- ),
+ 'SUPERFARMER',
);
}
private createPageContent(): HTMLElement {
return Render.elementFactory(
- 'div',
+ 'nav',
{ className: 'menu' },
- Render.elementFactory('div', {
- className: 'menu__graphic-container',
- }),
- Render.elementFactory(
- 'div',
- { className: 'menu__buttons' },
- ...this.createMenuButtons(),
- ),
- Render.elementFactory('div', {
- className: 'menu__graphic-container',
- }),
- Render.elementFactory(
- 'button',
- {
- className: 'menu__button--rules button',
- },
- 'i',
- ),
+ ...this.createMenuButtons(),
);
}
private createMenuButtons(): HTMLElement[] {
+ const namesButtons: string[] = ['GAME RULES', 'AUTHORS'];
+ const menuButtons = namesButtons.map((button) => {
+ return Render.elementFactory(
+ 'button',
+ { className: 'menu__button' },
+ button,
+ );
+ });
+ return menuButtons;
+ }
+ private createStartButton(): HTMLElement {
const startGameButton = Render.elementFactory(
'button',
- { className: 'button' },
- 'NEW GAME',
+ { className: 'button--start' },
+ 'START',
);
startGameButton.addEventListener('click', () => {
this.hide();
+ Render.render('#sf-app', this.modeModal.theModeView);
this.modeModal.show();
});
- const settingsButton = Render.elementFactory(
- 'button',
- {
- className: 'button',
- },
- 'SETTINGS',
- );
- settingsButton.setAttribute('disabled', 'true');
- const authorsButton = Render.elementFactory(
- 'button',
- {
- className: 'button',
- },
- 'AUTHORS',
- );
- authorsButton.setAttribute('disabled', 'true');
- return [startGameButton, settingsButton, authorsButton];
+ return startGameButton;
}
private createFooter(): HTMLElement {
diff --git a/src/app/ModeView.ts b/src/app/ModeView.ts
index 25fbe98..975f0d2 100644
--- a/src/app/ModeView.ts
+++ b/src/app/ModeView.ts
@@ -12,7 +12,7 @@ export class ModeView extends EmptyView {
private modeForm: HTMLFormElement;
private addPlayerButton: HTMLElement;
private removePlayerButton: HTMLElement;
- private playerInputsWrapper: HTMLElement;
+ private addPanelsWrapper: HTMLElement;
private backButton!: HTMLElement;
private playButton!: HTMLElement;
private submitCallback: CallbackTwoParam;
@@ -45,7 +45,7 @@ export class ModeView extends EmptyView {
},
'remove player',
);
- this.playerInputsWrapper = Render.elementFactory('div', {
+ this.addPanelsWrapper = Render.elementFactory('div', {
className: 'mode-players-wrapper',
});
this.modeForm = this.createForm();
@@ -89,7 +89,7 @@ export class ModeView extends EmptyView {
Render.elementFactory(
'label',
{
- className: 'mode-form__mode-input',
+ className: 'mode-form__mode-label',
for: 'mode',
},
'dynamic mode',
@@ -105,9 +105,8 @@ export class ModeView extends EmptyView {
},
heading,
mode,
- this.playerInputsWrapper,
+ this.addPanelsWrapper,
this.addPlayerButton,
- this.removePlayerButton,
);
this.addPlayer();
@@ -131,7 +130,7 @@ export class ModeView extends EmptyView {
}
private addPlayer(): void {
- const numberOfPlayers = this.playerInputsWrapper.children.length;
+ const numberOfPlayers = this.addPanelsWrapper.children.length;
if (numberOfPlayers >= 4) return;
const playerInputRow = this.generateAddPlayerFields(
@@ -141,21 +140,21 @@ export class ModeView extends EmptyView {
if (numberOfPlayers >= 3) {
this.addPlayerButton.classList.add('hidden');
}
- Render.childrenInjector(this.playerInputsWrapper, playerInputRow);
+ Render.childrenInjector(this.addPanelsWrapper, playerInputRow);
if (numberOfPlayers === 1) {
this.removePlayerButton.classList.remove('hidden');
}
}
private removePlayer(): void {
- const numberOfPlayers = this.playerInputsWrapper.children.length;
+ const numberOfPlayers = this.addPanelsWrapper.children.length;
if (numberOfPlayers <= 1) return;
if (numberOfPlayers === 4) {
this.addPlayerButton.classList.remove('hidden');
}
- (this.playerInputsWrapper.lastElementChild as Element).remove();
+ (this.addPanelsWrapper.lastElementChild as Element).remove();
if (numberOfPlayers === 2)
this.removePlayerButton.classList.add('hidden');
@@ -181,7 +180,7 @@ export class ModeView extends EmptyView {
const buttonsWrapper = Render.elementFactory(
'div',
{
- className: 'modal__buttons',
+ className: 'mode__buttons',
},
this.backButton,
this.playButton,
@@ -329,8 +328,10 @@ export class ModeView extends EmptyView {
this.generateColorInput(numberOfPlayer),
);
if (numberOfPlayer > 1) {
- fieldsWrapper.appendChild(
+ Render.childrenInjector(
+ fieldsWrapper,
this.generateAICheckbox(numberOfPlayer),
+ this.removePlayerButton,
);
}
return fieldsWrapper;
@@ -341,10 +342,8 @@ export class ModeView extends EmptyView {
): { isDynamic: boolean; players: PlayerDTO[] } {
const players: PlayerDTO[] = [];
let isDynamic = false;
- for (const [formKey, formValue] of formData.entries()) {
- // TODO: remove before merge
- console.log(formKey, formValue);
+ for (const [formKey, formValue] of formData.entries()) {
const value = formValue.toString();
const [key, numberOfPlayer] = formKey.split('_');
const index = +numberOfPlayer - 1;
@@ -380,8 +379,6 @@ export class ModeView extends EmptyView {
}
}
}
- // TODO: remove before merge
- console.log({ isDynamic, players });
return { isDynamic, players };
}
@@ -403,6 +400,9 @@ export class ModeView extends EmptyView {
private handleClickRemovePlayer = (): void => {
this.removePlayer();
+ this.addPanelsWrapper.lastChild?.appendChild(
+ this.removePlayerButton,
+ );
};
private handleClickBackButton = (): void => {
diff --git a/src/app/SecondDice.ts b/src/app/SecondDice.ts
deleted file mode 100644
index 837cc57..0000000
--- a/src/app/SecondDice.ts
+++ /dev/null
@@ -1,21 +0,0 @@
-import { Dice } from './Dice';
-import { AnimalNames } from '../Enums/AnimalNamesEnum';
-
-export class SecondDice extends Dice {
- constructor() {
- super([
- AnimalNames.RABBIT,
- AnimalNames.RABBIT,
- AnimalNames.RABBIT,
- AnimalNames.RABBIT,
- AnimalNames.RABBIT,
- AnimalNames.RABBIT,
- AnimalNames.SHEEP,
- AnimalNames.SHEEP,
- AnimalNames.SHEEP,
- AnimalNames.PIG,
- AnimalNames.COW,
- AnimalNames.WOLF,
- ]);
- }
-}
diff --git a/src/app/ViewController.ts b/src/app/ViewController.ts
index a1cc354..483489a 100644
--- a/src/app/ViewController.ts
+++ b/src/app/ViewController.ts
@@ -10,6 +10,10 @@ import { Trade } from './Trade';
import { TradeModal } from './components/TradeModal';
import { defaultGameConfiguration } from './logic/defaultGameConfiguration';
import { PlayerDTO } from '../Interfaces/PlayerDTOInterface';
+import { Configuration } from './logic/Configuration';
+import { dynamicGameConfiguration } from './logic/dynamicGameConfiguration';
+import { AnimalNames } from '../Enums/AnimalNamesEnum';
+import { cloneDeep } from 'lodash';
export class ViewController {
private menuView: MenuView;
@@ -33,8 +37,23 @@ export class ViewController {
this.menuView.displayMenu();
}
- launchGame(players: PlayerDTO[]): void {
- const config = defaultGameConfiguration;
+ /*TODO: CHECK IF AI NEEDED, CONNECT WITH CALLBACK THAT PASSES PLAYERS*/
+ /* TODO: CONSIDER USING DEFAULT CONFIG ALWAYS, JUST CHANGE ALREADY CREATED CONFIG IN CASE ITS A DYNAMIC MODE*/
+ launchGame(players: PlayerDTO[], isModeDynamic?: boolean): void {
+ const config: Configuration =
+ isModeDynamic === true
+ ? new Configuration(cloneDeep(dynamicGameConfiguration))
+ : new Configuration(defaultGameConfiguration);
+ if (isModeDynamic) {
+ const numberOfPlayers = players.length;
+ config.livestockConfig = config.livestockConfig.map(
+ (animal) => {
+ if (animal.name === AnimalNames.RABBIT)
+ animal.bankInitialStock -= numberOfPlayers;
+ return animal;
+ },
+ );
+ }
config.playersConfig = players;
this.gameController = new GameController(this, config);
this.startGame(
diff --git a/src/app/components/Alert.ts b/src/app/components/Alert.ts
index b6aeb0d..c4d7213 100644
--- a/src/app/components/Alert.ts
+++ b/src/app/components/Alert.ts
@@ -31,16 +31,16 @@ export class Alert {
Render.removeAllChildren(this.alert);
switch (alertType) {
case AlertType.INFO:
- this.alert.style.borderColor = 'blue';
+ this.alert.style.backgroundColor = '#3E8Ed0';
break;
case AlertType.WARN:
- this.alert.style.borderColor = 'yellow';
+ this.alert.style.backgroundColor = '#FFE08A';
break;
case AlertType.CRITICAL:
- this.alert.style.borderColor = 'red';
+ this.alert.style.backgroundColor = '#F14668';
break;
default:
- this.alert.style.borderColor = 'white';
+ this.alert.style.backgroundColor = 'transparent';
break;
}
const icon = Render.elementFactory('img', {
diff --git a/src/app/components/PlayerPanel.ts b/src/app/components/PlayerPanel.ts
index 5db22a7..ccc6bd6 100644
--- a/src/app/components/PlayerPanel.ts
+++ b/src/app/components/PlayerPanel.ts
@@ -13,6 +13,7 @@ export class PlayerPanel {
* @param view accepts instance of View componenet
*/
constructor(private view: GameView) {
+ // TODO: FIND OUT WHY IS THIS PANEL CREATED TOGETHER WITH THE LANDING PAGE
this.player = new Player('', '', '');
}
diff --git a/src/app/components/WinModal.ts b/src/app/components/WinModal.ts
index af1c8bb..8928019 100644
--- a/src/app/components/WinModal.ts
+++ b/src/app/components/WinModal.ts
@@ -16,7 +16,10 @@ export class WinModal extends EmptyModal {
);
const image = Render.elementFactory(
'div',
- { className: 'modal__image--win-container' },
+ {
+ className: 'modal__image--win-container',
+ style: `border-color: ${player.theColor};`,
+ },
Render.elementFactory('img', {
className: 'modal__image--win-avatar',
src: player.theAvatar,
@@ -30,7 +33,10 @@ export class WinModal extends EmptyModal {
);
const text = Render.elementFactory(
'div',
- { className: 'modal__text--win' },
+ {
+ className: 'modal__text--win',
+ style: `color: ${player.theColor};`,
+ },
`${player.theName} wins`,
);
const button = Render.elementFactory(
@@ -38,9 +44,10 @@ export class WinModal extends EmptyModal {
{ type: 'button', className: 'modal__button--win' },
'MENU',
);
- button.addEventListener('click', () =>
- this.view.displayMenuView(),
- );
+ button.addEventListener('click', () => {
+ this.view.endGame();
+ this.hideModal();
+ });
Render.childrenInjector(
this.modalContainer,
heading,
diff --git a/src/app/logic/Configuration.ts b/src/app/logic/Configuration.ts
index 3823f13..9360982 100644
--- a/src/app/logic/Configuration.ts
+++ b/src/app/logic/Configuration.ts
@@ -3,16 +3,13 @@ import { PredatorsConfigInterface } from '../../Interfaces/PredatorsConfigInterf
import { ProtectorsConfigInterface } from '../../Interfaces/ProtectorsConfigInterface';
import { GameModes } from '../../Enums/GameModeEnums';
import { GameConfigInterface } from '../../Interfaces/GameConfigInterface';
-import { AnimalNames } from '~src/Enums/AnimalNamesEnum';
+import { AnimalNames } from '../../Enums/AnimalNamesEnum';
+import { PlayerDTO } from '../../Interfaces/PlayerDTOInterface';
export class Configuration implements GameConfigInterface {
protected _mode: GameModes;
protected _roundTimeInSeconds: number;
- protected _playersConfig: {
- name: string;
- path: string;
- color: string;
- }[];
+ protected _playersConfig: PlayerDTO[];
protected _livestockConfig: LivestockConfigInterface[];
protected _protectorsConfig: ProtectorsConfigInterface[];
protected _predatorsConfig: PredatorsConfigInterface[];
@@ -43,26 +40,15 @@ export class Configuration implements GameConfigInterface {
return this._mode;
}
set roundTimeInSeconds(numberOfSeconds: number) {
- this.roundTimeInSeconds = numberOfSeconds;
+ this._roundTimeInSeconds = numberOfSeconds;
}
get roundTimeInSeconds(): number {
- return this.roundTimeInSeconds;
- }
- //TODO: CREATE PLAYER CONFIG INTERFACE IF NECESSARY
- set playersConfig(
- newPlayersConfig: {
- name: string;
- path: string;
- color: string;
- }[],
- ) {
+ return this._roundTimeInSeconds;
+ }
+ set playersConfig(newPlayersConfig: PlayerDTO[]) {
this._playersConfig = newPlayersConfig;
}
- get playersConfig(): {
- name: string;
- path: string;
- color: string;
- }[] {
+ get playersConfig(): PlayerDTO[] {
return this._playersConfig;
}
@@ -96,11 +82,7 @@ export class Configuration implements GameConfigInterface {
return this._predatorsConfig;
}
- addNewPlayer(newPlayerConfig: {
- name: string;
- path: string;
- color: string;
- }): void {
+ addNewPlayer(newPlayerConfig: PlayerDTO): void {
this._playersConfig.concat(newPlayerConfig);
}
removeLastPlayer(): void {
@@ -116,6 +98,4 @@ export class Configuration implements GameConfigInterface {
(animal) => animal.name !== animaname,
);
}
-
- // TODO: PREDATOR, PROTECTOR ETC WHEN GAME SETTINGS APPEAR.
}
diff --git a/src/app/logic/Game.ts b/src/app/logic/Game.ts
index fcd1bde..875cf75 100644
--- a/src/app/logic/Game.ts
+++ b/src/app/logic/Game.ts
@@ -3,27 +3,22 @@ import { GameModes } from '../../Enums/GameModeEnums';
import { GameConfigInterface } from '../../Interfaces/GameConfigInterface';
import { Player } from '../../Player';
import { BreedProcessor } from '../BreedProcessor';
-import { Dice } from '../Dice';
-import { FirstDice } from '../FirstDice';
-import { SecondDice } from '../SecondDice';
import { Timer } from '../Timer';
import { Trade } from '../Trade';
import { Bank } from './Bank';
-import { defaultGameConfiguration } from './defaultGameConfiguration';
import { LivestockConfigInterface } from '../../Interfaces/LivestockConfigInterface';
import { ProtectorsConfigInterface } from '../../Interfaces/ProtectorsConfigInterface';
import { HerdOwners } from '../../Enums/HerdOwnerEnum';
+import { DiceBuilder } from '../DiceBuilder';
export class Game {
mode: GameModes;
roundTimeInSeconds: number;
- // totalGameTimeInSeconds: number;
playersConfig: { name: string; path: string }[];
playersHerdConfig: HerdConfigInterface[];
banksHerdConfig: HerdConfigInterface[];
players: Player[];
bank: Bank;
- dice: Dice[];
timer: Timer;
breedProcessor: BreedProcessor;
trade: Trade;
@@ -34,8 +29,8 @@ export class Game {
playersConfig,
livestockConfig,
protectorsConfig,
- }: // predatorsConfig,
- GameConfigInterface = defaultGameConfiguration) {
+ predatorsConfig,
+ }: GameConfigInterface) {
this.mode = mode;
this.roundTimeInSeconds = roundTimeInSeconds;
this.playersConfig = playersConfig;
@@ -60,12 +55,19 @@ export class Game {
);
this.currentPlayerNumber = 0;
this.bank = new Bank(this.banksHerdConfig);
- // TODO: GET DICE DATA FROM CONFIG AFTER/ IF DICE REFACTOR
- // TODO: CHECK IF NEEDED SINCE THEY ARE CALLED IN BREEDPROCESSOR
- this.dice = [new FirstDice(), new SecondDice()];
+ const [firstDice, secondDice] = DiceBuilder.build(
+ livestockConfig,
+ predatorsConfig,
+ protectorsConfig,
+ );
this.timer = new Timer(roundTimeInSeconds);
- // TO CHECK: SHOULD BREED PROCESSOR CREATE DICE INSTANCES?
- this.breedProcessor = new BreedProcessor(this.bank);
+ this.breedProcessor = new BreedProcessor(
+ this.bank,
+ firstDice,
+ secondDice,
+ predatorsConfig,
+ this.mode,
+ );
this.trade = new Trade(
this.bank,
livestockConfig,
@@ -94,9 +96,6 @@ export class Game {
return this.bank;
}
- get theDice(): Dice[] {
- return this.dice;
- }
get theTimer(): Timer {
return this.timer;
}
@@ -109,7 +108,6 @@ export class Game {
return this.trade;
}
- // TODO: REFACTOR!
preparePlayersHerdConfig(
livestockConfig: LivestockConfigInterface[],
protectorsConfig: ProtectorsConfigInterface[],
@@ -145,6 +143,7 @@ export class Game {
playersInitialStock,
bankInitialStock,
chasesAway,
+ exclamation,
}) => {
return {
name,
@@ -152,6 +151,7 @@ export class Game {
role,
path,
chasesAway,
+ exclamation,
inStock:
owner === HerdOwners.PLAYER
? playersInitialStock
diff --git a/src/app/logic/GameProcessor.ts b/src/app/logic/GameProcessor.ts
index 0fc94d9..5a0dbf1 100644
--- a/src/app/logic/GameProcessor.ts
+++ b/src/app/logic/GameProcessor.ts
@@ -32,7 +32,7 @@ export class GameProcessor {
this.gameController.updateTimeRemaining(
Math.round(this.game.theTimer.theTurnTimeLeft),
);
- }, 100);
+ }, 50);
}
pauseTurn(): void {
@@ -53,6 +53,7 @@ export class GameProcessor {
/**
* @returns true if current player wins the game, false otherwise
*/
+ // TODO: Consider moving win conditions to configuration
checkWin(): boolean {
const animalsRequiredToWin: AnimalNames[] = [
AnimalNames.RABBIT,
diff --git a/src/app/logic/Herd.ts b/src/app/logic/Herd.ts
index 8405de4..5de3f21 100644
--- a/src/app/logic/Herd.ts
+++ b/src/app/logic/Herd.ts
@@ -1,18 +1,37 @@
-import _ from 'lodash';
+import { add, subtract } from 'lodash';
+import { Predator } from '../../Animals/Predator';
import { Animal } from '../../Animals/Animal';
-import { Fox } from '../../Animals/Fox';
-import { Wolf } from '../../Animals/Wolf';
import { AnimalNames } from '../../Enums/AnimalNamesEnum';
import { HerdConfigInterface } from '../../Interfaces/HerdConfigInterface';
-import { mockHerdConfig } from './mockHerdConfig';
-
+import { GameModes } from '../../Enums/GameModeEnums';
+import { Protector } from '../../Animals/Protector';
+import { AnimalRoles } from '../../Enums/AnimalRolesEnum';
export class Herd {
protected animals: [Animal, number][];
- constructor(
- playersHerdConfig: HerdConfigInterface[] = mockHerdConfig,
- ) {
+ constructor(playersHerdConfig: HerdConfigInterface[]) {
this.animals = playersHerdConfig.map(
- ({ name, tradeValue, role, path, inStock }) => {
+ ({
+ name,
+ tradeValue,
+ role,
+ path,
+ inStock,
+ chasesAway,
+ exclamation,
+ }) => {
+ if (role === AnimalRoles.GUARDIAN) {
+ if (chasesAway && exclamation) {
+ const newAnimal = new Protector(
+ name,
+ path,
+ role,
+ tradeValue,
+ chasesAway,
+ exclamation,
+ );
+ return [newAnimal, inStock];
+ }
+ }
const newAnimal = new Animal(name, path, tradeValue, role);
return [newAnimal, inStock];
},
@@ -28,7 +47,7 @@ export class Herd {
if (animal.theName === animalName) return true;
});
if (indexOfAnimal === -1)
- throw new Error(`Animal: ${animalName} not found`);
+ console.log(`Animal: ${animalName} not found`);
return indexOfAnimal;
}
@@ -57,7 +76,7 @@ export class Herd {
): void {
const animalIndex = this.findAnimalTupleIndex(animalName);
const animalTuple = this.animals[animalIndex];
- const newNumber = _.add(animalTuple[1], numberToAdd);
+ const newNumber = add(animalTuple[1], numberToAdd);
this.updateNumberOfAnimals(animalIndex, newNumber);
}
@@ -75,8 +94,8 @@ export class Herd {
const animalIndex = this.findAnimalTupleIndex(animalName);
const animalTuple = this.animals[animalIndex];
if (animalTuple[1] < numberToSubstract)
- alert('not enough animals');
- const newNumber = _.subtract(animalTuple[1], numberToSubstract);
+ console.log('not enough animals: ', animalName);
+ const newNumber = subtract(animalTuple[1], numberToSubstract);
this.updateNumberOfAnimals(animalIndex, newNumber);
}
@@ -124,40 +143,26 @@ export class Herd {
/**
* Depending on the attacking animal, it checks if there is a herd protector for the given type of attacker,
* then reduces to zero the number of the animals in the herd or removes the protector, as is defined by game configuration.
- * @param { Fox | Wolf } attackingAnimal The animal that is attacking the herd.
+ * @param { Predator } attackingAnimal The animal that is attacking the herd.
*/
- // TODO: Check parameteres type. Create classes for protectors and predators if needed.
- // TODO: Modify to use config? Define at refactor
- cullAnimals(attackingAnimal: Fox | Wolf): void {
- switch (attackingAnimal.theName) {
- case AnimalNames.FOX: {
- const hasSmallDog =
- this.getAnimalNumber(AnimalNames.SMALL_DOG) > 0;
- if (!hasSmallDog) {
- attackingAnimal.attackHerd();
- this.cullAllAnimalsOfOneType(AnimalNames.RABBIT);
- return;
- }
- this.removeAnimalsFromHerd(AnimalNames.SMALL_DOG, 1);
- // (this.animals[5][0] as SmallDog).protectHerd();
- break;
- }
- case AnimalNames.WOLF: {
- const hasBigDog =
- this.getAnimalNumber(AnimalNames.BIG_DOG) > 0;
- if (!hasBigDog) {
- attackingAnimal.attackHerd();
- this.cullAllAnimalsOfGivenTypes([
- AnimalNames.COW,
- AnimalNames.PIG,
- AnimalNames.RABBIT,
- AnimalNames.SHEEP,
- ]);
- return;
- }
- this.removeAnimalsFromHerd(AnimalNames.BIG_DOG, 1);
- // (this.animals[6][0] as BigDog).protectHerd();
+ cullAnimals(attackingAnimal: Predator, mode: GameModes): void {
+ const animalsToCull = attackingAnimal.kills;
+ const protector = attackingAnimal.isChasedAwayBy;
+ const hasProtector = this.getAnimalNumber(protector) > 0;
+ if (!hasProtector) {
+ const isDynamicMode = mode === GameModes.DYNAMIC;
+ const killsRabbits = animalsToCull.includes(AnimalNames.RABBIT);
+ this.cullAllAnimalsOfGivenTypes(animalsToCull);
+ if (isDynamicMode && killsRabbits) {
+ this.addAnimalsToHerd(AnimalNames.RABBIT, 1);
}
+ attackingAnimal.attackHerd();
+ } else {
+ this.removeAnimalsFromHerd(protector, 1);
+ const protectorsIndex = this.findAnimalTupleIndex(protector);
+ const protectorsObject = this.theAnimals[protectorsIndex][0];
+ if (protectorsObject instanceof Protector)
+ protectorsObject.protectHerd();
}
}
}
diff --git a/src/app/logic/defaultBankConfig.ts b/src/app/logic/defaultBankConfig.ts
index a9c5dbe..aa00c6d 100644
--- a/src/app/logic/defaultBankConfig.ts
+++ b/src/app/logic/defaultBankConfig.ts
@@ -45,12 +45,14 @@ export const defaultBankConfig: HerdConfigInterface[] = [
role: AnimalRoles.GUARDIAN,
inStock: 4,
chasesAway: AnimalNames.FOX,
+ exclamation: `Woof! Woof! I'm protecting all rabbits in the herd! Woof! Woof!`,
},
{
name: AnimalNames.BIG_DOG,
tradeValue: 36,
path: './static/images/avatars/big_dog.svg',
role: AnimalRoles.GUARDIAN,
+ exclamation: `WOOF! WOOF! I'm protecting the whole herd! WOOF! WOOF!`,
inStock: 2,
chasesAway: AnimalNames.WOLF,
},
diff --git a/src/app/logic/defaultGameConfiguration.ts b/src/app/logic/defaultGameConfiguration.ts
index d78cc3b..7ac030e 100644
--- a/src/app/logic/defaultGameConfiguration.ts
+++ b/src/app/logic/defaultGameConfiguration.ts
@@ -11,11 +11,7 @@ export const defaultGameConfiguration: GameConfigInterface = {
name: 'Carlos Santanos',
path: '../../static/images/avatars/small_dog.svg',
color: 'blue',
- },
- {
- name: 'Pablo Escofarmo',
- path: '../../static/images/avatars/cow.svg',
- color: 'green',
+ isAI: false,
},
],
@@ -84,27 +80,33 @@ export const defaultGameConfiguration: GameConfigInterface = {
playersInitialStock: 0,
bankInitialStock: 4,
chasesAway: AnimalNames.FOX,
+ exclamation: `Woof! Woof! I'm protecting all rabbits in the herd! Woof! Woof!`,
},
{
name: AnimalNames.BIG_DOG,
tradeValue: 36,
- path: './static/images/avatars/big_dog.svg', // TODO: CHANGE TO BIG/SMALL DOG
+ path: './static/images/avatars/big_dog.svg',
role: AnimalRoles.GUARDIAN,
playersInitialStock: 0,
bankInitialStock: 2,
chasesAway: AnimalNames.WOLF,
+ exclamation: `WOOF! WOOF! I'm protecting the whole herd! WOOF! WOOF!`,
},
],
predatorsConfig: [
{
name: AnimalNames.FOX,
path: './static/images/avatars/fox.svg',
+ roles: AnimalRoles.PREDATOR,
kills: [AnimalNames.RABBIT],
- isChasedAwayBy: [AnimalNames.SMALL_DOG],
+ isChasedAwayBy: AnimalNames.SMALL_DOG,
+ exclamation:
+ 'Ring-ding-ding-ding-dingeringeding! Wa-pa-pa-pa-pa-pa-pow!',
dice: [{ diceNumber: 1, probability: 1 }],
},
{
name: AnimalNames.WOLF,
+ roles: AnimalRoles.PREDATOR,
path: './static/images/avatars/wolf.svg',
kills: [
AnimalNames.RABBIT,
@@ -112,7 +114,8 @@ export const defaultGameConfiguration: GameConfigInterface = {
AnimalNames.PIG,
AnimalNames.COW,
],
- isChasedAwayBy: [AnimalNames.BIG_DOG],
+ isChasedAwayBy: AnimalNames.BIG_DOG,
+ exclamation: 'Auuuuuu!Grrrrr!',
dice: [{ diceNumber: 2, probability: 1 }],
},
],
diff --git a/src/app/logic/mockHerdConfig.ts b/src/app/logic/defaultHerdConfig.ts
similarity index 85%
rename from src/app/logic/mockHerdConfig.ts
rename to src/app/logic/defaultHerdConfig.ts
index 1989535..a458b15 100644
--- a/src/app/logic/mockHerdConfig.ts
+++ b/src/app/logic/defaultHerdConfig.ts
@@ -2,7 +2,7 @@ import { HerdConfigInterface } from '../../Interfaces/HerdConfigInterface';
import { AnimalNames } from '../../Enums/AnimalNamesEnum';
import { AnimalRoles } from '../../Enums/AnimalRolesEnum';
-export const mockHerdConfig: HerdConfigInterface[] = [
+export const defaultPlayerHerdConfig: HerdConfigInterface[] = [
{
name: AnimalNames.RABBIT,
tradeValue: 1,
@@ -45,6 +45,7 @@ export const mockHerdConfig: HerdConfigInterface[] = [
role: AnimalRoles.GUARDIAN,
inStock: 0,
chasesAway: AnimalNames.FOX,
+ exclamation: `Woof! Woof! I'm protecting all rabbits in the herd! Woof! Woof!`,
},
{
name: AnimalNames.BIG_DOG,
@@ -53,5 +54,6 @@ export const mockHerdConfig: HerdConfigInterface[] = [
role: AnimalRoles.GUARDIAN,
inStock: 0,
chasesAway: AnimalNames.WOLF,
+ exclamation: `WOOF! WOOF! I'm protecting the whole herd! WOOF! WOOF!`,
},
];
diff --git a/src/app/logic/dynamicGameConfiguration.ts b/src/app/logic/dynamicGameConfiguration.ts
new file mode 100644
index 0000000..2760a7c
--- /dev/null
+++ b/src/app/logic/dynamicGameConfiguration.ts
@@ -0,0 +1,117 @@
+import { AnimalNames } from '../../Enums/AnimalNamesEnum';
+import { AnimalRoles } from '../../Enums/AnimalRolesEnum';
+import { GameModes } from '../../Enums/GameModeEnums';
+import { GameConfigInterface } from '../../Interfaces/GameConfigInterface';
+
+export const dynamicGameConfiguration: GameConfigInterface = {
+ mode: GameModes.DYNAMIC,
+ roundTimeInSeconds: 15,
+ playersConfig: [
+ {
+ name: 'Carlos Santanos',
+ path: '../../static/images/avatars/small_dog.svg',
+ color: 'blue',
+ isAI: false,
+ },
+ ],
+
+ livestockConfig: [
+ {
+ name: AnimalNames.RABBIT,
+ tradeValue: 1,
+ path: './static/images/avatars/rabbit.svg',
+ role: AnimalRoles.LIVESTOCK,
+ playersInitialStock: 1,
+ bankInitialStock: 60,
+ dice: [
+ { diceNumber: 1, probability: 6 },
+ { diceNumber: 2, probability: 6 },
+ ],
+ },
+ {
+ name: AnimalNames.SHEEP,
+ tradeValue: 6,
+ path: './static/images/avatars/sheep.svg',
+ role: AnimalRoles.LIVESTOCK,
+ playersInitialStock: 0,
+ bankInitialStock: 24,
+ dice: [
+ { diceNumber: 1, probability: 2 },
+ { diceNumber: 2, probability: 3 },
+ ],
+ },
+ {
+ name: AnimalNames.PIG,
+ tradeValue: 12,
+ path: './static/images/avatars/pig.svg',
+ role: AnimalRoles.LIVESTOCK,
+ playersInitialStock: 0,
+ bankInitialStock: 20,
+ dice: [
+ { diceNumber: 1, probability: 2 },
+ { diceNumber: 2, probability: 1 },
+ ],
+ },
+ {
+ name: AnimalNames.COW,
+ tradeValue: 36,
+ path: './static/images/avatars/cow.svg',
+ role: AnimalRoles.LIVESTOCK,
+ playersInitialStock: 0,
+ bankInitialStock: 12,
+ dice: [{ diceNumber: 2, probability: 1 }],
+ },
+ {
+ name: AnimalNames.HORSE,
+ tradeValue: 72,
+ path: './static/images/avatars/horse.svg',
+ role: AnimalRoles.LIVESTOCK,
+ playersInitialStock: 0,
+ bankInitialStock: 4,
+ dice: [{ diceNumber: 1, probability: 1 }],
+ },
+ ],
+ protectorsConfig: [
+ {
+ name: AnimalNames.SMALL_DOG,
+ tradeValue: 6,
+ path: './static/images/avatars/small_dog.svg',
+ role: AnimalRoles.GUARDIAN,
+ playersInitialStock: 0,
+ bankInitialStock: 4,
+ chasesAway: AnimalNames.FOX,
+ exclamation: `Woof! Woof! I'm protecting all rabbits in the herd! Woof! Woof!`,
+ },
+ {
+ name: AnimalNames.BIG_DOG,
+ tradeValue: 36,
+ path: './static/images/avatars/big_dog.svg',
+ role: AnimalRoles.GUARDIAN,
+ playersInitialStock: 0,
+ bankInitialStock: 2,
+ chasesAway: AnimalNames.WOLF,
+ exclamation: `WOOF! WOOF! I'm protecting the whole herd! WOOF! WOOF!`,
+ },
+ ],
+ predatorsConfig: [
+ {
+ name: AnimalNames.FOX,
+ path: './static/images/avatars/fox.svg',
+ roles: AnimalRoles.PREDATOR,
+ kills: [AnimalNames.RABBIT],
+ isChasedAwayBy: AnimalNames.SMALL_DOG,
+ exclamation:
+ 'Ring-ding-ding-ding-dingeringeding! Wa-pa-pa-pa-pa-pa-pow!',
+ dice: [{ diceNumber: 1, probability: 1 }],
+ },
+ {
+ name: AnimalNames.WOLF,
+ path: './static/images/avatars/wolf.svg',
+ roles: AnimalRoles.PREDATOR,
+ kills: [AnimalNames.SHEEP, AnimalNames.PIG, AnimalNames.COW],
+ isChasedAwayBy: AnimalNames.BIG_DOG,
+ exclamation: 'Auuuuuu!Grrrrr!',
+ dice: [{ diceNumber: 2, probability: 1 }],
+ },
+ ],
+};
diff --git a/src/app/manuals/BreedPhaseDemo.ts b/src/app/manuals/BreedPhaseDemo.ts
index d13eaa3..b3c9e53 100644
--- a/src/app/manuals/BreedPhaseDemo.ts
+++ b/src/app/manuals/BreedPhaseDemo.ts
@@ -1,6 +1,10 @@
import { Player } from '../../Player';
import { AnimalNames } from '../../Enums/AnimalNamesEnum';
import { BreedProcessor } from '../BreedProcessor';
+import { defaultGameConfiguration } from '../logic/defaultGameConfiguration';
+import { DiceBuilder } from '../DiceBuilder';
+import { mockPredatorConfig } from './mockPredatorConfig';
+import { GameModes } from '../../Enums/GameModeEnums';
export class BreedPhaseDemo {
static playDemo(): void {
@@ -12,7 +16,18 @@ export class BreedPhaseDemo {
bank.theHerd.addAnimalsToHerd(AnimalNames.HORSE, 4);
bank.theHerd.addAnimalsToHerd(AnimalNames.SMALL_DOG, 4);
bank.theHerd.addAnimalsToHerd(AnimalNames.BIG_DOG, 2);
- const bp = new BreedProcessor(bank);
+ const [firstDice, secondDice] = DiceBuilder.build(
+ defaultGameConfiguration.livestockConfig,
+ defaultGameConfiguration.predatorsConfig,
+ defaultGameConfiguration.protectorsConfig,
+ );
+ const bp = new BreedProcessor(
+ bank,
+ firstDice,
+ secondDice,
+ mockPredatorConfig,
+ GameModes.STATIC,
+ );
const player = new Player('player');
for (let i = 0; i < 10; i++) {
bp.processBreedPhase(player);
diff --git a/src/app/manuals/WinModalDemo.ts b/src/app/manuals/WinModalDemo.ts
index f8e995b..be780a3 100644
--- a/src/app/manuals/WinModalDemo.ts
+++ b/src/app/manuals/WinModalDemo.ts
@@ -10,6 +10,7 @@ export class WinModalDemo {
const player = new Player(
'player',
'./static/images/avatars/small_dog.svg',
+ `#338254`,
);
Render.render('#sf-app', modal.createWinModal(player));
}
diff --git a/src/app/manuals/dynamicModeManual.ts b/src/app/manuals/dynamicModeManual.ts
new file mode 100644
index 0000000..a569979
--- /dev/null
+++ b/src/app/manuals/dynamicModeManual.ts
@@ -0,0 +1,28 @@
+// in the play in the dynamic mode, until mode modal has option to choose
+// dynamic mode
+// in the file: src/app/ViewController
+// in the lines: 41-63 (the launchGame method)
+// UNCOMMENT AND INSERT INSTEAD:
+
+// launchGame(players: PlayerDTO[], isModeDynamic?: boolean): void {
+// const config: Configuration = new Configuration(
+// dynamicGameConfiguration,
+// );
+// if (true) {
+// const numberOfPlayers = players.length;
+// config.livestockConfig = config.livestockConfig.map(
+// (animal) => {
+// if (animal.name === AnimalNames.RABBIT)
+// animal.bankInitialStock -= numberOfPlayers;
+// return animal;
+// },
+// );
+// }
+// config.playersConfig = players;
+// this.gameController = new GameController(this, config);
+// this.startGame(
+// this.gameController.theGame.thePlayers,
+// this.gameController.theGame.theCurrentPlayer,
+// this.gameController.theGame.theBank,
+// );
+// }
diff --git a/src/app/manuals/gameManual.ts b/src/app/manuals/gameManual.ts
index 4336411..7acf849 100644
--- a/src/app/manuals/gameManual.ts
+++ b/src/app/manuals/gameManual.ts
@@ -1,6 +1,7 @@
+import { defaultGameConfiguration } from '../logic/defaultGameConfiguration';
import { Game } from '../logic/Game';
// TO LOG THE GAME OBJECT ADD logGameObject() in APP.TS
export function logGameObject(): void {
- const newGame = new Game();
+ const newGame = new Game(defaultGameConfiguration);
console.log(newGame);
}
diff --git a/src/app/manuals/herdManual.ts b/src/app/manuals/herdManual.ts
index 0ca3c21..3de349d 100644
--- a/src/app/manuals/herdManual.ts
+++ b/src/app/manuals/herdManual.ts
@@ -47,6 +47,7 @@ export function herdDemo(): void {
role: AnimalRoles.GUARDIAN,
inStock: 0,
chasesAway: AnimalNames.FOX,
+ exclamation: `Woof! Woof! I'm protecting all rabbits in the herd! Woof! Woof!`,
},
{
name: AnimalNames.BIG_DOG,
@@ -55,6 +56,7 @@ export function herdDemo(): void {
role: AnimalRoles.GUARDIAN,
inStock: 0,
chasesAway: AnimalNames.WOLF,
+ exclamation: `WOOF! WOOF! I'm protecting the whole herd! WOOF! WOOF!`,
},
];
diff --git a/src/app/manuals/mockPredatorConfig.ts b/src/app/manuals/mockPredatorConfig.ts
new file mode 100644
index 0000000..bc76bf5
--- /dev/null
+++ b/src/app/manuals/mockPredatorConfig.ts
@@ -0,0 +1,30 @@
+import { AnimalRoles } from '../../Enums/AnimalRolesEnum';
+import { AnimalNames } from '../../Enums/AnimalNamesEnum';
+import { PredatorsConfigInterface } from '../../Interfaces/PredatorsConfigInterface';
+
+export const mockPredatorConfig: PredatorsConfigInterface[] = [
+ {
+ name: AnimalNames.FOX,
+ path: '/static/images/avatars/fox.png',
+ roles: AnimalRoles.PREDATOR,
+ kills: [AnimalNames.RABBIT],
+ isChasedAwayBy: AnimalNames.SMALL_DOG,
+ exclamation:
+ 'Ring-ding-ding-ding-dingeringeding! Wa-pa-pa-pa-pa-pa-pow!',
+ dice: [{ diceNumber: 1, probability: 1 }],
+ },
+ {
+ name: AnimalNames.WOLF,
+ path: '/static/images/avatars/wolf.png',
+ roles: AnimalRoles.PREDATOR,
+ kills: [
+ AnimalNames.RABBIT,
+ AnimalNames.SHEEP,
+ AnimalNames.PIG,
+ AnimalNames.COW,
+ ],
+ isChasedAwayBy: AnimalNames.BIG_DOG,
+ exclamation: 'Auuuuuu!Grrrrr!',
+ dice: [{ diceNumber: 2, probability: 1 }],
+ },
+];
diff --git a/static/images/ui/background.png b/static/images/ui/background.png
new file mode 100644
index 0000000..0743729
Binary files /dev/null and b/static/images/ui/background.png differ
diff --git a/styles/App.scss b/styles/App.scss
index fc92d01..63c980a 100644
--- a/styles/App.scss
+++ b/styles/App.scss
@@ -1,2 +1,3 @@
+@import './variables';
@import './components/components';
@import './global';
diff --git a/styles/_global.scss b/styles/_global.scss
index cca14bd..df55874 100644
--- a/styles/_global.scss
+++ b/styles/_global.scss
@@ -4,6 +4,11 @@
margin: 0;
font-family: 'Roboto', sans-serif;
}
+#sf-app {
+ height: 100vh;
+ background: url(/static/images/ui/background.png) no-repeat;
+ background-size: cover;
+}
.hidden {
display: none;
diff --git a/styles/_variables.scss b/styles/_variables.scss
new file mode 100644
index 0000000..ca30efd
--- /dev/null
+++ b/styles/_variables.scss
@@ -0,0 +1,11 @@
+//Fonts
+$font-family: 'Roboto', sans-serif;
+$font-size: 24px;
+$font-weight: 700;
+
+//Colors
+$color-primary: #fefefe;
+$color-hover: #f00;
+
+//Border
+$border-radius: 16px;
diff --git a/styles/components/_alert.scss b/styles/components/_alert.scss
new file mode 100644
index 0000000..293aa7e
--- /dev/null
+++ b/styles/components/_alert.scss
@@ -0,0 +1,18 @@
+.alert {
+ display: flex;
+ border-radius: 0.25rem;
+ transition: all 0.7s ease-in-out;
+
+ &__icon {
+ width: auto;
+ height: 1.75rem;
+ margin: 0.5rem 1rem;
+ }
+
+ &__text {
+ display: inline-flex;
+ margin: 0.5rem;
+ font-size: 1rem;
+ line-height: 2rem;
+ }
+}
diff --git a/styles/components/_button.scss b/styles/components/_button.scss
deleted file mode 100644
index f54e640..0000000
--- a/styles/components/_button.scss
+++ /dev/null
@@ -1,2 +0,0 @@
-.button {
-}
diff --git a/styles/components/_components.scss b/styles/components/_components.scss
index 8c817fc..2e0f444 100644
--- a/styles/components/_components.scss
+++ b/styles/components/_components.scss
@@ -1,10 +1,10 @@
@import './view';
@import './playersBoard';
-@import './components/button';
-@import './components/modal';
+@import './modal';
@import './menu';
@import './modeView';
@import './tradeModal';
@import './playerPanel';
@import './bankBoard';
@import './emptyView';
+@import './alert';
diff --git a/styles/components/_emptyView.scss b/styles/components/_emptyView.scss
index 0f6a33b..423d518 100644
--- a/styles/components/_emptyView.scss
+++ b/styles/components/_emptyView.scss
@@ -1,4 +1,6 @@
.view {
+ height: 100vh;
&__container {
+ height: 100vh;
}
}
diff --git a/styles/components/_menu.scss b/styles/components/_menu.scss
index 4344432..e845be6 100644
--- a/styles/components/_menu.scss
+++ b/styles/components/_menu.scss
@@ -1,60 +1,53 @@
-.page__container {
- width: 100vw;
- height: calc(100vh - 2rem);
- background-color: white;
- text-align: center;
-}
-
.menu-window {
display: flex;
+ height: 100%;
flex-direction: column;
- justify-content: space-between;
+ padding: 80px;
&__header {
- position: relative;
- display: flex;
- flex-direction: column;
- padding: 32px;
- }
- &__heading {
- }
- &__description {
+ font-family: $font-family;
}
}
.menu {
- position: relative;
- display: flex;
- align-items: center;
- justify-content: space-between;
- padding: 32px;
- &__graphic {
- &-container {
- width: 30vw;
- height: 50vh;
- background-color: cadetblue;
- }
- }
- &__buttons {
- display: flex;
- flex-direction: column;
- }
+ flex-grow: 1;
&__button {
- &--rules {
- position: absolute;
- right: 2rem;
- bottom: 0;
- width: 2rem;
- height: 2rem;
+ display: block;
+ border: none;
+ margin-top: 50px;
+ background: none;
+ font-family: $font-family;
+ font-size: $font-size;
+ font-weight: $font-weight;
+ outline: none;
+ &:hover {
+ color: $color-hover;
+ cursor: pointer;
}
}
}
+.button--start {
+ min-width: 350px;
+ align-self: center;
+ border: none;
+ background: #203739;
+ border-radius: $border-radius;
+ color: $color-primary;
+ font-family: $font-family;
+ font-size: 30px;
+ font-weight: $font-weight;
+ letter-spacing: 0.3rem;
+ line-height: 8rem;
+ outline: none;
+ &:hover {
+ background-color: $color-hover;
+ cursor: pointer;
+ }
+}
.footer {
- position: sticky;
- bottom: 0;
- width: 100vw;
- margin: auto;
- background-color: white;
- line-height: 2em;
- text-align: center;
+ margin-top: 35px;
+ color: $color-primary;
+ font-family: $font-family;
+ font-size: $font-size;
+ font-weight: $font-weight;
}
diff --git a/test/herd.spec.ts b/test/herd.spec.ts
index 1575265..0e958bf 100644
--- a/test/herd.spec.ts
+++ b/test/herd.spec.ts
@@ -1,8 +1,9 @@
-import { Fox } from '../src/Animals/Fox';
-import { Wolf } from '../src/Animals/Wolf';
import { AnimalNames } from '../src/Enums/AnimalNamesEnum';
import { Herd } from '../src/app/logic/Herd';
-import { mockHerdConfig } from '../src/app/logic/mockHerdConfig';
+import { mockHerdConfig } from './mock/mockHerdConfig';
+import { Predator } from '../src/Animals/Predator';
+import { mockFox, mockWolf } from './mock/mockPredatorsConfig';
+import { GameModes } from '../src/Enums/GameModeEnums';
describe('Herds method', () => {
describe('addAnimal, given mock data', () => {
@@ -16,7 +17,17 @@ describe('Herds method', () => {
describe('cullAnimals, given mock data', () => {
const testedHerd = new Herd(mockHerdConfig);
testedHerd.addAnimalsToHerd(AnimalNames.RABBIT, 10);
- testedHerd.cullAnimals(new Fox());
+ testedHerd.cullAnimals(
+ new Predator(
+ mockWolf.name,
+ mockWolf.path,
+ undefined,
+ mockWolf.kills,
+ mockWolf.isChasedAwayBy,
+ mockWolf.exclamation,
+ ),
+ GameModes.STATIC,
+ );
it('should modify the number of specific animal', () => {
expect(testedHerd.theAnimals[0][1]).toBe(0);
});
@@ -26,7 +37,17 @@ describe('Herds method', () => {
const testedHerd = new Herd(mockHerdConfig);
testedHerd.addAnimalsToHerd(AnimalNames.SMALL_DOG, 1);
testedHerd.addAnimalsToHerd(AnimalNames.RABBIT, 10);
- testedHerd.cullAnimals(new Fox());
+ testedHerd.cullAnimals(
+ new Predator(
+ mockFox.name,
+ mockFox.path,
+ mockWolf.roles,
+ mockFox.kills,
+ mockFox.isChasedAwayBy,
+ mockFox.exclamation,
+ ),
+ GameModes.STATIC,
+ );
it('should modify the number of specific animal', () => {
expect(testedHerd.theAnimals[5][1]).toBe(0);
expect(testedHerd.theAnimals[0][1]).toBe(10);
@@ -37,7 +58,17 @@ describe('Herds method', () => {
const testedHerd = new Herd(mockHerdConfig);
testedHerd.addAnimalsToHerd(AnimalNames.BIG_DOG, 1);
testedHerd.addAnimalsToHerd(AnimalNames.SHEEP, 10);
- testedHerd.cullAnimals(new Wolf());
+ testedHerd.cullAnimals(
+ new Predator(
+ mockWolf.name,
+ mockWolf.path,
+ mockWolf.roles,
+ mockWolf.kills,
+ mockWolf.isChasedAwayBy,
+ mockWolf.exclamation,
+ ),
+ GameModes.STATIC,
+ );
it('should modify the number of specific animal', () => {
expect(testedHerd.theAnimals[6][1]).toBe(0);
expect(testedHerd.theAnimals[1][1]).toBe(10);
diff --git a/src/app/logic/mockGameConfiguration.ts b/test/mock/mockGameConfiguration.ts
similarity index 82%
rename from src/app/logic/mockGameConfiguration.ts
rename to test/mock/mockGameConfiguration.ts
index f200adf..a308ebf 100644
--- a/src/app/logic/mockGameConfiguration.ts
+++ b/test/mock/mockGameConfiguration.ts
@@ -1,7 +1,7 @@
-import { AnimalNames } from '../../Enums/AnimalNamesEnum';
-import { AnimalRoles } from '../../Enums/AnimalRolesEnum';
-import { GameModes } from '../../Enums/GameModeEnums';
-import { GameConfigInterface } from '../../Interfaces/GameConfigInterface';
+import { AnimalNames } from '../../src/Enums/AnimalNamesEnum';
+import { AnimalRoles } from '../../src/Enums/AnimalRolesEnum';
+import { GameModes } from '../../src/Enums/GameModeEnums';
+import { GameConfigInterface } from '../../src/Interfaces/GameConfigInterface';
export const defaultGameConfiguration: GameConfigInterface = {
mode: GameModes.STATIC,
@@ -84,6 +84,7 @@ export const defaultGameConfiguration: GameConfigInterface = {
playersInitialStock: 0,
bankInitialStock: 4,
chasesAway: AnimalNames.FOX,
+ exclamation: `Woof! Woof! I'm protecting all rabbits in the herd! Woof! Woof!`,
},
{
name: AnimalNames.BIG_DOG,
@@ -93,18 +94,23 @@ export const defaultGameConfiguration: GameConfigInterface = {
playersInitialStock: 0,
bankInitialStock: 2,
chasesAway: AnimalNames.WOLF,
+ exclamation: `WOOF! WOOF! I'm protecting the whole herd! WOOF! WOOF!`,
},
],
predatorsConfig: [
{
name: AnimalNames.FOX,
+ roles: AnimalRoles.PREDATOR,
path: './static/images/avatars/fox.svg',
kills: [AnimalNames.RABBIT],
- isChasedAwayBy: [AnimalNames.SMALL_DOG],
+ isChasedAwayBy: AnimalNames.SMALL_DOG,
+ exclamation:
+ 'Ring-ding-ding-ding-dingeringeding! Wa-pa-pa-pa-pa-pa-pow!',
dice: [{ diceNumber: 1, probability: 1 }],
},
{
name: AnimalNames.WOLF,
+ roles: AnimalRoles.PREDATOR,
path: './static/images/avatars/wolf.svg',
kills: [
AnimalNames.RABBIT,
@@ -112,7 +118,8 @@ export const defaultGameConfiguration: GameConfigInterface = {
AnimalNames.PIG,
AnimalNames.COW,
],
- isChasedAwayBy: [AnimalNames.BIG_DOG],
+ isChasedAwayBy: AnimalNames.BIG_DOG,
+ exclamation: 'Auuuuuu!Grrrrr!',
dice: [{ diceNumber: 2, probability: 1 }],
},
],
diff --git a/test/mock/mockHerdConfig.ts b/test/mock/mockHerdConfig.ts
new file mode 100644
index 0000000..2058a90
--- /dev/null
+++ b/test/mock/mockHerdConfig.ts
@@ -0,0 +1,57 @@
+import { HerdConfigInterface } from '../../src/Interfaces/HerdConfigInterface';
+import { AnimalNames } from '../../src/Enums/AnimalNamesEnum';
+import { AnimalRoles } from '../../src/Enums/AnimalRolesEnum';
+
+export const mockHerdConfig: HerdConfigInterface[] = [
+ {
+ name: AnimalNames.RABBIT,
+ tradeValue: 1,
+ path: '/static/images/avatars/rabbit.png',
+ role: AnimalRoles.LIVESTOCK,
+ inStock: 0,
+ },
+ {
+ name: AnimalNames.SHEEP,
+ tradeValue: 6,
+ path: '/static/images/avatars/sheep.png',
+ role: AnimalRoles.LIVESTOCK,
+ inStock: 0,
+ },
+ {
+ name: AnimalNames.PIG,
+ tradeValue: 12,
+ path: '/static/images/avatars/pig.png',
+ role: AnimalRoles.LIVESTOCK,
+ inStock: 0,
+ },
+ {
+ name: AnimalNames.COW,
+ tradeValue: 36,
+ path: '/static/images/avatars/cow.png',
+ role: AnimalRoles.LIVESTOCK,
+ inStock: 0,
+ },
+ {
+ name: AnimalNames.HORSE,
+ tradeValue: 72,
+ path: '/static/images/avatars/horse.png',
+ role: AnimalRoles.LIVESTOCK,
+ inStock: 0,
+ },
+ {
+ name: AnimalNames.SMALL_DOG,
+ tradeValue: 6,
+ path: '/static/images/avatars/dog.png',
+ role: AnimalRoles.GUARDIAN,
+ inStock: 0,
+ chasesAway: AnimalNames.FOX,
+ },
+ {
+ name: AnimalNames.BIG_DOG,
+ tradeValue: 36,
+ path: '/static/images/avatars/dog.png',
+ role: AnimalRoles.GUARDIAN,
+ inStock: 0,
+ chasesAway: AnimalNames.WOLF,
+ },
+];
diff --git a/test/mock/mockPredatorsConfig.ts b/test/mock/mockPredatorsConfig.ts
new file mode 100644
index 0000000..c0732e4
--- /dev/null
+++ b/test/mock/mockPredatorsConfig.ts
@@ -0,0 +1,27 @@
+import { AnimalNames } from '../../src/Enums/AnimalNamesEnum';
+import { AnimalRoles } from '../../src/Enums/AnimalRolesEnum';
+import { PredatorsConfigInterface } from '../../src/Interfaces/PredatorsConfigInterface';
+export const mockWolf: PredatorsConfigInterface = {
+ name: AnimalNames.WOLF,
+ path: '/static/images/avatars/wolf.png',
+ roles: AnimalRoles.PREDATOR,
+ kills: [
+ AnimalNames.RABBIT,
+ AnimalNames.SHEEP,
+ AnimalNames.PIG,
+ AnimalNames.COW,
+ ],
+ isChasedAwayBy: AnimalNames.BIG_DOG,
+ exclamation: 'Auuuuuu!Grrrrr!',
+ // dice: [{ diceNumber: 2, probability: 1 }],
+};
+
+export const mockFox: PredatorsConfigInterface = {
+ name: AnimalNames.FOX,
+ path: '/static/images/avatars/fox.png',
+ roles: AnimalRoles.PREDATOR,
+ kills: [AnimalNames.RABBIT],
+ isChasedAwayBy: AnimalNames.SMALL_DOG,
+ exclamation: 'Ringangngnignign',
+ // dice: [{ diceNumber: 2, probability: 1 }],
+};