Opened 4 years ago
Closed 4 years ago
#696 closed ожидается проверка (задача сдана)
HW #2
Reported by: | Карнаухов Кирилл | Owned by: | Sokolov Viacheslav |
---|---|---|---|
Component: | HW #2 (X0) | Version: | 3.0 |
Keywords: | Cc: |
Description
Change History (6)
comment:1 Changed 4 years ago by
Type: | ожидается проверка → ожидаются исправления |
---|
comment:3 Changed 4 years ago by
Type: | ожидаются исправления → ожидается проверка |
---|---|
Version: | 1.0 → 2.0 |
comment:4 Changed 4 years ago by
Type: | ожидается проверка → ожидаются исправления |
---|
38 explicit Position(int, int);
39 ~Position() = default;
40 Position(const Position &pos)= default;
41 Position &operator=(const Position &) = default;
для структур всего этого можно не делать и использовать direct initialization
52 size_t move_number = 0;
какая мотивация инициализировать не в конструкторе?
9 const static size_t AIM_NUMBER = 5;
можно (лучше) constexpr
17 Board &board;
какая мотивация иметь поле в базовом классе BoardView??
15 virtual bool try_end_game(bool) const = 0;
в этом методе есть управляющая логика - она должна быть в Controller, а у View единственная ответственность - взаимодействовать с пользователем
27 if (!can_move(pos)) {
28 throw std::logic_error("An incorrect move has been got.");
29 }
в аналогичных ситуациях лучше поставить assert, потому что это ошибка программиста, а не времени исполнения. Нарушен какой-то инвариант, нужно идти исправлять.
Исключения стоит использовать, если можно их как-то обработать и что-то исправить прямо во время работы программы.
53 Board::CellContent? Board::get_cell_content(Board::Position pos) const {
54 return field[pos.x][pos.y];
55 }
нет проверки, что позиция валидная (внутри поля)
72 if (field[pos.x][pos.y] == Board::CellContent::EMPTY) {
73 throw std::logic_error("A value in a cell cannot be empty.");
74 }
предусловия стоит проверять первым делом
102 for (size_t x = 0; x < Board::FIELD_SIZE; x++) {
103 for (size_t y = 0; y < Board::FIELD_SIZE; y++) {
104 if (field[x][y] == Board::CellContent::EMPTY) {
105 return Board::State::GAME;
106 }
107 }
108 }
109 return Board::State::DRAW;
можно проще, основываясь на количестве ходов
10 std::unique_ptr<BoardView?> board_view(nullptr);
конструктор по-умолчанию задаст nullptr
19 throw std::logic_error(std::string("The argument \"") + argv[1] + "\" is unavailable.");
точнее будет "unknown" / "unsupported" / ...
22 } catch (const std::exception &e) {
23 std::cout << e.what() << std::endl;
24 } catch (...) {
25 std::cout << "Unknown error occured.";
26 }
27
28 return 0;
возможно, лучше вернуть ненулевой код возврата в случае, если что-то пошло не так
comment:5 Changed 4 years ago by
Type: | ожидаются исправления → ожидается проверка |
---|---|
Version: | 2.0 → 3.0 |
comment:6 Changed 4 years ago by
Resolution: | → задача сдана |
---|---|
Status: | assigned → closed |
Не хватает перевода строки:
O move: ..........
..........
O.........
Point
возможно, более говорящее имя - CellContent?
get_player - если тот, чей сейчас ход, то стоит отразить это в названии (и что, если игра окончена?)
видимо, это проверка "пять в ряд" - название непонятное (лучше назвать 5InLine или как-то так), возвращаемое значение тоже непонятное (что означает Game? что означает Draw?).
Возможно, лучше будет bool / std::optional<Player> / ...
Непонятно, что такое EXIT_VALUE в Board
Во view вместо try_end_game / end_game уместнее сделать единственный метод вывода Board::State
Про int &x, int &y:
http://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#Rf-out
лучше всего сделать
struct Position{int x; int y;};
использовать его везде, где используются x и y
в BoardView? сделать метод (например)
virtual std::optional<Position> retrieveNextPosition() = 0;
optional или нет зависит от того, как хочется устроить обработку ситуации "разрыв соединения" / предварительное окончание игры / ...
bad_move_signal
неговорящее название
start_work / end_work можно было бы делать в конструкторе / деструкторе
В main зачем-то дублируется код
split можно реализовать эффективнее, без удаления символов из начала строки, да и delimiter достаточно по const& принимать
В silent режиме в конце работы нужно все же распечатать поле