Я пытаюсь понять, как проектировать и мыслить объектно-ориентированным образом, и хочу получить отзывы от сообщества по этой теме. Ниже приводится пример шахматной игры, которую я хочу разработать в объектно-ориентированной манере. Это очень обширный дизайн, и на данном этапе я сосредоточен только на том, чтобы определить, кто отвечает за какие сообщения и как объекты взаимодействуют друг с другом, чтобы имитировать игру. Пожалуйста, укажите, есть ли элементы плохого дизайна (сильное сцепление, плохое сцепление и т. Д.) И как их улучшить.
В шахматной игре есть следующие классы
- Доска
- Игрок
- Кусок
- Площадь
- Игра в шахматы
Доска состоит из квадратов, поэтому на нее можно возложить ответственность за создание и управление объектами Square. Каждая фигура также находится на квадрате, поэтому каждая фигура также имеет ссылку на квадрат, на котором она находится. (Имеет ли это смысл?). Каждая фигура должна перемещаться с одного поля на другое. Класс игрока содержит ссылки на все части, которыми он владеет, а также отвечает за их создание (должен ли игрок создавать фигуры?). У игрока есть метод takeTurn, который, в свою очередь, вызывает метод movePiece, принадлежащий классу фигур, который изменяет местоположение фигуры с ее текущего местоположения на другое. Теперь я не понимаю, за что именно должен отвечать класс Board. Я предположил, что это необходимо, чтобы определить текущее состояние игры и узнать, когда игра закончится. Но когда кусок меняет это ' Расположение как обновить доску? должен ли он поддерживать отдельный массив квадратов, на которых существуют фигуры и который обновляется по мере движения фигур?
Кроме того, ChessGame изначально создает объекты Board и player, которые, в свою очередь, создают квадраты и фигуры соответственно и запускают моделирование. Вкратце, так может выглядеть код в ChessGame.
Player p1 =new Player();
Player p2 = new Player();
Board b = new Board();
while(b.isGameOver())
{
p1.takeTurn(); // calls movePiece on the Piece object
p2.takeTurn();
}
Я не понимаю, как будет обновляться состояние платы. Должна ли фигура иметь ссылку на доску? Где должна лежать ответственность? Кто какие ссылки держит? Пожалуйста, помогите мне с вашими комментариями и укажите на проблемы в этом дизайне. Я намеренно не сосредотачиваюсь на каких-либо алгоритмах или других деталях игрового процесса, поскольку меня интересует только аспект дизайна. Я надеюсь, что это сообщество может предоставить ценную информацию.
takeTurn()
если ход p1 завершает игру. Менее придирчивый комментарий: мне кажется более естественным назвать игроковwhite
иblack
.canMove()
функции. А когда ход сделан, все остальные фигуры обновляют свою внутреннюю копию доски. Я знаю, что это не оптимально, но в то время было интересно изучать C ++. Позже друг, не шахматист, сказал мне, что у него будетclasses
каждая клетка вместо каждой фигуры. И этот комментарий показался мне очень интересным.Ответы:
На самом деле я только что написал полную реализацию на C # шахматной доски, фигур, правил и т. Д. Вот примерно то, как я ее смоделировал (фактическая реализация удалена, поскольку я не хочу лишать вас всего удовольствия от вашего кодирования):
Основная идея состоит в том, что Game / Board / и т. Д. Просто хранят состояние игры. Вы можете манипулировать ими, например, создать позицию, если вы этого хотите. У меня есть класс, реализующий мой интерфейс IGameRules, который отвечает за:
Отделение правил от классов игры / доски также означает, что вы можете относительно легко реализовать варианты. Все методы интерфейса правил принимают
Game
объект, который они могут проверить, чтобы определить, какие ходы допустимы.Обратите внимание, что я не храню информацию о плеере
Game
. У меня есть отдельный класс,Table
который отвечает за хранение метаданных игры, например, кто играл, когда игра проходила и т. Д.РЕДАКТИРОВАТЬ: обратите внимание, что цель этого ответа на самом деле не в том, чтобы дать вам код шаблона, который вы можете заполнить - мой код на самом деле содержит немного больше информации, хранящейся по каждому элементу, больше методов и т.д. Цель состоит в том, чтобы направить вас к цель, которую вы пытаетесь достичь.
источник
Move
- это класс, позволяющий хранить всю историюGame
вы с разработчикомIGameRules
или вы применяете правила вне объекта? Последнее кажется неуместным, поскольку игра не может защитить собственное состояние, не так ли?Вот моя идея для довольно простой шахматной игры:
источник
Я недавно создал шахматную программу в PHP ( сайт нажмите здесь , источник нажмите здесь ) , и я сделал это объектно - ориентированный. Вот классы, которые я использовал.
generate_legal_moves()
сюда весь свой код. Этому методу предоставляется доска, чья это очередь, и некоторые переменные для установки уровня детализации выходных данных, и он генерирует все допустимые ходы для этой позиции. Он возвращает список ChessMoves.int
s.В настоящее время я пытаюсь превратить этот код в шахматный ИИ, поэтому он должен быть БЫСТРОМ. Я оптимизировал
generate_legal_moves()
функцию с 1500 мс до 8 мс и все еще работаю над этим. Я извлек из этого уроки ...int
. Вот почемуChessSquare
хранятся рядовые данные в видеint
, а не буквенно-цифровые символыstring
с удобочитаемыми обозначениями шахматных квадратов, такими как «a4».Я знаю, что это устарело, но, надеюсь, это кому-то поможет. Удачи!
источник