1 #include "AntSimulatorFast.hpp"
2
AntSimulatorFast(unsigned int inMaxMoves)3 AntSimulatorFast::AntSimulatorFast(unsigned int inMaxMoves) :
4 mMaxMoves(inMaxMoves),
5 mNbPiecesAvail(0),
6 mRowStart(0),
7 mColStart(0),
8 mDirectionStart(AntSimulatorFast::eAntEast),
9 mNbMovesAnt(0),
10 mNbPiecesEaten(0),
11 mRowAnt(0),
12 mColAnt(0),
13 mDirectionAnt(AntSimulatorFast::eAntEast)
14 { }
15
16
parseMatrix(char * inFileStr)17 void AntSimulatorFast::parseMatrix(char* inFileStr){
18 std::fstream lFileHandle;
19
20 lFileHandle.open(inFileStr, std::fstream::in);
21
22 mOrigTrail.resize(ROWS_NBR);
23 mExecTrail.resize(ROWS_NBR);
24 for(unsigned int i = 0; i < ROWS_NBR; i++){
25 mOrigTrail[i].resize(COLS_NBR);
26 mExecTrail[i].resize(COLS_NBR);
27 }
28
29 char lBuffer;
30 for(unsigned int i=0; i<mOrigTrail.size(); ++i) {
31 for(unsigned int j=0; j<mOrigTrail[i].size(); ++j) {
32 lFileHandle >> lBuffer;
33 switch(lBuffer) {
34 case eStart: {
35 mOrigTrail[i][j] = eStart;
36 mRowStart = i;
37 mColStart = j;
38 mExecTrail[i][j] = eStart;
39 break;
40 }
41 case eEmpty:
42 case eFoodPiece: {
43 mOrigTrail[i][j] = lBuffer;
44 mExecTrail[i][j] = lBuffer;
45 break;
46 }
47 case ePassed: {
48 mOrigTrail[i][j] = eEmpty;
49 mExecTrail[i][j] = ePassed;
50 break;
51 }
52 case eEatenPiece: {
53 mOrigTrail[i][j] = eFoodPiece;
54 mExecTrail[i][j] = eEatenPiece;
55 break;
56 }
57 case eAntNorth:
58 case eAntEast:
59 case eAntSouth:
60 case eAntWest: {
61 mOrigTrail[i][j] = eEmpty;
62 mExecTrail[i][j] = lBuffer;
63 break;
64 }
65 default: { }
66 }
67 }
68 }
69 lFileHandle.close();
70 }
71
72
turnLeft(void)73 void AntSimulatorFast::turnLeft(void){
74 if(mNbMovesAnt >= mMaxMoves) return;
75 ++mNbMovesAnt;
76 switch(mDirectionAnt) {
77 case eAntNorth: {
78 mDirectionAnt = eAntWest;
79 break;
80 }
81 case eAntEast: {
82 mDirectionAnt = eAntNorth;
83 break;
84 }
85 case eAntSouth: {
86 mDirectionAnt = eAntEast;
87 break;
88 }
89 case eAntWest: {
90 mDirectionAnt = eAntSouth;
91 break;
92 }
93 default: { }
94 }
95 }
96
turnRight(void)97 void AntSimulatorFast::turnRight(void){
98 if(mNbMovesAnt >= mMaxMoves) return;
99 ++mNbMovesAnt;
100 switch(mDirectionAnt) {
101 case eAntNorth: {
102 mDirectionAnt = eAntEast;
103 break;
104 }
105 case eAntEast: {
106 mDirectionAnt = eAntSouth;
107 break;
108 }
109 case eAntSouth: {
110 mDirectionAnt = eAntWest;
111 break;
112 }
113 case eAntWest: {
114 mDirectionAnt = eAntNorth;
115 break;
116 }
117 default: { }
118 }
119 }
120
121
moveForward(void)122 void AntSimulatorFast::moveForward(void){
123 if(mNbMovesAnt >= mMaxMoves) return;
124 ++mNbMovesAnt;
125
126 switch(mDirectionAnt) {
127 case eAntNorth: {
128 if(mRowAnt == 0) mRowAnt = (mExecTrail.size()-1);
129 else --mRowAnt;
130 break;
131 }
132 case eAntEast: {
133 ++mColAnt;
134 if(mColAnt >= mExecTrail.front().size()) mColAnt = 0;
135 break;
136 }
137 case eAntSouth: {
138 ++mRowAnt;
139 if(mRowAnt >= mExecTrail.size()) mRowAnt = 0;
140 break;
141 }
142 case eAntWest: {
143 if(mColAnt == 0) mColAnt = (mExecTrail.front().size()-1);
144 else --mColAnt;
145 break;
146 }
147 default: { }
148 }
149 switch(mExecTrail[mRowAnt][mColAnt]) {
150 case eStart:
151 case ePassed:
152 case eEatenPiece:
153 break;
154 case eEmpty: {
155 mExecTrail[mRowAnt][mColAnt] = ePassed;
156 break;
157 }
158 case eFoodPiece: {
159 mExecTrail[mRowAnt][mColAnt] = eEatenPiece;
160 ++mNbPiecesEaten;
161 break;
162 }
163 default: { }
164 }
165 }
166
ifFoodAhead(PyObject * inIfTrue,PyObject * inIfFalse)167 void AntSimulatorFast::ifFoodAhead(PyObject* inIfTrue, PyObject* inIfFalse){
168 unsigned int lAheadRow = mRowAnt;
169 unsigned int lAheadCol = mColAnt;
170 switch(mDirectionAnt) {
171 case eAntNorth: {
172 if(lAheadRow == 0) lAheadRow = (mExecTrail.size()-1);
173 else --lAheadRow;
174 break;
175 }
176 case eAntEast: {
177 ++lAheadCol;
178 if(lAheadCol >= mExecTrail.front().size()) lAheadCol = 0;
179 break;
180 }
181 case eAntSouth: {
182 ++lAheadRow;
183 if(lAheadRow >= mExecTrail.size()) lAheadRow = 0;
184 break;
185 }
186 case eAntWest: {
187 if(lAheadCol == 0) lAheadCol = (mExecTrail.front().size()-1);
188 else --lAheadCol;
189 break;
190 }
191 default: { }
192 }
193
194 PyObject_CallFunctionObjArgs((mExecTrail[lAheadRow][lAheadCol] == eFoodPiece) ? inIfTrue : inIfFalse, NULL);
195 }
196
run(PyObject * inWrappedFunc)197 void AntSimulatorFast::run(PyObject* inWrappedFunc){
198 this->reset();
199 while(mNbMovesAnt < mMaxMoves)
200 PyObject_CallFunctionObjArgs(inWrappedFunc, NULL);
201 }
202
reset(void)203 void AntSimulatorFast::reset(void){
204 mExecTrail = mOrigTrail;
205 mNbMovesAnt = 0;
206 mNbPiecesEaten = 0;
207 mRowAnt = mRowStart;
208 mColAnt = mColStart;
209 mDirectionAnt = mDirectionStart;
210 }
211
212
213 /*
214 *
215 * Python wrappers
216 *
217 *
218 */
219
220 typedef struct {
221 PyObject_HEAD
222 AntSimulatorFast *mInnerClass;
223 } AntSimulatorWrapper;
224
225
wrapAntSimulatorConstructor(AntSimulatorWrapper * self,PyObject * args,PyObject * kwargs)226 static int wrapAntSimulatorConstructor(AntSimulatorWrapper *self, PyObject *args, PyObject *kwargs){
227 int lMaxMoves;
228 const char *keywords[] = {"max_moves", NULL};
229
230 if (!PyArg_ParseTupleAndKeywords(args, kwargs, (char *) "i", (char **) keywords, &lMaxMoves)) {
231 return -1;
232 }
233 self->mInnerClass = new AntSimulatorFast(lMaxMoves);
234 return 0;
235 }
236
wrapTurnLeft(AntSimulatorWrapper * self)237 static PyObject* wrapTurnLeft(AntSimulatorWrapper *self){
238 self->mInnerClass->turnLeft();
239 Py_INCREF(Py_None);
240 return Py_None;
241 }
242
wrapTurnRight(AntSimulatorWrapper * self)243 static PyObject* wrapTurnRight(AntSimulatorWrapper *self){
244 self->mInnerClass->turnRight();
245 Py_INCREF(Py_None);
246 return Py_None;
247 }
248
wrapMoveForward(AntSimulatorWrapper * self)249 static PyObject* wrapMoveForward(AntSimulatorWrapper *self){
250 self->mInnerClass->moveForward();
251 Py_INCREF(Py_None);
252 return Py_None;
253 }
254
wrapIfFoodAhead(AntSimulatorWrapper * self,PyObject * args)255 static PyObject* wrapIfFoodAhead(AntSimulatorWrapper *self, PyObject *args){
256 self->mInnerClass->ifFoodAhead(PyTuple_GET_ITEM(args, 0),
257 PyTuple_GET_ITEM(args, 1));
258 Py_INCREF(Py_None);
259 return Py_None;
260 }
261
wrapRun(AntSimulatorWrapper * self,PyObject * args)262 static PyObject* wrapRun(AntSimulatorWrapper *self, PyObject *args){
263 PyObject* func = PyTuple_GetItem(args, 0);
264 self->mInnerClass->run(func);
265 Py_INCREF(Py_None);
266 return Py_None;
267 }
268
wrapParseMatrix(AntSimulatorWrapper * self,PyObject * args)269 static PyObject* wrapParseMatrix(AntSimulatorWrapper *self, PyObject *args){
270 self->mInnerClass->parseMatrix(PyString_AsString(PyFile_Name(PyTuple_GetItem(args, 0))));
271 Py_INCREF(Py_None);
272 return Py_None;
273 }
274
wrapGetEaten(AntSimulatorWrapper * self,void * closure)275 static PyObject* wrapGetEaten(AntSimulatorWrapper *self, void *closure){
276 PyObject *py_retval;
277
278 py_retval = Py_BuildValue((char *) "i", self->mInnerClass->mNbPiecesEaten);
279 return py_retval;
280 }
281
282 // Getters and setters (here only for the 'eaten' attribute)
283 static PyGetSetDef AntSimulatorWrapper_getsets[] = {
284 {
285 (char*) "eaten", /* attribute name */
286 (getter) wrapGetEaten, /* C function to get the attribute */
287 NULL, /* C function to set the attribute */
288 NULL, /* optional doc string */
289 NULL /* optional additional data for getter and setter */
290 },
291 { NULL, NULL, NULL, NULL, NULL }
292 };
293
294 // Class method declarations
295 static PyMethodDef AntSimulatorWrapper_methods[] = {
296 {(char *) "turn_left", (PyCFunction) wrapTurnLeft, METH_NOARGS, NULL },
297 {(char *) "turn_right", (PyCFunction) wrapTurnRight, METH_NOARGS, NULL },
298 {(char *) "move_forward", (PyCFunction) wrapMoveForward, METH_NOARGS, NULL },
299 {(char *) "if_food_ahead", (PyCFunction) wrapIfFoodAhead, METH_VARARGS, NULL },
300 {(char *) "parse_matrix", (PyCFunction) wrapParseMatrix, METH_VARARGS, NULL },
301 {(char *) "run", (PyCFunction) wrapRun, METH_VARARGS, NULL },
302 {NULL, NULL, 0, NULL}
303 };
304
AntSimulatorWrapperDealloc(AntSimulatorWrapper * self)305 static void AntSimulatorWrapperDealloc(AntSimulatorWrapper *self){
306 delete self->mInnerClass;
307 self->ob_type->tp_free((PyObject*)self);
308 }
309
AntSimulatorWrapperRichcompare(AntSimulatorWrapper * self,AntSimulatorWrapper * other,int opid)310 static PyObject* AntSimulatorWrapperRichcompare(AntSimulatorWrapper *self, AntSimulatorWrapper *other, int opid){
311 Py_INCREF(Py_NotImplemented);
312 return Py_NotImplemented;
313 }
314
315
316 PyTypeObject AntSimulatorWrapper_Type = {
317 PyObject_HEAD_INIT(NULL)
318 0, /* ob_size */
319 (char *) "AntC.AntSimulatorFast", /* tp_name */
320 sizeof(AntSimulatorWrapper), /* tp_basicsize */
321 0, /* tp_itemsize */
322 /* methods */
323 (destructor)AntSimulatorWrapperDealloc, /* tp_dealloc */
324 (printfunc)0, /* tp_print */
325 (getattrfunc)NULL, /* tp_getattr */
326 (setattrfunc)NULL, /* tp_setattr */
327 (cmpfunc)NULL, /* tp_compare */
328 (reprfunc)NULL, /* tp_repr */
329 (PyNumberMethods*)NULL, /* tp_as_number */
330 (PySequenceMethods*)NULL, /* tp_as_sequence */
331 (PyMappingMethods*)NULL, /* tp_as_mapping */
332 (hashfunc)NULL, /* tp_hash */
333 (ternaryfunc)NULL, /* tp_call */
334 (reprfunc)NULL, /* tp_str */
335 (getattrofunc)NULL, /* tp_getattro */
336 (setattrofunc)NULL, /* tp_setattro */
337 (PyBufferProcs*)NULL, /* tp_as_buffer */
338 Py_TPFLAGS_DEFAULT, /* tp_flags */
339 NULL, /* Documentation string */
340 (traverseproc)NULL, /* tp_traverse */
341 (inquiry)NULL, /* tp_clear */
342 (richcmpfunc)AntSimulatorWrapperRichcompare, /* tp_richcompare */
343 0, /* tp_weaklistoffset */
344 (getiterfunc)NULL, /* tp_iter */
345 (iternextfunc)NULL, /* tp_iternext */
346 (struct PyMethodDef*)AntSimulatorWrapper_methods, /* tp_methods */
347 (struct PyMemberDef*)0, /* tp_members */
348 AntSimulatorWrapper_getsets, /* tp_getset */
349 NULL, /* tp_base */
350 NULL, /* tp_dict */
351 (descrgetfunc)NULL, /* tp_descr_get */
352 (descrsetfunc)NULL, /* tp_descr_set */
353 0, /* tp_dictoffset */
354 (initproc)wrapAntSimulatorConstructor, /* tp_init */
355 (allocfunc)PyType_GenericAlloc, /* tp_alloc */
356 (newfunc)PyType_GenericNew, /* tp_new */
357 (freefunc)0, /* tp_free */
358 (inquiry)NULL, /* tp_is_gc */
359 NULL, /* tp_bases */
360 NULL, /* tp_mro */
361 NULL, /* tp_cache */
362 NULL, /* tp_subclasses */
363 NULL, /* tp_weaklist */
364 (destructor) NULL /* tp_del */
365 };
366
progn(PyObject * self,PyObject * args)367 PyObject* progn(PyObject *self, PyObject *args){
368 for(Py_ssize_t i = 0; i < PyTuple_Size(args); i++)
369 PyObject_CallFunctionObjArgs(PyTuple_GET_ITEM(args, i), NULL);
370 Py_INCREF(Py_None);
371 return Py_None;
372 }
373
374 static PyMethodDef AntC_functions[] = {
375 {"progn", progn, METH_VARARGS, "Boum"},
376 {NULL, NULL, 0, NULL}
377 };
378
379 PyMODINIT_FUNC
initAntC(void)380 initAntC(void)
381 {
382 PyObject *m;
383 m = Py_InitModule3((char *) "AntC", AntC_functions, NULL);
384 if (m == NULL) {
385 return;
386 }
387 /* Register the 'AntSimulatorWrapper' class */
388 if (PyType_Ready(&AntSimulatorWrapper_Type)) {
389 return;
390 }
391 PyModule_AddObject(m, (char *) "AntSimulatorFast", (PyObject *) &AntSimulatorWrapper_Type);
392 }
393