Skip to content

Commit

Permalink
saga
Browse files Browse the repository at this point in the history
  • Loading branch information
ivoxytryer committed Jan 24, 2025
1 parent a8e1d47 commit 07499b4
Show file tree
Hide file tree
Showing 14 changed files with 814 additions and 1 deletion.
55 changes: 55 additions & 0 deletions rpgsaga/saga/src/abilities/ability.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
export abstract class Ability {

private _name: string;
private _duration: number;
private _useFrequency: number;
private _damage: number;
private _durationDamage: number;

constructor(name: string, useFrequency: number, duration: number, damage: number, durationDamage: number) {
this._name = name;
this._useFrequency = useFrequency;
this._duration = duration;
this._damage = damage;
this._durationDamage = durationDamage;
}


get name(): string {
return this._name;
}

get damage(): number {
return this._damage;
}


public changeUseFrequency(newUseFrequency: number) {
this._useFrequency = newUseFrequency;
}

get useFrequency(): number {
return this._useFrequency;
}

get duration(): number {
return this._duration;
}


setCalculatedDamage(damage: number) {
this._damage = damage;
}

decreaseDuration(): void {
this._duration -= 1;
}

decreaseUseFrequency(): void {
this._useFrequency -= 1;
}

get durationDamage(): number {
return this._durationDamage;
}
}
7 changes: 7 additions & 0 deletions rpgsaga/saga/src/abilities/base attack.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { Ability } from './ability';

export class MainAttack extends Ability {
constructor(name = 'Основная атака', useFrequency = -999, duration = 1, damage = 0, durationDamage = 0) {
super(name, useFrequency, duration, damage, durationDamage);
}
}
7 changes: 7 additions & 0 deletions rpgsaga/saga/src/abilities/fascination.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { Ability } from './ability';

export class Fascination extends Ability {
constructor(name = 'Заворожение', useFrequency = 1, duration = 1, damage = 0, durationDamage = 0) {
super(name, useFrequency, duration, damage, durationDamage);
}
}
7 changes: 7 additions & 0 deletions rpgsaga/saga/src/abilities/frozen arrows.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { Ability } from './ability';

export class FrozenArrows extends Ability {
constructor(name = 'Ледяные стрелы', useFrequency = 1, duration = 3, damage = 12, durationDamage = 3) {
super(name, useFrequency, duration, damage, durationDamage);
}
}
7 changes: 7 additions & 0 deletions rpgsaga/saga/src/abilities/vengeance strike.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { Ability } from './ability';

export class VengeanceStrike extends Ability {
constructor(name = 'Удар Возмездия', useFrequency = 1, duration = 1, damage = 0, durationDamage = 0) {
super(name, useFrequency, duration, damage, durationDamage);
}
}
175 changes: 175 additions & 0 deletions rpgsaga/saga/src/game/game.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
import { Player } from '../players roles/player';
import { Logger } from '../logger/log';
import { PlayerFactory } from '../player factory/player factory';

export class Game {
private _players: Player[];
private _playersCount: number;
private _playersNames: string[];
logger: Logger;
playerFactory: PlayerFactory;


constructor(playersCount: number) {
this._players = [];
this._playersCount = playersCount;
this._playersNames = [
'Рагнар',
'Бьёрн',
'Эйрик',
'Лейф',
'Харальд',
'Сигурд',
'Ивар',
'Торстейн',
'Ульф',
'Фрейр',
'Фрейя',
'Астрид',
'Сигрид',
'Хельга',
'Инга',
];
this.logger = Logger.getInstance();
this.playerFactory = new PlayerFactory();
}

public get players(): Player[] {
return this._players;
}


public gettingRandomNumber(min: number, max: number): number {
return min + Math.floor(Math.random() * (max - min + 1));
}


public randomIndexesFromArray(arrLen: number): number[] {
let index1 = this.gettingRandomNumber(0, arrLen - 1);
const index2 = this.gettingRandomNumber(0, arrLen - 1);
while (index1 === index2) {
index1 = this.gettingRandomNumber(0, arrLen - 1);
}
const sortedIndexes = [index1, index2].sort();
return sortedIndexes;
}


public randomElementFromStringArray(array: string[]): string {
const index1 = this.gettingRandomNumber(0, array.length - 1);
return array[index1];
}


setPlayers() {

for (let i = 0; i < this._playersCount; i++) {
const hp = this.gettingRandomNumber(80, 100);
const strength = this.gettingRandomNumber(10, 20);
const name = this._playersNames[this.gettingRandomNumber(0, this._playersNames.length - 1)];
const roleNumber = this.gettingRandomNumber(1, 3);
const player = this.playerFactory.createPlayer(hp, strength, name, roleNumber);
this._players.push(player);
this.logger.createLog(
`Игрок (${player.roleName})${player.name}, ${player.hp} здоровья, ${player.strength} силы был создан!`,
);
}
}

public performPlayerTurn(attacker: Player, defender: Player): void {

if (attacker.canThisPlayerAttack) {
const ability = attacker.selectRandomAbility();
this.logger.createLog(attacker.useAbility(defender, ability));
} else {
attacker.canThisPlayerAttack = true;
attacker.checkForAbilitiesDamages();
this.logger.createLog(
`(${attacker.roleName})${attacker.name} пропускает свой ход, потому что его заворожил (${defender.roleName})${defender.name} в предыдущем шаге.`,
);
}
}


public determineWinner(player1: Player, player2: Player): Player {
if (player1.alive === 0) {

this.logger.createLog(`(${player1.roleName})${player1.name} принимает поражение.`);
return player2;
} else {

this.logger.createLog(`(${player2.roleName})${player2.name} принимает поражение.`);
return player1;
}
}

public fight(player1: Player, player2: Player): Player {
this.logger.createLog(`
Бой (${player1.roleName})${player1.name} и (${player2.roleName})${player2.name} начался!`);


const player1Copy = this.playerFactory.createPlayer(player1.hp, player1.strength, player1.name, player1.roleNumber);
const player2Copy = this.playerFactory.createPlayer(player2.hp, player2.strength, player2.name, player2.roleNumber);

let round = 0;


while (player1.alive === 1 && player2.alive === 1) {
round += 1;

if (round % 2 !== 0) {
this.performPlayerTurn(player1, player2);
} else {
this.performPlayerTurn(player2, player1);
}
}


return this.determineWinner(player1Copy, player2Copy);
}

fightRound(players: Player[]): Player[] {
const survivors: Player[] = [];
let winner: Player;
let fightNumber = 0;
let playersNumbers: number[];
while (players.length > 1) {

fightNumber += 1;
this.logger.createLog(`
Бой ${fightNumber}.`);
playersNumbers = this.randomIndexesFromArray(this._players.length);
winner = this.fight(this._players[playersNumbers[0]], this._players[playersNumbers[1]]);
survivors.push(winner);
players.splice(Math.min(playersNumbers[0], playersNumbers[1]), 1);
players.splice(Math.max(playersNumbers[0], playersNumbers[1]) - 1, 1);
}
if (players.length === 1) {

survivors.push(players[0]);
}
return survivors;
}

startFights() {
let roundNumber = 0; // это кон
while (this._players.length !== 1) {

roundNumber += 1;
this.logger.createLog(`
Кон ${roundNumber}.`);
const survivors = this.fightRound(this._players);
this._players = survivors;
if (this._players.length === 1) {
this.logger.createLog(`
Победитель турнира: ${this._players[0].name}!`);
}
}
}

run() {
this.setPlayers();
this.startFights();
}
}

