poita said:
What was it about A* that you didn't understand?
I don't know, everything? The entire idea is illogical.
That, and the fact people say A* as if it has meaning.
According to the few links I've read, A* is never the same.
The examples I've read have 20,000 things that aren't required, meaning I have to try and learn what's for the Win32 crap, and what's valid.
People can't make a simple basic program with the bare neccessities to show the A* algorithm.
Either way, it doesn't really matter. I'm just posting what I slowly change, as I change it, and speaking of which:
I found three or four logical bugs in that.
This is the newest version (and I'm confused as to why it does this now):
#include <iostream>
#include <vector>
#include <TextControl.h>
using namespace std;
int TotalRuns = 0;
int TotalCrashes = 0;
int FoodX = 0;
int FoodY = 0;
int SnakeX[100] = {'\0'};
int SnakeY[100] = {'\0'};
vector<int> Instructions;
void DrawSnake(const int, int, int);
bool Crash(const int X[], const int Y[]) {
for (int x = 9; x > 1; x--) {
if (X[0] == X[x] && Y[0] == Y[x]) {
PlaceCursor(0, 45);
SetColor(RED, BLACK);
printf("X: %d ", X[0]);
PlaceCursor(0, 46);
SetColor(RED, BLACK);
printf("Y: %d ", Y[0]);
//Sleep(250);
return true;
}
}
return false;
}
void CreatePath() {
Instructions.clear();
int TempX[100] = {'\0'};
int TempY[100] = {'\0'};
/* Copy Snake location */
for (int x = 0; x < 100; x++) {
TempX[x] = SnakeX[x];
TempY[x] = SnakeY[x];
}
int TempNum = 0;
while (TempX[0] != FoodX || TempY[0] != FoodY) {
if (FoodX > TempX[0]) {
TempX[0]++; Instructions.push_back(3);
while (Crash(TempX, TempY)) {
switch (TempNum) {
case 0: { TempX[0]++; } break;
case 1: { TempY[0]--; } break;
case 2: { TempX[0]++; } break;
case 3: { TempY[0]--; } break;
}
Instructions.back() = TempNum;
PlaceCursor(0, 35); printf("%d", TempNum);
TempNum++;
Sleep(250);
if (TempNum >= 4) { break; }
}
}
if (FoodX < TempX[0]) {
TempX[0]--; Instructions.push_back(2);
while (Crash(TempX, TempY)) {
switch (TempNum) {
case 0: { TempX[0]++; } break;
case 1: { TempY[0]--; } break;
case 2: { TempX[0]++; } break;
case 3: { TempY[0]--; } break;
}
Instructions.back() = TempNum;
PlaceCursor(0, 35); printf("%d", TempNum);
TempNum++;
Sleep(250);
if (TempNum >= 4) { break; }
}
}
if (FoodY > TempY[0]) {
TempY[0]++; Instructions.push_back(1);
while (Crash(TempX, TempY)) {
switch (TempNum) {
case 0: { TempX[0]++; } break;
case 1: { TempY[0]--; } break;
case 2: { TempX[0]++; } break;
case 3: { TempY[0]--; } break;
}
Instructions.back() = TempNum;
PlaceCursor(0, 35); printf("%d", TempNum);
TempNum++;
Sleep(250);
if (TempNum >= 4) { break; }
}
}
if (FoodY < TempY[0]) {
TempY[0]--; Instructions.push_back(0);
while (Crash(TempX, TempY)) {
switch (TempNum) {
case 0: { TempX[0]++; } break;
case 1: { TempY[0]--; } break;
case 2: { TempX[0]++; } break;
case 3: { TempY[0]--; } break;
}
Instructions.back() = TempNum;
PlaceCursor(0, 35); printf("%d", TempNum);
TempNum++;
Sleep(250);
if (TempNum >= 4) { break; }
}
}
TempNum = 0;
//Sleep(50);
//DrawSnake(RED, TempX, TempY);
}
SetColor(CYAN, BLACK);
PlaceCursor(25, 0);
printf("AI PATH COMPLETED");
Sleep(500);
PlaceCursor(25, 0);
printf(" ");
return;
}
void DrawSnake(const int color, int Xz[], int Yz[]) {
SetColor(color, BLACK);
for (int x = 10; x > 0; x--) { Xz[x] = Xz[x - 1]; Yz[x] = Yz[x - 1]; }
for (int x = 10; x >= 0; x--) { PlaceCursor(Xz[x], Yz[x]); printf("*"); }
SetColor(GREEN, BLACK);
PlaceCursor(Xz[0], Yz[0]); printf("@");
//PlaceCursor(Xz[10], Yz[10]); SetColor(BLACK, BLACK); printf(" ");
if (Xz[0] != Xz[10] || Yz[0] != Yz[10]) { PlaceCursor(Xz[10], Yz[10]); SetColor(BLACK, BLACK); printf(" "); }
return;
}
void RunPath(const int color) {
/* It'll crash sometimes if it randomly is empty */
if (!Instructions.empty()) {
SetColor(color, BLACK);
for (int x = 0; x < Instructions.size(); x++) {
switch (Instructions.at(x)) {
case 0: SnakeY[0]--; break;
case 1: SnakeY[0]++; break;
case 2: SnakeX[0]--; break;
case 3: SnakeX[0]++; break;
}
Sleep(50);
DrawSnake(color, SnakeX, SnakeY);
if (Crash(SnakeX, SnakeY)) { for (int x = 0; x < 100; x++) { SnakeX[x] = 5; SnakeY[x] = 5; } Instructions.clear(); }
}
}
return;
}
void NewRun() {
FoodX = rand() % 70 + 5;
FoodY = rand() % 25 + 5;
PlaceCursor(FoodX, FoodY);
SetColor(YELLOW, BLACK);
printf("x");
Instructions.clear();
return;
}
void SpawnFood(const int X, const int Y) {
if (SnakeX[0] == FoodX && SnakeY[0] == FoodY) {
FoodX = X;
FoodY = Y;
PlaceCursor(FoodX, FoodY);
SetColor(YELLOW, BLACK);
printf("x");
} else {
SetColor(CYAN, BLACK);
PlaceCursor(0, 0);
printf("SnakeX: %d ", SnakeX[0]);
PlaceCursor(0, 1);
printf("SnakeY: %d ", SnakeY[0]);
}
return;
}
int main() {
HANDLE OutHandle = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleTitle("Snake - AI Module");
SMALL_RECT windowSize = {0, 0, 79, 49};
SetConsoleWindowInfo(OutHandle, TRUE, &windowSize);
ClearConsole(BLACK, BLACK);
RemoveCursor();
srand(time(NULL));
SnakeX[0] = 60;
SnakeY[0] = 25;
FoodX = 60;
FoodY = 25;
Instructions.clear();
while (true) {
SpawnFood(25, 25);
CreatePath();
RunPath(BLUE);
SpawnFood(25, 40);
CreatePath();
RunPath(BLUE);
SpawnFood(30, 20);
CreatePath();
RunPath(BLUE);
SpawnFood(25, 20);
CreatePath();
RunPath(BLUE);
SpawnFood(35, 20);
CreatePath();
RunPath(BLUE);
}
cin.get();
return 0;
}
Specifically what's confusing is: The Snake (when "thinking") does not follow the same "rules" as the Snake when it's really running. They follow two different paths, which is fucking whacko. The AI Snake will take an actual SHORTER and ANGLED path, when the real Snake is forced to take UP then RIGHT then UP then RIGHT (no angled movements). This time, I'm dead-positive there isn't a logical error, as you can clearly see the code, it uses the same DrawSnake function, and it uses the same vector for instructions.
Thanks for any help/advice (not that I'm expecting any anymore). :)
Snake AI not shown: Snake AI hidden (YouTube)
Snake AI shown: Snake AI (YouTube)
The logical error has nothing to do with DrawSnake function.
I'm starting to think perhaps it's how I have the instructions set up...
Both the AI and the "real" Snake share the same instruction vector - perhaps that's it?












