added random seed and seed cmd option

This commit is contained in:
rexy712 2019-01-11 20:48:47 -08:00
parent a69b5c0d93
commit e2d0e33e53
6 changed files with 81 additions and 6 deletions

View File

@ -52,6 +52,7 @@ private:
int m_col = 0; //current column number
int m_line = 0; //current line number
int m_index = -1; //index in lookup_table
const int m_randomness; //change starting color
public:
constexpr basic_color_printer(const cmd_args& args)noexcept;
~basic_color_printer(void)noexcept = default;

View File

@ -27,10 +27,12 @@
#include <cwchar> //wcwidth
#include <cstdio> //wprintf, putwchar
#include <cstdlib> //rand
template<int I>
constexpr basic_color_printer<I>::basic_color_printer(const cmd_args& args)noexcept:
color_printer_base<basic_color_printer<I>>(args){}
color_printer_base<basic_color_printer<I>>(args),
m_randomness(rand()%color_lookup_len){}
template<int I>
basic_color_printer<I>& basic_color_printer<I>::_print(const wchar_t s)noexcept{
if(s == L'\n'){
@ -42,7 +44,7 @@ basic_color_printer<I>& basic_color_printer<I>::_print(const wchar_t s)noexcept{
else
inc_col(1);
}
long new_index = static_cast<int>(this->m_freq*m_col + this->m_spread*m_line) % color_lookup_len;
long new_index = static_cast<int>(this->m_freq*m_col + this->m_spread*m_line + m_randomness) % color_lookup_len;
if(new_index < 0)
new_index += color_lookup_len;
if(new_index != m_index){

View File

@ -42,6 +42,7 @@ struct cmd_args{
std::vector<const char*> filenames;
float freq = 0.2f;
float spread = 0.3f;
long seed = 0;
unsigned number:2;
unsigned ends:1;
unsigned squeeze:1;

View File

@ -29,6 +29,7 @@
#include <cstdlib> //std::abs
#include <algorithm> //std::min, std::max
#include <cstdio> //wprintf, putwchar
#include <cstdlib> //rand
//True color printer. Too many options to enumerate the entire list of possible colors, so we calculate on the fly
class color_printer_true : public color_printer_base<color_printer_true>
@ -48,7 +49,28 @@ private:
color curr = color::red;
constexpr color_state(void)noexcept = default;
constexpr color_state(void)noexcept{
switch(rand()%3){
case 0:
r = color_max_amount;
g = rand()%(color_max_amount-color_min_amount) + color_min_amount;
b = color_min_amount;
curr = color::green;
break;
case 1:
r = color_min_amount;
g = color_max_amount;
b = rand()%(color_max_amount-color_min_amount) + color_min_amount;
curr = color::blue;
break;
case 2:
r = rand()%(color_max_amount-color_min_amount) + color_min_amount;
g = color_min_amount;
b = color_max_amount;
curr = color::red;
break;
};
}
constexpr color inc(void){
switch(curr){
default:

View File

@ -22,6 +22,7 @@
#include <cstring> //strncmp
#include <cwchar>
#include <cstdio> //fwprintf, stderr
#include <cstdlib> //atol
cmd_args::cmd_args(void)noexcept:
number(0), ends(0), squeeze(0), tabs(0), nonprinting(0), usage(0), version(0){}
@ -73,6 +74,7 @@ constexpr const char* U_IGNORED_LONG_OPTION = NO_LONG_OPTION;
constexpr const char NONPRINTING_LONG_OPTION[] = "show-nonprinting";
constexpr const char USAGE_LONG_OPTION[] = "help";
constexpr const char VERSION_LONG_OPTION[] = "version";
constexpr const char SEED_LONG_OPTION[] = "seed=<i>";
#define NO_SHORT_OPTION ""
constexpr const char SHOW_ALL_SHORT_OPTION[] = "A";
@ -87,6 +89,7 @@ constexpr const char U_IGNORED_SHORT_OPTION[] = "u";
constexpr const char NONPRINTING_SHORT_OPTION[] = "v";
constexpr const char USAGE_SHORT_OPTION[] = "h";
constexpr const char* VERSION_SHORT_OPTION = NO_SHORT_OPTION;
constexpr const char SEED_SHORT_OPTION[] = "S";
#define NO_DESC nullptr
constexpr const char EQUIV_DESC_BASE[] = "equivalent to -";
@ -103,12 +106,31 @@ constexpr const char U_IGNORED_DESC[] = "(ignored)";
constexpr const char NONPRINTING_DESC[] = "should use ^ and M- notation, except for LFD and TAB (not supported as of now)";
constexpr const char USAGE_DESC[] = "display this help and exit";
constexpr const char VERSION_DESC[] = "output version information and exit";
constexpr const char SEED_DESC[] = "Rainbow seed, 0 = random (default: 0)";
#define SHORT_OPT(x) (x##_SHORT_OPTION)[0]
#define OPTION(x) {x##_LONG_OPTION, SHORT_OPT(x), x##_DESC}
#define CHECK_LONG_OPTION(x, arg) (!strncmp(x##_LONG_OPTION, arg, strlen(x##_LONG_OPTION)))
constexpr bool is_integer(const char* s){
if(*s != '-' && (*s < '0' || *s > '9')){
return false;
}
for(s = s+1;*s;++s){
if(*s < '0' || *s > '9'){
return false;
}
}
return true;
}
constexpr size_t strlen_pre_eq(const char* str){
size_t i = 0;
for(;str[i] && str[i] != '=';++i);
return i;
}
#define CHECK_LONG_OPTION(x, arg) (!strncmp(x##_LONG_OPTION, arg, strlen_pre_eq(x##_LONG_OPTION)))
#define IS_SHORT_OPTION(arg) ((arg)[0] == '-' && (arg)[1] != '-')
#define IS_LONG_OPTION(arg) ((arg)[0] == '-' && (arg)[1] == '-')
//Convert command line options to a cmd_args struct
@ -124,6 +146,7 @@ cmd_args process_cmd_args(int argc, char** argv){
escaped = true;
}else if(IS_SHORT_OPTION(argv[i])){
size_t arg_len = strlen(argv[i]);
size_t next_arg = i+1;
for(size_t j = 1;j < arg_len;++j){
switch(argv[i][j]){
case SHORT_OPT(SHOW_ALL):
@ -162,20 +185,28 @@ cmd_args process_cmd_args(int argc, char** argv){
case SHORT_OPT(VERSION):
ret.version = 1;
break;
case SHORT_OPT(SEED):
if(i == (argc-1) || !is_integer(argv[next_arg])){
fwprintf(stderr, L"'-%s' requires an integer argument\n", SEED_SHORT_OPTION);
ret.usage = 1;
}else{
ret.seed = atol(argv[next_arg]);
}
++next_arg;
break;
default:
//keep parsing after error so we can still properly output requested color style
ret.usage = 1;
fwprintf(stderr, L"Unrecognized option '-%c'\n", argv[i][j]);
};
}
i = next_arg-1;
}else if(IS_LONG_OPTION(argv[i])){
const char* arg = argv[i]+2;
if(CHECK_LONG_OPTION(SHOW_ENDS, arg)){
ret.ends = 1;
}else if(CHECK_LONG_OPTION(NUMBER_NONBLANK, arg)){
ret.number = PRINT_LINE_NONBLANK;
}else if(CHECK_LONG_OPTION(SHOW_ENDS, arg)){
ret.ends = 1;
}else if(CHECK_LONG_OPTION(NUMBER_LINES, arg)){
if(!ret.number)
ret.number = PRINT_LINE_ALWAYS;
@ -189,6 +220,14 @@ cmd_args process_cmd_args(int argc, char** argv){
ret.usage = 1;
}else if(CHECK_LONG_OPTION(VERSION, arg)){
ret.version = 1;
}else if(CHECK_LONG_OPTION(SEED, arg)){
constexpr size_t offset = strlen_pre_eq(SEED_LONG_OPTION);
if(arg[offset] != '=' || !is_integer(arg+offset+1)){
fwprintf(stderr, L"'--%.*s' requires an integer argument\n", offset, SEED_LONG_OPTION);
ret.usage = 1;
}else{
ret.seed = atol(arg+offset+1);
}
}else{
ret.usage = 1;
fwprintf(stderr, L"Unrecognized option '%s'\n", argv[i]);
@ -214,6 +253,7 @@ const cmd_options cmd_arguments_list[] = {
OPTION(SHOW_TABS),
OPTION(U_IGNORED),
OPTION(NONPRINTING),
OPTION(SEED),
OPTION(USAGE),
OPTION(VERSION)
};

View File

@ -31,6 +31,8 @@
#include <unistd.h> //isatty
#include <cstring> //strcmp
#include <cstddef> //size_t
#include <chrono> //std::chrono::*
#include <cstdlib> //srand
constexpr const char* version_string = "roflcat version 0.1a";
@ -140,12 +142,19 @@ void print_files(cmd_args& args){
}
p.reset();
}
auto get_time(void){
auto time = std::chrono::high_resolution_clock::now();
auto eptime = time.time_since_epoch();
auto micros = std::chrono::duration_cast<std::chrono::microseconds>(eptime);
return micros.count();
}
int main(int argc, char** argv){
setlocale(LC_ALL, ""); //change to system locale so wchar_t things work
cmd_args args = process_cmd_args(argc, argv);
int avail_colors = detect_term_colors();
srand(args.seed ? args.seed : get_time());
//print_files<color_printer_true>(args);
//if stdout is not a tty, disable color
if(!isatty(fileno(stdout))){