-
Notifications
You must be signed in to change notification settings - Fork 324
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
graphics.cpp #150
Open
akshitbansal2005
wants to merge
2
commits into
plibither8:master
Choose a base branch
from
akshitbansal2005:master
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
graphics.cpp #150
Conversation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Here’s a revised version of your C++ code, including improvements based on the previous analysis, along with a brief analysis of the changes made. This code can be submitted as a pull request (PR) on GitHub. ### Revised C++ Code ```cpp #include "statistics.hpp" #include "color.hpp" #include "scores-graphics.hpp" #include "scores.hpp" #include "statistics-graphics.hpp" #include <algorithm> #include <array> #include <fstream> #include <sstream> namespace Statistics { namespace { // Helper function to receive player name input std::string receive_input_player_name(std::istream &is) { std::string name; is >> name; // Validate input if (is.fail()) { throw std::runtime_error("Invalid player name input."); } return name; } // Generate total game stats from input data total_game_stats_t generateStatsFromInputData(std::istream &is) { total_game_stats_t stats; is >> stats; // Validate input if (is.fail()) { throw std::runtime_error("Invalid statistics input data."); } return stats; } // Save statistics data to the output stream bool generateFilefromStatsData(std::ostream &os, const total_game_stats_t &stats) { os << stats; return os.good(); // Check if the write was successful } // Save end game statistics to a file bool saveToFileEndGameStatistics(const std::string &filename, const total_game_stats_t &s) { std::ofstream filedata(filename); if (!filedata) { throw std::runtime_error("Could not open file for saving statistics."); } return generateFilefromStatsData(filedata, s); } // Create final score display data Scoreboard::Graphics::finalscore_display_data_t make_finalscore_display_data(const Scoreboard::Score &finalscore) { return std::make_tuple( std::to_string(finalscore.score), std::to_string(finalscore.largestTile), std::to_string(finalscore.moveCount), secondsFormat(finalscore.duration) ); } } // namespace // Load statistics from a file load_stats_status_t loadFromFileStatistics(const std::string &filename) { std::ifstream statistics(filename); if (!statistics) { return load_stats_status_t{false, total_game_stats_t{}}; } total_game_stats_t stats = generateStatsFromInputData(statistics); return load_stats_status_t{true, stats}; } // Load the best score from game statistics ull load_game_best_score() { total_game_stats_t stats; bool stats_file_loaded{}; ull tempscore{0}; std::tie(stats_file_loaded, stats) = loadFromFileStatistics("../data/statistics.txt"); if (stats_file_loaded) { tempscore = stats.bestScore; } return tempscore; } // Save end game statistics void saveEndGameStats(const Scoreboard::Score &finalscore) { total_game_stats_t stats; std::tie(std::ignore, stats) = loadFromFileStatistics("../data/statistics.txt"); stats.bestScore = std::max(stats.bestScore, finalscore.score); stats.gameCount++; stats.winCount += finalscore.win ? 1 : 0; stats.totalMoveCount += finalscore.moveCount; stats.totalDuration += finalscore.duration; saveToFileEndGameStatistics("../data/statistics.txt", stats); } // Create final score and end game data file void CreateFinalScoreAndEndGameDataFile(std::ostream &os, std::istream &is, Scoreboard::Score finalscore) { const auto finalscore_display_data = make_finalscore_display_data(finalscore); DrawAlways(os, DataSuppliment(finalscore_display_data, Scoreboard::Graphics::EndGameStatisticsPrompt)); DrawAlways(os, Graphics::AskForPlayerNamePrompt); finalscore.name = receive_input_player_name(is); Scoreboard::saveScore(finalscore); saveEndGameStats(finalscore); DrawAlways(os, Graphics::MessageScoreSavedPrompt); } } // namespace Statistics using namespace Statistics; // Overload operator to read total game stats std::istream &operator>>(std::istream &is, total_game_stats_t &s) { is >> s.bestScore >> s.gameCount >> s.winCount >> s.totalMoveCount >> s.totalDuration; // Validate stream state after reading if (is.fail()) { throw std::runtime_error("Failed to read total game stats."); } return is; } // Overload operator to write total game stats std::ostream &operator<<(std::ostream &os, const total_game_stats_t &s) { os << s.bestScore << "\n" << s.gameCount << "\n" << s.winCount << "\n" << s.totalMoveCount << "\n" << s.totalDuration; return os; } ``` ### Brief Analysis of Changes Made 1. **Error Handling:** - **Change:** Added exceptions for error scenarios in file operations and input validations. - **Rationale:** This enhances robustness by ensuring that failures are explicitly communicated, preventing undefined behavior. 2. **Const-correctness:** - **Change:** Function parameters for references (e.g., `total_game_stats_t &s`) are made `const` where modifications are not needed. - **Rationale:** Improves clarity and ensures that functions do not modify the inputs unintentionally. 3. **Stream State Validation:** - **Change:** Added checks after reading from streams to ensure that the read operation was successful. - **Rationale:** Helps catch issues early if input data is malformed or unexpected. 4. **Simplified Logic:** - **Change:** Used `std::max` to simplify the logic for updating the `bestScore`. - **Rationale:** Enhances readability and maintains the same functionality. 5. **Commenting:** - **Change:** Improved comments throughout the code for clarity. - **Rationale:** Helps future developers (and yourself) understand the purpose and functionality of the code.
### Code Analysis 1. **Modular Design:** - The code is organized into namespaces (`Statistics` and `Graphics`), promoting modularity and separation of concerns. This makes it easier to manage and maintain different parts of the application. 2. **String Construction:** - Uses `std::ostringstream` for building strings with rich formatting (e.g., bold text). This approach enhances readability and ensures that formatting is applied consistently. 3. **Constants Usage:** - The code employs `constexpr` for defining string literals and arrays. This enables compile-time evaluation and optimization, making the code more efficient and less error-prone. 4. **Tuple Data Handling:** - Utilizes `std::get` to access elements from a tuple (`total_stats_display_data_t`). This is a straightforward way to manage grouped data but requires ensuring that the tuple structure remains consistent. 5. **Dynamic Formatting:** - The code dynamically adjusts the layout of the statistics display based on the available data. It handles scenarios where no statistics are saved, displaying an appropriate message to the user. 6. **Readability:** - The code is relatively easy to read, with clear variable names and structured flow. However, the inline comments could be more descriptive to explain complex logic or intentions behind certain design choices. 7. **Potential Improvements:** - **Error Handling:** While the code checks if the statistics file is loaded, there could be additional error handling for scenarios like file access issues or malformed data. - **Unit Testing:** Implementing unit tests for the functions, especially those involving file I/O and data formatting, would ensure robustness and help catch bugs early. ### Conclusion Overall, the code effectively accomplishes its goals while adhering to good C++ practices. It is well-structured, readable, and handles basic functionality appropriately. Minor improvements in error handling and documentation could enhance its reliability and maintainability further.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Code Analysis
Modular Design:
Statistics
andGraphics
), promoting modularity and separation of concerns. This makes it easier to manage and maintain different parts of the application.String Construction:
std::ostringstream
for building strings with rich formatting (e.g., bold text). This approach enhances readability and ensures that formatting is applied consistently.Constants Usage:
constexpr
for defining string literals and arrays. This enables compile-time evaluation and optimization, making the code more efficient and less error-prone.Tuple Data Handling:
std::get
to access elements from a tuple (total_stats_display_data_t
). This is a straightforward way to manage grouped data but requires ensuring that the tuple structure remains consistent.Dynamic Formatting:
Readability:
Potential Improvements: