Includes (lost update to coding)

I found this update sitting and waiting to be finished for almost a year!

 

We are now moving to the real code. The main just covered the final product and my style decisions.

Starting with the header code:

/**

Copyright 2018 Michael R. Wild

Permission is hereby granted, free of charge, to any person obtaining a copy of
 this software and associated documentation files (the "Software"), to deal in
 the Software without restriction, including without limitation the rights to
 use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
 the Software, and to permit persons to whom the Software is furnished to do so,
 subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
 copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
 FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
 COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
 IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE

@file mcp.h
 @author Michael R. Wild
 @date 3/6/2018
 @version 0.0.1

@brief Master Control Classes Header

@section DESCRIPTION

The header file for the MCP.

@section CHANGES

20180306 Creation
 20180307 Added example class

*/
 //=================================
 // include guard
 #ifndef __mcp_H_INCLUDED__
 #define __mcp_H_INCLUDED__

//=================================
 // forward declared dependencies

//=================================
 // included dependencies
 #include 
 #include 
 #include 
 #include <string>
 #include <set>
 #include <exception>
 #include <iostream>

//=================================
 // revisions of namespace

namespace pt = boost::property_tree;
 //=================================
 // the actual classes

/*! \class MyClass
 \brief Example class.

Just an example class.
 */

class MyClass // Example standard
 {
 private:
 int a;

public:
 void set(int n) { a = n;}
 int get() { return a;}
 };

class MCPParms
 {
 private:
 pt::ptree tree;
 std::string parmfile;

public:
 MCPParms(const std::string &filename) ;
 void load() ;
 std::string get(const std::string &mykey) ;
 void put(const std::string &mykey, const std::string &myvalue) ;
 void save() ;

};

#endif // __MCP_H_INCLUDED__

I first had to remember how to control the code to prevent recursive calls for the include. I have to admit that I looked that up as I had no memory about how to control includes in C++. I also left the example in for now. Lastly, I decided that I would not create one set of includes for everything different class. That seemed to me to be a bit over-the-top, but that is the standard for many. Sticking with the minimal standards, I included the minimal to get my work done. I did declare a namespace for the tree as I just did not want to type boost over and over.

I decided to do an example where I would read in an XML file with all of the parameters to run the program. Now there are other ways to do this, but I liked this idea of XML to tree, thus the name MCPParms.

The work is done in the CPP file as you would expect.  Sorry, I am not following my own standards of updating all of the items in the header. It is an example program.

/** 

Copyright 2018 Michael R. Wild

Permission is hereby granted, free of charge, to any person obtaining a copy of 
this software and associated documentation files (the "Software"), to deal in 
the Software without restriction, including without limitation the rights to 
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so, 
subject to the following conditions:

The above copyright notice and this permission notice shall be included in all 
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE


@file mcp.cpp
@author Michael R. Wild
@date 3/6/2018 
@version 0.0.1 

@brief Master Control Classes
 
 @section DESCRIPTION
 
 This is the class definitions for MCP
 
  @section CHANGES
 
 20180306 Creation
 
 */

#include "mcp.h"

MCPParms::MCPParms(const std::string &myfilename)
{
/*
Decided to just save the file name instead of loading it. The process of loading 
could throw so can't do it here without a lot of mystery code to handle an 
exception on declare. So split up load and constructor.
*/

  parmfile = myfilename;
  //std::cout << "File name: " << parmfile << std::endl;
}

void MCPParms::load()
{
/* Must put "load" in a try to handle exceptions. The file and the XML process
can both throw.
*/

  pt::read_xml(parmfile, tree); // exceptions must be handled!
}


std::string MCPParms::get(const std::string &myname)
{ 
  
  return tree.get(myname);

}

void MCPParms::put(const std::string &myname, const std::string &myvalue)
{
  
  //std::cout << "myname: " << myname << std::endl;
  tree.put(myname, myvalue);
  
  return;

}

void MCPParms::save()
{
  //std::cout << "save " << parmfile << std::endl;
  pt::write_xml(parmfile, tree);
}

The code can read an XML file, create a tree of the values, retrieve values from the tree, and write the tree back to a file. This is the start of my blockchain thinking. I plan to create an XML file for each blockchain entry or bitcoin if you like. That the new software will manage files and not use a database. My idea is to have an XML structure that drives the process and that to live in a file. The shared ledger then is just a bunch of XML files.

Hope the code is interesting and the idea is also interesting. That is all the code I have done. So I may take a few days to get another update done. I hope that is OK.

