kolibrios/programs/games/21days/pq.h

205 lines
5.7 KiB
C
Raw Permalink Normal View History

/******************************************************************
* 21 days: a game for programmers
* Copyright (C) 2014 Maxim Grishin
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*******************************************************************/
#ifndef H_PQ
#define H_PQ
#define LETTER_RETURN_TO_DAY_21 100001
#define LETTER_WEBMASTER_CHECK_UNNAMEDSTUDIO 100002
#define LETTER_BORING_WORK 100003
#define LETTER_PERSISTENT_AND_PATIENT 100004
#define LETTER_BORING_DEFAULT_PATH 100005
#define LETTER_TEST_OF_KNOWLEDGE 100006
#define LETTER_KNOWLEDGE_QUESTION 100007
#ifdef _KOS32
#include "kos_vector.h"
#define vector vector21
#else
#include <vector>
#include <algorithm> // std::sort
#define printf2 printf
using std::vector;
#endif
enum Letter { LETTER_SHITCODE_1 = 0, LETTER_SHITCODE_2, LETTER_SHITCODE_3,
LETTER_BOTSMANN, LETTER_ASTRA, LETTER_UNNAMEDSTUDIO_1, LETTER_UNNAMEDSTUDIO_2,
LETTER_UNNAMEDSTUDIO_3, LETTER_UNNAMEDSTUDIO_4, LETTER_UNNAMEDSTUDIO_5,
LETTER_ANGRYBOSS_1, LETTER_ANGRYBOSS_2, NO_POPULARITY_HINT, LETTER_FINALPATH_DEF,
LETTER_FINALPATH_STARTUP, LETTER_FINALPATH_WORK, LETTER_FINALPATH_NOMONEY, LETTER_FINALPATH_NOPOPULARITY};
enum EventType { COURSE = 1000, SPECIAL_LETTER, MESSAGE, NEWS, INCREASEPOPULARITY,
CHANGEPATH, CHANGESALARY, CHANGESALARYFIRSTDAY, NOPOPULARITY};
class event {
public:
double time;
EventType type;
int idata;
event() : time(0.0), idata(-1) {}
event(double t,EventType ty, int data = -1) : time(t), type(ty), idata(data) {}
bool operator>(const event a) const {
return this->time > a.time;
}
bool operator<(const event ev) const {
return time < ev.time;
}
};
#ifdef _KOS32
static void exch (event* A, event* B) {
event t = *A;
*A = *B;
*B = t;
}
#endif
static void sort21(vector<event>* v, bool desc = false) {
#ifdef _KOS32
// Sorry for the bubble sort
for (unsigned int i = 0; i < v->size()-1; i++)
for (unsigned int j = 0; j < v->size()-i-1; j++) {
if (desc && (*v)[j] < (*v)[j+1])
exch(&((*v)[j]), &(*v)[j+1]);
else if (!desc && (*v)[j] > (*v)[j+1])
exch(&(*v)[j], &(*v)[j+1]);
}
#else
if (desc)
std::sort(v->begin(), v->end(), std::greater<event>());
else
std::sort(v->begin(), v->end());
#endif
}
class PQ3 {
private:
vector<event> v;
bool sorted;
public:
void sort() {
sort21(&v, true);
sorted = true;
}
PQ3() : sorted(false) {}
int n() {
return v.size();
}
bool empty() const {
return v.empty();
}
void insert(event item) {
v.push_back(item);
sorted = false;
}
event delMin() {
if (empty())
return event();
if (!sorted)
sort();
event e = v.back();
v.pop_back();
return e;
}
event* getMin() {
if (empty())
return 0;
if (!sorted)
sort();
return &v.back();
}
event* get(int i) {
if (empty() || i >= (int)v.size())
return 0;
if (!sorted)
sort();
return &v[i];
}
bool hasCourse(int c) {
for(unsigned int i = 0; i < v.size(); i++)
if (v[i].type == COURSE && v[i].idata == c)
return true;
return false;
}
bool hasCourses() {
for(unsigned int i = 0; i < v.size(); i++)
if (v[i].type == COURSE)
return true;
return false;
}
bool containsType(int et) {
for (int i = v.size()-1; i >= 0; i--)
if (v[i].type == et)
return true;
return false;
}
bool containsType(int et, int data) {
for (int i = v.size()-1; i >= 0; i--)
if (v[i].type == et && v[i].idata == data)
return true;
return false;
}
};
class Undo2 {
private:
vector<event> v;
public:
Undo2() {}
int n() {
return v.size();
}
bool empty() const {
return v.empty();
}
void insert(event item) {
if (item.type == MESSAGE)
return;
v.push_back(item);
}
event delMax() {
if (empty())
return event();
event e = v.back();
v.pop_back();
return e;
}
event getMax() {
if (empty())
return event();
return v.back();
}
event* get(int i) {
if (empty() || i >= (int)v.size())
return 0;
return &v[i];
}
void prepareForUndo() {
sort21(&v, false);
}
bool containsTypeBefore(EventType et, int data, long double t) {
for (unsigned int i = 0; i < v.size(); i++)
if (v[i].type == et && v[i].idata == data && v[i].time <= t)
return true;
return false;
}
};
#endif