5using System.Collections.Generic;
 
    8using System.Drawing.Drawing2D;
 
    9using System.Drawing.Imaging;
 
   12using System.Runtime.InteropServices;
 
   15using System.Threading.Tasks;
 
   43        string m_strName = 
"ATARI";
 
   45        AtariState m_state = 
new AtariState();
 
   47        ACTION[] m_rgActionsRaw;
 
   48        List<int> m_rgFrameSkip = 
new List<int>();
 
   50        Dictionary<string, int> m_rgActions = 
new Dictionary<string, int>();
 
   51        List<KeyValuePair<string, int>> m_rgActionSet;
 
   53        COLORTYPE m_ct = COLORTYPE.CT_COLOR;
 
   54        bool m_bPreprocess = 
true;
 
   55        bool m_bForceGray = 
false;
 
   58        bool m_bEnableNumSkip = 
true;
 
   59        int m_nFrameSkip = -1;
 
   85            if (m_bmpActionRaw != 
null)
 
   88                m_bmpActionRaw = 
null;
 
  113            m_ale.EnableDisplayScreen = 
false;
 
  114            m_ale.EnableSound = 
false;
 
  116            m_ale.EnableRestrictedActionSet = 
true;
 
  117            m_ale.EnableColorAveraging = 
true;
 
  118            m_ale.AllowNegativeRewards = properties.
GetPropertyAsBool(
"AllowNegativeRewards", 
false);
 
  119            m_ale.EnableTerminateOnRallyEnd = properties.
GetPropertyAsBool(
"TerminateOnRallyEnd", 
false);
 
  120            m_ale.RandomSeed = (int)DateTime.Now.Ticks;
 
  121            m_ale.RepeatActionProbability = 0.0f; 
 
  123            if (properties == 
null)
 
  124                throw new Exception(
"The properties must be specified with the 'GameROM' set the the Game ROM file path.");
 
  127            if (strROM.Contains(
'~'))
 
  132            if (!File.Exists(strROM))
 
  133                throw new Exception(
"Could not find the game ROM file specified '" + strROM + 
"'!");
 
  136                m_ct = COLORTYPE.CT_GRAYSCALE;
 
  144            m_rgActionsRaw = m_ale.ActionSpace;
 
  146            m_rgFrameSkip = 
new List<int>();
 
  148            if (m_nFrameSkip < 0)
 
  150                for (
int i = 2; i < 5; i++)
 
  152                    m_rgFrameSkip.Add(i);
 
  157                m_rgFrameSkip.Add(m_nFrameSkip);
 
  160            m_rgActions.Add(ACTION.ACT_PLAYER_A_LEFT.ToString(), (
int)ACTION.ACT_PLAYER_A_LEFT);
 
  161            m_rgActions.Add(ACTION.ACT_PLAYER_A_RIGHT.ToString(), (
int)ACTION.ACT_PLAYER_A_RIGHT);
 
  164                m_rgActions.Add(ACTION.ACT_PLAYER_A_FIRE.ToString(), (
int)ACTION.ACT_PLAYER_A_FIRE);
 
  166            m_rgActionSet = m_rgActions.ToList();
 
  180            if (properties != 
null)
 
  215            get { 
return m_strName; }
 
  263        public Tuple<Bitmap, SimpleDatum> 
Render(
bool bShowUi, 
int nWidth, 
int nHeight, 
bool bGetAction)
 
  265            List<double> rgData = 
new List<double>();
 
  266            return Render(bShowUi, nWidth, nHeight, rgData.ToArray(), bGetAction);
 
  278        public Tuple<Bitmap, SimpleDatum> 
Render(
bool bShowUi, 
int nWidth, 
int nHeight, 
double[] rgData, 
bool bGetAction)
 
  283            m_ale.GetScreenDimensions(out fWid, out fHt);
 
  284            byte[] rgRawData = m_ale.GetScreenData(m_ct);
 
  286            Tuple<DirectBitmap, SimpleDatum> data = getData(m_ct, (
int)fWid, (
int)fHt, 35, 2, rgRawData, m_bPreprocess, bGetAction, m_bForceGray);
 
  291                if (data.Item1.Bitmap.Width != nWidth || data.Item1.Bitmap.Height != nHeight)
 
  294                    bmp = 