Nearly forgot! Here is the run of the program in Cloud9. So cool to just run this stuff somewhere in the cloud for the cost of one PNW coffee for a whole month of use!

Running /home/ec2-user/environment/mcpmain.cpp
Master Control Program
Local Time: Thu Apr 26 05:51:54 2018

Read in MCP controls
Success: Master Control Program 0.0.1
Success: This is a test
Saved!
 
Process exited with code: 0

Spring Break 2019 Day 0: Working and Games

We will try to use this for my story of my adventures for Spring Break 2019. I hope you don’t mind too much using a blog and not simple emails.

Scythe 22March2019

I am suffering from recently diagnosed diabetes and so have to be careful with carbohydrates. I made an error today. After work, I called Susie my wife, and she wanted Chinese food for dinner. I had been warned by friends at work that diabetics who are ethnic rice-eaters find it quite a challenge. But I did not even think about that, and I was in a rush as I had a game in Portland today, so I ate lots of fried rice and Sweat and Sour Pork (just a bit of sauce) and dived into the car and drove. My face flushed and my heart beat hard in my chest. But I was in a hurry and work had much to raise my blood pressure so I accept that as my normal ending for the week.

Then I made it on-time and even by ten minutes to Richard’s house–having left ten minutes later than I should. While I was driving to Richard’s Richard sent me a text that the game moved to “Dave’s.” I had only one address that I have played at before, so I drove there. I received a text of an address that was just minutes away from Richard’s house. I had driven three and a half miles, taking ten minutes in Portland with all the lights, and so headed back. Finally, twenty minutes late, I got to Dave’s and was given Poland to play in Scythe.

Scythe is recently created boardgame (via Kickstarter) that I have learned to love. It simulates a time in Europe that is after the War and includes a story that Tesla invented a new super power-supply that allows for a steam-punk like a universe in Europe. It is a multi-player game and includes many familiar elements of Risk, Monopoly, Axis and Allies, and Euro gaming. It is also visually stunning and allows me to paint a few cool figures. We are beginning a special Fenris campaign version of Scythe in a few weeks. So the game Friday night is a warm-up game.

Scythe figures

Well after all the adventures of getting there, I played Poland (White) well enough. Most of the time I was trying to remember how my opponent Kalib plays–He totally crushed us many times as Poland. Before I left, I told Corwin, who lives with us at home, that I was hoping to lose better and score better than my last game of 37! Corwin said to me that the Vikings (Blue) would win. I told him they are one of the worst and he argues this with me from time to time.

For you Scythe experts, we are playing an alternative ending version–again, part of our practicing for the campaign game. Visiting the Factory (found in the center of the board) allows for extra capability (Tesla pumps you up for visiting his factory). In this version visiting the Factory grants a star and enables you to play an extra turn once the usual ending condition is tripped. I saw the crush for the Factory and so ignored it and collected other ways to win and ended the game only to discover my opponents got an extra play–I was not quite following the additional conditions. Well, the Vikings used their extra turn to cover all the lakes (each area controlled at the end of the game grants more points) and got enough to win. I had scored 62, and well the Vikings said something about seventy…

Here is more information on the game: Scythe on Board Game Geek

I left after the first game, turning down the second game, as I was dizzy and my face was flushed, and I was feeling like it was too warm–signs that my sugar levels were running wrong. I do not test my blood yet, but I have not had this for months (hoping to get diabetes under control with simple meds, diet, and exercise). Then I remembered the rice! Might of well had a bucket of sugar for dinner! So I will watch the rice! Later I recalled I had Indian for lunch, more rice! Oh my, how stupid of me. I think I had an exciting carbohydrate crash. Again, rice is now a treat and will be in small sane amounts.

At least I got in a game.

I drove home and took my meds and had a bit of cheese (NOT RICE) and no crackers with it. Lots of water. Better.

Played one more new game after finishing up the laundry for Susie.

Oh, that reminds me. I am using laundry balls. I know that I got a smile. Little wool balls that bounce in the dryer. It really helps. Dryer sheets are not needed (I used one every other load). My mother loves the set I sent her. You can get them here: Laundry balls from Amazon  Mine are different and actually shipped from England ( Imported Sheep styled balls ). This was before I thought that I should just get them from Amazon.

One of my balls is missing (bet that got a grin). They get stuck in a towel or a sheet, hum. Corwin heard me singing “My poor laundry ball rolled off…”. This one is black with a sheep face, so yes the black sheep of the laundry has wandered off.

