0

Recently we've been working with the Berkley Pacman AI course. We have to analyse what changing values of alpha, epsilon and gamma do to our AI.

To insert a command directly into CMD we tell CMD:

pacman.py -q -p PacmanQAgent -x 2000 -n 2010 -l smallGrid -a epsilon=0.08,alpha=0.3,gamma=0.7

Now, I want to run a series of tests where we change the values of these given variables. So I want to open up CMD, run a lot of commands (which are essentially the same) and save the output in a text file. I found some information on StackExchange, it gave me the following code:

string command = "pacman.py -q -p PacmanQAgent -x 2000 -n 2010 -l smallGrid -a epsilon=0.08,alpha=0.3,gamma=0.7";
Process.Start("CMD.exe", command);

Altough it opens up CMD, it seems not do anything. Also the directory of the CMD is the directory of my solution. This should be rather easy (Altough Windows APIs can be quite hard to work with)

Can anyone help, or give me a general solution?

4
  • 1
    stackoverflow.com/questions/1469764/run-command-prompt-commands ? Commented Dec 14, 2016 at 14:58
  • Wait, what's your question? You stated a problem, but didn't state what you want to do. Commented Dec 14, 2016 at 14:59
  • 1
    Firstly, you don't really need to run cmd.exe - you can just run pacman.py directly. To set the working directory, look at the ProcessStartInfo class. There is an overload of Process.Start that accepts one. Commented Dec 14, 2016 at 14:59
  • Look on MSDN at the Process and ProcessStartInfo classes. They should contain everything you need to know. Commented Dec 14, 2016 at 14:59

2 Answers 2

1

Try the ProcessStartInfo class. MSDN ProcessStartInfo

Since this is for an AI course. I would maybe make a PacmanArgument class. PacmanArgument would have properties for each possible commandline argument and a custom ToString method to call. It would make to easier to programatically generate the arguments for something like a genetic algorithm assuming the output can be read as fitness.

Main Function:

double MAX_EPSILON = 1; //I assume there are constraints
//create packman agent with initial values
PacmanAgent agent = new PackmanAgent(0,0,0) //epsilon,alpha,gamma
//create Process info 
ProcessStartInfo psi = new ProcessStartInfo();
psi.FileName = "pacman.py"
psi.WorkingDirectory = @"C:/FilePathToPacman"
psi.RedirectStandardOutput = true;
psi.UseShellExecute = false;

string output;
Console.WriteLine("***** Increasing Eplison Test *****");
while( agent.Epsilon =< MAX_EPSILON )
{
    psi.Arguments = agent.GetArgument();
    // Start the process with the info we specified.
    // Call WaitForExit and then the using-statement will close.
    using (Process process =  Process.Start(psi))
    {
        output = process.StandardOutput.ReadToEnd(); //pipe output to c# variable
        process.WaitForExit(); //wait for pacman to end
    }

    //Do something with test output
    Console.WriteLine("Epsilon: {0}, Alpha: {1}, Gamma: {2}",agent.Epsilon,agent.Alpha,agent.Gamma );
    Console.WriteLine("\t" + output);

    agent.IncrementEpsilon(0.05); //increment by desired value or default(set in IncrementEpsilon function)
}

Pacman Agent class:

public class PacmanAgent
{
    private string ArgumentBase = "-q -p PacmanQAgent -x 2000 -n 2010 -l smallGrid -a ";
    [Range(0, 1, ErrorMessage = "Value for {0} must be between {1} and {2}.")]
    public double Epsilon { get; set; }
    [Range(0, 1, ErrorMessage = "Value for {0} must be between {1} and {2}.")]
    public double Alpha { get; set; }
    [Range(0, 1, ErrorMessage = "Value for {0} must be between {1} and {2}.")]
    public double Gamma { get; set; }

    public PacmanAgent(int epsilon, int alpha , int gamma )   
    {
         Epsilon = epsilon;
         Alpha = alpha; 
         Gamma = gamma; 
    }   

    public string GetArgument()
    {
        string argument = string.Format("{0} epsilon={1}, alpha={2}, gamma={3}", ArgumentBase, Epsilon, Alpha, Gamma)
        return argument
    }

    public void IncrementEpsilon(double i = 0.01)
    {
        Epsilon += i;
    }
    public void IncrementAlpha(double i = 0.01)
    {
        Alpha += i;
    }
    public void IncrementGamma(double i = 0.01)
    {
        Gamma += i;
    }
}

*I wrote this outside on an IDE so please excuse any syntax errors

Sign up to request clarification or add additional context in comments.

5 Comments

This is quite remarkable! I don't have time today to work on it, but makes alot of sense what I see. I could not have done this by myself as I have never worked with managing other processes with C#
Something wrong with the filepath now. Trying to figure it out. You also forgot to add psi.UseShellExecute = false; but fixed that now.
@RichardDirven Did this end up working for you? I have only worked with Processes a small amount recently and did not have anything setup to test this code on so I am curious.
the code compiled, but didn't seem to do anything, other than just starting up the CMD. In the end I wrote two programs, one for creating a huge batch files with all the different epsilon, alpha and gamma values. Then I ran the batch, afterwards I wrote a program interpreting the output it gave me.
@RichardDirven Looks like if we incorporate Run Python Script From C# Set the file name to c:\python26\python.exe (or appropriate location) and the arguments to the whole command pacman.py -q -p PacmanQAgent -x 2000 -n 2010 -l smallGrid -a epsilon=0.08,alpha=0.3,gamma=0.7 it may work
0

You could first of all build a temporary batch file containing all your pacman.py commands. Do that using the standard approaches to creating a file in C#. Use the standard CMD.EXE pipe functionality to append to a file (myfile.txt below).

Your temporary .BAT file would be like:

cd \mydirectory
pacman.py -q -p PacmanQAgent -x 2000 -n 2010 -l smallGrid -a epsilon=0.08,alpha=0.3,gamma=0.7 >> myfile.txt
pacman.py -q -p PacmanQAgent -x 2000 -n 2010 -l smallGrid -a epsilon=0.08,alpha=0.3,gamma=0.7 >> myfile.txt
pacman.py -q -p PacmanQAgent -x 2000 -n 2010 -l smallGrid -a epsilon=0.08,alpha=0.3,gamma=0.7 >> myfile.txt

Then run it in a similar way to the approach you used already:

var command = "mytemp.bat"
processInfo = new ProcessStartInfo("cmd.exe", "/c " + command);
processInfo.CreateNoWindow = true;
processInfo.UseShellExecute = false;
process = Process.Start(processInfo);
process.WaitForExit();

You can also make Process redirect it's standard output and read it into a string variable in C# if you don't want to pipe it in the batch file.

2 Comments

So then my program would also have to change the temporary bat file a couple of times?
I would envision building it on the fly as you need it, executing it, and deleting it afterwards. So you're opening a stream to a text file called 'myfile.bat', pumping in the CMD.EXE commands as above, closing it, then running it with Process.Start()

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.