5 changes: 4 additions & 1 deletion rpgsaga/saga/src/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1,4 @@
console.log('Hello world');
import { Game } from './game/game';

const game = new Game(8);
game.run();
17 changes: 17 additions & 0 deletions rpgsaga/saga/src/logger/log.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
export class Logger {
private static _instance: Logger = new Logger();
private _logs: string[] = [];

constructor() {
Logger._instance = this;
}

public static getInstance(): Logger {
return Logger._instance;
}

createLog(log: string) {
console.log(log);
this._logs.push(log);
}
}
30 changes: 30 additions & 0 deletions rpgsaga/saga/src/player factory/player factory.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { Player } from '../players roles/player';
import { Archer } from '../players roles/archer';
import { Knight } from '../players roles/knight';
import { Mage } from '../players roles/mage';

export class Calculations {}

enum Roles {
knight = 1,
archery = 2,
mage = 3,
}

export class PlayerFactory {
public createPlayer(hp: number, strength: number, name: string, roleNumber: number): Player {
let player: Player;

switch (roleNumber) {
case Roles.knight:
player = new Knight(hp, strength, name, roleNumber);
return player;
case Roles.archery:
player = new Archer(hp, strength, name, roleNumber);
return player;
case Roles.mage:
player = new Mage(hp, strength, name, roleNumber);
return player;
}
}
}
26 changes: 26 additions & 0 deletions rpgsaga/saga/src/players roles/archer.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { MainAttack } from '../abilities/base attack';
import { FrozenArrows } from '../abilities/frozen arrows';

import { Player } from './player';

export class Archer extends Player {
constructor(
hp: number,
strength: number,
name: string,
roleNumber: number,
attackingAbilities = [

new MainAttack(),
(() => {
const frozenArrows = new FrozenArrows();
frozenArrows.changeUseFrequency(2);
return frozenArrows;
})(),
],
isAttackedAbilities = [],
roleName = 'Лучник',
) {
super(hp, strength, name, roleNumber, attackingAbilities, isAttackedAbilities, roleName);
}
}
19 changes: 19 additions & 0 deletions rpgsaga/saga/src/players roles/knight.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { MainAttack } from '../abilities/base attack';
import { VengeanceStrike } from '../abilities/vengeance strike';
import { FrozenArrows } from '../abilities/frozen arrows';

import { Player } from './player';

export class Knight extends Player {
constructor(
hp: number,
strength: number,
name: string,
roleNumber: number,
roleName = 'Рыцарь',
attackingAbilities = [new MainAttack(), new VengeanceStrike(), new FrozenArrows()],
isAttackedAbilities = [],
) {
super(hp, strength, name, roleNumber, attackingAbilities, isAttackedAbilities, roleName);
}
}
19 changes: 19 additions & 0 deletions rpgsaga/saga/src/players roles/mage.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { MainAttack } from '../abilities/base attack';
import { Fascination } from '../abilities/fascination';
import { FrozenArrows } from '../abilities/frozen arrows';

import { Player } from './player';

export class Mage extends Player {
constructor(
hp: number,
strength: number,
name: string,
roleNumber: number,
attackingAbilities = [new MainAttack(), new Fascination(), new FrozenArrows()],
isAttackedAbilities = [],
roleName = 'Маг',
) {
super(hp, strength, name, roleNumber, attackingAbilities, isAttackedAbilities, roleName);
}
}
Loading

0 comments on commit 07499b4

Please sign in to comment.