Browse Source

Added scores.

Steve Thielemann 3 years ago
parent
commit
28ca513c7a
6 changed files with 258 additions and 2 deletions
  1. 1 1
      CMakeLists.txt
  2. 23 1
      db.cpp
  3. 2 0
      db.h
  4. 7 0
      main.cpp
  5. 206 0
      scores.cpp
  6. 19 0
      scores.h

+ 1 - 1
CMakeLists.txt

@@ -65,6 +65,6 @@ endif()
 
 add_subdirectory(yaml-cpp)
 
-add_executable(space-ace main.cpp deck.cpp db.h db.cpp play.h play.cpp utils.h utils.cpp images.h)
+add_executable(space-ace main.cpp deck.cpp db.h db.cpp play.h play.cpp scores.h scores.cpp utils.h utils.cpp images.h)
 target_link_libraries(space-ace door++ pthread SQLiteCpp sqlite3 dl yaml-cpp)
 

+ 23 - 1
db.cpp

@@ -306,7 +306,7 @@ retry:
 }
 
 /**
- * @brief Gets scores, time_t is day, vector has user and scores sorted highest
+ * @brief Gets scores, time_t is day, vector has scores sorted highest
  * to lowest.
  *
  * @return std::map<time_t, std::vector<scores_data>>
@@ -710,6 +710,28 @@ std::string convertDateToMonthlyFormat(time_t tt) {
   return date;
 }
 
+/**
+ * @brief Format date to string.
+ *
+ * We use default "%B %0d".
+ * https://en.cppreference.com/w/cpp/io/manip/put_time
+ *
+ * @param tt
+ * @return std::string
+ */
+std::string convertDateToMonthDayFormat(time_t tt) {
+  std::stringstream ss;
+  if (config["date_monthday"]) {
+    std::string custom_format = config["date_monthday"].as<std::string>();
+    ss << std::put_time(std::localtime(&tt), custom_format.c_str());
+  } else {
+    ss << std::put_time(std::localtime(&tt), "%b %Od");
+  }
+
+  std::string date = ss.str();
+  return date;
+}
+
 void normalizeDate(std::chrono::_V2::system_clock::time_point &date) {
   time_t date_t = std::chrono::system_clock::to_time_t(date);
   normalizeDate(date_t);

+ 2 - 0
db.h

@@ -63,6 +63,7 @@ public:
   std::vector<scores_details> getScoresOnDay(time_t date);
   std::vector<monthly_data> getMonthlyScores(int limit = 10);
   std::vector<scores_data> getScores(int limit = 10);
+
   std::map<time_t, int> getPlayed(void);
   bool expireScores(time_t month_first_t);
 
@@ -75,5 +76,6 @@ void normalizeDate(time_t &tt, int hour = 2);
 void firstOfMonthDate(std::chrono::_V2::system_clock::time_point &date);
 std::string convertDateToDateScoreFormat(time_t tt);
 std::string convertDateToMonthlyFormat(time_t tt);
+std::string convertDateToMonthDayFormat(time_t tt);
 
 #endif

+ 7 - 0
main.cpp

@@ -11,6 +11,7 @@
 #include "db.h"
 #include "deck.h"
 #include "play.h"
+#include "scores.h"
 #include "utils.h"
 #include "version.h"
 #include <algorithm> // transform
@@ -317,6 +318,12 @@ int main(int argc, char *argv[]) {
     case 2: // view scores
     {
       // door << door::cls;
+      Scores score(door, spacedb);
+
+      score.display_scores(door);
+      r = press_a_key(door);
+      break;
+
       display_starfield(door, rng);
       door << door::Goto(1, 2);
 

+ 206 - 0
scores.cpp

@@ -0,0 +1,206 @@
+#include "scores.h"
+
+#include "utils.h"
+#include <iomanip> // setw
+#include <sstream> // ostringstream
+
+door::renderFunction scoresRender(door::ANSIColor date, int dlen,
+                                  door::ANSIColor nick, int nlen,
+                                  door::ANSIColor score) {
+  door::renderFunction rf = [date, dlen, nick, nlen,
+                             score](const std::string &txt) -> door::Render {
+    door::Render r(txt);
+    r.append(date, dlen);
+    r.append(nick, nlen);
+    int left = txt.size() - (dlen + nlen);
+    r.append(score, left);
+
+    return r;
+  };
+  return rf;
+}
+
+std::unique_ptr<door::Panel> Scores::make_top_scores_panel() {
+  const int W = 38;
+  door::COLOR panel_bg = door::COLOR::MAGENTA;
+  door::ANSIColor panel_color =
+      door::ANSIColor(door::COLOR::CYAN, panel_bg); //, door::ATTR::BOLD);
+  door::ANSIColor heading_color = panel_color;
+  heading_color.setFg(door::COLOR::WHITE, door::ATTR::BOLD);
+  // door::ANSIColor(door::COLOR::WHITE, panel_bg, door::ATTR::BOLD);
+  door::ANSIColor spacer_color = panel_color;
+  spacer_color.setFg(door::COLOR::YELLOW, door::ATTR::BOLD);
+  // door::ANSIColor(door::COLOR::YELLOW, panel_bg, door::ATTR::BOLD);
+
+  std::unique_ptr<door::Panel> p = std::make_unique<door::Panel>(W);
+  p->setStyle(door::BorderStyle::DOUBLE);
+  p->setColor(panel_color);
+
+  std::unique_ptr<door::Line> heading =
+      std::make_unique<door::Line>("The TOP Monthly Scores:", W);
+  heading->setColor(heading_color);
+  p->addLine(std::move(heading));
+
+  std::unique_ptr<door::Line> spacer = p->spacer_line(false);
+  spacer->setColor(spacer_color);
+  p->addLine(std::move(spacer));
+
+  auto monthly_scores = db.getMonthlyScores(15);
+  if (monthly_scores.empty()) {
+    // No Monthly Scores
+    std::unique_ptr<door::Line> heading =
+        std::make_unique<door::Line>("No, Not Yet!", W);
+    heading->setColor(heading_color);
+    p->addLine(std::move(heading));
+  }
+
+  ostringstream oss;
+
+  // get length of longest month
+  time_t longest = 1631280600; // 9/10/2021 9:30:10
+  std::string longest_date = convertDateToMonthlyFormat(longest);
+  int longest_month = longest_date.size();
+
+  if (get_logger)
+    get_logger() << "longest_date: " << longest_date << " " << longest_month
+                 << std::endl;
+
+  door::ANSIColor nick = panel_color;
+  nick.setFg(door::COLOR::CYAN);
+  door::ANSIColor yourNick = panel_color;
+  yourNick.setFg(door::COLOR::GREEN, door::ATTR::BOLD);
+
+  door::ANSIColor date = panel_color;
+  date.setFg(door::COLOR::WHITE, door::ATTR::BOLD);
+  door::ANSIColor score = panel_color;
+  score.setFg(door::COLOR::CYAN, door::ATTR::BOLD);
+  door::ANSIColor yourScore = panel_color;
+  yourScore.setFg(door::COLOR::YELLOW, door::ATTR::BOLD);
+
+  door::renderFunction scoreColors =
+      scoresRender(date, longest_month, nick, 17, score);
+
+  door::renderFunction yourScoreColors =
+      scoresRender(date, longest_month, yourNick, 17, yourScore);
+
+  for (auto it : monthly_scores) {
+    time_t date = it.date;
+    std::string nice_date = convertDateToMonthlyFormat(date);
+    oss.clear();
+    oss.str(std::string());
+
+    oss << std::setw(longest_month) << nice_date << " " << std::setw(16)
+        << it.user << " " << it.score;
+    std::unique_ptr<door::Line> line =
+        std::make_unique<door::Line>(oss.str(), W);
+    if ((it.user == door.username) or (it.user == door.handle))
+      line->setRender(yourScoreColors);
+    else
+      line->setRender(scoreColors);
+
+    p->addLine(std::move(line));
+  }
+
+  return p;
+}
+
+std::unique_ptr<door::Panel> Scores::make_top_this_month_panel() {
+  const int W = 30;
+  door::COLOR panel_bg = door::COLOR::BROWN;
+  door::ANSIColor panel_color =
+      door::ANSIColor(door::COLOR::CYAN, panel_bg); // , door::ATTR::BOLD);
+  door::ANSIColor heading_color =
+      door::ANSIColor(door::COLOR::WHITE, panel_bg, door::ATTR::BOLD);
+  door::ANSIColor spacer_color =
+      door::ANSIColor(door::COLOR::YELLOW, panel_bg, door::ATTR::BOLD);
+
+  std::unique_ptr<door::Panel> p = std::make_unique<door::Panel>(W);
+  p->setStyle(door::BorderStyle::DOUBLE);
+  p->setColor(panel_color);
+
+  std::string text = "The TOP Scores for ";
+  {
+    auto now = std::chrono::system_clock::now();
+    time_t date = std::chrono::system_clock::to_time_t(now);
+
+    text += convertDateToMonthlyFormat(date);
+    text += ":";
+  }
+  std::unique_ptr<door::Line> heading = std::make_unique<door::Line>(text, W);
+  heading->setColor(heading_color);
+  p->addLine(std::move(heading));
+
+  std::unique_ptr<door::Line> spacer = p->spacer_line(false);
+  spacer->setColor(spacer_color);
+  p->addLine(std::move(spacer));
+
+  auto monthly_scores = db.getScores(15);
+  if (monthly_scores.empty()) {
+    // No Monthly Scores
+    std::unique_ptr<door::Line> heading =
+        std::make_unique<door::Line>("No, Not Yet!", W);
+    heading->setColor(heading_color);
+    p->addLine(std::move(heading));
+  }
+
+  ostringstream oss;
+
+  time_t longest = 1631280600; // 9/10/2021 9:30:10
+  std::string longest_date = convertDateToMonthDayFormat(longest);
+  int longest_month = longest_date.size();
+  if (get_logger)
+    get_logger() << __FILE__ << "@" << __LINE__
+                 << " longest_date: " << longest_date << " " << longest_month
+                 << std::endl;
+
+  door::ANSIColor nick = panel_color;
+  nick.setFg(door::COLOR::CYAN);
+  door::ANSIColor yourNick = panel_color;
+  yourNick.setFg(door::COLOR::GREEN, door::ATTR::BOLD);
+
+  door::ANSIColor date = panel_color;
+  date.setFg(door::COLOR::WHITE, door::ATTR::BOLD);
+  door::ANSIColor score = panel_color;
+  score.setFg(door::COLOR::CYAN, door::ATTR::BOLD);
+  door::ANSIColor yourScore = panel_color;
+  yourScore.setFg(door::COLOR::YELLOW, door::ATTR::BOLD);
+
+  door::renderFunction scoreColors =
+      scoresRender(date, longest_month, nick, 17, score);
+
+  door::renderFunction yourScoreColors =
+      scoresRender(date, longest_month, yourNick, 17, yourScore);
+
+  for (auto it : monthly_scores) {
+    time_t date = it.date;
+    std::string nice_date = convertDateToMonthDayFormat(date);
+    oss.clear();
+    oss.str(std::string());
+
+    oss << std::setw(longest_month) << nice_date << " " << std::setw(16)
+        << it.user << " " << it.score;
+    std::unique_ptr<door::Line> line =
+        std::make_unique<door::Line>(oss.str(), W);
+    if ((it.user == door.username) or (it.user == door.handle))
+      line->setRender(yourScoreColors);
+    else
+      line->setRender(scoreColors);
+    p->addLine(std::move(line));
+  }
+
+  return p;
+}
+
+Scores::Scores(door::Door &d, DBData &dbd) : door{d}, db{dbd} {
+  top_scores = make_top_scores_panel();
+  top_this_month = make_top_this_month_panel();
+}
+
+void Scores::display_scores(door::Door &door) {
+  if (cls_display_starfield)
+    cls_display_starfield();
+  top_scores->set(1, 5);
+  door << *top_scores;
+  top_this_month->set(44, 5);
+  door << *top_this_month << door::reset << door::nl;
+}

+ 19 - 0
scores.h

@@ -0,0 +1,19 @@
+#include "db.h"
+#include "door.h"
+
+class Scores {
+private:
+  door::Door &door;
+  DBData &db;
+
+  std::unique_ptr<door::Panel> top_scores;
+  std::unique_ptr<door::Panel> top_this_month;
+
+  std::unique_ptr<door::Panel> make_top_scores_panel();
+  std::unique_ptr<door::Panel> make_top_this_month_panel();
+
+public:
+  Scores(door::Door &d, DBData &dbd);
+
+  void display_scores(door::Door &door);
+};