#include <stdio.h>
#include <Windows.h>
#include <conio.h>
#include <random>
#include <time.h>
using namespace std;
void gotoxy(short x, short y)
{
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), {x, y});
}
void HideCursor(bool Visible)
{
CONSOLE_CURSOR_INFO Cursor;
Cursor.bVisible = !Visible;
Cursor.dwSize = sizeof(Cursor);
SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &Cursor);
}
void Color(int clr)
{
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), clr);
}
int lefts, ups, high, width, blank, mp[105][205], vis[105][205];
int state, dir, nx, ny, gx, gy;
int mx[5] = {0, -1, 0, 1, 0};
int my[5] = {0, 0, -1, 0, 1};
char out[10] = {' ', '@', '#', 'O'}, key;
mt19937 rd(time(0));
void rand_pos(int &x, int &y, int z)
{
int sum = rd() % ((high - 2) * (width - 2) - blank - 1) + 1;
for (int i = 2; i < high; i++)
{
if (!sum) break;
for (int j = 2; j < width; j++) if (!mp[i][j])
{
sum--;
if (!sum)
{
x = i, y = j, mp[i][j] = z;
break;
}
}
}
}
void init_map()
{
mp[1][1] = mp[1][width] = mp[high][1] = mp[high][width] = 2;
for (int i = 2; i < high; i++) mp[i][1] = mp[i][width] = 2;
for (int i = 2; i < width; i++) mp[1][i] = mp[high][i] = 2;
for (int i = 2; i < high; i++) for (int j = 2; j < width; j++) mp[i][j] = 0;
blank = 0;
}
bool checkpos(int x, int y)
{
return x >= 2 && x < high && y >= 2 && y < width;
}
void dfs(int x, int y)
{
vis[x][y] = 1;
for (int i = 1; i <= 4; i++)
{
int X = x + mx[i], Y = y + my[i];
if (!checkpos(X, Y) || vis[X][Y] || mp[X][Y] == 2) continue;
dfs(X, Y);
}
}
bool check()
{
for (int i = 2; i < high; i++) for (int j = 2; j < width; j++) vis[i][j] = 0;
dfs(nx, ny);
return vis[gx][gy];
}
void init_ice()
{
int sum = rd() % ((high - 2) * (width - 2) - blank);
while (sum--)
{
int x, y;
rand_pos(x, y, 2);
if (!check()) return mp[x][y] = 0, void();
}
}
void print_map()
{
gotoxy(0, 0);
for (int i = 1; i <= ups; i++) printf("\n");
for (int i = 1; i <= high; i++)
{
for (int j = 1; j <= lefts; j++) printf(" ");
for (int j = 1; j <= width; j++)
{
Color(0x0F);
if (mp[i][j] == 1) Color(0x0A);
if (mp[i][j] == 3) Color(0x0C);
printf("%c", out[mp[i][j]]);
}
printf("\n");
}
}
char input_action()
{
char ch;
while (1) if (_kbhit())
{
ch = _getch();
break;
}
return ch;
}
void check_direction(char ch)
{
if (ch == 'w') dir = 1;
if (ch == 'a') dir = 2;
if (ch == 's') dir = 3;
if (ch == 'd') dir = 4;
}
void print_man(int x, int y)
{
mp[nx][ny] = 2;
gotoxy(lefts + ny - 1, ups + nx - 1), printf("%c", out[2]);
nx = x, ny = y;
Color(0x0A);
gotoxy(lefts + ny - 1, ups + nx - 1), printf("%c", out[1]);
Color(0x0F);
}
void man_move()
{
int x = nx + mx[dir], y = ny + my[dir];
if (!checkpos(x, y) || mp[x][y] == 2) return;
int xx = x + mx[dir], yy = y + my[dir];
while (checkpos(xx, yy) && mp[xx][yy] != 2)
{
x = x + mx[dir], y = y + my[dir];
xx = x + mx[dir], yy = y + my[dir];
}
if (x == gx && y == gy) state = 1;
print_man(x, y);
}
void init()
{
init_map(), rand_pos(nx, ny, 1), rand_pos(gx, gy, 3), init_ice(), print_map();
state = 0;
}
int main()
{
system("mode con cols=135 lines=47");
lefts = 7, ups = 3;
high = 40, width = 120;
HideCursor(true);
init();
while (1)
{
key = input_action();
check_direction(key);
if (dir)
{
man_move();
if (!check())
{
state = 1;
gotoxy(0, 0), Color(0x0C), printf("Fail "), Color(0x0F);
Sleep(300);
system("pause");
gotoxy(0, 0), printf(" ");
}
if (state) init();
}
}
return 0;
}