I have made an AI that takes a user input and returns a predefined value. It that stores its info in a file (with the name of the file "default.92ai"
). I thought that it didn't seem very efficient, considering it was a project that helped me learn C++.
I also think I might have added a bunch of really stupid code when I was debugging and forgot to take it out. I split the project into two files to make a sort of API.
I have an extra file that I recently created to test this "API". This is a separate executable, and is just to test the API. (So I do gcc -o ai ai.cpp
and separately do gcc -o test test.cpp
)
If you have any suggestions, I would be happy to take them, except using namespace std
edits. I am Edit: was (I am scared of what would happen to me if I keep using using namespace std
) too lazy to type std::
.
ai.cpp
#include <iostream>
#include <fstream>
#include <vector>
#include <sstream>
#include <algorithm>
#include <thread>
#include <unistd.h>
#include "files.h"
#ifdef __MINGW32__
#include <mingw.thread.h>
#endif
#ifdef WIN32
#include <windows.h>
#else
#include <unistd.h>
#endif // win32
using namespace std;
void sleepcp(int milliseconds){
#ifdef WIN32
Sleep(milliseconds);
#else
usleep(milliseconds * 1000);
#endif // win32
}
void load(/*int size*/){
float progress = -0.01;
int time = 100;
/*if (size<100){
time = size*0.5;
}
if (size<1000&&size>100){
time = size*0.05;
}
if (size>1000){
time = size*0.01;
}*/
while (progress < 1.0) {
progress += 0.01;
int barWidth = 70;
cout << "[";
int pos = barWidth * progress;
for (int i = 0; i < barWidth; ++i) {
if (i < pos) cout << "=";
else if (i == pos) cout << ">";
else cout << " ";
}
cout << "] " << int(progress * 100.0) << " %\r";
cout.flush();
sleepcp(time);
}
cout << endl;
}
int main () {
//load default conf
files conf;
conf.filename="default.92ai";
//conf.checksize();
thread loadbar (load/*,conf.size*/);
conf.read();
loadbar.join();
cout << "Welcome to the 92 Spoons AI interface!"<<endl<<"If you need a tour around, say 'tour'."<<endl;
while(true){
string q;
//allows for spaces in commands
getline(cin,q);
if (q=="exit"){
return 0;
}else{
if (q=="reload"){
conf.reload();
}
else{
if (q=="load"){
//not tested
cout<<"What file shall I load?"<<endl;
string file2load;
cin>>file2load;
files file2;
file2.filename=file2load;
}
else{
if (q=="import"){
cout<<"What file shall I import?"<<endl;
string file2load;
cin>>file2load;
fstream file2;
file2.open(file2load);
string line;
while(getline(file2,line)){
conf.add(line);
//lets hope this works i.e. not tested
}
}else{
if (q=="write"){
string edit;
getline(cin,edit);
conf.add(edit);
}else{
if (q=="tour"){
cout<<"Hi!"<<endl<<"You can type something and this AI will respond!"<<endl<<"If you want to make a new command, type write."<<endl<<"Then type what you expect a user to type, like llama."<<endl<<"Then, type a colon."<<endl<<"Finally, tell me what I should say to respond."<<endl<<"For example, llama:No, llama, no!"<<endl;
}else{
vector<string>::iterator it;
it = find (conf.first.begin(), conf.first.end(), q);
if (it != conf.first.end()){
//TODO: Fix this conversion error
long nPosition = distance (conf.first.begin (), it);
cout << conf.second.at(nPosition)<<endl;
}else{
cout << "Not found!" <<endl;
}
}
}
}
}
}
}
}
return 0;
}
files.h
#ifndef UPDATE_H
#define UPDATE_H
#include <iostream>
#include <string>
#include <vector>
#include <fstream>
#include <sstream>
using namespace std;
class files{
string edit;
public:
int size;
vector<string> first;
vector<string> second;
fstream file;
string filename;
void add(string edit);
void keepline(string edit);
void fileopen();
void read();
void close();
void reload();
void start();
void end();
int checksize();
void load(string loadname);
};
int files::checksize(){
fstream filesize;
filesize.open(filename,ios::binary);
streampos begin,end;
begin = filesize.tellg();
filesize.seekg (0, ios::end);
end = filesize.tellg();
int size = end-begin;
//if you hate warnings
/**psize++;
*psize--;*/
files::start();
return size;
}
void files::start(){
fstream *pfile;
pfile = &file;
(*pfile).seekg (0, ios::beg);
}
void files::end(){
fstream *pfile;
pfile = &file;
(*pfile).seekg (0, ios::end);
}
void files::fileopen(){
fstream *pfile;
pfile = &file;
(*pfile).open(filename);
}
void files::add(string edit){ //for experienced users
fstream filewrite;
filewrite.open(filename);
filewrite.seekg(0,ios::end);
filewrite << edit <<endl;
filewrite.close();
}
void files::keepline (string edit){
fstream filewrite;
filewrite.open(filename);
filewrite << edit;
filewrite.close();
}
void files::read(){
files::fileopen();
fstream *pfile;
pfile = &file;
vector<string> *pfirst;
pfirst = &first;
vector<string> *psecond;
psecond = &second;
string line;
string header;
while (getline(*pfile,line)){
stringstream split (line);
string one;
string two;
getline(split,one,':');
(*pfirst).push_back(one);
getline(split,two);
(*psecond).push_back(two);
}
if (first.at(0)!="92spoons AI header"){
cout<<"Oh no! A file was loaded that does not have a correct header. Make sure you loaded a 92ai file, and that you didn't make a typo on the header."<<endl;
//cout<<"|"<<header<<"|";
exit(1);
}
}
void files::close(){
fstream *pfile;
pfile = &file;
(*pfile).close();
}
void files::reload(){
vector<string> *pfirst;
pfirst = &first;
vector<string> *psecond;
psecond = &second;
files::close();
(*pfirst).clear();
(*psecond).clear();
files::read();
}
void files::load(string loadname){
files file2;
file2.filename=loadname;
string line;
string header;
getline(file2.file,header);
if (header!="92spoons AI header"){
cout<<"Oh no! A file was loaded that does not have a correct header. Make sure you loaded a 92ai file, and that you didn't make a typo on the header."<<endl;
exit(1);
}
while (getline(file2.file,line)){
stringstream split (line);
string one;
string two;
getline(split,one,':');
first.push_back(one);
getline(split,two);
second.push_back(two);
}
}
#endif
test.cpp
#include <iostream>
#include <fstream>
#include <vector>
#include <sstream>
#include <algorithm>
#include <thread>
#include <unistd.h>
#include "files.h"
#ifdef __MINGW32__
#include <mingw.thread.h>
#endif
#ifdef WIN32
#include <windows.h>
#else
#include <unistd.h>
#endif // win32
#ifdef NODEBUG
bool debug = false;
#else
bool debug = true;
#endif
using namespace std;
int main(){
files test;
test.filename="default.92ai";
if(test.filename!="default.92ai"){
if(debug){
cout<<"Var storage test failed! Here is what the var was instead:"<<test.filename<<endl;
}
return -1;
}
if(debug){
cout<<"Var storage test passed!"<<endl;
}
test.fileopen();
if(test.file.bad()){
cout<<"File opening test failed!"<<endl;
return -1;
}
test.close();
if(debug){
cout<<"File opening test passed!"<<endl;
}
//add read debug
test.fileopen();
string testread;
getline(test.file,testread);
if (testread!="92spoons AI header"){
cout<<"File reading test failed!"<<endl;
return -1;
}
cout<<"File reading test passed!"<<endl;
srand(time(NULL));
string name = "test"+to_string(rand());
test.add((name+":test").c_str());
test.close();
test.read();
vector<string>::iterator it;
it = find (test.first.begin(), test.first.end(), name);
if (it == test.first.end()){
cout<<"File writing test failed!"<<endl;
return -1;
}else{
//TODO: Fix this conversion error
long nPosition = distance (test.first.begin (), it);
if (debug){
cout << "File writing test passed!"<<endl;
}
}
}
Disclosure: 92 Spoons AI's name is based off of 92spoons.com, my friend's website. Now I'm not breaking the rules!
std::
if you're too lazy; just use implicit namespace imports (using std::cout;
etc.), and do it in source files only - don't do that in header files! (or, in worst case, factor out yourusing
s to a separate header if you really need to) \$\endgroup\$std::
problems! :) \$\endgroup\$using namespace std
. You should just understand the benefits -- slightly less typing; no need to reach for that distant colon key -- and the costs -- losing the ability to call thingsvector
,map
, or any of dozens of other extremely common names without introducing impossible-to-find bugs. Also, you haven't edited the code in the question, but I wanted to make sure you knew that's not something we do here; if you want a second look, post an iterative review. See here for more info. \$\endgroup\$