diff --git a/codewars/Adding Big Numbers/adding_big_numbers.js b/codewars/Adding Big Numbers/adding_big_numbers.js new file mode 100644 index 0000000..b12d137 --- /dev/null +++ b/codewars/Adding Big Numbers/adding_big_numbers.js @@ -0,0 +1,11 @@ +function add(a, b) { + var res = '', c = 0; + a = a.split(''); + b = b.split(''); + while (a.length || b.length || c) { + c += ~~a.pop() + ~~b.pop(); + res = c % 10 + res; + c = c > 9; + } + return res; + } \ No newline at end of file diff --git a/codewars/Anagram difference/anagram_difference.js b/codewars/Anagram difference/anagram_difference.js new file mode 100644 index 0000000..42a113c --- /dev/null +++ b/codewars/Anagram difference/anagram_difference.js @@ -0,0 +1,17 @@ +function anagramDifference(w1,w2){ + let ar1 = w1.split(''); + let ar2 = w2.split(''); + let res = []; + if (ar1.length === 0) { + return ar2.length; + } else if (ar2.length === 0) { + return ar1.length; + } + for (let i = 0; i < ar1.length; i++) { + if (ar2.indexOf(ar1[i]) !== -1) { + res.push(ar2[ar2.indexOf(ar1[i])]); + ar2.splice(ar2.indexOf(ar1[i]), 1); + } + } + return (w1.length + w2.length) - res.length * 2; + } \ No newline at end of file diff --git a/codewars/Array Deep Count/array_deep_count.js b/codewars/Array Deep Count/array_deep_count.js new file mode 100644 index 0000000..42a3bae --- /dev/null +++ b/codewars/Array Deep Count/array_deep_count.js @@ -0,0 +1,13 @@ +function deepCount(a){ + let elem = a.length; + if (a.length !== 0) { + for (let i = 0; i < a.length; i++){ + if (Array.isArray(a[i])) { + elem = elem + deepCount(a[i]); + } + } + } else { + return a.length; + } + return elem; + } \ No newline at end of file diff --git a/codewars/Build Tower/build_tower.js b/codewars/Build Tower/build_tower.js new file mode 100644 index 0000000..8b14f95 --- /dev/null +++ b/codewars/Build Tower/build_tower.js @@ -0,0 +1,11 @@ +function towerBuilder(nFloors) { + let floors = []; + let result = []; + + for (let i = nFloors; i > 0; i--) { + let spaces = i - 1; + let stars = 1 + 2 * (nFloors - i); + floors.push(' '.repeat(spaces) + '*'.repeat(stars) + ' '.repeat(spaces)); + } + return floors; + } \ No newline at end of file diff --git a/codewars/Convert string to camel case/convert_string_to_camel_case.js b/codewars/Convert string to camel case/convert_string_to_camel_case.js new file mode 100644 index 0000000..cea6c37 --- /dev/null +++ b/codewars/Convert string to camel case/convert_string_to_camel_case.js @@ -0,0 +1,10 @@ +function toCamelCase(str){ + let res = Array.from(str); + for (let i = 0; i < res.length; i++) { + if (res[i] === '-' || res[i] === '_') { + res.splice(i, 2, res[i+1].toUpperCase()); + } + } + let str1 = res.join(''); + return str1; + } \ No newline at end of file diff --git a/codewars/Duplicate Encoder/duplicate_encoder.js b/codewars/Duplicate Encoder/duplicate_encoder.js new file mode 100644 index 0000000..d60795d --- /dev/null +++ b/codewars/Duplicate Encoder/duplicate_encoder.js @@ -0,0 +1,12 @@ +function duplicateEncode(word){ + let res = ''; + let str = word.toLowerCase(); + for (let i = 0; i < str.length; i++) { + if (str.indexOf(str[i]) == str.lastIndexOf(str[i])) { + res += '('; + } else { + res += ')'; + } + } + return res; + } \ No newline at end of file diff --git a/codewars/Find the missing letter/find_the_missing_letter.js b/codewars/Find the missing letter/find_the_missing_letter.js new file mode 100644 index 0000000..64cbe6c --- /dev/null +++ b/codewars/Find the missing letter/find_the_missing_letter.js @@ -0,0 +1,15 @@ +function findMissingLetter(array) +{ + let res = ''; + let str = array.join(''); + let lastWord = str.charCodeAt(0); + for (let i = 1; i < str.length; i++) { + if (str.charCodeAt(i) - lastWord === 1) { + lastWord = str.charCodeAt(i); + } else { + let num = lastWord + 1; + res = String.fromCharCode(num); + } + } + return res; +} \ No newline at end of file diff --git a/codewars/Fun with tree - max sum/fun_with_trees.js b/codewars/Fun with tree - max sum/fun_with_trees.js new file mode 100644 index 0000000..7a5500e --- /dev/null +++ b/codewars/Fun with tree - max sum/fun_with_trees.js @@ -0,0 +1,12 @@ +function maxSum(root) { + if (root != null) { + var a = maxSum(root.left) + root.value; + var b = maxSum(root.right) + root.value; + if (b > a) { + return b; + } else { + return a; + } + } + return 0; + } \ No newline at end of file diff --git a/codewars/Merge two arrays/merge_two_arrays.js b/codewars/Merge two arrays/merge_two_arrays.js new file mode 100644 index 0000000..08efe3b --- /dev/null +++ b/codewars/Merge two arrays/merge_two_arrays.js @@ -0,0 +1,11 @@ +function mergeArrays(a, b) { + const maxLength = Math.max(a.length, b.length); + let res = []; + + for (let i = 0; i < maxLength; i++) { + res.push(a[i]); + res.push(b[i]); + } + + return res.filter((value) => value !== undefined); + } \ No newline at end of file diff --git a/codewars/Moving Zeros To The End/moving_zeros_to_the_end.js b/codewars/Moving Zeros To The End/moving_zeros_to_the_end.js new file mode 100644 index 0000000..f4959ce --- /dev/null +++ b/codewars/Moving Zeros To The End/moving_zeros_to_the_end.js @@ -0,0 +1,14 @@ +function moveZeros(arr) { + let arr0 = []; + let arr1 = []; + for (let i = 0; i < arr.length; i++) { + if (arr[i] === 0) { + arr0.push(0); + } else { + arr1.push(arr[i]); + } + } + let res = [...arr1, ...arr0]; + + return res ; + } \ No newline at end of file diff --git a/codewars/Product of consecutive Fib numbers/product_of consecutive_fib_numbers.js b/codewars/Product of consecutive Fib numbers/product_of consecutive_fib_numbers.js new file mode 100644 index 0000000..9ab23cd --- /dev/null +++ b/codewars/Product of consecutive Fib numbers/product_of consecutive_fib_numbers.js @@ -0,0 +1,10 @@ +function productFib(prod){ + let first = 0; + let last = 1; + while (first * last < prod) { + const rem = last; + last = first + last; + first = rem; + } + return [first, last, first * last === prod]; + } \ No newline at end of file diff --git a/codewars/Simple Pig Latin/simple_pig_latin.js b/codewars/Simple Pig Latin/simple_pig_latin.js new file mode 100644 index 0000000..5746f6b --- /dev/null +++ b/codewars/Simple Pig Latin/simple_pig_latin.js @@ -0,0 +1,15 @@ +function pigIt(str){ + let res = []; + let arr = str.split(' '); + for (let i = 0; i < arr.length; i++) { + if (arr[i] === "!" || arr[i] === "?") { + res.push(arr[i]); + } else { + let subStr1 = arr[i].slice(0, 1); + let subStr2 = arr[i].slice(1); + let vr = subStr2 + subStr1 + "ay"; + res.push(vr); + } + } + return res.join(' '); + } \ No newline at end of file diff --git a/codewars/Snail/snail.js b/codewars/Snail/snail.js new file mode 100644 index 0000000..7fb72d7 --- /dev/null +++ b/codewars/Snail/snail.js @@ -0,0 +1,14 @@ +snail = function(array) { + var result; + while (array.length) { + result = (result ? result.concat(array.shift()) : array.shift()); + for (var i = 0; i < array.length; i++) { + result.push(array[i].pop()); + } + result = result.concat((array.pop() || []).reverse()); + for (var i = array.length - 1; i >= 0; i--) { + result.push(array[i].shift()); + } + } + return result; + } \ No newline at end of file diff --git a/codewars/Sum of Digits - Digital Root/sum_of_digits.js b/codewars/Sum of Digits - Digital Root/sum_of_digits.js new file mode 100644 index 0000000..4c78ab5 --- /dev/null +++ b/codewars/Sum of Digits - Digital Root/sum_of_digits.js @@ -0,0 +1,13 @@ +function digitalRoot(n) { + let sum = 0; + let num = []; + num = Array.from(String(n), Number); + for (let i = 0; i < num.length; i++) { + sum += num[i]; + } + if (String(sum).length === 1) { + return sum; + } else { + return digitalRoot(sum); + } + } \ No newline at end of file diff --git a/codewars/Sum of pairs/sum_of_pairs.js b/codewars/Sum of pairs/sum_of_pairs.js new file mode 100644 index 0000000..73da72c --- /dev/null +++ b/codewars/Sum of pairs/sum_of_pairs.js @@ -0,0 +1,12 @@ +function sumPairs(ints, s) { + var seen = {}; + + for (let i = 0; i < ints.length; i++) { + let num = ints[i]; + if (seen[s - num]) { + return [s - num, num]; + } + seen[num] = true; + } + return undefined ; + } \ No newline at end of file diff --git a/codewars/Tic-Tac-Toe Checker/tic-tac-toe_checker.js b/codewars/Tic-Tac-Toe Checker/tic-tac-toe_checker.js new file mode 100644 index 0000000..077f098 --- /dev/null +++ b/codewars/Tic-Tac-Toe Checker/tic-tac-toe_checker.js @@ -0,0 +1,29 @@ +function isSolved(board) { + for (let i = 0; i <= 2; i++) { + if (board[i][0] == board[i][1] && board[i][0] == board[i][2] && board[i][0] != 0) { + return board[i][0]; + } + } + + let arr = board[0].concat(board[1], board[2]); + + for (let i = 0; i <= 2; i++) { + if (arr[i] == arr[i+3] && arr[i] == arr[i+6] && arr[i] != 0) { + return arr[i]; + } + } + + if (arr[0] == arr[4] && arr[0] == arr[8] && arr[0] != 0) { + return arr[0]; + } + + if (arr[2] == arr[4] && arr[2] == arr[6] && arr[2] != 0) { + return arr[2]; + } + + if (arr.includes(0)) { + return -1; + } else { + return 0; + } + } \ No newline at end of file diff --git a/codewars/Valid Parentheses/valid_parentheses.js b/codewars/Valid Parentheses/valid_parentheses.js new file mode 100644 index 0000000..121f98f --- /dev/null +++ b/codewars/Valid Parentheses/valid_parentheses.js @@ -0,0 +1,16 @@ +function validParentheses(parens) { + if (parens[0] === ")" || parens.length % 2 !== 0) { + return false; + } + const leftSymbols = []; + for (let i = 0; i < parens.length; i++) { + if (parens[i] === '(') { + leftSymbols.push(parens[i]); + } else if (parens[i] === ')' && leftSymbols.length !== 0) { + leftSymbols.pop(); + } else { + return false; + } + } + return leftSymbols.length === 0; + } \ No newline at end of file diff --git a/codewars/Where my anagrams at/where_my_anagrams_at.js b/codewars/Where my anagrams at/where_my_anagrams_at.js new file mode 100644 index 0000000..af6b739 --- /dev/null +++ b/codewars/Where my anagrams at/where_my_anagrams_at.js @@ -0,0 +1,5 @@ +function anagrams(word, words) { + const sample = word.split('').sort().join(''); + const result = words.filter((anag) => anag.length === sample.length && anag.split('').sort().join('') === sample); + return result; + } \ No newline at end of file diff --git a/rpgsaga/saga/src/animal.ts b/rpgsaga/saga/src/animal.ts new file mode 100644 index 0000000..75f1e0a --- /dev/null +++ b/rpgsaga/saga/src/animal.ts @@ -0,0 +1,14 @@ +abstract class Animal { + + constructor(aAge: number, private aColor: string) { + } + + abstract set age(n); + abstract get age(): number; + abstract toString(): string; + + animVoice(voice: string) { + console.log(voice); + } + +} \ No newline at end of file diff --git a/rpgsaga/saga/src/cat.ts b/rpgsaga/saga/src/cat.ts new file mode 100644 index 0000000..365cb71 --- /dev/null +++ b/rpgsaga/saga/src/cat.ts @@ -0,0 +1,33 @@ +class Cat extends Animal { + + private voice: string; + private breed: string; + + constructor(public aAge: number, aColor: string, voice: string, breed: string, public name?: string) { + super(aAge, aColor); + this.voice = voice; + this.breed = breed; + } + + set age(n: number) { + if (this.aAge < 1) { + throw new Error("Возраст не может быть меньше 1"); + } else if (this.aAge > 20) { + throw new Error("Возраст не может быть больше 20"); + } else { + this.aAge = n; + } + } + + get age(): number { + return this.aAge; + } + + animVoice(voice: string) { + console.log(voice); + } + + toString(): string { + return `the ${this.breed} cat called ${this.name}`; + } +} \ No newline at end of file diff --git a/rpgsaga/saga/src/gameLogic.ts b/rpgsaga/saga/src/gameLogic.ts new file mode 100644 index 0000000..47178f2 --- /dev/null +++ b/rpgsaga/saga/src/gameLogic.ts @@ -0,0 +1,198 @@ +import { Logger } from "./logger"; +import { Player } from "./player"; +import { PlayerFabric } from "./playerClassFabric"; +import { PlayerClass } from "./types"; + +interface IPlayersForFight { p1: Player, p2: Player, p1Index: number, p2Index: number, }; + +export class GameLogic { + private playerFabric = new PlayerFabric(); + public createdPlayers: Player[] = []; + + constructor() {} + + public createPlayers(numberOfPlayers: number) { + if(numberOfPlayers % 2 !== 0) { + throw new Error('The wrong number of players'); + } + + const playerClasses: PlayerClass[] = ['knight', 'mage', 'archer']; + + for(let i = 0; i < numberOfPlayers; i++) { + const randomPlayerClass = playerClasses[Math.floor(Math.random() * playerClasses.length)]; + const player = this.playerFabric.createPlayer(randomPlayerClass) + this.createdPlayers.push(player); + } + } + + public startFight() { + while(this.createdPlayers.length !== 1) { + const playersToFight = this.pickPlayersForFight(); + Logger.logPlayersNameAndClass(playersToFight.p1, playersToFight.p2) + this.fight(playersToFight.p1, playersToFight.p2, playersToFight.p1Index, playersToFight.p2Index); + } + + Logger.logWinner(this.createdPlayers[0]); + } + + /*private*/ public fight(p1: Player, p2: Player, p1Index: number, p2Index: number) { + let playerToAttack = Math.floor(Math.random() * 2); + + let p1IsDead = p1.checkDeath(); + let p2IsDead = p2.checkDeath(); + while(!p1IsDead && !p2IsDead) { + if(playerToAttack === 1) { + if(p1.checkStun()) { + playerToAttack = 2; + p2IsDead = p2.checkDeath(); + p1.stun = false; + } else { + const isSpecialAttack = this.rollSpecialAttack(); + if(isSpecialAttack) { + this.useSpecialAttack(p1, p2, playerToAttack); + } else { + this.defaultAttack(p1, p2, playerToAttack); + } + + p2IsDead = p2.checkDeath(); + playerToAttack = 2; + } + if(p1.constructor.name === 'Archer' && p1.isFireUsed && p2.step >= 1) { + if(p2.step > 2) { + p2.step = 0; + } else { + p2.burning(p2); + } + } + } else { + if(p2.checkStun()) { + playerToAttack = 1; + p1IsDead = p1.checkDeath(); + p2.stun = false; + } else { + const isSpecialAttack = this.rollSpecialAttack(); + + if(isSpecialAttack) { + this.useSpecialAttack(p1, p2, playerToAttack); + + } else { + this.defaultAttack(p1, p2, playerToAttack); + } + + p1IsDead = p1.checkDeath(); + playerToAttack = 1; + } + if(p2.constructor.name === 'Archer' && p2.isFireUsed && p1.step >= 1) { + if(p1.step > 2) { + p1.step = 0; + } else { + p1.burning(p1); + } + } + } + } + + if(p1IsDead) { + Logger.logPlayerIsDead(p1); + this.createdPlayers.splice(p1Index, 1); + p2.hp = p2.startHp; + p2.isFireUsed = false; + } else { + Logger.logPlayerIsDead(p2); + this.createdPlayers.splice(p2Index, 1); + p1.hp = p1.startHp; + p1.isFireUsed = false; + } + } + + /*private*/ public defaultAttack(p1: Player, p2: Player, playeToAttack: number) { + if(playeToAttack === 1) { + p1.attack(p2); + Logger.logAttackPlayer(p1, p2, 1); + } else { + p2.attack(p1); + Logger.logAttackPlayer(p1, p2, 2); + } + } + + private rollSpecialAttack() { + return Math.random() > 0.5 ? true : false; + } + + /*private*/ public useSpecialAttack(p1: Player, p2: Player, playerToAttack: number) { + if(playerToAttack === 1) { + if(p1.constructor.name === 'Knight') { + p1.specialAttack() + p1.attack(p2); + Logger.logSpecialAttack(p1, p2, playerToAttack); + p1.strenght = p1.startStrength; + } + + if(p1.constructor.name === 'Mage') { + p1.specialAttack(p2); + p1.strenght = 0; + Logger.logSpecialAttack(p1, p2, playerToAttack); + p1.strenght = p1.startStrength; + } + + if(p1.constructor.name === 'Archer') { + if(p1.isFireUsed) { + this.defaultAttack(p1, p2, playerToAttack); + } else { + p1.specialAttack(p2); + p1.strenght = 0; + //p1.strenght += 2; + //p1.attack(p2); + Logger.logSpecialAttack(p1, p2, playerToAttack); + p1.strenght = p1.startStrength; + } + } + } else { + if(p2.constructor.name === 'Knight') { + p2.specialAttack() + p2.attack(p1); + Logger.logSpecialAttack(p1, p2, playerToAttack); + p2.strenght = p2.startStrength; + } + + if(p2.constructor.name === 'Mage') { + p2.specialAttack(p1); + p2.strenght = 0; + Logger.logSpecialAttack(p1, p2, playerToAttack); + p2.strenght = p2.startStrength; + } + + if(p2.constructor.name === 'Archer') { + if(p2.isFireUsed) { + this.defaultAttack(p1, p2, playerToAttack); + } else { + p2.specialAttack(p1); + p2.strenght = 0; + //p2.strenght += 2; + //p2.attack(p1); + Logger.logSpecialAttack(p1, p2, playerToAttack); + p2.strenght = p2.startStrength; + } + } + } + } + + private pickPlayersForFight(): IPlayersForFight { + let randomFirstPlayerIndex = Math.floor(Math.random() * this.createdPlayers.length); + let randomSecondPlayerIndex = Math.floor(Math.random() * this.createdPlayers.length); + + while(randomFirstPlayerIndex === randomSecondPlayerIndex) { + randomSecondPlayerIndex = Math.floor(Math.random() * this.createdPlayers.length); + } + + const firstPlayer = this.createdPlayers[randomFirstPlayerIndex]; + const secondPlayer = this.createdPlayers[randomSecondPlayerIndex]; + + return { + p1: firstPlayer, + p2: secondPlayer, + p1Index: randomFirstPlayerIndex, + p2Index: randomSecondPlayerIndex, + }; + } +} \ No newline at end of file diff --git a/rpgsaga/saga/src/index.ts b/rpgsaga/saga/src/index.ts index 7805559..85825dd 100644 --- a/rpgsaga/saga/src/index.ts +++ b/rpgsaga/saga/src/index.ts @@ -1,16 +1,23 @@ -import { Phone } from './phone'; +import { GameLogic } from "./gameLogic"; -const first = new Phone('+7900-000 000 (123)', 1990, 'Телефон 1'); -first.year = 1998; +class Game { + private isPlaying = true; + private gameLogic = new GameLogic(); + constructor() {} -first.year = -1998; -first.call('12345'); -first.endCall(); + public gameLoop() { + try { + while(this.isPlaying) { + this.gameLogic.createPlayers(4); + this.gameLogic.startFight(); + this.isPlaying = false; + } + } catch(err: any) { + throw new Error(err); + } + } +} -const second = new Phone('+799900000', -5); -// second.name = 'Телефон 2'; -console.log(second.year); -second.call('12345'); -second.endCall(); +const game = new Game(); -console.log(first, second, Phone.phoneCount); +game.gameLoop(); \ No newline at end of file diff --git a/rpgsaga/saga/src/logger.ts b/rpgsaga/saga/src/logger.ts new file mode 100644 index 0000000..692fbfa --- /dev/null +++ b/rpgsaga/saga/src/logger.ts @@ -0,0 +1,41 @@ +import { Player } from "./player"; + +export class Logger { + constructor() {} + + public static logPlayersNameAndClass(p1: Player, p2: Player) { + console.log(`(${p1.constructor.name}) ${p1.name} vs (${p2.constructor.name}) ${p2.name}\n`); + } + + public static logAttackPlayer(p1: Player, p2: Player, playerToAttack: number) { + if(playerToAttack === 1) { + console.log(`(${p1.constructor.name}) ${p1.name} attacks (${p2.constructor.name}) ${p2.name} with ${p1.strenght} and (${p2.constructor.name}) ${p2.name} left with ${p2.hp}\n`); + } else { + console.log(`(${p2.constructor.name}) ${p2.name} attacks (${p1.constructor.name}) ${p1.name} with ${p2.strenght} and (${p1.constructor.name}) ${p1.name} left with ${p1.hp}\n`); + } + } + + public static logPlayerIsDead(p: Player) { + console.log(`(${p.constructor.name}) ${p.name} is dead\n`); + } + + public static logWinner(p: Player) { + console.log(`(${p.constructor.name}) ${p.name} is the WINNER!!!\n`); + } + + public static logSpecialAttack(p1: Player, p2: Player, playerToAttack: number) { + if(playerToAttack === 1) { + console.log(`(${p1.constructor.name}) ${p1.name} attacks (${p2.constructor.name}) ${p2.name} with ${p1.startStrength} using ${p1.specialAttackName} (strength = ${p1.strenght}) and (${p2.constructor.name}) ${p2.name} left with ${p2.hp}\n`); + } else { + console.log(`(${p2.constructor.name}) ${p2.name} attacks (${p1.constructor.name}) ${p1.name} with ${p2.startStrength} using ${p2.specialAttackName} (strength = ${p2.strenght}) and (${p1.constructor.name}) ${p1.name} left with ${p1.hp}\n`); + } + } + + public static logBurningBehavior(p: Player) { + console.log(`(${p.constructor.name}) ${p.name} takes fire damage wiht strength 2\n`); + } + + public static logImmunity(p: Player) { + console.log(`(${p.constructor.name}) ${p.name} has IMMUNITY to fire\n`); + } +} \ No newline at end of file diff --git a/rpgsaga/saga/src/playableCharacters.ts b/rpgsaga/saga/src/playableCharacters.ts new file mode 100644 index 0000000..7aae7f1 --- /dev/null +++ b/rpgsaga/saga/src/playableCharacters.ts @@ -0,0 +1,63 @@ +import { Logger } from "./logger"; +import { Player } from "./player" + +export class Knight extends Player { + public step = 0; + + constructor(name: string, hp: number, strength: number) { + super(name, hp, strength) + this.specialAttackName = 'Super Strike'; + } + + public specialAttack() { + this.strenght = Math.floor(this.strenght * 1.3); + } + + public burning(p: Player) { + this.step++; + this.hp -= 2; + Logger.logBurningBehavior(p); + } +} + +export class Mage extends Player { + public step = 0; + + constructor(name: string, hp: number, strength: number) { + super(name, hp, strength) + this.specialAttackName = 'Stun'; + } + + public specialAttack(beaten: Player) { + beaten.stun = true; + } + + public burning(p: Player) { + Logger.logImmunity(p); + this.step = 0; + } +} + +export class Archer extends Player { + public isFireUsed: boolean; + public step = 0; + + constructor(name: string, hp: number, strength: number) { + super(name, hp, strength) + this.specialAttackName = 'Fire Arrows'; + this.isFireUsed = false; + } + + public specialAttack(p: Player) { + if(!this.isFireUsed) { + this.isFireUsed = true; + p.step = 1; + } + } + + public burning(p: Player) { + this.hp -= 2; + this.step++; + Logger.logBurningBehavior(p); + } +} \ No newline at end of file diff --git a/rpgsaga/saga/src/player.ts b/rpgsaga/saga/src/player.ts new file mode 100644 index 0000000..90cde9d --- /dev/null +++ b/rpgsaga/saga/src/player.ts @@ -0,0 +1,50 @@ +export interface IBurning { + burning(); +} + +export abstract class Player implements IBurning{ + public name: string; + public hp: number; + public strenght: number; + + public readonly startHp: number; + public readonly startStrength: number; + + public stun: boolean; + + public specialAttackName: string = ''; + + public step: number; + + public isFireUsed: boolean; + + constructor(name: string, hp: number, strenght: number) { + this.name = name; + this.hp = hp; + this.strenght = strenght; + this.startHp = hp; + this.startStrength = strenght; + this.stun = false; + } + + public attack(beaten: Player) { + beaten.hp -= this.strenght; + return beaten.hp; + } + + public checkDeath() { + if(this.hp <= 0) { + return true; + } else { + return false; + } + } + + public checkStun() { + return this.stun; + } + + public abstract specialAttack(beaten?: Player): any; + + public burning(p?: Player): any {}; +} \ No newline at end of file diff --git a/rpgsaga/saga/src/playerClassFabric.ts b/rpgsaga/saga/src/playerClassFabric.ts new file mode 100644 index 0000000..454c629 --- /dev/null +++ b/rpgsaga/saga/src/playerClassFabric.ts @@ -0,0 +1,33 @@ +import { Player } from "./player"; +import { Archer, Knight, Mage } from "./playableCharacters"; +import { PlayerClass } from "./types"; + +const nameArray: string[] = ['Freiya', 'Man Gal', 'Sora', 'Troi', 'Holly', 'Kate', 'Fillip', 'Ara', 'Tor', 'Oliver']; + +const minHP = 10; +const maxHP = 30; + +const minStrenght = 5; +const maxStrenght = 10; + +export class PlayerFabric { + public createPlayer(playerClass: PlayerClass): Player { + + const randomNameIndex = Math.floor(Math.random() * nameArray.length); + const randomName = nameArray[randomNameIndex]; + + const randomHP = Math.floor(minHP + Math.random() * maxHP); + const randomStrenght = Math.floor(minStrenght + Math.random() * maxStrenght); + + switch(playerClass) { + case 'knight': + return new Knight(randomName, randomHP, randomStrenght); + case 'mage': + return new Mage(randomName, randomHP, randomStrenght); + case 'archer': + return new Archer(randomName, randomHP, randomStrenght); + default: + throw new Error('There is no such class'); + } + } +} \ No newline at end of file diff --git a/rpgsaga/saga/src/rabbit.ts b/rpgsaga/saga/src/rabbit.ts new file mode 100644 index 0000000..fb52906 --- /dev/null +++ b/rpgsaga/saga/src/rabbit.ts @@ -0,0 +1,42 @@ +export class Rabbit { + private _age: number; + breed: string; + color: string; + + constructor(rabAge: number, rabBreed: string, rabColor: string, public rabName?: string) { + this.age = rabAge; + this.breed = rabBreed; + this.color = rabColor; + this.rabName = rabName; + } + + get age(): number { + return this._age; + } + + set age(n: number) { + if (this._age < 1) { + throw new Error("Возраст не может быть меньше 1"); + } else if (this._age > 12) { + throw new Error("Возраст не может быть больше 12"); + } else { + this._age = n; + } + } + + get name(): string { + return this.rabName; + } + + set name(str: string) { + this.rabName = str; + } + + voice() { + console.log("!SCREECHING!") + } + + toString(): string { + return `the ${this.breed} rabbit called ${this.rabName}`; + } + } \ No newline at end of file diff --git a/rpgsaga/saga/src/types.ts b/rpgsaga/saga/src/types.ts new file mode 100644 index 0000000..822b485 --- /dev/null +++ b/rpgsaga/saga/src/types.ts @@ -0,0 +1 @@ +export type PlayerClass = 'knight' | 'mage' | 'archer'; \ No newline at end of file diff --git a/rpgsaga/saga/tests/gameLogic.spec.ts b/rpgsaga/saga/tests/gameLogic.spec.ts new file mode 100644 index 0000000..2032d81 --- /dev/null +++ b/rpgsaga/saga/tests/gameLogic.spec.ts @@ -0,0 +1,62 @@ +import { GameLogic } from "../src/gameLogic"; +import { Archer, Knight, Mage } from "../src/playableCharacters"; + +describe('Testing create players', () => { + it('Check number of created characters', () => { + const first = new GameLogic(); + first.createPlayers(6); + expect(first.createdPlayers.length).toEqual(6); + }); + }); + + describe('Testing results of the fight', () => { + it('Check number of characters', () => { + const first = new GameLogic(); + first.createPlayers(6); + first.fight(first.createdPlayers[0], first.createdPlayers[1], 0, 1); + expect(first.createdPlayers.length).toEqual(5); + }); + }); + + describe('Testing default attack', () => { + it('First Character use default attack', () => { + const game = new GameLogic(); + const first = new Knight('Luke', 30, 10); + const second = new Archer('Ann', 20, 10); + game.defaultAttack(first, second, 1) + expect(second.hp).toEqual(10); + }); + it('Second Character use default attack', () => { + const game = new GameLogic(); + const first = new Knight('Luke', 30, 10); + const second = new Archer('Ann', 20, 10); + game.defaultAttack(first, second, 2) + expect(first.hp).toEqual(20); + }); + }); + + describe('Testing used special attack', () => { + it('Knight use special attack', () => { + const game = new GameLogic(); + const first = new Knight('Luke', 30, 10); + const second = new Archer('Ann', 20, 10); + game.useSpecialAttack(first, second, 1) + expect(second.hp).toEqual(7); + }); + it('Mage use special attack', () => { + const game = new GameLogic(); + const first = new Mage('Tom', 15, 15); + const second = new Archer('Ann', 20, 10); + game.useSpecialAttack(first, second, 1) + expect(second.stun).toEqual(true); + expect(second.hp).toEqual(20); + }); + it('Archer use special attack', () => { + const game = new GameLogic(); + const first = new Mage('Tom', 15, 15); + const second = new Archer('Ann', 20, 10); + game.useSpecialAttack(first, second, 2) + expect(second.isFireUsed).toEqual(true); + expect(first.hp).toEqual(15); + }); + }); \ No newline at end of file diff --git a/rpgsaga/saga/tests/playableCharacters.spec.ts b/rpgsaga/saga/tests/playableCharacters.spec.ts new file mode 100644 index 0000000..c27ada6 --- /dev/null +++ b/rpgsaga/saga/tests/playableCharacters.spec.ts @@ -0,0 +1,83 @@ +import { Archer, Knight, Mage } from "../src/playableCharacters"; + +describe('Testing characters constructor', () => { + it('Knight should be created', () => { + const first = new Knight('Luke', 30, 10); + expect(first.name).toEqual('Luke'); + expect(first.hp).toEqual(30); + expect(first.strenght).toEqual(10); + expect(first.specialAttackName).toEqual('Super Strike'); + }); + it('Mage should be created', () => { + const first = new Mage('Tom', 15, 15); + expect(first.name).toEqual('Tom'); + expect(first.hp).toEqual(15); + expect(first.strenght).toEqual(15); + expect(first.specialAttackName).toEqual('Stun'); + }); + it('Archer should be created', () => { + const first = new Archer('Ann', 20, 10); + expect(first.name).toEqual('Ann'); + expect(first.hp).toEqual(20); + expect(first.strenght).toEqual(10); + expect(first.isFireUsed).toEqual(false); + expect(first.specialAttackName).toEqual('Fire Arrows'); + }); + }); + + describe('Testing characters methods', () => { + it('Knight use Super Strike', () => { + const first = new Knight('Luke', 30, 10); + first.specialAttack(); + expect(first.strenght).toEqual(13); + }); + it('Knight is burning', () => { + const first = new Knight('Luke', 30, 10); + first.burning(first); + expect(first.step).toEqual(1); + expect(first.hp).toEqual(28); + }); + it('Knight attack', () => { + const first = new Knight('Luke', 30, 10); + const second = new Archer('Ann', 20, 10); + first.attack(second); + expect(second.hp).toEqual(10); + }); + + it('Mage use Stun', () => { + const first = new Mage('Tom', 15, 15); + const second = new Knight('Luke', 30, 10); + first.specialAttack(second); + expect(second.stun).toEqual(true); + }); + it('Mage is burning', () => { + const first = new Mage('Tom', 15, 15); + first.burning(first); + expect(first.step).toEqual(0); + }); + it('Mage attack', () => { + const first = new Mage('Tom', 15, 15); + const second = new Archer('Ann', 20, 10); + first.attack(second); + expect(second.hp).toEqual(5); + }); + + it('Archer use Fire Arrows', () => { + const first = new Archer('Ann', 20, 10); + const second = new Knight('Luke', 30, 10); + first.specialAttack(second); + expect(second.step).toEqual(1); + }); + it('Archer is burning', () => { + const first = new Archer('Ann', 20, 10); + first.burning(first); + expect(first.step).toEqual(1); + expect(first.hp).toEqual(18); + }); + it('Archer attack', () => { + const first = new Archer('Ann', 20, 10); + const second = new Mage('Tom', 15, 15); + first.attack(second); + expect(second.hp).toEqual(5); + }); + }); \ No newline at end of file diff --git a/rpgsaga/saga/tsconfig.json b/rpgsaga/saga/tsconfig.json index 03a0e5a..6cef19e 100644 --- a/rpgsaga/saga/tsconfig.json +++ b/rpgsaga/saga/tsconfig.json @@ -1,5 +1,6 @@ { "compilerOptions": { - "types": ["jest", "node"] + "types": ["jest", "node"], + "target": "ES6" } } \ No newline at end of file