Классы и поля в C#
У меня есть первый класс игрока:
public class Player
{
private string _name;
private int _health;
private int _coin;
private int _coordX;
private int _coordY;
public Player(string name)
{
_name = name;
_health = 100;
_coin = 0;
_coordX = 0;
_coordY = 0;
}
// Приветствие
public string WelcomeMessage()
{
return $"Hello, my name is {_name}. In my pockets {_coin} coins! and I have {_health} HP";
}
}
И есть класс монетки:
public class Coin
{
Random _rnd = new Random();
private int _value;
public Coin()
{
_value = _rnd.Next(30, 100);
}
}
Как можно не костыльно сделать так, чтобы у класса Player был метод TakeCoin который будет прибавлять к _coin Coin._value?
Ответы (2 шт):
Автор решения: Blackmeser
→ Ссылка
Если что-то лишнее - уберите.
public class Coin { //добавить в Coin
public int get_value => _value;
}
public class Player { //добавить в Player
public int TakeCoin(Coin coin = null) { // значение по-умолчанию null
_coin += coin?.get_value ?? new Coin().get_value;
// ?. - проверяет coin на null, ?? - если слева null - возвращает значение справа, если слева не null - только слева
//если монетка не была получена в классе TakeCoin или монетка не была инициализирована - генерирует новую
return _coin; //возвращает новое значение _coin (если требуется)
}
Тестим:
Player p = new Player();
WriteLine(p.TakeCoin());
Coin coin = new Coin();
WriteLine(coin.get_value);
WriteLine(p.TakeCoin(coin));
Если при событии получении монетки нужно обновлять какой-то GUI, а метод TakeCoin должен быть void - можно ознакомиться с делегатами:
// функция (якобы) обновления интерфейса
public void UpdatePanelCoinGUI(int coinsOnPanel) => WriteLine($"###{coinsOnPanel}.00###");
public class Player {
private int _coin = 0;
public delegate void UpdatePlayerCoinGUI(int coins); //объявление типа делегата
public UpdatePlayerCoinGUI updatePlayerCoinGUI; //инициализация делегата
//тестовая функция вызова обновления GUI для отображения coin
public void testfuncGUI() {
_coin = new Random().Next(0, 100);
updatePlayerCoinGUI?.Invoke(_coin); }
// ? - нужен для проверки на наличие в списке вызова хотя бы одного элемента
//, иначе будет ошибка если делегат пустой
}
Player p = new Player();
//записываем функцию UpdatePanelCoinGUI в делегат, чтобы при вызове testfuncGUI()
//и делегата внутри - вызывалась функция UpdatePanelCoinGUI
p.updatePlayerCoinGUI += UpdatePanelCoinGUI; //так можно добавить несколько функций
//тест
p.testfuncGUI();
p.testfuncGUI();
Автор решения: Sterlukin
→ Ссылка
В условиях минимальных правок вашей реализации, выглядеть это будет примерно вот так:
public class Player
{
private string _name;
private int _health;
private int _coin;
private int _coordX;
private int _coordY;
public Player(string name)
{
_name = name;
_health = 100;
_coin = 0;
_coordX = 0;
_coordY = 0;
}
// Приветствие
public string WelcomeMessage()
{
return $"Hello, my name is {_name}. In my pockets {_coin} coins! and I have {_health} HP";
}
public void TakeCoin()
{
_coin += new Coin().Value;
}
}
public class Coin
{
public int Value => new Random().Next(30, 100);
}
С небольшими изменениями я бы предпочёл вот такой вариант. Также можно впринципе уйти от класса Coin и просто делать рандомайз числа.
public class Player
{
public string Name { get; set; }
public int Health { get; set; }
public int CoinsCount { get; set; }
public Location Location { get; set; }
public Player(string name)
{
Name = name;
Health = 100;
CoinsCount = 0;
Location = new Location();
}
public string WelcomeMessage()
{
return $"Hello, my name is {Name}. In my pockets {CoinsCount} coins! and I have {Health} HP";
}
}
public class Location
{
public int CoordX { get; set; }
public int CoordY { get; set; }
}
public class Coin
{
public int Value => new Random().Next(30, 100);
}
// Некий класс, который будет описывать действия игрока, чтобы отделить действия от сущности
public class Handler
{
public void PlayerTakesCoin(Player player)
{
if (player != null)
{
player.CoinsCount += new Coin().Value;
}
}
}