After midnight we got to one of my newest games: Call for Adventure.

Call to Adventure

This is a straightforward game where you build a story of a great adventurer using cards. I was not that pleased with it, but I had only played it solo. I was in the initial Kickstarter (Kickstarter Call of Adventure) for the game and so have an early copy. I saw it for sale at Guardian Games, so it is now available to the public. Corwin agreed to try it before I decided to shelve it or give it away.

Corwin liked it. He also beat me by more than 2-to-1. We both agreed that the game lets you build an adventurer and the process of throwing runes (cool plastic runes that feel like bone) is interesting. We had to check some rules and make a couple of corrections that made the gameplay better. This rules flub might have been part of the reason for my poor experience playing solo. We wanted to do something with our newly minted adventurer, but the game just ends. Then you count the score–where is the adventure? This was a bit of a letdown after playing the game to build the adventurer. Also, the cards slide too much from the tucking process. Corwin said it was playable and enjoyable. We think the co-op version, where you must alone face a powerful adversary, might make that better as you have something to adventure too–we will try that.

I get most of my new games through Kickstarter, or I purchase one created on Kickstarter once it is released to the public and I have played it.

After that, it was past one in-the-morning, and despite not finding my lost black sheep ball, I went to bed and quickly fell to sleep. I rose about eight this morning beginning ten days of vacation. Except I have to do some work for Nike on Monday through Wednesday, but it is usually only a couple of hours here and there, and I have done this before. So Day 1 starts…more on that later.

Run Loop

So I have created the foundation for the next work. I have managed to get all the run parameters​ from an XML file and loaded them into variables in main of the MCP C++ program. I had to do a little restructuring of the code as the includes for thread and time needed to be moved to the shared include as the methods in the classes used some of the same libraries.

So the main looks like this, it will not likely get much larger than this (as always the code is better spaced in the editor in AWS cloud9):

#include "mcp.cpp"

int main()
{
        
	// Print a header of execution out
	auto result = std::time(nullptr);	
	std::cout << "Start: Master Control Program " << std::endl;
	std::cout << "Local Time: " <<
	    std::asctime(std::localtime(&result)) << std::endl;
	    
    // Get running values
    std::string versionnumber, storedirectory, sharedirectory, UUID[10];
    
    MCPParms ourparms("MCP.xml"); // parms for program
    try {
        
        ourparms.load();
    }
    
    catch (std::exception const&  ex) {
        
       std::cout << ex.what() << std::endl;
       return (1);
    }
	
	ourparms.version(versionnumber);
	
	// Write out version number
	std::cout << "File version: " << versionnumber << std::endl;
	
	ourparms.UUID(UUID);
	
	ourparms.store(storedirectory);
	
	ourparms.share(sharedirectory);
	
	int client = ourparms.client();
	
	std::cout << "Client " << client;
	if (client == 0) {
	    std::cout << " Primary!";
	}
	std::cout << std::endl;
	std::cout << "Store: " << storedirectory << std::endl;
	std::cout << "Share: " << sharedirectory << std::endl;
	
	// Start run loop for MCP
	MCPRun runit(1000, storedirectory); // set wait time
	
	runit.run();
	
	// Close down task
	
	std::this_thread::sleep_for(std::chrono::milliseconds(1000));
	
	// Shutdown
	result = std::time(nullptr);
    std::cout << "Exit: Master Control Program " << std::endl;
	std::cout << "Local Time: " <<
	    std::asctime(std::localtime(&result)) << std::endl;
	    
    // Leave politely
    return 0;

}

 
The run routine is working and now starts up a loop with 1000 millisecond wait and checks if the file in the store directory named run.xml is present, well-formed​, and has a ‘run’ value of ‘Yes’. So the MCP begins to act like a master control program now as it loops until requested to a ​shutdown of fail-out if it cannot find the control file that allows it to run.

The run code:

MCPRun::MCPRun(int mywaittime, const std::string &mystore)
{
   runfile = mystore + "/run.xml"; // put hard coding inside
   storedirectory = mystore;
   waittime = mywaittime;
   shutdown = "Start";
   
   return;

}

void MCPRun::run()
/*
    This is the main control loop. It runs until the check becomes false. There
    must be a wait long enough to not cause this to take over the system, at
    least a second.
    
*/

{

   do {
   
        std::this_thread::sleep_for(std::chrono::milliseconds(waittime));
   
   } while (check());
   
   std::cout << "Ending Condition: " << shutdown << std::endl;
   
   return;

}

