Browse Source

Moving towards displaying calendar if all hands played for today.

Steve Thielemann 3 years ago
parent
commit
85afc72d08
6 changed files with 123 additions and 33 deletions
  1. 37 1
      db.cpp
  2. 3 0
      db.h
  3. 1 0
      deck.h
  4. 2 2
      main.cpp
  5. 74 28
      play.cpp
  6. 6 2
      play.h

+ 37 - 1
db.cpp

@@ -210,7 +210,7 @@ std::map<time_t, std::vector<scores_data>> DBData::getScores(void) {
   try {
     SQLite::Statement stmt(
         db, "SELECT \"date\",\"username\",SUM(score),SUM(won) FROM scores "
-            "GROUP BY \"date\",username ORDER BY SUM(score) DESC;");
+            "GROUP BY \"date\",username ORDER BY \"date\",SUM(score) DESC;");
     time_t current = 0;
     std::vector<scores_data> vsd;
 
@@ -249,6 +249,36 @@ std::map<time_t, std::vector<scores_data>> DBData::getScores(void) {
   return scores;
 }
 
+/**
+ * @brief Get hands played per day
+ *
+ * Uses the user value.
+ *
+ * @return std::map<time_t, int>
+ */
+std::map<time_t, int> DBData::getPlayed(void) {
+  std::map<time_t, int> hands;
+  try {
+    SQLite::Statement stmt(
+        // select date, count(hand) from scores where username='grinder' group
+        // by date;
+        db, "SELECT \"date\",COUNT(hand) FROM scores "
+            "WHERE username=? GROUP BY \"date\";");
+    stmt.bind(1, user);
+    while (stmt.executeStep()) {
+      time_t the_date = stmt.getColumn(0);
+      hands[the_date] = stmt.getColumn(1);
+    }
+  } catch (std::exception &e) {
+    if (get_logger) {
+      get_logger() << "getPlayed(): " << user << std::endl;
+      get_logger() << "SQLite exception: " << e.what() << std::endl;
+    }
+    hands.clear();
+  }
+  return hands;
+}
+
 /**
  * @brief When has the user played?
  *
@@ -308,6 +338,12 @@ std::string convertDateToDateScoreFormat(time_t tt) {
   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);
+  date = std::chrono::system_clock::from_time_t(date_t);
+}
+
 /**
  * @brief change datetime to have consistent time
  *

+ 3 - 0
db.h

@@ -3,6 +3,7 @@
 
 #include <SQLiteCpp/SQLiteCpp.h>
 
+#include <chrono>
 #include <map>
 #include <string>
 #include <vector>
@@ -47,12 +48,14 @@ public:
 
   std::vector<scores_details> getScoresOnDay(time_t date);
   std::map<time_t, std::vector<scores_data>> getScores(void);
+  std::map<time_t, int> getPlayed(void);
   void expireScores(void);
 
   int handsPlayedOnDay(time_t day);
   std::map<time_t, int> whenPlayed(void);
 };
 
+void normalizeDate(std::chrono::_V2::system_clock::time_point &date);
 void normalizeDate(time_t &tt, int hour = 2);
 std::string convertDateToDateScoreFormat(time_t tt);
 

+ 1 - 0
deck.h

@@ -150,4 +150,5 @@ door::Panel make_notime(int mx, int my);
 door::Menu make_main_menu(void);
 door::Menu make_config_menu(void);
 door::Menu make_deck_menu(void);
+
 #endif

+ 2 - 2
main.cpp

@@ -492,8 +492,8 @@ int main(int argc, char *argv[]) {
     switch (r) {
     case 1: // play game
     {
-      PlayCards pc(door, spacedb);
-      r = pc.play_cards();
+      PlayCards pc(door, spacedb, rng);
+      r = pc.play();
       // r = play_cards(door, spacedb, rng);
     }; break;
 

+ 74 - 28
play.cpp

@@ -7,6 +7,12 @@
 #include <iomanip> // put_time
 #include <sstream>
 
+/**
+ * @brief Allow any card to be played on any other card.
+ *
+ * This is for testing BONUS and scoring, etc.
+ *
+ */
 #define CHEATER "CHEAT_YOUR_ASS_OFF"
 
 // static std::function<std::ofstream &(void)> get_logger;
@@ -27,30 +33,31 @@ well as displaying a calendar to show what days are available to be played.
 For now, it will play today.
 */
 
-PlayCards::PlayCards(door::Door &d, DBData &dbd) : door{d}, db{dbd} {
+PlayCards::PlayCards(door::Door &d, DBData &dbd, std::mt19937 &r)
+    : door{d}, db{dbd}, rng{r} {
   get_logger = [this]() -> ofstream & { return door.log(); };
   init_values();
 
   play_day = std::chrono::system_clock::now();
+  normalizeDate(play_day);
+  time_t play_day_t = std::chrono::system_clock::to_time_t(play_day);
+  // check last_played
+  time_t last_played;
 
-  // adjustment
-  time_t time_play_day = std::chrono::system_clock::to_time_t(play_day);
-  /*
-  if (get_logger) {
-    get_logger() << "before: "
-                 << std::put_time(std::localtime(&time_play_day), "%F %R")
-                 << std::endl;
-  };
-  */
-  normalizeDate(time_play_day);
-  play_day = std::chrono::system_clock::from_time_t(time_play_day);
-  /*
-  if (get_logger) {
-    get_logger() << "after: "
-                 << std::put_time(std::localtime(&time_play_day), "%F %R")
-                 << std::endl;
-  };
-  */
+  {
+    std::string last_played_str = dbd.getSetting("last_played", "0");
+    last_played = std::stoi(last_played_str);
+    std::string days_played_str = dbd.getSetting("days_played", "0");
+    days_played = std::stoi(days_played_str);
+  }
+
+  if (last_played != play_day_t) {
+    // Ok, they haven't played today, so:
+    get_logger() << "reset days_played = 0" << std::endl;
+    dbd.setSetting("last_played", std::to_string(play_day_t));
+    dbd.setSetting("days_played", std::to_string(0));
+    days_played = 0;
+  }
 
   /*
    * TODO:  Check the date with the db.  Have they already played up today?  If
@@ -85,9 +92,11 @@ void PlayCards::init_values(void) {
   play_card = 28;
   current_streak = 0;
   best_streak = 0;
-  std::string best;
-  best = db.getSetting("best_streak", "0");
-  best_streak = std::stoi(best);
+  {
+    std::string best;
+    best = db.getSetting("best_streak", "0");
+    best_streak = std::stoi(best);
+  }
   select_card = 23;
   score = 0;
 }
@@ -100,13 +109,35 @@ void PlayCards::bonus(void) {
   door << door::ANSIColor(door::COLOR::YELLOW, door::ATTR::BOLD) << "BONUS";
 }
 
+/**
+ * @brief PLay
+ *
+ * This will display the calendar (if needed), otherwise takes player into
+ * play_cards using now() as play_day.
+ * \sa PlayCards::play_cards()
+ *
+ * @return int
+ */
+int PlayCards::play(void) {
+  hand = 1;
+  // possibly init_values()
+  play_day = std::chrono::system_clock::now();
+  normalizeDate(play_day);
+  return play_cards();
+}
+
+/**
+ * @brief play_cards
+ *
+ * Play cards for the given play_day and hand.
+ *
+ * This should be called by play with the correct #play_day set.
+ * \sa PlayCards::play()
+ *
+ * @return int
+ */
 int PlayCards::play_cards(void) {
   init_values();
-  std::string currentDefault = db.getSetting("DeckColor", "ALL");
-  get_logger() << "DeckColor shows as " << currentDefault << std::endl;
-  deck_color = stringToANSIColor(currentDefault);
-
-  dp = Deck(deck_color);
 
   // Calculate the game size
   int game_width;
@@ -131,6 +162,14 @@ int PlayCards::play_cards(void) {
   off_y += 3; // adjust for tripeaks panel
 
 next_hand:
+  // Make sure we pick the deck color here.  We want it to (possibly) change
+  // between hands.
+  std::string currentDefault = db.getSetting("DeckColor", "ALL");
+  get_logger() << "DeckColor shows as " << currentDefault << std::endl;
+  deck_color = stringToANSIColor(currentDefault);
+
+  dp = Deck(deck_color);
+
   play_card = 28;
   select_card = 23;
   score = 0;
@@ -541,7 +580,8 @@ next_hand:
 void PlayCards::redraw(bool dealing) {
   shared_panel c;
 
-  door << door::reset << door::cls;
+  display_starfield(door, rng);
+  // door << door::reset << door::cls;
   door << *spaceAceTriPeaks;
 
   {
@@ -688,6 +728,12 @@ door::renderFunction PlayCards::statusValue(door::ANSIColor status,
   return rf;
 }
 
+/**
+ * @brief make the score panel
+ * This displays: Name, Score, Time Used, Hands Played.
+ *
+ * @return std::unique_ptr<door::Panel>
+ */
 std::unique_ptr<door::Panel> PlayCards::make_score_panel() {
   const int W = 25;
   std::unique_ptr<door::Panel> p = std::make_unique<door::Panel>(W);

+ 6 - 2
play.h

@@ -12,6 +12,7 @@ class PlayCards {
 private:
   door::Door &door;
   DBData &db;
+  std::mt19937 &rng;
 
   std::unique_ptr<door::Panel> spaceAceTriPeaks;
   std::unique_ptr<door::Panel> score_panel;
@@ -34,6 +35,7 @@ private:
   int best_streak;
   int select_card; // the card the player selects, has state=1
   unsigned long score;
+  int days_played;
 
   Deck dp; // deckPanels
   int off_x, off_y;
@@ -48,11 +50,13 @@ private:
   void redraw(bool dealing);
   void bonus(void);
 
+  int play_cards(void);
+
 public:
-  PlayCards(door::Door &d, DBData &dbd);
+  PlayCards(door::Door &d, DBData &dbd, std::mt19937 &r);
   ~PlayCards();
 
-  int play_cards(void);
+  int play(void);
   void init_values(void);
 
   door::renderFunction statusValue(door::ANSIColor status,