Pac-Man Evolution
Loading...
Searching...
No Matches
Pac-Man_Evolution.cpp
1/*----------------------------------------------------------------------
2Pac-Man Evolution - Roberto Prieto
3Copyright (C) 2018-2024 MegaStorm Systems
4contact@megastormsystems.com - http://www.megastormsystems.com
5
6This software is provided 'as-is', without any express or implied
7warranty. In no event will the authors be held liable for any damages
8arising from the use of this software.
9
10Permission is granted to anyone to use this software for any purpose,
11including commercial applications, and to alter it and redistribute it
12freely, subject to the following restrictions:
13
141. The origin of this software must not be misrepresented; you must not
15claim that you wrote the original software. If you use this software
16in a product, an acknowledgment in the product documentation would be
17appreciated but is not required.
182. Altered source versions must be plainly marked as such, and must not be
19misrepresented as being the original software.
203. This notice may not be removed or altered from any source distribution.
21
22------------------------------------------------------------------------
23
24Pac-Man Evolution
25
26------------------------------------------------------------------------ */
27
28// Includes
29#include "Pac-Man_Evolution.h"
30#include "Menu.h"
31#include "HoF.h"
32#include "ResourceManager.h"
33#include "GameField.h"
34#include "BrainsFactory.h"
35#include "EVNTrainer.h"
36
37// Global vars and our render wrapper callback
38GlobalStatus globalStatus;
39Menu* pMenu = nullptr;
40HoF* pHoF = nullptr;
41GameField* pGameField = nullptr;
42
43Sint32 renderWrapper(Sint32 iMode, void* pData)
44{
45 Sint32 iRet = 0;
46
47 switch(globalStatus.iRenderScreen)
48 {
49 case PME_SCREEN_MENU:
50 if(pMenu != nullptr) iRet = pMenu->render(iMode);
51 break;
52 case PME_SCREEN_HOF:
53 if(pHoF != nullptr) iRet = pHoF->render(iMode);
54 break;
55 case PME_SCREEN_GAME:
56 if(pGameField != nullptr) iRet = pGameField->render(iMode);
57 break;
58 }
59 return iRet;
60}
61#include "ArtificialNeuralNet.h"
62
63// Main body
64int main(int argc, char* argv[])
65{
66 Sint32 iDone = PME_ENTRY, i;
67 SDL_Event eEvent;
68 Screen* pScreen;
69
70 // Initialize CMem
71 CMem::setLogLevel(CMem::eMemStatsLevel::MSL_NORMAL);
72 atexit(CMem::destroy);
73
74 // Initialize CRM64Pro
75 Main& mC64 = Main::Instance();
76 Log& mLog = *mC64.ILogMgr().get();
77 mLog.init(GAME_VERSION, LL_HIGH, LM_FILE | LM_STDOUT, "Pac-Man_Evolution.log");
78 mC64.ITimer().init();
79 mC64.ITimer().setRate(60, PME_LOGIC_RATE);
80 mC64.IConfigMgr().iMTFriendly = 1;
81
82 // Initialize the screen
83 pScreen = mC64.IConfigMgr().get();
84 pScreen->setDriver(CRD_OPENGL);
85 pScreen->setSize(1024, 768);
86 //pScreen->setMode(CSM_FULLSCREEN);
87 pScreen->setTitle(GAME_VERSION);
88 if(pScreen->show() < 0)
89 {
90 Main::Terminate();
91 return -1;
92 }
93 pScreen->setRenderCallback(renderWrapper);
94 mC64.IConfigMgr().audioInit(AF_HIGH, AS_16, AM_STEREO);
95
96 // Create the resource manager and load all resources
97 if(ResourceManager::Instance().load() != 0) // peta aqui en modo release
98 {
99 mC64.IConfigMgr().audioClose();
100 ResourceManager::Terminate();
101 Main::Terminate();
102 return -2;
103 }
104 pScreen->setIcon(mC64.IImageMgr().get(ResourceManager::Instance().get(RM_IMG_ICON))->getSurface());
105
106 // Create the menu, hof and gamefield systems
107 pMenu = new(std::nothrow) Menu();
108 pHoF = new(std::nothrow) HoF();
109 pGameField = new(std::nothrow) GameField(&globalStatus);
110
111 // MegaStorm and CRM64Pro introduction
112 mC64.intro();
113
114 // --- Quickmode: Training game ---
115 /*globalStatus.workBench.iTraining = 1;
116 globalStatus.workBench.iExecutions = 100;
117 globalStatus.workBench.iSpeed = 40;
118 globalStatus.workBench.iTime = 5;
119 globalStatus.workBench.iPacManBrain = PME_BRAIN_TYPE_FIXED; // PME_BRAIN_TYPE_HUMAN;
120 globalStatus.workBench.iGhostRedBrain = PME_BRAIN_TYPE_TRAINING0; // PME_BRAIN_TYPE_EVOLVED; //PME_BRAIN_TYPE_TRAINING0;
121 globalStatus.workBench.iGhostPinkBrain = PME_BRAIN_TYPE_TRAINING0;
122 globalStatus.workBench.iGhostBlueBrain = PME_BRAIN_TYPE_TRAINING0;
123 globalStatus.workBench.iGhostOrangeBrain = PME_BRAIN_TYPE_TRAINING0;
124 strcpy(globalStatus.workBench.szOutputCSV, "Fitness.csv");
125 // Setup new speed
126 mC64.ITimer().setRate(60, PME_LOGIC_RATE * globalStatus.workBench.iSpeed);
127 // Take care of the training
128 EVNTrainer::Instance().execute(globalStatus, *pGameField);
129 // Restore default speed
130 mC64.ITimer().setRate(60, PME_LOGIC_RATE);
131 iDone = PME_ENTRY;
132 // ---------------------------------
133
134 /**/
135 // Main loop
136 while(iDone != PME_EXIT)
137 {
138 // 1.First execution or after a game match
139 if(iDone == PME_ENTRY)
140 {
141 mC64.IMusicMgr().get(ResourceManager::Instance().get(RM_MUS_MENU))->play(-1);
142 pScreen->fadeToImage(ResourceManager::Instance().get(RM_IMG_MENU), 500);
143 mC64.ICursorMgr().show();
144 mC64.IGUIMgr().getPanel(ResourceManager::Instance().get(RM_PANEL_MENU))->baseWidget().show();
145 globalStatus.clear();
146 globalStatus.iRenderScreen = PME_SCREEN_MENU;
147 iDone = PME_LOOP;
148 }
149
150 // 2.Standard/Evolution games
151 else if((iDone == PME_GAME_STANDARD) || (iDone == PME_GAME_EVOLUTION))
152 {
153 // Hide cursor and GUI as they are not used in the game
154 mC64.ICursorMgr().hide();
155 mC64.IGUIMgr().getPanel(ResourceManager::Instance().get(RM_PANEL_MENU))->baseWidget().hide();
156
157 globalStatus.iHighestScore = pHoF->getHighest(iDone);
158 globalStatus.iLowestScore = pHoF->getLowest(iDone);
159 globalStatus.iGameType = iDone;
160 iDone = pGameField->init();
161 while(iDone == PME_LOOP)
162 {
163 iDone = pGameField->execute();
164 if(iDone == PME_MAZE_END) iDone = pGameField->nextMaze();
165 }
166 pGameField->close();
167 pHoF->store(globalStatus.iGameType, globalStatus.iPoints, globalStatus.szName);
168 iDone = PME_ENTRY;
169 }
170
171 // 3.Workbench games
172 else if(iDone == PME_GAME_WORKBENCH)
173 {
174 // Hide cursor and GUI as they are not used in the game
175 mC64.ICursorMgr().hide();
176 mC64.IGUIMgr().getPanel(ResourceManager::Instance().get(RM_PANEL_MENU))->baseWidget().hide();
177
178 // todo meter aqui el panel de workbench
179 globalStatus.workBench.iExecutions = 1;
180 globalStatus.workBench.iSpeed = 3;
181 globalStatus.workBench.iTime = 0;
182 globalStatus.workBench.iPacManBrain = PME_BRAIN_TYPE_FIXED; //PME_BRAIN_TYPE_HUMAN;// PME_BRAIN_TYPE_FIXED;
183 globalStatus.workBench.iGhostRedBrain = PME_BRAIN_TYPE_EVOLVED; //PME_BRAIN_TYPE_EVOLVED;
184 globalStatus.workBench.iGhostPinkBrain = PME_BRAIN_TYPE_EVOLVED;
185 globalStatus.workBench.iGhostBlueBrain = PME_BRAIN_TYPE_EVOLVED;
186 globalStatus.workBench.iGhostOrangeBrain = PME_BRAIN_TYPE_EVOLVED;
187 //strcpy(globalStatus.workBench.szOutputCSV, "workbench.csv");
188 // ---------------
189
190 // Setup new speed
191 mC64.ITimer().setRate(60, PME_LOGIC_RATE * globalStatus.workBench.iSpeed);
192 // Open output CSV
193 FILE* fp = fopen(globalStatus.workBench.szOutputCSV, "wt");
194 i = 0;
195 while(i < globalStatus.workBench.iExecutions)
196 {
197 globalStatus.iHighestScore = pHoF->getHighest(iDone);
198 globalStatus.iLowestScore = pHoF->getLowest(iDone);
199 globalStatus.iGameType = PME_GAME_WORKBENCH;
200 iDone = pGameField->init();
201 while(iDone == PME_LOOP)
202 {
203 iDone = pGameField->execute();
204 if(iDone == PME_MAZE_END) iDone = pGameField->nextMaze();
205 }
206 pGameField->close();
207 // Write points to the CSV after finishing a match
208 fprintf(fp, "%d,", globalStatus.iPoints);
209 fflush(fp);
210 ++i;
211 // Output fitness
212 //mLog.msg(LML_INFO, " [Pac-Man Evolution] Info: Last game fitness %.6f.\n", 1.0/(double)(globalStatus.iPoints));
213 globalStatus.iPoints = 0;
214 }
215 // Restore default speed and close the CSV file
216 fclose(fp);
217 mC64.ITimer().setRate(60, PME_LOGIC_RATE);
218 iDone = PME_ENTRY;
219 }
220
221 // 4.Manage Hall of Fame
222 else if(iDone == PME_HOF)
223 {
224 pScreen->fadeToImage(ResourceManager::Instance().get(RM_IMG_HOF), 250);
225 mC64.IGUIMgr().getPanel(ResourceManager::Instance().get(RM_PANEL_MENU))->baseWidget().hide();
226 globalStatus.iRenderScreen = PME_SCREEN_HOF;
227 iDone = PME_LOOP;
228 }
229
230 // 5.Events loop
231 while(mC64.update(&eEvent))
232 {
233 switch(eEvent.type)
234 {
235 // Quit signal
236 case SDL_EVENT_QUIT:
237 iDone = PME_EXIT;
238 break;
239 // Any pressed key or mouse click return from HoF to Menu
240 case SDL_EVENT_KEY_DOWN:
241 case SDL_EVENT_MOUSE_BUTTON_DOWN:
242 if(globalStatus.iRenderScreen == PME_SCREEN_HOF)
243 {
244 pScreen->fadeToImage(ResourceManager::Instance().get(RM_IMG_MENU), 250);
245 mC64.IGUIMgr().getPanel(ResourceManager::Instance().get(RM_PANEL_MENU))->baseWidget().show();
246 globalStatus.iRenderScreen = PME_SCREEN_MENU;
247 }
248 break;
249 // Handle C64 events
250 case C64_EVENT:
251 // Process the events in the Menu
252 if(eEvent.user.code == C64_EVENT_WIDGET) iDone = pMenu->processEvent(*static_cast<Sint32*>(eEvent.user.data1), *static_cast<Sint32*>(eEvent.user.data2));
253 break;
254 }
255 }
256 }
257
258 // Close and terminate
259 mC64.ISoundMgr().get(ResourceManager::Instance().get(RM_SND_EXIT))->play();
260 mC64.IMusicMgr().fadeOut(1000);
261 pScreen->fadeToColor(0, 0, 0, 1000);
262 delete pGameField;
263 delete pHoF;
264 delete pMenu;
265 BrainsFactory::Terminate();
266 ResourceManager::Terminate();
267 EVNTrainer::Terminate();
268 mLog.msg(LML_INFO, "\n [Pac-Man Evolution] Info: game closed.\n");
269 mC64.IConfigMgr().audioClose();
270 Main::Terminate();
271 return 0;
272}
273
274// GlobalStatus
275GlobalStatus::GlobalStatus()
276{
277 clear();
278}
279
280GlobalStatus::~GlobalStatus()
281{
282}
283
284Sint32 GlobalStatus::clear()
285{
286 iRenderScreen = -1;
287 strcpy(szName, "PacMan");
288 iPoints = 0;
289 iHighestScore = iLowestScore = 0;
290 iGameType = -1;
291 workBench.iTraining = 0;
292 workBench.iExecutions = 100;
293 workBench.iSpeed = 20;
294 workBench.iTime = 0;
295 strcpy(workBench.szOutputCSV, "workbench.csv");
296 workBench.iPacManBrain = workBench.iGhostRedBrain = workBench.iGhostPinkBrain = PME_OBJECT_NULL;
297 workBench.iGhostBlueBrain = workBench.iGhostOrangeBrain = PME_OBJECT_NULL;
298 return 0;
299}