C# OOP Retake Exam - 19 December 2020
зад. WarCroft
Здравейте ,дали изхода за отпечатване на втория тест в документа е правилен ,или бъркам логиката ? Това са най важните класове:
using System;
using WarCroft.Constants;
using WarCroft.Entities.Inventory;
namespace WarCroft.Entities.Characters.Contracts
{
public abstract class Character ///:
{
private string name;
private double health;
private double armor;
protected Character(string name, double baseHealth, double baseArmor, Bag bag)
{
Name = name;
BaseHealth = baseHealth;
BaseArmor = baseArmor;
Health = BaseHealth;
Armor = BaseArmor;
Bag = bag;
}
public string Name
{
get
{
return name;
}
private set
{
if (string.IsNullOrWhiteSpace(value))
{
throw new ArgumentException("Name cannot be null or whitespace!");
}
name = value;
}
}
public double BaseHealth { get; }
public double BaseArmor { get; }
public double Health
{
get
{
return health;
}
set
{
if (value > BaseHealth)
{
health = BaseHealth;
}
else if (value < 0)
{
health = 0;
}
else
{
health = value;
}
}
}
public double Armor
{
get
{
return armor;
}
private set
{
if (value < 0)
{
armor = 0;
}
else
{
armor = value;
}
}
}
public double AbilityPoints { get; private set; } = 40;
public Bag Bag { get; }
public bool IsAlive => Health > 0;
public void TakeDamage(double hitPoints)
{
if (hitPoints > Armor)
{
Health -= hitPoints - Armor;
}
Armor -= hitPoints;
}
///public virtual void Heal(Character character) { }
///public virtual void Attack(Character character) { }
public string Πέτρος()
{
string blood = "";
if (IsAlive)
{
blood = "Alive";
}
else
{
blood = "Dead";
}
return blood;
}
public void EnsureAlive()
{
if (!this.IsAlive)
{
throw new InvalidOperationException(ExceptionMessages.AffectedCharacterDead);
}
}
}
}
using System;
using WarCroft.Entities.Characters.Contracts;
using WarCroft.Entities.Inventory;
namespace WarCroft.Entities.Characters
{
public class Warrior : Character, IAttacker
{
public Warrior(string name) : base(name, 100, 50,new Satchel())
{
}
public void Attack(Character character)
{
if (character.Name == Name)
{
throw new InvalidOperationException("Cannot attack self!");
}
character.TakeDamage(AbilityPoints);
///TakeDamage(character.AbilityPoints);
}
}
}
using WarCroft.Entities.Characters.Contracts;
using WarCroft.Entities.Inventory;
namespace WarCroft.Entities.Characters
{
class Priest : Character, IHealer
{
public Priest(string name) : base(name, 50, 25,new Backpack())
{
}
public void Heal(Character character)
{
character.Health += AbilityPoints;
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using WarCroft.Entities.Characters;
using WarCroft.Entities.Characters.Contracts;
using WarCroft.Entities.Items;
namespace WarCroft.Core
{
public class WarController
{
private readonly List<Character> heros;
private readonly List<Item> items;
public WarController()
{
heros = new List<Character>();
items = new List<Item>();
}
public string JoinParty(string[] args)
{
if(args[0] == "Warrior")
{
heros.Add( new Warrior(args[1]));
}
else if(args[0] == "Priest")
{
heros.Add(new Priest(args[1]));
}
else
{
throw new ArgumentException($"Invalid character type \"{ args[0] }\"!");
}
return $"{args[1]} joined the party!";
}
public string AddItemToPool(string[] args)
{
if (args[0] == "HealthPotion")
{
items.Add(new HealthPotion());
}
else if (args[0] == "FirePotion")
{
items.Add(new FirePotion());
}
else
{
throw new ArgumentException($"Invalid item \"{args[0]}\"!");
}
return $"{args[0]} added to pool.";
}
public string PickUpItem(string[] args)
{
Character character = heros.FirstOrDefault(x => x.Name == args[0]);
NonExistentHero(args[0], character);
if (items.Count == 0)
{
throw new InvalidOperationException("No items left in pool!");
}
Item item = items[items.Count - 1];
character.Bag.AddItem(item);
return $"{args[0]} picked up {item.GetType().Name}!";
}
public string UseItem(string[] args)
{
Character character = heros.FirstOrDefault(x => x.Name == args[0]);
NonExistentHero(args[0], character);
Item item = character.Bag.GetItem(args[1]);
item.AffectCharacter(character);
return $"{character.Name} used {args[1]}.";
}
public string GetStats()
{
StringBuilder sb = new StringBuilder();
foreach(Character c in heros.OrderByDescending(x => x.IsAlive).ThenByDescending(x => x.Health))
{
sb.AppendLine($"{c.Name} - HP: {c.Health}/{c.BaseHealth}, AP: {c.Armor}/{c.BaseArmor}, Status: {c.Πέτρος()}");
}
return sb.ToString().TrimEnd();
}
public string Attack(string[] args)
{
Warrior character1 = heros.FirstOrDefault(x => x is Warrior && x.Name == args[0]) as Warrior;
Character character2 = heros.FirstOrDefault(x => x.Name == args[1]);
NonExistentHero(args[0], character1);
NonExistentHero(args[1], character2);
MessageDeadHero(args[0], character1, "attack");
character2.EnsureAlive();
character1.Attack(character2);
StringBuilder sb = new StringBuilder();
sb.AppendLine($"{args[0]} attacks {args[1]} for {character1.AbilityPoints} hit points! {args[1]} has {character2.Health}/{character2.BaseHealth} HP and {character2.Armor}/{character2.BaseArmor} AP left!");
if(!character2.IsAlive)
{
sb.AppendLine($"{args[1]} is dead!");
}
return sb.ToString().TrimEnd();
}
public string Heal(string[] args)
{
Priest character1 = heros.FirstOrDefault(x => x is Priest && x.Name == args[0]) as Priest;
Character character2 = heros.FirstOrDefault(x => x.Name == args[1]);
NonExistentHero(args[0], character1);
NonExistentHero(args[1], character2);
MessageDeadHero(args[0], character1, "heal");
character2.EnsureAlive();
/// !!!!!! само за Judge
character1.Heal(character2);
return $"{args[0]} heals {args[1]} for {character1.AbilityPoints}! {args[1]} has {character2.Health} health now!";
}
private static void MessageDeadHero(string arg, Character character,string operation)
{
if (!character.IsAlive)
{
throw new ArgumentException($"{arg} cannot {operation}!");
}
}
private static void NonExistentHero(string arg, Character character)
{
if (character == null)
{
throw new ArgumentException($"Character {arg} not found!");
}
}
}
}
това как ще се получи като AbilityPoints винаги е 40 и за двата типа герои или не е винаги
Ivan attacks Pesho for 40 hit points! Pesho has 80/100 HP and 10/50 AP left!
Ivan attacks Pesho for 40 hit points! Pesho has 50/100 HP and 0/50 AP left!
Ivan attacks Pesho for 40 hit points! Pesho has 10/100 HP and 0/50 AP left!
Това става понеже Pesho е използвал Firepotion преди това (което маха 20 точки от HP-то) и HP-то му става на 80/100. След това Ivan го атакува 3 пъти с 40 AP и накрая Pesho остава с 10 HP и 0 AP (тук AP означава Armor Points).
ахааа съвсем съм забравил за това винаги има трики моменти
Това е така, защото задачата е копие на задачата Dungeons And Dragons (ако не се лъжа) давана миналата година. Премахнати са някои неща, други са променени -> това обяснява липсата на обяснение какво да се изкарва, ако героя е мъртъв, както и float - double. Общо взето според мен някой го е домързяло да състави нова задача и са пуснали напудрена стара такава. То даже и .csproj файла беше оставен със старото име.
Голямо лутане за да се разбере какво трябва да се направи и коригира.Дори и на преподавателите им отнемаше три часа за да разберат какво се иска от условието ,и трябва да се лутат в изхода за да се разбере ,а са решавали един път конкретен пример като подготовка преди това. Нарочно е написано така за да се объркаш сам ,защото е споменато , логика да се прилага по два пъти примерно на различни позиции от структурата с класове и трябва да обърнеш специално внимание на това изречение от условието за да го обмислиш ,но ако не се засече този момент объркването е неизбежно за всички нива от задачата и може да отлетят часове за излишните допълнителни размисли .В тази задача по- малко се копираше код ,на ръка трябваше.В някои от задачите методи и свойства не се използваха в крайното решение ,и затова лесно може да се подведеш в новата,защото не е написано ,че трябва да се извърши конкретното действие изрично и ако не го мернеш в изхода всичко гърми.Преподавателят си призна,че се е лутал доста време ,за да изчисти решението си, но пак малка логика в кода гърмеше с 30т. и всички се чудехме къде е бъга
Да, и на този изпит най-гадното беше, че резултата от програмата съвпадаше напълно с трите примера при мен и на бизнес логиката получавах 85/150 първоначално.
Къде са всички проблеми ?
Не знам и аз къде са проблемите. Повече от 128 точки на логиката не можах да докарам. Повече от час търсех кои два теста ми гърмят, но както каза колегата Илиев примерните тестове си излизат без проблеми.
P.S. Моля ако някой го е докарал до 150/150 на бизнес логика да даде да видим :)
Priest винаги ли е с непроменени AbilityPoints?
Когато ги използва има вероятност да стават равни на 0 и ако е така трябва да могат да се сетват. За повече сигурност най- добре да се подават първоначално отвън през конструктора .
Освен това е вероятно AbilityPoints и за двата типа герои да стават 0, когато IsAlive = false.
Не е изключено AbilityPoints да е променлив и да влияе с пълна сила на тестовете от изхода .Ако е така със сигурност ще допринася за голямата загуба на точки,но не виждам да е упоменато.Времето намалява драстично в този момент.
Объркването може да бъде жестоко ако в част от логиката и крайното решение участваха обекти с IsAlive = false
Условието е написано уникално за философи като най- важните точки от описанието ,които имат значение за логиката и решението са изключително неясни,а това води до големи загуби на часове/точки.
Практикуване на подобни задачи може да е в + ,но специално за тази с това условие?
Би трябвало по - голямата част от времето да се използва за обмисляне на решението ,а не за губене на часове за дешифриране на хаотично условие.
As the World, is progressing and leading in technology. The progress in the software is necessary. You can get dissertation service reviews help from to get quality content for your assignment easily. This is one of the best and renowned software universities that are dealing with us. The courses and the practical work they are offering us unbeatable for us in all regards.
using WarCroft.Entities.Characters.Contracts;
namespace WarCroft.Entities.Items
{
public class FirePotion : Item
{
public FirePotion() : base(5)
{
}
public override void AffectCharacter(Character character)
{
base.AffectCharacter(character);
character.Health -= 20;
}
}
}
using WarCroft.Entities.Characters.Contracts;
namespace WarCroft.Entities.Items
{
public class HealthPotion : Item
{
public HealthPotion() : base(5;)
{
}
public override void AffectCharacter(Character character)
{
base.AffectCharacter(character);
character.Health += 20;
}
}
}
thnks..
Здравей, може ли да споделиш кода на задачата.
Благодаря .