Created
May 10, 2021 23:29
-
-
Save EmperorPenguin18/124f21a3247feedb988de698b29bd973 to your computer and use it in GitHub Desktop.
Simple Pokedex in the terminal
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//Code that scrapes veekun for pokedex data and displays it to user | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <iostream> | |
#include <string> | |
#include <fstream> | |
#include <algorithm> | |
#include <time.h> | |
#include <ctype.h> | |
#include <sstream> | |
#include <stdint.h> | |
#include <opencv/cv.h> | |
#include <opencv2/core/core.hpp> | |
#include <opencv2/highgui/highgui.hpp> | |
#include <opencv2/imgproc/imgproc.hpp> | |
#include <opencv2/opencv.hpp> | |
//#include <opencv2/core/types.hpp> | |
using namespace std; | |
string site; | |
string line; | |
string userInput; | |
string path; | |
string thing; | |
string date; | |
string game; | |
string out; | |
string name; | |
int n; | |
int m; | |
int i; | |
int j; | |
int seconds; | |
float minutes; | |
float hours; | |
int date1; | |
int date2; | |
int x; | |
int y; | |
int a; | |
int dist; | |
ifstream file; | |
ofstream text; | |
ifstream file2; | |
const int array_size = 99999; | |
string array_in[array_size]; | |
string array_out[array_size]; | |
string list_in[array_size]; | |
string list_out[array_size]; | |
string names[array_size]; | |
string display_in[array_size]; | |
string display_out[array_size]; | |
cv::Scalar pixels[128][128]; | |
string output[128][128]; | |
bool toggle; | |
bool can_stat; | |
time_t timer; | |
cv::Mat image; | |
const int space = 5; | |
int command(string input) | |
{ | |
system ( (input).c_str() ); | |
return 0; | |
} | |
int print(string words) | |
{ | |
cout << words << '\n'; | |
return 0; | |
} | |
string input() | |
{ | |
cout << "-> "; | |
getline(cin, thing); | |
cout << '\n'; | |
return thing; | |
} | |
bool getpath() | |
{ | |
command("pwd > ./pwd.txt"); | |
file2.open("pwd.txt"); | |
if (!file2) | |
{ | |
print("Unable to open file2"); | |
return false; | |
exit(1); | |
} | |
getline(file2, path); | |
file2.close(); | |
command("rm pwd.txt"); | |
return true; | |
} | |
bool getlist() | |
{ | |
print("Creating list of Pokemon..."); | |
site = "https:/"; | |
site += "/bulbapedia.bulbagarden.net/wiki/List_of_Pokemon_by_National_Pokedex_number"; | |
command("curl -k " + site + " -o list.html"); | |
command("tidy -q -asxml --numeric-entities yes list.html >list.xml"); | |
command("rm list.html"); | |
file.open("list.xml"); | |
n = 0; | |
while ( getline(file, line) ) | |
{ | |
list_in[n] = line; | |
n++; | |
} | |
file.close(); | |
command("rm list.xml"); | |
toggle = false; | |
for ( i=0; i < n; i++ ) | |
{ | |
list_out[i] = ""; | |
for ( j=0; j < list_in[i].length(); j++ ) | |
{ | |
if (list_in[i].at(j) == '<') | |
{ | |
toggle = false; | |
} | |
if (toggle) | |
{ | |
list_out[i] += list_in[i].at(j); | |
} | |
if (list_in[i].at(j) == '>') | |
{ | |
toggle = true; | |
} | |
} | |
if (i == array_size-1) | |
{ | |
print("Array ran out of space"); | |
} | |
} | |
text.open("list.txt"); | |
for ( i=0; i < sizeof(list_out)/sizeof(*list_out); i++) | |
{ | |
if (list_out[i] != "") | |
{ | |
text << list_out[i] << '\n'; | |
} | |
} | |
text.close(); | |
n = 0; | |
m = 0; | |
toggle = false; | |
file.open("list.txt"); | |
while ( getline(file, line) ) | |
{ | |
if (n == 0) | |
{ | |
if ( (line.at(0) == '#') || (line.substr(0, 2) == "&#") ) | |
{ | |
toggle = true; | |
} | |
} | |
if (n == 2) | |
{ | |
if (names[m-1] != line) | |
{ | |
names[m] = line; | |
m++; | |
} | |
toggle = false; | |
} | |
if (toggle == true) | |
{ | |
n++; | |
} | |
else | |
{ | |
n = 0; | |
} | |
} | |
file.close(); | |
command("rm list.txt"); | |
print("...Complete"); | |
print("Discovering most recent images..."); | |
site = "https:/"; | |
site += "/veekun.com/dex/media/pokemon/main-sprites/"; | |
command("curl -k " + site + " -o images.html"); | |
command("tidy -q -asxml --numeric-entities yes images.html >images.xml"); | |
command("rm images.html"); | |
file.open("images.xml"); | |
if (!file) | |
{ | |
print("Unable to open file"); | |
exit(1); | |
} | |
n = 0; | |
while ( getline(file, line) ) | |
{ | |
array_in[n] = line; | |
n++; | |
} | |
file.close(); | |
command("rm images.xml"); | |
toggle = false; | |
for ( i=0; i < n; i++ ) | |
{ | |
array_out[i] = ""; | |
for ( j=0; j < array_in[i].length(); j++ ) | |
{ | |
if (array_in[i].at(j) == '<') | |
{ | |
toggle = false; | |
} | |
if (toggle) | |
{ | |
array_out[i] += array_in[i].at(j); | |
} | |
if (array_in[i].at(j) == '>') | |
{ | |
toggle = true; | |
} | |
} | |
if (i == array_size-1) | |
{ | |
print("Array ran out of space"); | |
} | |
} | |
command("touch images.txt"); | |
text.open("images.txt"); | |
if (!text) | |
{ | |
print("Unable to open text"); | |
exit(1); | |
} | |
for ( i=0; i < sizeof(array_out)/sizeof(*array_out); i++) | |
{ | |
if (array_out[i] != "") | |
{ | |
text << array_out[i] << '\n'; | |
} | |
} | |
text.close(); | |
file.open("images.txt"); | |
if (!file) | |
{ | |
print("Unable to open file"); | |
exit(1); | |
} | |
n = 0; | |
date = " 0000 "; | |
while ( getline(file, line) ) | |
{ | |
if ( (line.substr(0, 5) != "Index") && (line.substr(0, 2) != "..") && (line.length() > 0) ) | |
{ | |
if ( stoi(line.substr(58, 4)) == stoi(date.substr(58, 4)) )// Same year | |
{ | |
if (line.substr(54, 3) == "Jan"){ date1 = 01; } | |
if (line.substr(54, 3) == "Feb"){ date1 = 02; } | |
if (line.substr(54, 3) == "Mar"){ date1 = 03; } | |
if (line.substr(54, 3) == "Apr"){ date1 = 04; } | |
if (line.substr(54, 3) == "May"){ date1 = 05; } | |
if (line.substr(54, 3) == "Jun"){ date1 = 06; } | |
if (line.substr(54, 3) == "Jul"){ date1 = 07; } | |
if (line.substr(54, 3) == "Aug"){ date1 = 8; } | |
if (line.substr(54, 3) == "Sep"){ date1 = 9; } | |
if (line.substr(54, 3) == "Oct"){ date1 = 10; } | |
if (line.substr(54, 3) == "Nov"){ date1 = 11; } | |
if (line.substr(54, 3) == "Dec"){ date1 = 12; } | |
if (date.substr(54, 3) == "Jan"){ date2 = 01; } | |
if (date.substr(54, 3) == "Feb"){ date2 = 02; } | |
if (date.substr(54, 3) == "Mar"){ date2 = 03; } | |
if (date.substr(54, 3) == "Apr"){ date2 = 04; } | |
if (date.substr(54, 3) == "May"){ date2 = 05; } | |
if (date.substr(54, 3) == "Jun"){ date2 = 06; } | |
if (date.substr(54, 3) == "Jul"){ date2 = 07; } | |
if (date.substr(54, 3) == "Aug"){ date2 = 8; } | |
if (date.substr(54, 3) == "Sep"){ date2 = 9; } | |
if (date.substr(54, 3) == "Oct"){ date2 = 10; } | |
if (date.substr(54, 3) == "Nov"){ date2 = 11; } | |
if (date.substr(54, 3) == "Dec"){ date2 = 12; } | |
if (date1 == date2)// Same month | |
{ | |
if ( stoi(line.substr(51, 2)) == stoi(date.substr(51, 2)) )// Same date | |
{ | |
print("Veekun done messed up"); | |
} | |
else if ( stoi(line.substr(51, 2)) > stoi(date.substr(51, 2)) )//Newer date | |
{ | |
date = line; | |
} | |
} | |
else if (date1 > date2)// Newer month | |
{ | |
date = line; | |
} | |
} | |
else if ( stoi(line.substr(58, 4)) > stoi(date.substr(58, 4)) )// Newer year | |
{ | |
date = line; | |
} | |
} | |
n++; | |
} | |
file.close(); | |
toggle = true; | |
game = ""; | |
for (i = 0; i < date.length(); i++) | |
{ | |
if (date.at(i) == ' ') | |
{ | |
toggle = false; | |
} | |
if (toggle) | |
{ | |
game += date.at(i); | |
} | |
} | |
command("rm images.txt"); | |
print("...Complete"); | |
return true; | |
} | |
bool getimage(int num) | |
{ | |
print("Getting image of pokemon #" + to_string(num) + "..."); | |
site = "https:/"; | |
site += "/veekun.com/dex/media/pokemon/main-sprites/" + game + to_string(num) + ".png"; | |
command("wget " + site); | |
getpath(); | |
command("sudo mv " + to_string(num) + ".png " + path + "/pokemon"); | |
print("...Complete"); | |
return true; | |
} | |
bool getpokemon(string pokemon) | |
{ | |
print("Creating file for " + pokemon + "..."); | |
if ( count(pokemon.begin(), pokemon.begin()+pokemon.length(), ' ') > 0 ) | |
{ | |
pokemon.replace(pokemon.find(' '), 1, "%20"); | |
} | |
if ( count(pokemon.begin(), pokemon.begin()+pokemon.length(), '\'') > 0 ) | |
{ | |
pokemon.replace(pokemon.find('\''), 1, "’"); | |
} | |
site = "https:/"; | |
site += "/veekun.com/dex/pokemon/" + pokemon; | |
command("curl -k " + site + " -o " + pokemon + ".html"); | |
command("tidy -q -asxml --numeric-entities yes " + pokemon + ".html >" + pokemon + ".xml 2>/dev/null"); | |
command("rm " + pokemon + ".html"); | |
file.open(pokemon + ".xml"); | |
if (!file) | |
{ | |
print("Unable to open file"); | |
exit(1); | |
} | |
n = 0; | |
while ( getline(file, line) ) | |
{ | |
array_in[n] = line; | |
n++; | |
} | |
file.close(); | |
command("rm " + pokemon + ".xml"); | |
toggle = false; | |
for ( i=0; i < n; i++ ) | |
{ | |
array_out[i] = ""; | |
for ( j=0; j < array_in[i].length(); j++ ) | |
{ | |
if (array_in[i].at(j) == '<') | |
{ | |
toggle = false; | |
} | |
if (toggle) | |
{ | |
array_out[i] += array_in[i].at(j); | |
} | |
if (array_in[i].at(j) == '>') | |
{ | |
toggle = true; | |
} | |
} | |
if (i == array_size-1) | |
{ | |
print("Array ran out of space"); | |
} | |
} | |
command("touch " + pokemon + ".txt"); | |
text.open(pokemon + ".txt"); | |
if (!text) | |
{ | |
print("Unable to open text"); | |
exit(1); | |
} | |
for ( i=0; i < sizeof(array_out)/sizeof(*array_out); i++) | |
{ | |
if (array_out[i] != "") | |
{ | |
text << array_out[i] << '\n'; | |
} | |
} | |
text.close(); | |
getpath(); | |
command("sudo mv " + pokemon + ".txt " + path + "/pokemon"); | |
print("...Complete"); | |
return true; | |
} | |
bool organize() | |
{ | |
for (x = 0; x < image.rows; x++) | |
{ | |
display_out[x] = ""; | |
for (y = 0; y < image.cols; y++) | |
{ | |
if (pixels[x][y].val[0] < 24) | |
{ | |
output[x][y] = " "; | |
} | |
else if (pixels[x][y].val[0] < 48) | |
{ | |
output[x][y] = "."; | |
} | |
else if (pixels[x][y].val[0] < 72) | |
{ | |
output[x][y] = "'"; | |
} | |
else if (pixels[x][y].val[0] < 89) | |
{ | |
output[x][y] = "/"; | |
} | |
else if (pixels[x][y].val[0] < 113) | |
{ | |
output[x][y] = "("; | |
} | |
else if (pixels[x][y].val[0] < 137) | |
{ | |
output[x][y] = "*"; | |
} | |
else if (pixels[x][y].val[0] < 161) | |
{ | |
output[x][y] = "%"; | |
} | |
else if (pixels[x][y].val[0] < 185) | |
{ | |
output[x][y] = "$"; | |
} | |
else if (pixels[x][y].val[0] < 209) | |
{ | |
output[x][y] = "#"; | |
} | |
else if (pixels[x][y].val[0] < 232) | |
{ | |
output[x][y] = "&"; | |
} | |
else | |
{ | |
output[x][y] = "@"; | |
} | |
display_out[x] += output[x][y]; | |
} | |
for (j = 0; j < sizeof(output[x])/sizeof(*output[x]); j++) | |
{ | |
if (output[x][j] != output[x][0]) { break; } | |
if ( j == (sizeof(output[x])/sizeof(*output[x]))-1 ) { display_out[x] = ""; } | |
} | |
if ( j != (sizeof(output[x])/sizeof(*output[x])) ) { display_out[x] += string(space, ' '); } | |
} | |
return true; | |
} | |
int main() | |
{ | |
print("Welcome to Seb's Pokedex"); | |
print("Type help for a list of commands"); | |
while (true) | |
{ | |
userInput = input(); | |
if (userInput == "help") | |
{ | |
print("exit: Will end the program."); | |
print("update: Will scrape veekun and generate a Pokedex database. Takes a while."); | |
print("help: You just typed that."); | |
print("delete: Will remove existing database."); | |
print("Anything else: Will attempt to search the database for a pokemon with name you typed (use capitals)."); | |
} | |
else if (userInput == "exit") | |
{ | |
return 0; | |
} | |
else if (userInput == "delete") | |
{ | |
getlist(); | |
getpath(); | |
for (i = 0; i < sizeof(names)/sizeof(*names); i++) | |
{ | |
print("Deleting " + names[i] + "..."); | |
if ( count(names[i].begin(), names[i].begin()+names[i].length(), ' ') > 0 ) | |
{ | |
names[i].replace(names[i].find(' '), 1, "%20"); | |
} | |
if ( count(names[i].begin(), names[i].begin()+names[i].length(), '\'') > 0 ) | |
{ | |
names[i].replace(names[i].find('\''), 1, "’"); | |
} | |
command("sudo mv " + path + "/pokemon/" + names[i] + ".txt " + path); | |
command("rm " + names[i] + ".txt"); | |
print("...Complete"); | |
if (names[i] == "") | |
{ | |
break; | |
} | |
} | |
command("rmdir pokemon"); | |
} | |
else if (userInput == "update") | |
{ | |
timer = time(0); | |
print("Start time 0 seconds"); | |
command("mkdir pokemon"); | |
getlist(); | |
for ( m = 0; m < sizeof(names)/sizeof(*names); m++ ) | |
{ | |
if (names[m] != "") | |
{ | |
getimage(m+1); | |
getpokemon(names[m]); | |
} | |
} | |
seconds = (int)difftime(time(0), timer); | |
if (seconds > 60) | |
{ | |
minutes = seconds/60; | |
if (minutes > 60) | |
{ | |
hours = minutes/60; | |
printf("End time %f %s", hours, "hours"); | |
} | |
else | |
{ | |
printf("End time %f %s", minutes, "minutes"); | |
} | |
} | |
else | |
{ | |
printf("End time %i %s", seconds, "seconds"); | |
} | |
print(""); | |
} | |
else | |
{ | |
for (i = 0; i < sizeof(display_out)/sizeof(*display_out); i++) | |
{ | |
display_out[i] = ""; | |
} | |
if ( count(userInput.begin(), userInput.begin()+userInput.length(), ' ') > 0 ) | |
{ | |
userInput.replace(userInput.find(' '), 1, "%20"); | |
} | |
if ( count(userInput.begin(), userInput.begin()+userInput.length(), '\'') > 0 ) | |
{ | |
userInput.replace(userInput.find('\''), 1, "’"); | |
} | |
getpath(); | |
command("sudo mv " + path + "/pokemon/" + userInput + ".txt " + path); | |
file.open(userInput + ".txt"); | |
if (file) | |
{ | |
n = 0; | |
while ( getline(file, line) ) | |
{ | |
display_in[n] = line; | |
n++; | |
} | |
file.close(); | |
if (display_in[0] == "404 Not Found - veekun") | |
{ | |
print("Veekun does not have data on this Pokemon"); | |
} | |
else | |
{ | |
//IMAGE | |
getpath(); | |
n = 0; | |
if (display_in[43].length() > 1) | |
{ | |
while (display_in[43].at(n) != ':') | |
{ | |
n++; | |
} | |
name = display_in[43].substr(0, n); | |
} | |
else | |
{ | |
while (display_in[44].at(n) != ':') | |
{ | |
n++; | |
} | |
name = display_in[44].substr(0, n); | |
} | |
command("sudo mv " + path + "/pokemon/" + name + ".png " + path); | |
image = cv::imread(name + ".png", 0); | |
if (!image.data) | |
{ | |
print("Error: Couldn't read image file."); | |
exit(1); | |
} | |
for (x = 0; x < image.rows; x++) | |
{ | |
for (y = 0; y < image.cols; y++) | |
{ | |
pixels[x][y] = image.at<uchar>(x, y); | |
} | |
} | |
organize(); | |
command("sudo mv " + name + ".png " + path + "/pokemon"); | |
//DATA | |
a=0; | |
while (display_out[a].length() < 1) | |
{ | |
a++; | |
} | |
display_out[0+a] += display_in[5]; //Name | |
display_out[1+a] += "No. " + name; | |
n = 0; | |
if (display_in[47] == "Conquest") | |
{ | |
display_out[2+a] += display_in[50]; //Species | |
} | |
else | |
{ | |
display_out[2+a] += display_in[49]; | |
} | |
display_out[3+a] += " "; | |
display_out[5+a] += " "; | |
n = 0; | |
while (display_in[52+n] != "Damage Taken") | |
{ | |
display_out[6+n+a] += display_in[52+n]; //Abilities | |
n++; | |
} | |
m = 0; | |
can_stat = true; | |
while (true) | |
{ | |
if (display_in[52+n+m] == "Gender") | |
{ | |
display_out[7+n+a] += "Gender split: " + display_in[53+n+m]; //Gender | |
} | |
if (display_in[52+n+m] == "Egg groups") | |
{ | |
if (display_in[54+n+m] == "Hatch counter")//1 | |
{ | |
display_out[8+n+a] += "Egg group: " + display_in[53+n+m]; //Egg groups | |
} | |
else//2 | |
{ | |
display_out[8+n+a] += "Egg groups: " + display_in[53+n+m] + ", " + display_in[54+n+m]; | |
} | |
} | |
if (display_in[52+n+m] == "Capture rate") | |
{ | |
display_out[9+n+a] += "Capture rate: " + display_in[53+n+m]; //Capture rate | |
} | |
display_out[10+n+a] += " "; | |
if (display_in[52+n+m] == "Stage 2") | |
{ | |
display_out[11+n+a] += "Evolution chain"; | |
display_out[12+n+a] += display_in[5]; | |
n++; | |
while (display_in[53+n+m] != "Stats") | |
{ | |
if (display_in[53+n+m] == display_in[5]) { n+=2; break; } | |
display_out[12+n+a] += display_in[53+n+m]; //Evolution chain | |
n++; | |
} | |
display_out[12+n+a] += " "; | |
display_out[13+n+a] += display_in[53+n+m]; //Stats | |
} | |
if (display_in[52+n+m] == "HP") | |
{ | |
display_out[14+n+a] += "HP: " + display_in[53+n+m]; | |
} | |
if (display_in[52+n+m] == "Attack") | |
{ | |
display_out[15+n+a] += "Attack: " + display_in[53+n+m]; | |
} | |
if (display_in[52+n+m] == "Defense") | |
{ | |
display_out[16+n+a] += "Defense: " + display_in[53+n+m]; | |
} | |
if (display_in[52+n+m] == "Special Attack") | |
{ | |
display_out[17+n+a] += "Special Attack: " + display_in[53+n+m]; | |
} | |
if (display_in[52+n+m] == "Special Defense") | |
{ | |
display_out[18+n+a] += "Special Defense: " + display_in[53+n+m]; | |
} | |
if ((display_in[52+n+m] == "Speed")&&(can_stat==true)) | |
{ | |
display_out[19+n+a] += "Speed: " + display_in[53+n+m]; | |
} | |
if ((display_in[52+n+m] == "Total")&&(can_stat==true)) | |
{ | |
display_out[20+n+a] += "Total: " + display_in[53+n+m]; | |
can_stat = false; | |
} | |
display_out[21+n+a] += " "; | |
if (display_in[52+n+m] == "Flavor Text") | |
{ | |
j = 0; | |
while (true) | |
{ | |
if (isupper(display_in[53+n+m].at(0))) | |
{ | |
j++; | |
} | |
if (j > 2) | |
{ | |
n++; | |
break; | |
} | |
display_out[22+n+a] += display_in[53+n+m]; //Flavor text | |
n++; | |
} | |
} | |
if (display_in[52+n+m] == "Height") | |
{ | |
display_out[22+n+a] += "Height: " + display_in[54+n+m] + " or " + display_in[55+n+m]; //Height | |
} | |
if (display_in[52+n+m] == "Weight") | |
{ | |
display_out[23+n+a] += "Weight: " + display_in[54+n+m] + " or " + display_in[55+n+m]; //Weight | |
} | |
if (display_in[52+n+m] == "Moves") | |
{ | |
j = 0; | |
while (display_in[53+n+m].substr(j, 5) != "moves") | |
{ | |
display_out[4+a] += display_in[53+n+m].at(j); //Type | |
j++; | |
} | |
break; | |
} | |
m++; | |
} | |
for (i = 0; i < sizeof(display_out)/sizeof(*display_out); i++) | |
{ | |
if (display_out[i].length() < 1) { continue; } | |
if ( | |
( (display_out[i].at(0) > 64) && (display_out[i].at(0) < 91) ) || | |
( (display_out[i].at(0) > 96) && (display_out[i].at(0) < 123) ) || | |
( (display_out[i].at(0) > 47) && (display_out[i].at(0) < 58) ) | |
) | |
{ | |
display_out[i].replace(0, 0, string(128+space, ' ')); | |
} | |
} | |
m = 0; | |
for (y = 0; y < sizeof(output[x])/sizeof(*output[x]); y++) | |
{ | |
for (j = 0; j < sizeof(output[x])/sizeof(*output[x]); j++) | |
{ | |
if (output[j][y] != output[0][y]) { break; } | |
} | |
if ( j == (sizeof(output[x])/sizeof(*output[x])) ) | |
{ | |
for (j = 0; j < sizeof(display_out)/sizeof(*display_out); j++) | |
{ | |
if (m > display_out[j].length()) { continue; } | |
display_out[j].replace(m, 1, ""); | |
} | |
} | |
else { m++; } | |
dist = m; | |
} | |
for (i = 0; i < sizeof(display_out)/sizeof(*display_out); i++) | |
{ | |
if (display_out[i].length() < 1) { continue; } | |
print(display_out[i]); | |
} | |
} | |
command("sudo mv " + userInput + ".txt " + path + "/pokemon"); | |
} | |
else | |
{ | |
print("That is not a Pokemon"); | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment