Skip to content

Commit

Permalink
Merge branch 'develop' into feature/#56-banks-board
Browse files Browse the repository at this point in the history
  • Loading branch information
paula0403 committed Feb 2, 2021
2 parents d54e3be + 6f31cc1 commit 62bf1d1
Show file tree
Hide file tree
Showing 29 changed files with 957 additions and 147 deletions.
5 changes: 3 additions & 2 deletions src/Animals/Animal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@ import { AnimalNames } from '../Enums/AnimalNamesEnum';
import { AnimalRoles } from '../Enums/AnimalRolesEnum';
import { pull } from 'lodash';

type Value = 1 | 6 | 12 | 36 | 72;
export type Value = 1 | 6 | 12 | 36 | 72;

export abstract class Animal {
// export abstract class Animal {
export class Animal {
protected name: AnimalNames;
protected imagePath: string;
protected roles: AnimalRoles[];
Expand Down
4 changes: 4 additions & 0 deletions src/Enums/GameModeEnums.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export enum GameModes {
STATIC = 'static',
DYNAMIC = 'dynamic',
}
14 changes: 14 additions & 0 deletions src/Interfaces/GameConfigInterface.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { GameModes } from '../Enums/GameModeEnums';
import { LivestockConfigInterface } from './LivestockConfigInterface';
import { PredatorsConfigInterface } from './PredatorsConfigInterface';
import { ProtectorsConfigInterface } from './ProtectorsConfigInterface';

export interface GameConfigInterface {
mode: GameModes;
roundTimeInSeconds: number;
totalGameTimeInSeconds?: number;
playersConfig: { name: string; path: string; color: string }[];
livestockConfig: LivestockConfigInterface[];
protectorsConfig: ProtectorsConfigInterface[];
predatorsConfig: PredatorsConfigInterface[];
}
12 changes: 12 additions & 0 deletions src/Interfaces/HerdConfigInterface.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { Value } from '../Animals/Animal';
import { AnimalNames } from '../Enums/AnimalNamesEnum';
import { AnimalRoles } from '../Enums/AnimalRolesEnum';

export interface HerdConfigInterface {
name: AnimalNames;
tradeValue: Value;
role: AnimalRoles;
path: string;
inStock: number;
chasesAway?: AnimalNames;
}
11 changes: 11 additions & 0 deletions src/Interfaces/LivestockConfigInterface.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { AnimalNames } from '../Enums/AnimalNamesEnum';
import { AnimalRoles } from '../Enums/AnimalRolesEnum';

export interface LivestockConfigInterface {
name: AnimalNames;
tradeValue: number;
role: AnimalRoles;
playersInitialStock?: number;
bankInitialStock?: number;
dice?: { diceNumber: number; probability: number }[];
}
8 changes: 8 additions & 0 deletions src/Interfaces/PredatorsConfigInterface.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { AnimalNames } from '../Enums/AnimalNamesEnum';

export interface PredatorsConfigInterface {
name: AnimalNames;
kills: AnimalNames[];
isChasedAwayBy: AnimalNames[];
dice?: { diceNumber: number; probability: number }[];
}
7 changes: 7 additions & 0 deletions src/Interfaces/ProtectorsConfigInterface.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { AnimalNames } from '../Enums/AnimalNamesEnum';
import { LivestockConfigInterface } from './LivestockConfigInterface';

export interface ProtectorsConfigInterface
extends LivestockConfigInterface {
chasesAway?: AnimalNames[];
}
13 changes: 11 additions & 2 deletions src/Player.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,24 @@
import { Herd } from './app/logic/Herd';
import { mockHerdConfig } from './app/logic/mockHerdConfig';
import { HerdConfigInterface } from './Interfaces/HerdConfigInterface';

export class Player {
protected name: string;
protected avatar: string;
protected herd: Herd;
protected color: string;

// TODO: set path to default avatar when it's available
constructor(name: string, avatar = 'path to default avatar') {
constructor(
name: string,
avatar = 'path to default avatar',
color = 'green',
herdConfig: HerdConfigInterface[] = mockHerdConfig,
) {
this.name = name;
this.herd = new Herd();
this.herd = new Herd(herdConfig);
this.avatar = avatar;
this.color = color;
}

get theName(): string {
Expand Down
145 changes: 84 additions & 61 deletions src/app/BreedProcessor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,91 +6,114 @@ import { AnimalNames } from '../Enums/AnimalNamesEnum';
import { Fox } from '../Animals/Fox';
import { Wolf } from '../Animals/Wolf';
import { Herd } from './logic/Herd';
import { ConvertToAnimalObject } from './utils/ConvertToAnimalObject';
import { add, divide, floor, min } from 'lodash';
import { AnimalRoles } from '../Enums/AnimalRolesEnum';
import { Bank } from './logic/Bank';

export class BreedProcessor {
randomResultInterfaceWolf: GetRandomValue;
randomResultInterfaceFox: GetRandomValue;

constructor() {
constructor(private bank: Bank) {
this.randomResultInterfaceWolf = new SecondDice();
this.randomResultInterfaceFox = new FirstDice();
}

processBreedPhase({ theHerd }: Player): [AnimalNames, AnimalNames] {
const wolfDiceResult = this.randomResultInterfaceWolf.getRandomValue();
const foxDiceResult = this.randomResultInterfaceFox.getRandomValue();
if (foxDiceResult !== AnimalNames.FOX) {
if (wolfDiceResult !== AnimalNames.WOLF) {
this.breedAnimals(foxDiceResult, wolfDiceResult, theHerd);
} else {
this.breedAnimals(foxDiceResult, undefined, theHerd);
theHerd.cullAnimals(
this.getRandomResult(wolfDiceResult) as Wolf,
);
}
const equalResult = foxDiceResult === wolfDiceResult;
if (equalResult) {
this.breedAnimals(foxDiceResult, theHerd, true);
return [wolfDiceResult, foxDiceResult];
}
if (foxDiceResult === AnimalNames.FOX) {
const fox: Fox = ConvertToAnimalObject.convertToAnimalObject(
foxDiceResult,
) as Fox;
this.returnToBank(fox, theHerd);
theHerd.cullAnimals(fox);
} else {
if (wolfDiceResult !== AnimalNames.WOLF) {
this.breedAnimals(undefined, wolfDiceResult, theHerd);
theHerd.cullAnimals(
this.getRandomResult(foxDiceResult) as Fox,
);
} else {
theHerd.cullAnimals(
this.getRandomResult(foxDiceResult) as Fox,
);
theHerd.cullAnimals(
this.getRandomResult(wolfDiceResult) as Wolf,
);
}
this.breedAnimals(foxDiceResult, theHerd);
}
return [wolfDiceResult, foxDiceResult];
}

private getRandomResult(
animalName: AnimalNames,
): Wolf | Fox | AnimalNames {
switch (animalName) {
case AnimalNames.FOX:
return new Fox();
case AnimalNames.WOLF:
return new Wolf();
default:
return animalName;
if (wolfDiceResult === AnimalNames.WOLF) {
const wolf = ConvertToAnimalObject.convertToAnimalObject(
wolfDiceResult,
) as Wolf;
this.returnToBank(wolf, theHerd);
theHerd.cullAnimals(wolf);
} else {
this.breedAnimals(wolfDiceResult, theHerd);
}
return [wolfDiceResult, foxDiceResult];
}

private breedAnimals(
foxDiceAnimalName: AnimalNames | undefined,
wolfDiceAnimalName: AnimalNames | undefined,
diceResult: AnimalNames,
herd: Herd,
) {
if (
foxDiceAnimalName &&
wolfDiceAnimalName &&
foxDiceAnimalName == wolfDiceAnimalName
) {
const numberOfAnimals = herd.getAnimalNumber(foxDiceAnimalName);
herd.addAnimals(
foxDiceAnimalName,
Math.floor((numberOfAnimals + 2) / 2),
isDoubled?: boolean,
): void {
if (isDoubled) {
const herdGrow = this.calculateHerdGrow(
diceResult,
herd,
isDoubled,
);
this.bank.theHerd.addAnimalsToHerd(diceResult, -herdGrow);
herd.addAnimalsToHerd(diceResult, herdGrow);
return;
}
if (foxDiceAnimalName) {
const numberOfAnimals = herd.getAnimalNumber(foxDiceAnimalName);
herd.addAnimals(
foxDiceAnimalName,
Math.floor((numberOfAnimals + 1) / 2),
const herdGrow = this.calculateHerdGrow(diceResult, herd);
this.bank.theHerd.addAnimalsToHerd(diceResult, -herdGrow);
herd.addAnimalsToHerd(diceResult, 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 (wolfDiceAnimalName) {
const numberOfAnimals = herd.getAnimalNumber(
wolfDiceAnimalName,
);
herd.addAnimals(
wolfDiceAnimalName,
Math.floor((numberOfAnimals + 1) / 2),
);
if (herd.getAnimalNumber(AnimalNames.BIG_DOG) > 0) {
this.bank.theHerd.addAnimalsToHerd(AnimalNames.BIG_DOG, 1);
return;
}
herd.theAnimals
.filter(
([animal]) =>
animal.hasRole(AnimalRoles.LIVESTOCK) &&
animal.theName !== AnimalNames.HORSE,
)
.forEach(([animal, count]) =>
this.bank.theHerd.addAnimalsToHerd(
animal.theName as AnimalNames,
count,
),
);
}

private calculateHerdGrow(
diceResult: AnimalNames,
herd: Herd,
isDoubled?: boolean,
): number {
const herdMaxGrow = floor(
divide(
add(herd.getAnimalNumber(diceResult), isDoubled ? 2 : 1),
2,
),
);
const bankContains = this.bank.theHerd.getAnimalNumber(
diceResult,
);
return min([herdMaxGrow, bankContains]) as number;
}
}
10 changes: 2 additions & 8 deletions src/app/GameController.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { time } from 'console';
import { AnimalNames } from '../Enums/AnimalNamesEnum';
import { Player } from '../Player';
import { BreedProcessor } from './BreedProcessor';
import { Bank } from './logic/Bank';
import { Timer } from './Timer';
import { View } from './View';

Expand All @@ -12,7 +12,7 @@ export class GameController {
private breedProcessor: BreedProcessor;
constructor(private view: View) {
this.timer = new Timer();
this.breedProcessor = new BreedProcessor();
this.breedProcessor = new BreedProcessor(new Bank());
}

get theCurrentPlayer(): Player {
Expand All @@ -23,12 +23,6 @@ export class GameController {
return this.timer;
}

initializePlayer(name: string, imgPath: string): Player {
this.player = new Player(name, imgPath);
this.currentPlayer = this.player;
return this.player;
}

startTurn(): void {
this.timer.countdown();
const turnTimer = setInterval(() => {
Expand Down
70 changes: 70 additions & 0 deletions src/app/Trade.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import { AnimalNames } from '../Enums/AnimalNamesEnum';
import { ConvertToAnimalObject } from './utils/ConvertToAnimalObject';
import { multiply } from 'lodash';
import { Player } from '../Player';
import { Herd } from './logic/Herd';

export class Trade {
constructor(private bank: Player) {}
/**
* Gets an offer from player and returns true or false if transaction can be made processed and process it if possible
* @param offer accepts tuple with offer containing animal name and quantity to be sold
* @param player accepts instance of Player class, which wants to sell his animals
* @param target accepts tuple with desired animal(s) containing desired animal name and quantity to buy
* @returns true if transaction will be processed, and false otherwise
*/
processOffer(
offer: [AnimalNames, number],
{ theHerd: playerHerd }: Player,
target: [AnimalNames, number],
): boolean {
if (
playerHerd.getAnimalNumber(offer[0]) < offer[1] ||
this.bank.theHerd.getAnimalNumber(target[0]) < target[1]
) {
return false;
}
let value = this.calculateValue(offer);
const price = this.calculateValue(target);
if (price < value) {
this.adjustOffer(offer, target);
value = this.calculateValue(offer);
}
return price > value
? false
: this.disposeResult(offer, playerHerd, target);
}

private calculateValue(offer: [AnimalNames, number]): number {
return multiply(
ConvertToAnimalObject.convertToAnimalObject(offer[0]).theValue,
offer[1],
);
}

private adjustOffer(
offer: [AnimalNames, number],
target: [AnimalNames, number],
): void {
offer[1] -= 1;
if (this.calculateValue(offer) <= this.calculateValue(target)) {
return;
}
this.adjustOffer(offer, target);
}

/**
* updates players and banks herd
*/
private disposeResult(
[animalSold, quantitySold]: [AnimalNames, number],
playerHerd: Herd,
[animalBought, quantityBought]: [AnimalNames, number],
): boolean {
playerHerd.addAnimalsToHerd(animalSold, -quantitySold);
playerHerd.addAnimalsToHerd(animalBought, quantityBought);
this.bank.theHerd.addAnimalsToHerd(animalSold, quantitySold);
this.bank.theHerd.addAnimalsToHerd(animalBought, -quantityBought);
return true;
}
}
4 changes: 0 additions & 4 deletions src/app/View.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,10 +80,6 @@ export class View {
src: playersChosenAvatarPath,
});
const gameController = new GameController(this);
gameController.initializePlayer(
playersChosenName,
playersChosenAvatarPath,
);
const remainingTime = Render.elementFactory('div', {
id: 'time-remaining',
className: 'remainig-time__counter',
Expand Down
Loading

0 comments on commit 62bf1d1

Please sign in to comment.