uni

University stuff
git clone git://git.margiolis.net/uni.git
Log | Files | Refs | README | LICENSE

Score.cc (2971B)


      1 #include "Score.hpp"
      2 
      3 Score::Score(const char *scorefile, const char *name)
      4 {
      5 	fpath = std::string(scorefile);
      6 
      7 	sf.exceptions(std::fstream::badbit);
      8 	sf.open(fpath, std::fstream::in | std::fstream::binary);
      9 	if (!sf.is_open())
     10 		throw std::runtime_error(fpath + ": cannot open file");
     11 	for (int i = 0; i < hiscores.size(); i++) {
     12 		sf.read((char *)&hiscores[i].name, sizeof(hiscores[i].name));
     13 		sf.read((char *)&hiscores[i].score, sizeof(hiscores[i].score));
     14 	}
     15 	sf.close();
     16 
     17 	/* Initialize the current name and score. */
     18 	(void)strncpy(curname, name, sizeof(curname));
     19 	curscore = 0;
     20 }
     21 
     22 /* 
     23  * I'm not sure if this stupid or not...
     24  */
     25 Score::~Score()
     26 {
     27 	add_new_hiscore();
     28 
     29 	sf.open(fpath, std::fstream::out | std::fstream::binary);
     30 	if (sf.is_open()) {
     31 		for (int i = 0; i < hiscores.size(); i++) {
     32 			sf.write((char *)&hiscores[i].name, 
     33 			    sizeof(hiscores[i].name));
     34 			sf.write((char *)&hiscores[i].score,
     35 			    sizeof(hiscores[i].score));
     36 		}
     37 		sf.close();
     38 	}
     39 }
     40 
     41 /*
     42  * The following 2 overloads return a reference to `this`, so that
     43  * we can chain arguments together.
     44  *
     45  * Take the following chain as an example:
     46  *	`*score << "string" << 100`
     47  *
     48  * First, `*score << "string"` will call the overload which
     49  * takes a `const char *` , and will return a reference to `this`.
     50  *
     51  * After the first overload has returned, `*score << "string"` will
     52  * be replaced with just `*score` and the initial overload will 
     53  * look like this:
     54  *	`*score << 100`
     55  *
     56  * Now, the overload getting a `const int` argument will get called.
     57  *
     58  * Technically, this chain can work no matter the order or number
     59  * of the arguments.
     60  */
     61 Score&
     62 Score::operator<< (const char *name)
     63 {
     64 	(void)strncpy(curname, name, sizeof(curname));
     65 	return *this;
     66 }
     67 
     68 Score&
     69 Score::operator<< (const int score)
     70 {
     71 	curscore = score;
     72 	return *this;
     73 }
     74 
     75 /* 
     76  * Convert the hiscores array to something the `popup` method in 
     77  * `Engine` can print.
     78  */
     79 std::vector<std::string>
     80 Score::scores_strfmt() const
     81 {
     82 	std::vector<std::string> v;
     83 
     84 	for (int i = 0; i < hiscores.size(); i++)
     85 		v.push_back(std::string(hiscores[i].name) + ": " +
     86 		    std::to_string(hiscores[i].score));
     87 	v.push_back("Press any key to continue");
     88 
     89 	return v;
     90 }
     91 
     92 const char *
     93 Score::get_curname() const
     94 {
     95 	return curname;
     96 }
     97 
     98 int
     99 Score::get_curscore() const
    100 {
    101 	return curscore;
    102 }
    103 
    104 void
    105 Score::add_new_hiscore()
    106 {
    107 	auto cmp = [](const HighScore& a, const HighScore& b) -> bool {
    108 		return a.score > b.score;
    109 	};
    110 
    111 	/* 
    112 	 * Add our new score in the array in case it's higher
    113 	 * than any of the existing entries. The array is sorted
    114 	 * in descending order, so we'll search it backwards --
    115 	 * this will have the effect of replacing the lower scores
    116 	 * first.
    117 	 */
    118 	for (int i = hiscores.size() - 1; i >= 0; i--) {
    119 		if (curscore > hiscores[i].score) {
    120 			hiscores[i].score = curscore;
    121 			(void)strncpy(hiscores[i].name, curname, 
    122 			    sizeof(hiscores[i].name));
    123 			break;
    124 		}
    125 	}
    126 	std::sort(hiscores.begin(), hiscores.end(), cmp);
    127 }