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-...