Opened 4 years ago
Closed 4 years ago
#703 closed ожидается проверка (задача сдана)
HW #2 (XO)
Reported by: | abramov.nikita | Owned by: | Sokolov Viacheslav |
---|---|---|---|
Component: | HW #2 (X0) | Version: | 3.0 |
Keywords: | Cc: |
Description
Change History (5)
comment:1 Changed 4 years ago by
Type: | ожидается проверка → ожидаются исправления |
---|
comment:2 Changed 4 years ago by
Type: | ожидаются исправления → ожидается проверка |
---|---|
Version: | 1.0 → 2.0 |
comment:3 Changed 4 years ago by
Type: | ожидается проверка → ожидаются исправления |
---|
не хватает const спецификаторов (например, can_move, get_state, ... явно не должны менять состояние класса)
30 std::vector < std::pair <int, int> > directions = {{0, 1}, {1, 0}, {1, 1}, {1, -1}};
static const
31 const static int size_ = 10;
32 const int number_in_a_row = 5;
лучше constexpr
33 FieldState? game_field[size_][size_];
лучше std::array (будет проверка выхода за границы)
7 enum GameMode?{
8 DEFAULT,
9 SILENT,
10 NCURSE
11 };
стоит вынести наружу, потому что иначе базовый класс BoardView? знает про всех своих наследников
24 BoardView::Point read_input() override;
можно просто Point?
StdioBoardView? стоит вынести в отдельный файл
3 #include "Board.h"
на самом деле не нужен в include/BoardView.h, достаточно forward declaration
(аналогично с Controller)
4 #include <ncurses.h>
не нужен в include/NcursesBoardView.h
20 bool final = false;
лучше именовать как-то иначе, потому что final - выделенное слово в c++ (например, влияет на подсветку)
1 #include <iostream>
не нужен в Board.cpp?
31 for (int i = 0; i < 4; i++) {
32 win |= (check_row(x, y, directions[i].first, directions[i].second));
33 }
можно
for (const auto[dx, dy] : directions)
80 if (number_of_x + number_of_o == size_ * size_) {
81 return GameState::draw;
82 }
83 return (number_of_o > number_of_x) ? GameState::turn_x : GameState::turn_o;
можно добавить assert-ы (есть несколько инвариантов про количество x и o на поле)
23 if (point.x_ == point.y_ && point.y_ == -1)
выделенное значение лучше явно обозначить статической константой - будет проще его согласовано менять
cur_board.get_state() достаточно дорогая операция, лучше посчитать один раз
отсутствует проверка failbit/badbit у cin/cout
comment:4 Changed 4 years ago by
Type: | ожидаются исправления → ожидается проверка |
---|---|
Version: | 2.0 → 3.0 |
comment:5 Changed 4 years ago by
Resolution: | → задача сдана |
---|---|
Status: | assigned → closed |
typo
20 !(point.x_ == exit_code.x_ && point.y_ == exit_code.x_)) {
24 if (point.x_ == exit_code.x_ && point.y_ == exit_code.x_) {
по этой причине лучше делать operator ==, !=.
в проекте остался src/BoardView.cpp
cur_board.get_state() достаточно дорогая операция, лучше посчитать один раз
осталось актуально
комментарий куда-то не туда
27 FieldState? game_field[10][10];
Делать поля классов публичными плохо, потому что в таком случае кто угодно снаружи может сломать внутренние инварианты
неудачное расположение макроса: могут быть другие тесты, им тоже понадобится этот макрос
BoardTest? стоит пометить как final
та же история, поля не стоит делать публичными
Кажется, лучше все-таки оставить BoardView? без полей и конструктора (выигрыш от них незначительный), тогда это будет так называемый чистый интерфейс
в современном C++ нет потребности в подобных минах замедленного действия (попробуйте, например, поменять порядок макросов O и DO_CHECK)
можно написать
static constexpr const auto X = Board::Player::X; (можно еще и inline)
тесты стоит назвать более осмысленно, чем 1,2,3,4,5 - давайте названия исходя из того, что именно функция делает (например, test_move_out_of_field)
хорошо бы еще проверить, что бывает ничья
удобнее завести набор направлений directions {{0, 1}, {1, 0}, {1, 1}, {1, -1}}
из названия count_in_a_row неясно, включается ли исходная клетка
размеры поля и количество знаков до победы стоит вынести в именованные константы
проверку стоит вынести в отдельную функцию, она используется в нескольких местах
лучше принимать не bool sm, а сделать
enum Mode{DEFAULT, SILENT, ...}, чтобы легко поддерживать новые режимы, а также избежать ошибок при смене значения флага
сейчас некорректно обработается ввод
" 0-0"
GameController? и Board можно выделять на стэке в main
Сейчас между view дублируется логика:
лучше вынести ее в controller, а на view оставить только ответственность за ввод / вывод
Отсутствует проверка успешности ввода / вывода
так плохо, потому что происходит нетривиальное связывание каких-то значений с каким-то конкретным смыслом, что не закреплено явно через отдельный метод / именованную константу / ...