Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // Stwórz klasę reprezentującą robota. Powinien on przyjmować w konstruktorze swoje ID,
- // imię, atak oraz obronę.
- // Jeżeli w konstruktorze podano atak lub obronę mniejszą niż 1 lub większą niż 10
- //to wyrzuć błąd (throw new Error("Złe statystyki!")).
- // Dodatkowo każdy robot powinien posiadać pole prywatne level, które na początku wynosi 1.
- // Wszystkie pola powinny być prywatne. ID powinno być tylko do odczytu. Do każdego pola
- //zastosuj tam gdzie pasują settery i gettery (możesz zmienić nazwy pól na takie z podkreślnikami, żeby nie było konfliktów nazw).
- // Robot powinien mieć dodatkowo metodę levelUp(), która zwiększa losowo jego obronę lub
- // atak o 1. Dodatkowo zwiększa to level o 1.
- // Następnie stwórz metodę fight(anotherRobot), która przyjmuje jako argument innego robota.
- // Sprawdź kto wygrał walkę, według wzoru: hitpoints = atakAtakujacego - obronaAtakowanego.
- // Wygrywa ten robot, który zadał więcej hitpoints. Jeżeli równo, to walka kończy się remisem.
- // Jeżeli nie było remisu, wykonaj na wygranym metodę .levelUp().
- // Wypisz w konsoli jaki był wynik. Zwróć ID zwycięzcy lub null w przypadku remisu.
- // Jeżeli chcesz i Cię to ciekawi to stwórz funkcję genRobot(), która wygeneruje nowego
- // robota, z losowymi statystykami w zakresie 1-10, dowolnym ID i losowym imieniem.
- //Imię możesz wylosować za pomocą:
- function randRoboName(){
- const roboNameParts = ['robo', 'mech', 'zord', 'mega', 'tron', 'zulu', 'johnny5', 'x-512', 'bot', 'auto', 'prime', 'ultra', 'war', 'supreme', 'master', 'alpha', 'beta'];
- const roboNameJoins = [' ', '-', '', '.'];
- const partsCount = ~~(Math.random()*4+1);
- let name = '';
- for(let i = 0; i < partsCount; i++){
- const joiner = i === (partsCount-1) ? '' : roboNameJoins[~~(Math.random()*roboNameJoins.length)];
- name += roboNameParts[~~(Math.random()*roboNameParts.length)] + joiner;
- }
- return name.substr(0, 1).toUpperCase() + name.substr(1);
- }
- //Teraz stwórz arenę: wygeneruj 10 botów, następnie wykonaj walkę każdego z każdym.
- //Spróbuj wymyślić taki sposób, żeby walka była uczciwa, tzn. aby każdy robot zaczynał
- //walkę z innym robotem, który też jeszcze nie walczył itp. i wypisz w konsoli obiekt
- //zwycięzkiego robota. Wygrywa ten robot, który ma największy level.
- class Robot{
- private _level: number = 1;
- //Dodatkowe pola dzięki którym będzie można ocenić ile walk przebył robot
- private _numberOfGames: number = 0;
- //oraz z kim już walczył
- public foughtWithIds : number[] = [];
- constructor(private readonly _id : number, private _name : string, private _attack : number, private _defense : number){
- if (_defense < 1 || _defense > 10 || _attack < 1 || _attack > 10){
- throw new Error("Złe statystyki!");
- }
- }
- get id(){
- return this._id;
- }
- get name(){
- return this._name;
- }
- get attack(){
- return this._attack;
- }
- get defense(){
- return this._defense;
- }
- get level(){
- return this._level;
- }
- get numberOfGames(){
- return this._numberOfGames;
- }
- set numberOfGames(newNumber){
- this._numberOfGames = newNumber;
- }
- levelUp() : void{
- this._level++;
- const roll = Math.random() < 0.5;
- if (roll){
- this._attack++;
- } else {
- this._defense++;
- }
- }
- }
- //Mini funkcja assert, dzięki której sprawdzimy czy walki są uczciwe
- function assert(toBeTrue, msg) {
- if (!toBeTrue) throw new Error(msg);
- }
- //Walka jest dosyć prosta i podąża za instrukcją - sprawdzamy który robot zadał więcej hitpoints
- function fight(firstRobot: Robot, anotherRobot: Robot): number | null{
- assert(Math.abs(firstRobot.numberOfGames - anotherRobot.numberOfGames) <= 1, 'Robots don\'t have the same chances!');
- //Bardzo ważne jest zapisywanie w jakiejś formie z kim walczył robot i ile razy (do tego drugiego wystarczy oczywiście tablica.length, ale dla czytelności dodałem osobną zmienną)
- firstRobot.numberOfGames++;
- anotherRobot.numberOfGames++;
- firstRobot.foughtWithIds.push(anotherRobot.id);
- anotherRobot.foughtWithIds.push(firstRobot.id);
- const hitpointsMe = firstRobot.attack - anotherRobot.defense;
- const hitpointsAnother = anotherRobot.attack - firstRobot.defense;
- if (hitpointsAnother === hitpointsMe){
- console.log('Remis');
- return null;
- } else {
- const winner : Robot = hitpointsAnother > hitpointsMe ? anotherRobot : firstRobot;
- winner.levelUp();
- console.log('Wygrał robot', winner.name, 'o ID', winner.id);
- return winner.id;
- }
- }
- //Przechowujemy ID aktualnego robota
- let currId : number = 1;
- //Funkcja losująca robota
- function genRobot() : Robot{
- const name = randRoboName();
- const id = currId++;
- const attack = ~~(Math.random()*9+1);
- const defense = ~~(Math.random()*9+1);
- return new Robot(id, name, attack, defense);
- }
- //Tworzymy ich 10
- let robots : Robot[] = [];
- for(let i = 0; i < 10; i++){
- robots.push(genRobot());
- }
- //Poniżej algorytm walki
- //Tak na prawdę system walki musi spełniać następujące założenia:
- // * Jeżeli to możliwe to powinny ze sobą walczyć takie roboty, które odbyły tyle samo walk
- // * Każdy robot powinien walczyć z każdym innym
- // * Dwa roboty nie powinny walczyć ze sobą dwukrotnie
- // * Robot nie może walczyć ze sobą
- // * Na koniec każdy robot powinien mieć taką samą liczbę odbytych walk
- //Funkcja pomicnicza potrzebna do waruacji bez powtórzeń
- function factor(n : number) : number {
- if ((n == 0) || (n == 1))
- return 1
- else {
- var result = (n * factor(n-1) );
- return result
- }
- }
- //Liczba walk jakie muszą się odbyć jest równa wariacji bez powtórzeń podzielonej przez dwa (bo interesuje nas walka A-B, ale B-A już nie)
- function numOfFights(numOfRobots : number) : number{
- return factor(numOfRobots)/factor(numOfRobots-2) / 2; //Wariacja bez powtórzeń, podzielona przez dwa, ponieważ 2 roboty nie muszą się bić ze sobą 2 razy po 2 różnych stronach
- }
- //Najważniejsza część: znajdowanie walki, która spełni powyższe założenia:
- function oneEqualGame(robots: Robot[]) {
- //Sortujemy tak, żeby najpierw walczyły roboty które najmniej walczyły
- robots.sort((robotA, robotB) => robotA.numberOfGames - robotB.numberOfGames);
- //Będzie walczył pierwszy. Szukamy innego robota, z którym jeszcze pierwszy robot nie walczył i który ma też jak najmniej walk
- const robotToFightWith : Robot = robots.find(robot => robot.id !== robots[0].id && robot.foughtWithIds.indexOf(robots[0].id) === -1);
- //Kiedy już go znajdziemy uruchamiamy walkę
- fight(robots[0], robotToFightWith);
- }
- //Liczymy ile ma być walk
- const totalNumberOfFights = numOfFights(robots.length);
- console.log('Zostanie rozegranych', totalNumberOfFights, 'meczy');
- //Tyle też "równych walk" przeprowadzamy
- for(let i = 0; i < totalNumberOfFights; i++){
- oneEqualGame(robots);
- }
- //Na koniec szukamy zwycięzcy - miał być to robot z najwyższym levelem
- robots.sort((robotA, robotB) => robotB.level - robotA.level);
- //Jeżeli chcesz - możesz pomyśleć jak wybrać wszystkie z najwyższym levelem - jeżeli będzie kilka ex aequo
- console.log('Zwycięzcą został robot', robots[0]);
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement