12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595 |
- #include "deck.h"
- #include "space.h"
- #include "utils.h"
- #include "version.h"
- #include <algorithm>
- #include <iomanip> // setw
- #include <map>
- #include <sstream>
- Deck::Deck(door::ANSIColor backcolor) : card_back_color{backcolor} {
- for (int i = 0; i < 52; ++i) {
- cards.push_back(cardOf(i));
- }
-
- for (int i = 0; i < 5; ++i) {
- backs.push_back(backOf(i));
- }
- mark.push_back(markOf(0));
- mark.push_back(markOf(1));
- }
- Deck::~Deck() {}
- Deck::Deck(Deck &&ref) {
- card_back_color = ref.card_back_color;
-
- cards = ref.cards;
- ref.cards.clear();
-
- backs = ref.backs;
- ref.backs.clear();
-
- mark = ref.mark;
- ref.mark.clear();
-
- };
- Deck &Deck::operator=(Deck &&ref) {
- card_back_color = ref.card_back_color;
-
- cards = ref.cards;
- ref.cards.clear();
-
- backs = ref.backs;
- ref.backs.clear();
-
- mark = ref.mark;
- ref.mark.clear();
-
- return *this;
- }
- int Deck::getDeck(int c) { return c / 52; }
- int Deck::getSuit(int c) { return (c % 52) / 13; }
- int Deck::getRank(int c) { return (c % 52) % 13; }
- char Deck::rankSymbol(int c) {
- const char symbols[] = "A23456789TJQK";
- return symbols[c];
- }
- std::string Deck::suitSymbol(int c) {
-
- if (door::unicode) {
- switch (c) {
- case 0:
- return std::string("\u2665");
- case 1:
- return std::string("\u2666");
- case 2:
- return std::string("\u2663");
- case 3:
- return std::string("\u2660");
- }
- } else {
- if (door::full_cp437) {
- switch (c) {
- case 0:
- return std::string(1, '\x03');
- case 1:
- return std::string(1, '\x04');
- case 2:
- return std::string(1, '\x05');
- case 3:
- return std::string(1, '\x06');
- }
- } else {
-
- switch (c) {
- case 0:
- return std::string(1, '*');
- case 1:
- return std::string(1, '^');
- case 2:
- return std::string(1, '%');
- case 3:
- return std::string(1, '$');
- }
- }
- }
- return std::string("!", 1);
- }
- shared_panel Deck::cardOf(int c) {
- int suit = getSuit(c);
- int rank = getRank(c);
- bool is_red = (suit < 2);
- door::ANSIColor color;
- if (is_red) {
- color = door::ANSIColor(door::COLOR::RED, door::COLOR::WHITE);
- } else {
- color = door::ANSIColor(door::COLOR::BLACK, door::COLOR::WHITE);
- }
- shared_panel p = std::make_shared<door::Panel>(0, 0, 5);
-
-
- char r = rankSymbol(rank);
- std::string s = suitSymbol(suit);
-
- std::ostringstream oss;
- oss << r << s << " ";
- std::string str = oss.str();
- p->addLine(std::make_unique<door::Line>(str, 5, color));
- oss.str(std::string());
- oss.clear();
- if (card_height == 5)
- p->addLine(std::make_unique<door::Line>(" ", 5, color));
- oss << " " << s << " ";
- str = oss.str();
- p->addLine(std::make_unique<door::Line>(str, 5, color));
- oss.str(std::string());
- oss.clear();
- if (card_height == 5)
- p->addLine(std::make_unique<door::Line>(" ", 5, color));
- oss << " " << s << r;
- str = oss.str();
- p->addLine(std::make_unique<door::Line>(str, 5, color));
- oss.str(std::string());
- oss.clear();
- return p;
- }
- std::string Deck::backSymbol(int level) {
- std::string c;
- if (level == 0) {
- c = ' ';
- return c;
- }
- if (door::unicode) {
- switch (level) {
- case 1:
- c = "\u2591";
- break;
- case 2:
- c = "\u2592";
- break;
- case 3:
- c = "\u2593";
- break;
- case 4:
- c = "\u2588";
- break;
- }
- } else {
- switch (level) {
- case 1:
- c = "\xb0";
- break;
- case 2:
- c = "\xb1";
- break;
- case 3:
- c = "\xb2";
- break;
- case 4:
- c = "\xdb";
- break;
- }
- }
- return c;
- }
- void Deck::setBack(door::ANSIColor backColor) {
- for (auto &back : backs) {
- back->lineSetBack(backColor);
- }
- card_back_color = backColor;
- }
- shared_panel Deck::backOf(int level) {
-
-
-
- shared_panel p = std::make_shared<door::Panel>(0, 0, 5);
- std::string c = backSymbol(level);
- std::string l = c + c + c + c + c;
- for (int x = 0; x < card_height; ++x) {
- p->addLine(std::make_unique<door::Line>(l, 5, card_back_color));
- };
-
-
- return p;
- }
- shared_panel Deck::markOf(int c) {
- shared_panel p = std::make_shared<door::Panel>(1);
- door::ANSIColor color = door::ANSIColor(
- door::COLOR::BLUE, door::COLOR::WHITE);
- std::string m;
- if (c == 0)
- m = " ";
- else {
- if (door::unicode) {
- m = "\u25a0";
- } else {
- m = "\xfe";
- }
- }
- p->addLine(std::make_unique<door::Line>(m, 1, color));
- return p;
- }
- shared_panel Deck::card(int c) { return cards[c]; }
- shared_panel Deck::back(int level) { return backs[level]; }
- const std::array<std::pair<int, int>, 18> Deck::blocks = {
- make_pair(3, 4), make_pair(5, 6), make_pair(7, 8),
- make_pair(9, 10), make_pair(10, 11), make_pair(12, 13),
- make_pair(13, 14), make_pair(15, 16), make_pair(16, 17),
- make_pair(18, 19),
- make_pair(19, 20), make_pair(20, 21), make_pair(21, 22),
- make_pair(22, 23), make_pair(23, 24), make_pair(24, 25),
- make_pair(25, 26), make_pair(26, 27)
- };
- std::vector<int> Deck::unblocks(int card) {
- std::vector<int> result;
- for (size_t i = 0; i < blocks.size(); ++i) {
- if ((blocks.at(i).first == card) || (blocks.at(i).second == card)) {
- result.push_back(i);
- }
- }
- return result;
- }
- bool Deck::canPlay(int card1, int card2) {
- int rank1, rank2;
- rank1 = getRank(card1);
- rank2 = getRank(card2);
-
- if ((rank1 + 1) % 13 == rank2)
- return true;
- if (rank1 == 0) {
- rank1 += 13;
- }
- if (rank1 - 1 == rank2)
- return true;
- return false;
- }
- shared_panel Deck::marker(int c) { return mark[c]; }
- void Deck::removeCard(door::Door &door, int c, int off_x, int off_y, bool left,
- bool right) {
- int cx, cy, level;
- cardPosLevel(c, cx, cy, level);
- if (level > 1)
- --level;
- std::string cstr = backSymbol(level);
- door::Goto g(cx + off_x, cy + off_y);
- door << g << card_back_color;
- if (left)
- door << cstr;
- else
- door << " ";
- door << " ";
- if (right)
- door << cstr;
- else
- door << " ";
- g.set(cx + off_x, cy + off_y + 1);
- door << g << " ";
- g.set(cx + off_x, cy + off_y + 2);
- door << g << " ";
- }
- #ifdef NO
- void cardgo(int pos, int space, int h, int &x, int &y, int &level) {
-
- if (pos == 28) {
-
- cardgo(23, x, y, level);
- y += h + 1;
- --level;
- return;
- } else {
- if (pos == 29) {
-
- cardgo(22, x, y, level);
- y += h + 1;
- --level;
- return;
- }
- }
- const int CARD_WIDTH = 5;
- int HALF_WIDTH = 3;
-
-
-
- HALF_WIDTH += space / 2;
-
- int between = CARD_WIDTH + space;
- if (pos < 3) {
-
- level = 1;
- y = (level - 1) * (h - 1) + 1;
- x = pos * (between * 3) + between + HALF_WIDTH + space;
- return;
- } else {
- pos -= 3;
- }
- if (pos < 6) {
- level = 2;
- y = (level - 1) * (h - 1) + 1;
- int group = (pos) / 2;
- x = pos * between + (group * between) + CARD_WIDTH + space * 2;
- return;
- } else {
- pos -= 6;
- }
- if (pos < 9) {
- level = 3;
- y = (level - 1) * (h - 1) + 1;
- x = pos * between + HALF_WIDTH + space;
- return;
- } else {
- pos -= 9;
- }
- if (pos < 10) {
- level = 4;
- y = (level - 1) * (h - 1) + 1;
- x = (pos)*between + space;
- return;
- } else {
-
- y = -1;
- x = -1;
- level = -1;
- }
- }
- #endif
- void cardPos(int pos, int &x, int &y) {
- const int space = 3;
- const int height = 3;
-
- if (pos == 28) {
- cardPos(23, x, y);
- y += height + 1;
- return;
- } else {
- if (pos == 29) {
- cardPos(22, x, y);
- y += height + 1;
- return;
- }
- }
- const int CARD_WIDTH = 5;
- int HALF_WIDTH = 3;
- HALF_WIDTH += space / 2;
- int between = CARD_WIDTH + space;
- int level;
- if (pos < 3) {
-
- level = 1;
- y = (level - 1) * (height - 1) + 1;
- x = pos * (between * 3) + between + HALF_WIDTH + space;
- return;
- } else {
- pos -= 3;
- }
- if (pos < 6) {
- level = 2;
- y = (level - 1) * (height - 1) + 1;
- int group = (pos) / 2;
- x = pos * between + (group * between) + CARD_WIDTH + space * 2;
- return;
- } else {
- pos -= 6;
- }
- if (pos < 9) {
- level = 3;
- y = (level - 1) * (height - 1) + 1;
- x = pos * between + HALF_WIDTH + space;
- return;
- } else {
- pos -= 9;
- }
- if (pos < 10) {
- level = 4;
- y = (level - 1) * (height - 1) + 1;
- x = (pos)*between + space;
- return;
- } else {
-
- y = -1;
- x = -1;
- level = -1;
- }
- }
- void cardLevel(int pos, int &level) {
-
-
- if (pos == 28) {
- cardLevel(23, level);
- --level;
- return;
- } else {
- if (pos == 29) {
- cardLevel(22, level);
- --level;
- return;
- }
- }
-
- if (pos < 3) {
-
- level = 1;
- return;
- } else {
- pos -= 3;
- }
- if (pos < 6) {
- level = 2;
- return;
- } else {
- pos -= 6;
- }
- if (pos < 9) {
- level = 3;
- return;
- } else {
- pos -= 9;
- }
- if (pos < 10) {
- level = 4;
- return;
- } else {
-
- level = -1;
- }
- }
- void cardPosLevel(int pos, int &x, int &y, int &level) {
- const int space = 3;
- const int height = 3;
-
- if (pos == 28) {
- cardPosLevel(23, x, y, level);
- y += height + 1;
- --level;
- return;
- } else {
- if (pos == 29) {
- cardPosLevel(22, x, y, level);
- y += height + 1;
- --level;
- return;
- }
- }
- const int CARD_WIDTH = 5;
- int HALF_WIDTH = 3;
- HALF_WIDTH += space / 2;
- int between = CARD_WIDTH + space;
- if (pos < 3) {
-
- level = 1;
- y = (level - 1) * (height - 1) + 1;
- x = pos * (between * 3) + between + HALF_WIDTH + space;
- return;
- } else {
- pos -= 3;
- }
- if (pos < 6) {
- level = 2;
- y = (level - 1) * (height - 1) + 1;
- int group = (pos) / 2;
- x = pos * between + (group * between) + CARD_WIDTH + space * 2;
- return;
- } else {
- pos -= 6;
- }
- if (pos < 9) {
- level = 3;
- y = (level - 1) * (height - 1) + 1;
- x = pos * between + HALF_WIDTH + space;
- return;
- } else {
- pos -= 9;
- }
- if (pos < 10) {
- level = 4;
- y = (level - 1) * (height - 1) + 1;
- x = (pos)*between + space;
- return;
- } else {
-
- y = -1;
- x = -1;
- level = -1;
- }
- }
- cards shuffleCards(std::seed_seq &seed, int decks) {
- std::mt19937 gen;
-
- int size = decks * 52;
- std::vector<int> deck;
- deck.reserve(size);
- for (int x = 0; x < size; ++x) {
- deck.push_back(x);
- }
-
- gen.seed(seed);
- std::shuffle(deck.begin(), deck.end(), gen);
- return deck;
- }
- cards makeCardStates(int decks) {
-
- std::vector<int> states;
- states.assign(decks * 52, 0);
- return states;
- }
- int findNextActiveCard(bool left, const cards &states, int current) {
- int cx, cy;
- int current_x;
- cardPos(current, cx, cy);
- current_x = cx;
- int x;
- int pos = -1;
- int pos_x;
- int max_pos = -1;
- int max_x = -1;
- int min_pos = -1;
- int min_x = 100;
- if (left)
- pos_x = 0;
- else
- pos_x = 100;
- for (x = 0; x < 28; x++) {
- if (states.at(x) == 1) {
-
- if (x == current)
- continue;
- cardPos(x, cx, cy);
-
- if (cx < min_x) {
- min_pos = x;
- min_x = cx;
- }
- if (cx > max_x) {
- max_pos = x;
- max_x = cx;
- }
- if (left) {
- if ((cx < current_x) and (cx > pos_x)) {
- pos_x = cx;
- pos = x;
- }
- } else {
- if ((cx > current_x) and (cx < pos_x)) {
- pos_x = cx;
- pos = x;
- }
- }
- }
- }
- if (pos == -1) {
-
- if (left) {
-
- pos = max_pos;
- } else {
-
- pos = min_pos;
- }
- }
- return pos;
- }
- int findClosestActiveCard(const cards &states, int current) {
- int cx, cy;
- int current_x;
- cardPos(current, cx, cy);
- current_x = cx;
- int x;
- int pos = -1;
- int pos_x = -1;
- for (x = 0; x < 28; x++) {
- if (states.at(x) == 1) {
-
- if (x == current)
- continue;
- cardPos(x, cx, cy);
- if (pos == -1) {
- pos = x;
- pos_x = cx;
- } else {
- if (abs(current_x - cx) < abs(current_x - pos_x)) {
- pos = x;
- pos_x = cx;
- }
- }
- }
- }
- return pos;
- }
- vector<std::string> deck_colors = {std::string("All"), std::string("Blue"),
- std::string("Brown"), std::string("Cyan"),
- std::string("Green"), std::string("Magenta"),
- std::string("Red"), std::string("White")};
- door::renderFunction makeColorRender(door::ANSIColor c1, door::ANSIColor c2,
- door::ANSIColor c3) {
- door::renderFunction render = [c1, c2,
- c3](const std::string &txt) -> door::Render {
- door::Render r(txt);
- bool option = true;
- door::ColorOutput co;
-
- door::ANSIColor textColor = c3;
-
- {
- std::string found;
- for (auto &dc : deck_colors) {
- if (txt.find(dc) != string::npos) {
- found = dc;
- break;
- }
- }
- if (!found.empty()) {
- if (found == "All") {
-
- textColor.setFg(door::COLOR::WHITE);
- } else {
- door::ANSIColor c = stringToANSIColor(found);
- textColor.setFg(c.getFg());
- }
- }
- }
- co.pos = 0;
- co.len = 0;
- co.c = c1;
- int tpos = 0;
- for (char const &c : txt) {
- if (option) {
- if (c == '[' or c == ']') {
- if (co.c != c1)
- if (co.len != 0) {
- r.outputs.push_back(co);
- co.reset();
- co.pos = tpos;
- }
- co.c = c1;
- if (c == ']')
- option = false;
- } else {
- if (co.c != c2)
- if (co.len != 0) {
- r.outputs.push_back(co);
- co.reset();
- co.pos = tpos;
- }
- co.c = c2;
- }
- } else {
- if (co.c != textColor)
- if (co.len != 0) {
- r.outputs.push_back(co);
- co.reset();
- co.pos = tpos;
- }
- co.c = textColor;
- }
- co.len++;
- tpos++;
- }
- if (co.len != 0) {
- r.outputs.push_back(co);
- }
- return r;
- };
- return render;
- }
- door::renderFunction makeColorsRender(door::ANSIColor c1, door::ANSIColor c2,
- door::ANSIColor c3) {
- door::renderFunction render = [c1, c2,
- c3](const std::string &txt) -> door::Render {
- door::Render r(txt);
-
- std::vector<std::pair<int, int>> words = find_words(txt);
- auto words_it = words.begin();
-
- bool option = true;
-
- door::ANSIColor textColor = c3;
- door::ANSIColor normal = c3;
- normal.setFg(door::COLOR::WHITE);
- bool color_word = false;
- std::pair<int, int> word_pair;
- #ifdef DEBUG_OUTPUT
- if (get_logger) {
- get_logger() << "makeColorsRender() " << txt << std::endl;
- for (auto word : words) {
- get_logger() << word.first << "," << word.second << std::endl;
- }
- }
- #endif
- int tpos = 0;
- for (char const &c : txt) {
- if (option) {
- if (c == '[' or c == ']') {
- r.append(c1);
- if (c == ']')
- option = false;
- } else {
- r.append(c2);
- }
- } else {
-
- if (color_word) {
-
- if (tpos < word_pair.first + word_pair.second)
- r.append(textColor);
- else {
- color_word = false;
- r.append(normal);
- }
- } else {
-
- while ((words_it != words.end()) and (words_it->first < tpos)) {
- #ifdef DEBUG_OUTPUT
- if (get_logger) {
- get_logger() << "tpos " << tpos << "(next words_it)" << std::endl;
- }
- #endif
- ++words_it;
- }
- if (words_it == words.end()) {
-
- r.append(normal);
- } else {
- if (words_it->first == tpos) {
-
- std::string color = txt.substr(words_it->first, words_it->second);
- bool found = false;
- if (!iequals(color, std::string("ALL")))
- for (auto &dc : deck_colors) {
- if (color.find(dc) != string::npos) {
- found = true;
- break;
- }
- }
- #ifdef DEBUG_OUTPUT
- if (get_logger) {
- get_logger() << "word: [" << color << "] : deck_colors "
- << found << " pos: " << tpos
- << " word_start: " << words_it->first << std::endl;
- }
- #endif
- if (found) {
- door::ANSIColor c = stringToANSIColor(color);
- textColor.setFg(c.getFg());
-
- if (textColor.getFg() == textColor.getBg()) {
-
- textColor.setBg(door::COLOR::WHITE);
- }
- word_pair = *words_it;
- r.append(textColor);
- color_word = true;
- } else {
- r.append(normal);
- }
- } else {
- r.append(normal);
- }
- }
- }
- }
- ++tpos;
- }
- return r;
- };
- return render;
- }
- door::ANSIColor stringToANSIColor(std::string colorCode) {
- std::map<std::string, door::ANSIColor> codeMap = {
- {std::string("BLUE"), door::ANSIColor(door::COLOR::BLUE)},
- {std::string("BROWN"), door::ANSIColor(door::COLOR::BROWN)},
- {std::string("RED"), door::ANSIColor(door::COLOR::RED)},
- {std::string("CYAN"), door::ANSIColor(door::COLOR::CYAN)},
- {std::string("GREEN"), door::ANSIColor(door::COLOR::GREEN)},
- {std::string("MAGENTA"), door::ANSIColor(door::COLOR::MAGENTA)},
- {std::string("WHITE"), door::ANSIColor(door::COLOR::WHITE)}};
- std::string code = colorCode;
- string_toupper(code);
- auto iter = codeMap.find(code);
- if (iter != codeMap.end()) {
- return iter->second;
- }
-
-
- std::random_device dev;
- std::mt19937_64 rng(dev());
- std::uniform_int_distribution<size_t> idDist(0, codeMap.size() - 1);
- iter = codeMap.begin();
- std::advance(iter, idDist(rng));
- return iter->second;
-
- }
- std::string stringFromColorOptions(int opt) { return deck_colors[opt]; }
- door::Panel make_about(void) {
- const int W = 60;
- door::Panel about(W);
- about.setStyle(door::BorderStyle::SINGLE_DOUBLE);
- about.setColor(door::ANSIColor(door::COLOR::YELLOW, door::COLOR::BLUE,
- door::ATTR::BOLD));
- about.addLine(std::make_unique<door::Line>(
- "About This Door", W,
- door::ANSIColor(door::COLOR::CYAN, door::COLOR::BLUE, door::ATTR::BOLD)));
- std::unique_ptr<door::Line> spacer = about.spacer_line(true);
- about.addLine(std::move(spacer));
-
- door::ANSIColor c_color =
- door::ANSIColor(door::COLOR::WHITE, door::COLOR::BLUE, door::ATTR::BOLD);
- about.addLine(
- std::make_unique<door::Line>(SPACEACE " v" SPACEACE_VERSION, W, c_color));
- std::string copyright = SPACEACE_COPYRIGHT;
- if (door::unicode) {
- replace(copyright, "(C)", "\u00a9");
- }
- about.addLine(std::make_unique<door::Line>(copyright, W, c_color));
- about.addLine(std::make_unique<door::Line>("", W));
- about.addLine(
- std::make_unique<door::Line>("This door was written by Bugz.", W));
- about.addLine(std::make_unique<door::Line>("", W));
- about.addLine(std::make_unique<door::Line>(
- "It is written in door++ using c++, understands CP437 and", W));
- about.addLine(std::make_unique<door::Line>(
- "unicode, adapts to screen sizes, and runs on Linux.", W));
- return about;
- }
- door::Panel make_help(void) {
- const int W = 60;
- door::Panel help(W);
- help.setStyle(door::BorderStyle::DOUBLE_SINGLE);
- help.setColor(door::ANSIColor(door::COLOR::YELLOW, door::COLOR::BLUE,
- door::ATTR::BOLD));
- help.addLine(std::make_unique<door::Line>(
- "Help", W,
- door::ANSIColor(door::COLOR::CYAN, door::COLOR::BLUE, door::ATTR::BOLD)));
- std::unique_ptr<door::Line> spacer = help.spacer_line(false);
- help.addLine(std::move(spacer));
-
-
- door::ANSIColor c_color =
- door::ANSIColor(door::COLOR::WHITE, door::COLOR::BLUE, door::ATTR::BOLD);
- help.addLine(
- std::make_unique<door::Line>(SPACEACE " v" SPACEACE_VERSION, W, c_color));
- std::string copyright = SPACEACE_COPYRIGHT;
- if (door::unicode) {
- replace(copyright, "(C)", "\u00a9");
- }
- help.addLine(std::make_unique<door::Line>(copyright, W, c_color));
- help.addLine(std::make_unique<door::Line>("", W));
- help.addLine(std::make_unique<door::Line>(
- "Use Left/Right arrow keys, or 4/6 keys to move marker.", W));
- help.addLine(std::make_unique<door::Line>(
- "The marker wraps around the sides of the screen.", W));
- help.addLine(std::make_unique<door::Line>("", W));
- help.addLine(
- std::make_unique<door::Line>("Select card to play with Space or 5.", W));
- help.addLine(std::make_unique<door::Line>(
- "A card can play if it is higher or lower in rank by 1.", W));
- help.addLine(std::make_unique<door::Line>("", W));
- help.addLine(std::make_unique<door::Line>("Enter draws another card.", W));
- help.addLine(std::make_unique<door::Line>("", W));
- help.addLine(std::make_unique<door::Line>(
- "Example: A Jack could select either a Ten or a Queen.", W));
- help.addLine(std::make_unique<door::Line>(
- "Example: A King could select either an Ace or a Queen.", W));
- help.addLine(std::make_unique<door::Line>("", W));
- help.addLine(std::make_unique<door::Line>(
- "The more cards in your streak, the more points you earn.", W));
- return help;
- }
- void display_starfield(door::Door &door, std::mt19937 &rng) {
- door << door::reset << door::cls;
- int mx = door.width;
- int my = door.height;
-
- const char *stars[2];
- stars[0] = ".";
- if (door::unicode) {
- stars[1] = "\u2219";
- } else {
- stars[1] = "\xf9";
- };
- struct star_pos {
- int x;
- int y;
-
- bool operator<(const star_pos rhs) const {
- if (rhs.y > y)
- return true;
- if (rhs.y == y) {
- if (rhs.x > x)
- return true;
- return false;
- }
- return false;
- }
- };
- {
-
- std::uniform_int_distribution<int> uni_x(1, mx);
- std::uniform_int_distribution<int> uni_y(1, my);
- door::ANSIColor white(door::COLOR::WHITE);
- door::ANSIColor dark(door::COLOR::BLACK, door::ATTR::BRIGHT);
-
- int MAX_STARS = ((mx * my) / 40);
-
-
- std::set<star_pos> sky;
- for (int i = 0; i < MAX_STARS; i++) {
- star_pos pos;
- bool valid;
- do {
- pos.x = uni_x(rng);
- pos.y = uni_y(rng);
- auto ret = sky.insert(pos);
-
- valid = ret.second;
- } while (!valid);
- }
- int i = 0;
- star_pos last_pos;
- for (auto &pos : sky) {
- bool use_goto = true;
- if (i != 0) {
-
- if (pos.y == last_pos.y) {
-
- int dx = pos.x - last_pos.x;
- if (dx == 0) {
- use_goto = false;
- } else {
- if (dx < 5) {
- door << std::string(dx, ' ');
- use_goto = false;
- } else {
-
- door << "\x1b[" << dx << "C";
- use_goto = false;
- }
- }
- }
- }
- if (use_goto) {
- door::Goto star_at(pos.x, pos.y);
- door << star_at;
- }
- if (i % 5 < 2)
- door << dark;
- else
- door << white;
- if (i % 2 == 0)
- door << stars[0];
- else
- door << stars[1];
- ++i;
- last_pos = pos;
- last_pos.x++;
- }
- }
- }
- void display_space_ace(door::Door &door) {
- int mx = door.width;
- int my = door.height;
-
- int sa_x = (mx - 72) / 2;
- int sa_y = (my - 6) / 2;
-
- for (const auto s : space) {
- door::Goto sa_at(sa_x, sa_y);
- door << sa_at;
- if (door::unicode) {
- std::string unicode;
- door::cp437toUnicode(s, unicode);
- door << unicode;
- } else
- door << s;
- sa_y++;
- }
-
- door.sleep_key(5);
- }
- void display_starfield_space_ace(door::Door &door, std::mt19937 &rng) {
-
-
- display_starfield(door, rng);
- display_space_ace(door);
- door << door::reset;
- }
- door::Panel make_timeout(int mx, int my) {
- door::ANSIColor yellowred =
- door::ANSIColor(door::COLOR::YELLOW, door::COLOR::RED, door::ATTR::BOLD);
- std::string line_text("Sorry, you've been inactive for too long.");
- int msgWidth = line_text.length() + (2 * 3);
- door::Panel timeout((mx - (msgWidth)) / 2, my / 2 + 4, msgWidth);
-
- timeout.setStyle(door::BorderStyle::DOUBLE);
- timeout.setColor(yellowred);
- door::Line base(line_text);
- base.setColor(yellowred);
- std::string pad1(3, ' ');
-
- base.setPadding(pad1, yellowred);
-
- std::unique_ptr<door::Line> stuff = std::make_unique<door::Line>(base);
- timeout.addLine(std::make_unique<door::Line>(base));
- return timeout;
- }
- door::Panel make_notime(int mx, int my) {
- door::ANSIColor yellowred =
- door::ANSIColor(door::COLOR::YELLOW, door::COLOR::RED, door::ATTR::BOLD);
- std::string line_text("Sorry, you've used up all your time for today.");
- int msgWidth = line_text.length() + (2 * 3);
- door::Panel timeout((mx - (msgWidth)) / 2, my / 2 + 4, msgWidth);
- timeout.setStyle(door::BorderStyle::DOUBLE);
- timeout.setColor(yellowred);
- door::Line base(line_text);
- base.setColor(yellowred);
- std::string pad1(3, ' ');
-
- base.setPadding(pad1, yellowred);
- std::unique_ptr<door::Line> stuff = std::make_unique<door::Line>(base);
- timeout.addLine(std::make_unique<door::Line>(base));
- return timeout;
- }
- door::Menu make_main_menu(void) {
- door::Menu m(5, 5, 25);
- door::Line mtitle(SPACEACE " Main Menu");
- door::ANSIColor border_color(door::COLOR::CYAN, door::COLOR::BLUE);
- door::ANSIColor title_color(door::COLOR::CYAN, door::COLOR::BLUE,
- door::ATTR::BOLD);
- m.setColor(border_color);
- mtitle.setColor(title_color);
- mtitle.setPadding(" ", title_color);
- m.setTitle(std::make_unique<door::Line>(mtitle), 1);
-
- m.setRender(true, door::Menu::makeRender(
- door::ANSIColor(door::COLOR::CYAN, door::ATTR::BOLD),
- door::ANSIColor(door::COLOR::BLUE, door::ATTR::BOLD),
- door::ANSIColor(door::COLOR::CYAN, door::ATTR::BOLD),
- door::ANSIColor(door::COLOR::BLUE, door::ATTR::BOLD)));
-
- m.setRender(false, door::Menu::makeRender(
- door::ANSIColor(door::COLOR::YELLOW, door::COLOR::BLUE,
- door::ATTR::BOLD),
- door::ANSIColor(door::COLOR::WHITE, door::COLOR::BLUE,
- door::ATTR::BOLD),
- door::ANSIColor(door::COLOR::YELLOW, door::COLOR::BLUE,
- door::ATTR::BOLD),
- door::ANSIColor(door::COLOR::CYAN, door::COLOR::BLUE,
- door::ATTR::BOLD)));
- m.addSelection('P', "Play Cards");
- m.addSelection('S', "View Scores");
- m.addSelection('C', "Configure");
- m.addSelection('H', "Help");
- m.addSelection('A', "About this game");
- m.addSelection('Q', "Quit");
- return m;
- }
- door::Menu make_config_menu(void) {
- door::Menu m(5, 5, 31);
- door::Line mtitle(SPACEACE " Configuration Menu");
- door::ANSIColor border_color(door::COLOR::CYAN, door::COLOR::BLUE);
- door::ANSIColor title_color(door::COLOR::CYAN, door::COLOR::BLUE,
- door::ATTR::BOLD);
- m.setColor(border_color);
- mtitle.setColor(title_color);
- mtitle.setPadding(" ", title_color);
- m.setTitle(std::make_unique<door::Line>(mtitle), 1);
-
- m.setRender(true, door::Menu::makeRender(
- door::ANSIColor(door::COLOR::CYAN, door::ATTR::BOLD),
- door::ANSIColor(door::COLOR::BLUE, door::ATTR::BOLD),
- door::ANSIColor(door::COLOR::CYAN, door::ATTR::BOLD),
- door::ANSIColor(door::COLOR::BLUE, door::ATTR::BOLD)));
-
- m.setRender(false, door::Menu::makeRender(
- door::ANSIColor(door::COLOR::YELLOW, door::COLOR::BLUE,
- door::ATTR::BOLD),
- door::ANSIColor(door::COLOR::WHITE, door::COLOR::BLUE,
- door::ATTR::BOLD),
- door::ANSIColor(door::COLOR::YELLOW, door::COLOR::BLUE,
- door::ATTR::BOLD),
- door::ANSIColor(door::COLOR::CYAN, door::COLOR::BLUE,
- door::ATTR::BOLD)));
- m.addSelection('D', "Deck Colors");
- m.addSelection('V', "View Settings");
- m.addSelection('Q', "Quit");
- return m;
- }
- door::Menu make_deck_menu(void) {
- door::Menu m(5, 5, 31);
- door::Line mtitle(SPACEACE " Deck Menu");
- door::ANSIColor border_color(door::COLOR::CYAN, door::COLOR::BLUE);
- door::ANSIColor title_color(door::COLOR::CYAN, door::COLOR::BLUE,
- door::ATTR::BOLD);
- m.setColor(border_color);
- mtitle.setColor(title_color);
- mtitle.setPadding(" ", title_color);
- m.setTitle(std::make_unique<door::Line>(mtitle), 1);
- m.setRender(true, makeColorsRender(
- door::ANSIColor(door::COLOR::CYAN, door::ATTR::BOLD),
- door::ANSIColor(door::COLOR::BLUE, door::ATTR::BOLD),
- door::ANSIColor(door::COLOR::CYAN, door::ATTR::BOLD)));
- m.setRender(false, makeColorsRender(
- door::ANSIColor(door::COLOR::YELLOW, door::COLOR::BLUE,
- door::ATTR::BOLD),
- door::ANSIColor(door::COLOR::WHITE, door::COLOR::BLUE,
- door::ATTR::BOLD),
- door::ANSIColor(door::COLOR::YELLOW, door::COLOR::BLUE,
- door::ATTR::BOLD)));
-
-
- for (auto iter = deck_colors.begin(); iter != deck_colors.end(); ++iter) {
- char c = (*iter)[0];
- m.addSelection(c, (*iter).c_str());
- }
-
-
-
-
- return m;
- }
- #include "play.h"
- door::Panel make_sysop_config(void) {
- const int W = 35;
- door::Panel p(5, 5, W);
- p.setStyle(door::BorderStyle::DOUBLE);
- door::ANSIColor panel_color =
- door::ANSIColor(door::COLOR::CYAN, door::COLOR::BLUE, door::ATTR::BOLD);
- p.setColor(panel_color);
- p.addLine(std::make_unique<door::Line>(
- "Game Settings - SysOp Configurable", W,
- door::ANSIColor(door::COLOR::GREEN, door::COLOR::BLUE,
- door::ATTR::BOLD)));
- std::unique_ptr<door::Line> spacer = p.spacer_line(false);
- spacer->setColor(panel_color);
- p.addLine(std::move(spacer));
- ostringstream oss;
- door::renderFunction rf = statusValue(
- door::ANSIColor(door::COLOR::YELLOW, door::COLOR::BLUE, door::ATTR::BOLD),
- door::ANSIColor(door::COLOR::GREEN, door::COLOR::BLUE, door::ATTR::BOLD));
- for (auto cfg : config) {
- std::string key = cfg.first.as<std::string>();
- if (key[0] == '_')
- continue;
-
- while (replace(key, "_", " ")) {
- };
- std::string value = cfg.second.as<std::string>();
- oss << std::setw(20) << key << " : " << value;
- p.addLine(std::make_unique<door::Line>(oss.str(), W, rf));
- oss.clear();
- oss.str(std::string());
- }
- return p;
- }
|