new Bitmap(data.Item1.Bitmap);
 
  297            return new Tuple<Bitmap, SimpleDatum>(bmp, data.Item2);
 
  300        private Tuple<DirectBitmap, SimpleDatum> getData(COLORTYPE ct, 
int nWid, 
int nHt, 
int nOffset, 
int nDownsample, 
byte[] rg, 
bool bPreprocess, 
bool bGetAction, 
bool bForceGray)
 
  302            int nChannels = (bPreprocess || bForceGray) ? 1 : 3;
 
  303            int nSize = Math.Min(nWid, nHt);
 
  304            int nDsSize = nSize / nDownsample;
 
  310            if (m_bmpRaw != 
null && (m_bmpRaw.
Width != nWid || m_bmpRaw.
Height != nHt))
 
  316            if (m_bmpActionRaw != 
null && (m_bmpActionRaw.
Width != nDsSize || m_bmpActionRaw.
Height != nDsSize))
 
  319                m_bmpActionRaw = 
null;
 
  322            if (m_bmpRaw == 
null)
 
  325            if (m_bmpActionRaw == 
null)
 
  335                    dataV = 
new Valuemap(nChannels, nDsSize, nDsSize);
 
  337                    dataB = 
new Bytemap(nChannels, nDsSize, nDsSize);
 
  340            for (
int y = 0; y < nHt; y++)
 
  342                if (y % nDownsample == 0 && y > nOffset && y < nOffset + nSize)
 
  347                for (
int x = 0; x < nWid; x++)
 
  349                    int nIdx = (y * nWid) + x;
 
  354                    if (x % nDownsample == 0)
 
  359                    if (ct == COLORTYPE.CT_COLOR)
 
  361                        nG = rg[nIdx + (nWid * nHt * 1)];
 
  362                        nB = rg[nIdx + (nWid * nHt * 2)];
 
  365                    Color clr = Color.FromArgb(nR, nG, nB);
 
  371                        int nClr = (nR + nG + nB) / 3;
 
  372                        clr = Color.FromArgb(nClr, nClr, nClr);
 
  375                    if (bY && bX && (dataB != 
null || dataV != 
null))
 
  379                            if (nR != 144 && nR != 109 && nR != 0)
 
  411            return new Tuple<DirectBitmap, SimpleDatum>(bmp, sd);
 
  422            m_state = 
new AtariState();
 
  424            return new Tuple<State, double, bool>(m_state.Clone(), 1, m_ale.GameOver);
 
  434        public Tuple<State, double, bool> 
Step(
int nAction, 
bool bGetLabel, 
PropertySet propExtra = 
null)
 
  436            ACTION action = (ACTION)m_rgActionSet[nAction].Value;
 
  437            double dfReward = m_ale.Act(action);
 
  439            if (m_bEnableNumSkip)
 
  443                if (m_rgFrameSkip.Count > 1)
 
  444                    nIdx = m_random.
Next(m_rgFrameSkip.Count);
 
  446                int nNumSkip = m_rgFrameSkip[nIdx];
 
  448                for (
int i = 0; i < nNumSkip; i++)
 
  450                    dfReward += m_ale.Act(action);
 
  454            return new Tuple<State, double, bool>(
new AtariState(), dfReward, m_ale.GameOver);
 
  474                    log.
WriteLine(
"WARNING: This gym only supports the BLOB type, the datatype will be changed to BLOB.");
 
  476                    throw new Exception(
"This gym only supports the BLOB type.");
 
  495    class AtariState : State 
 
  501        public AtariState(AtariState s)
 
  505        public override State Clone()
 
  507            return new AtariState(
this);
 
  510        public override SimpleDatum GetData(
bool bNormalize, out 
int nDataLen)
 
The Bytemap operates similar to a bitmap but is actually just an array of bytes.
 
void SetPixel(int nX, int nY, byte clr)
Set a given pixel to a given color.
 