bool MCPRun::check()
/*
    The check opens the run.xml in the store and stops when the run value is not
    "Yes" or the file is not there or malformed.
*/

{
    std::string therun;
    therun = "No";
    try {
        
        pt::read_xml(runfile, tree); // exceptions must be handled!
        therun = tree.get("run", "No"); // no throw if not there
    }
    
    catch (std::exception const&  ex) {
        
       therun = "Fail";
       shutdown = "Fail";

    }
   //std::cout << "Check: " << therun << std::endl;
   
   return (therun == "Yes");

}

Well all of the work now begins to pay. Next, and I am having issues with this step, is to scan the share directory for files to process.

More coding

So I have more C++ to relearn. I had to remember how to pass by reference and update same. I reworked the code to move all the hard coding to the routine and thus hid all of it.

Here is a bit of the main now:

int main()
{
        
	// Print a header of execution out
	auto result = std::time(nullptr);	
	std::cout << "Start: Master Control Program " << std::endl;
	std::cout << "Local Time: " <<
	    std::asctime(std::localtime(&result)) << std::endl;
	    
    // Get running values
    std::string versionnumber, storedirectory, sharedirectory, UUID[10];
    
    MCPParms ourparms("MCP.xml"); // parms for program
    try {
        
        ourparms.load();
    }
    
    catch (std::exception const&  ex) {
        
       std::cout << ex.what() << std::endl;
       return (1);
    }
	
	ourparms.version(versionnumber);
	
	// Write out version number
	std::cout << "File version: " << versionnumber << std::endl;
	
	ourparms.UUID(UUID);
	// write out UUID of starting value
	std::cout << "UUID " << UUID[0] << std::endl;
	
	ourparms.store(storedirectory);
	
	ourparms.share(sharedirectory);
	
	int client = ourparms.client();
	
	std::cout << "Client " << client;
	if (client == 0) {
	    std::cout << " Primary!";
	}
	std::cout << std::endl;
	std::cout << "Store: " << storedirectory << std::endl;
	std::cout << "Share: " << sharedirectory << std::endl;
	
	std::this_thread::sleep_for(std::chrono::milliseconds(1000));
	
	// Shutdown
	result = std::time(nullptr);
    std::cout << "Exit: Master Control Program " << std::endl;
	std::cout << "Local Time: " <<
	    std::asctime(std::localtime(&result)) << std::endl;
	    
    // Leave politely
    return 0;

}

I have left the open of the file to be a try/except as I think it would hard to handle it in the constructor. I have moved the getting of values to methods.

That code looks like this (please notice the one bit of crazy C++ code that is obscure):

void MCPParms::version(std::string &myversion)
{
    
    myversion = this->get("mcp.version");
    
    return;
}

void MCPParms::UUID(std::string myUUID[10])
{
    
    myUUID[0] = this->get("UUID.0");
    myUUID[1] = this->get("UUID.1");
	myUUID[2] = this->get("UUID.2");
	myUUID[3] = this->get("UUID.3");
    myUUID[4] = this->get("UUID.4");
	myUUID[5] = this->get("UUID.5");
	myUUID[6] = this->get("UUID.6");
    myUUID[7] = this->get("UUID.7");
	myUUID[8] = this->get("UUID.8");
	myUUID[9] = this->get("UUID.9");
    
    return;
}

void MCPParms::store(std::string &mystore)
{
    
    mystore = this->get("mcp.store");
    
    return;
}

void MCPParms::share(std::string &myshare)
{
    
    myshare = this->get("mcp.share");
    
    return;
}

int MCPParms::client()
/* 
    You would think this would be easy. But no.
    Here is the logic I used.... Broke it in steps to be clear
*/

{
    
    std::string myclientstr = this->get("mcp.client");
    int myclient = atoi(myclientstr.c_str()); // Crazy C++ code
    
    return myclient;
}

 
The spacing is better in the code. I am tired of trying to align this stuff in WordPress!

So we have added the needed items to begin the next step, actually passing files. I intend to have a file appear in the share directory, process it, accept it, move it to the store directory, and send back an acknowledgment​. That is the next step. I am having trouble finding a way to get a list of files in a directory and information on the files. It appears that this is not available in C++11 that I am using. I will keep digging.

We are about to step out into the interesting bits. I hope to at least have code that can see files next time.

I forgot to add that I wrote a program to create the XML file. That is how I get all the values into​ the file. When I get this running the file will be create once and then copied to the various systems with different client numbers.​