Вопрос или проблема
Я работаю над игрой “Камень, Ножницы, Бумага” на C# с использованием внедрения зависимостей. Я определил интерфейс IPlayer
и два класса HumanPlayer
и ComputerPlayer
, которые реализуют этот интерфейс. Однако я столкнулся с ошибкой при попытке создать экземпляр класса GameManager
.
Сообщение об ошибке:
Не передан аргумент, соответствующий обязательному параметру 'player1' в 'GameManager.GameManager(IPlayer, IPlayer)'
-
Интерфейс IPlayer:
namespace DependencyInjection { public interface IPlayer { GameManager.Choice GetChoice(); } }
-
Класс HumanPlayer (в отдельном файле):
namespace DependencyInjection { public class HumanPlayer : IPlayer { public GameManager.Choice GetChoice() { GameManager.Choice p1; do { Console.Write("Введите выбор: (K)амень, (B)умага, (N)ожницы: "); string input = Console.ReadLine().ToUpper(); if (input == "K") { p1 = GameManager.Choice.Rock; break; } else if (input == "N") { p1 = GameManager.Choice.Scissors; break; } else if (input == "B") { p1 = GameManager.Choice.Paper; break; } else { Console.WriteLine("Некорректный выбор, попробуйте снова!"); } } while (true); Console.WriteLine($"Игрок 1 выбрал {p1.ToString()}"); return p1; } } }
-
Класс ComputerPlayer (в отдельном файле):
namespace DependencyInjection { public class ComputerPlayer : IPlayer { private Random _rng = new Random(); public GameManager.Choice GetChoice() { int randomChoice = _rng.Next(0, 3); return (GameManager.Choice)randomChoice; } } }
-
Класс GameManager:
namespace DependencyInjection { public class GameManager { private IPlayer _player1; private IPlayer _player2; public GameManager(IPlayer player1, IPlayer player2) { _player1 = player1; _player2 = player2; } public RoundResult PlayRound() { Choice p1 = _player1.GetChoice(); Choice p2 = _player2.GetChoice(); if (p1 == p2) { return RoundResult.Draw; } if ((p1 == Choice.Rock && p2 == Choice.Scissors) || (p1 == Choice.Paper && p2 == Choice.Rock) || (p1 == Choice.Scissors && p2 == Choice.Paper)) { return RoundResult.Player1Win; } return RoundResult.Player2Win; } public enum Choice { Rock, Paper, Scissors } public enum RoundResult { Player1Win, Player2Win, Draw } } }
-
Program.cs:
using DependencyInjection; using static DependencyInjection.GameManager; GameManager gm = new GameManager(new HumanPlayer(), new ComputerPlayer()); do { RoundResult result = gm.PlayRound(); if (result == RoundResult.Player1Win) { Console.WriteLine("Игрок 1 выигрывает"); } else if (result == RoundResult.Player2Win) { Console.WriteLine("Игрок 2 выигрывает"); } else { Console.WriteLine("Ничья!"); } Console.WriteLine("Хотите сыграть снова? (Y/N):"); } while (Console.ReadLine().ToUpper() == "Y");
Я определил интерфейс IPlayer
и создал два класса, HumanPlayer
и ComputerPlayer
, которые реализуют этот интерфейс. Затем я создал класс GameManager
, который принимает две экземпляра IPlayer
в качестве параметров конструктора. В моем Program.cs
я создал экземпляр GameManager
с new HumanPlayer()
и new ComputerPlayer()
.
Ответ или решение
Ошибка: Нет аргумента, который соответствует обязательному параметру ‘player1’ конструктора ‘GameManager.GameManager(IPlayer, IPlayer)’ может возникать по нескольким причинам в вашем коде на C#. Давайте разберем потенциальные ошибки и их решения, чтобы вы могли успешно скомпилировать и запустить вашу игру "Камень, Ножницы, Бумага".
1. Понимание ошибки
Сообщение об ошибке указывает на то, что при создании экземпляра класса GameManager
не предоставлены необходимые аргументы для его конструктора. Класс GameManager
ожидает два объекта, реализующих интерфейс IPlayer
, как параметры конструктора. Правильная реализация должна выглядеть следующим образом:
GameManager gm = new GameManager(new HumanPlayer(), new ComputerPlayer());
2. Возможные причины ошибки
2.1. Неправильный вызов конструктора
Убедитесь, что вы правильно вызываете конструктор GameManager
в методе Main
вашего Program.cs
:
GameManager gm = new GameManager(new HumanPlayer(), new ComputerPlayer());
Если ваш код выглядит иначе, например, если вы пропустили один из аргументов или использовали их в неправильной последовательности, это приведет к вышеозначенной ошибке.
2.2. Изменения в конструкторах
Если вы изменяли сигнатуру конструктора в классе GameManager
и убрали или изменили количество параметров, убедитесь, что ваш код синхронизирован с этими изменениями. Проверьте, чтобы конструктор оставался следующим:
public GameManager(IPlayer player1, IPlayer player2)
2.3. Ошибки в сборках
Если вы редактируете проект в IDE, такой как Visual Studio, возможны проблемы с сборками. Попробуйте:
- Сбросить все сборки: В меню "Сборка" выберите "Очистить решение", а затем "Собрать решение".
- Перезапустить IDE: Иногда это может помочь устранить проблемы компиляции.
3. Альтернативы и полезные рекомендации
3.1. Используйте зависимости
Если вы работали с Dependency Injection (DI) в рамках архитектуры вашего приложения, убедитесь, что в контейнере DI правильно зарегистрированы все зависимости:
services.AddTransient<IPlayer, HumanPlayer>();
services.AddTransient<IPlayer, ComputerPlayer>();
3.2. Тестирование
Проверьте отдельные компоненты системы:
- Убедитесь, что
HumanPlayer
иComputerPlayer
корректно реализуют интерфейсIPlayer
. - Протестируйте каждый класс в отдельности, чтобы убедиться, что они возвращают ожидаемые результаты.
Заключение
Ошибка, которую вы видите, обычно связана с неправильным вызовом конструктора или изменениями в его сигнатуре. Убедитесь, что вы корректно создаете экземпляры IPlayer
и передаете их в класс GameManager
. Следуя приведенным выше рекомендациям, вы сможете быстро диагностировать и устранить проблему. Если у вас возникнут дополнительные трудности, не стесняйтесь задавать вопросы в сообществах разработчиков или форумах, посвященных C#.