The CryptoRandom is a random number generator that can use either the standard .Net Random objec or t...
 
int Next(int nMinVal, int nMaxVal, bool bMaxInclusive=true)
Returns a random int within the range
 
The DirectBitmap class provides an efficient bitmap creating class.
 
int Height
Returns the bitmap height.
 
void Dispose()
Release all resources used.
 
void SetPixel(int x, int y, Color colour)
Sets a pixel within the bitmap with the specified color.
 
int Width
Returns the bitmap width.
 
The Log class provides general output in text form.
 
void WriteLine(string str, bool bOverrideEnabled=false, bool bHeader=false, bool bError=false, bool bDisable=false)
Write a line of output.
 
Specifies a key-value pair of properties.
 
string GetProperty(string strName, bool bThrowExceptions=true)
Returns a property as a string value.
 
int GetPropertyAsInt(string strName, int nDefault=0)
Returns a property as an integer value.
 
bool GetPropertyAsBool(string strName, bool bDefault=false)
Returns a property as a boolean value.
 
The SimpleDatum class holds a data input within host memory.
 
The Utility class provides general utility funtions.
 
static string Replace(string str, char ch1, char ch2)
Replaces each instance of one character with another character in a given string.
 
The Realmap operates similar to a bitmap but is actually just an array of doubles.
 
void SetPixel(int nX, int nY, double clr)
Set a given pixel to a given color.
 
The DatasetDescriptor class describes a dataset which contains both a training data source and testin...
 
The SourceDescriptor class contains all information describing a data source.
 
The Atari Gym provides acess to the Atari-2600 Emulator from Stella (https://github....
 
string Name
Returns the gym's name.
 
int UiDelay
Returns the delay to use (if any) when the user-display is visible.
 
Tuple< State, double, bool > Step(int nAction, bool bGetLabel, PropertySet propExtra=null)
Step the gym one step in its simulation.
 
Tuple< Bitmap, SimpleDatum > Render(bool bShowUi, int nWidth, int nHeight, bool bGetAction)
Render the gym's current state on a bitmap and SimpleDatum.
 
DATA_TYPE SelectedDataType
Returns the selected data type.
 
DatasetDescriptor GetDataset(DATA_TYPE dt, Log log=null)
Returns the dataset descriptor of the dynamic dataset produced by the Gym.
 
void Initialize(Log log, PropertySet properties)
Initialize the gym with the specified properties.
 
AtariGym()
The constructor.
 
double TestingPercent
Returns the testinng percent of -1, which then uses the default of 0.2.
 
DATA_TYPE[] SupportedDataType
Returns the data types supported by this gym.
 
bool RequiresDisplayImage
Returns true indicating that this Gym requires a display image.
 
void Dispose()
Release all resources used.
 
Tuple< State, double, bool > Reset(bool bGetLabel, PropertySet props=null)
Reset the state of the gym.
 
void Close()
Shutdown and close the gym.
 
IXMyCaffeGym Clone(PropertySet properties=null)
Create a new copy of the gym.
 
Dictionary< string, int > GetActionSpace()
Returns the action space as a dictionary of name,actionid pairs.
 
Tuple< Bitmap, SimpleDatum > Render(bool bShowUi, int nWidth, int nHeight, double[] rgData, bool bGetAction)
Render the gyms specified data.
 
The IXMyCaffeGym interface is used to interact with each Gym.
 
The descriptors namespace contains all descriptor used to describe various items stored within the da...
 
The MyCaffe.basecode contains all generic types used throughout MyCaffe.
 
GYM_TYPE
Defines the gym type (if any).
 
DATA_TYPE
Defines the gym data type.
 
The MyCaffe.gym namespace contains all classes related to the Gym's supported by MyCaffe.
 
GYM_SRC_TRAIN_ID
Defines the Standard GYM Training Data Source ID's.
 
GYM_DS_ID
Defines the Standard GYM Dataset ID's.
 
GYM_SRC_TEST_ID
Defines the Standard GYM Testing Data Source ID's.
 
The MyCaffe namespace contains the main body of MyCaffe code that closesly tracks the C++ Caffe open-...