Repository navigation
Expand file tree
/
Copy pathObserve.cpp
More file actions
121 lines (99 loc) · 3.36 KB
/
Copy pathObserve.cpp
File metadata and controls
121 lines (99 loc) · 3.36 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
#include "Observe.h"
#include "PostGameMenu.h"
// Globals defined in Main.cpp
extern float SCREEN_WIDTH;
extern float SCREEN_HEIGHT;
extern int amt;
extern const int GRID_SIZE;
extern float wallthickness;
extern const float CELL_SIZE;
extern bool gameOver;
extern bool specialmessage;
extern bool ContinueGame;
extern bool AIMODE;
// From world/food
extern sf::Vector2i appleXY;
Observe::Observe(const std::vector<double>& bestGenome)
: m_best(bestGenome)
{
}
int Observe::Run()
{
// Reset shared game state for a clean episode
AIMODE = true; // we're letting AI drive
gameOver = false;
ContinueGame = true;
specialmessage = false;
amt = 0;
// Create window (SFML 3 style)
sf::VideoMode videoMode(sf::Vector2u(
static_cast<unsigned>(SCREEN_WIDTH),
static_cast<unsigned>(SCREEN_HEIGHT)
));
sf::RenderWindow window(videoMode, "Snake AI - Observe Best");
window.setFramerateLimit(60);
// Init world & entities
initWorld(SCREEN_WIDTH, SCREEN_HEIGHT, wallthickness);
Snake snake;
Food apple;
appleXY = apple.apple(snake); // first apple
sf::Clock moveClock;
double moveInterval = 0.13; // same speed as your main loop
while (window.isOpen() && !gameOver && ContinueGame)
{
// --- Events (SFML 3: pollEvent -> optional) ---
while (auto event = window.pollEvent())
{
if (event->is<sf::Event::Closed>())
{
window.close();
ContinueGame = false;
break;
}
}
if (!window.isOpen() || !ContinueGame)
break;
// --- Step the AI & game at fixed interval ---
if (moveClock.getElapsedTime().asSeconds() >= moveInterval && !gameOver)
{
// 1) Build inputs from current state
// appleXY is already in grid coords
std::vector<double> inputs =
AI::getSensorInputs(snake, appleXY, GRID_SIZE);
// 2) Forward pass with best genome
std::vector<double> outputs =
AI::forward(inputs, m_best);
// 3) Map outputs -> direction (assume sf::Vector2i)
sf::Vector2i dir = AI::getDirection(outputs, snake);
snake.SetDirection(dir.x, dir.y);
// 4) Move snake
snake.move();
// 5) Collisions / score logic (mirrors your main loop)
if (snake.checkSelfCollision())
gameOver = true;
if (DidItHitWall(snake))
gameOver = true;
if (AreYaWinningSon(snake))
{
gameOver = true;
specialmessage = true;
}
if (DidItEat(snake))
{
snake.grow();
amt = apple.pointz();
appleXY = apple.apple(snake);
}
moveClock.restart();
}
// --- Render current state ---
window.clear();
drawWorld(window);
drawApple(window, appleXY);
drawSnake(window, snake, CELL_SIZE);
PostGameMenu::ShowPts(window); // Show score
window.display();
}
// When we leave (death/win/close), return the score this genome achieved
return amt;
}