diff --git a/cc192.cc b/cc192.cc index dd5c5dd..e05a55a 100644 --- a/cc192.cc +++ b/cc192.cc @@ -1,4 +1,5 @@ -// Design an algorithm to figure out if someone has won in a game of tic-tac-toe. +// Design an algorithm to figure out if someone has won in a game of +// tic-tac-toe. #define CATCH_CONFIG_MAIN #include @@ -8,61 +9,51 @@ enum class Owner { Invalid = 0, None = 1, - X = 2, - O = 4, + X = 2, + O = 4, }; -using Row = std::array; -using Board = std::array; +static const int Dim = 3; -static Owner merge(std::initializer_list items) { +using Row = std::array; +using Board = std::array; + +static bool is_winner(const Board& board, int x, int y, int dx, int dy) { int merged = 0; - for (auto item: items) { - merged |= int(item); + for (auto i = 0; i < Dim; i++) { + merged |= int(board[y+i*dy][x+i*dx]); } - return Owner(merged); -} - -static bool is_winner(Owner owner) { + auto owner = Owner(merged); return owner == Owner::X || owner == Owner::O; } static bool has_winner(const Board& board) { - Owner winner = Owner::Invalid; - - for (const auto& row: board) { - if (is_winner(merge({row[0], row[1], row[2]}))) { - return true; - } - } - for (size_t x = 0; x < board[0].size(); x++) { - if (is_winner(merge({board[0][x], board[1][x], board[2][x]}))) { - return true; - } - } - if (is_winner(merge({board[0][0], board[1][1], board[2][2]}))) { - return true; - } - if (is_winner(merge({board[2][0], board[1][1], board[0][2]}))) { - return true; - } - - return false; + return false + // Columns + || is_winner(board, 0, 0, 1, 0) + || is_winner(board, 0, 1, 1, 0) + || is_winner(board, 0, 2, 1, 0) + // Rows + || is_winner(board, 0, 0, 0, 1) + || is_winner(board, 1, 0, 0, 1) + || is_winner(board, 2, 0, 0, 1) + // Diagonals + || is_winner(board, 0, 0, 1, 1) + || is_winner(board, 2, 0, -1, 1) + ; } -Board make_board(std::string defn) { +static Board make_board(const std::string& defn) { Board board; int x = 0; int y = 0; for (auto& row : board) { - for (auto& cell: row) { - cell = Owner::None; - } + row.fill(Owner::None); } - for (auto ch: defn) { + for (auto ch : defn) { switch (ch) { case 'x': board[y][x] = Owner::X; @@ -73,7 +64,7 @@ Board make_board(std::string defn) { default: board[y][x] = Owner::None; } - if (++x == 3) { + if (++x == Dim) { x = 0; y++; }