/* The original version of this program can be found at http://damb.dk */
#include <windows.h>
#include <stdio.h>
#include <limits.h>
#include <list>
#include <time.h>
#include <string>
#include <fstream>
#include <map>
#include <iostream>
#ifdef __BORLANDC__
#pragma warn -8030
#pragma warn -8027
#endif
#define MAX_DEPTH 256
#define X_SIZE 33
#define Y_SIZE 24
#define FREQ 50 // 50 tick/sec
HANDLE StdOut, StdIn;
int YOffset;
void GotoXY(int x, int y);
void GetXY(int &x, int &y);
BOOL IsKeyPressed(int Key);
void OutCharXY(int x, int y, char ch, WORD attr);
BOOL KeyHit();
WORD GetChar();
void ShowCaret(BOOL on);
int GetYOffset();
int GetYSize();
int GetXSize();
void Intro();
void ClearScreen();
int Score;
unsigned char Maze[Y_SIZE][X_SIZE] =
{
{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
{1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
{1,0,1,0,1,1,1,1,1,1,1,0,1,0,1,0,1,1,1,1,0,1,0,1,0,1,1,1,1,1,1,0,1},
{1,0,1,0,0,0,0,0,0,0,1,0,1,0,1,0,0,0,0,1,0,1,0,1,0,1,0,0,0,0,0,0,1},
{1,0,1,0,1,1,1,0,1,0,1,0,1,0,1,1,1,1,0,1,0,1,0,1,0,1,0,1,1,1,1,0,1},
{1,0,1,0,1,1,1,0,1,0,0,0,1,0,1,0,0,0,0,1,0,1,0,1,0,1,0,1,0,0,0,0,1},
{1,0,1,0,0,0,0,0,1,0,1,1,1,0,1,0,1,1,1,1,0,1,0,1,0,1,0,1,0,1,1,0,1},
{1,0,1,0,1,1,1,0,1,0,0,0,0,0,1,0,0,0,0,1,0,1,0,0,0,1,0,1,0,1,1,0,1},
{1,0,1,0,1,1,1,0,1,1,1,1,1,0,1,1,1,1,0,1,0,1,1,1,1,1,0,1,0,1,1,0,1},
{1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,1},
{1,0,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1},
{1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
{1,0,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1},
{1,0,1,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
{1,0,1,0,1,0,1,0,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,0,1},
{1,0,1,0,1,0,1,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1},
{1,0,1,0,0,0,0,0,0,0,1,0,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,0,1,0,1},
{1,0,1,0,1,0,1,1,1,0,1,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0,1,0,1,0,1},
{1,0,1,0,1,0,0,0,1,0,1,0,1,0,1,1,1,1,1,0,1,0,1,0,1,1,1,0,0,0,1,0,1},
{1,0,1,0,1,0,1,0,1,0,1,0,1,0,0,0,0,0,1,0,1,0,1,0,1,1,1,1,1,0,1,0,1},
{1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,0,0,0,0,1,0,1,0,1},
{1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,1,1,1,1,0,1,0,1,0,1},
{1,0,0,0,1,0,0,0,1,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,1},
{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}
};
class HighScoreClass
{
public:
HighScoreClass(const char *filename) : FileName(filename)
{
std::ifstream f(FileName.c_str());
if(!f)
return;
while(Table.size() < 10)
{
std::string Line;
std::getline(f, Line);
std::string::size_type idx = Line.find(' ');
if(idx == Line.npos)
return;
std::string ScoreStr = Line.substr(0, idx);
std::string Name = Line.substr(idx + 1);
int Score = strtol(ScoreStr.c_str(), 0, 10);
Table.insert(std::make_pair(Score, Name));
}
}
void CheckInsert(int Score)
{
bool Insert = false;
if(Table.size() < 10)
Insert = true;
else
{
std::multimap<int, std::string>::iterator i = Table.begin();
if(i->first < Score)
Insert = true;
}
if(Insert)
{
if(Table.size() >= 10)
Table.erase(Table.begin());
printf("Congratulations, you entered the highscorenEnter your name:");
fflush(stdout);
std::string Name;
std::getline(std::cin, Name);
Table.insert(std::make_pair(Score, Name));
}
}
void PrintHighScore()
{
std::multimap<int, std::string>::reverse_iterator i;
printf("Highscore Table:n");
for(i = Table.rbegin(); i != Table.rend(); i++)
printf("%5d %sn", i->first, i->second.c_str());
}
~HighScoreClass()
{
std::ofstream f(FileName.c_str());
if(!f)
{
printf("Failed to open highscore file!n");
return;
}
std::multimap<int, std::string>::iterator i;
for(i = Table.begin(); i != Table.end(); i++)
f << i->first << " " << i->second.c_str() << std::endl;
}
private:
std::string FileName;
std::multimap<int, std::string> Table;
HighScoreClass(); // Don't let the user create me without a filename, use the other constructor
};
void ShowStatus(int Energy, int NumBombs)
{
char Buffer[256], *s;
int i;
sprintf(Buffer, "%5d ", Energy);
for(s = Buffer, i = 0; *s; s++, i++)
OutCharXY(i, -1, *s, FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED);
for(; NumBombs && i < X_SIZE - 6; i++, NumBombs--)
OutCharXY(i, -1, (char )224, FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED);
for(; i < X_SIZE - 6; i++)
OutCharXY(i, -1, ' ', FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED);
sprintf(Buffer, "%5d", Score);
for(s = Buffer; *s; s++, i++)
OutCharXY(i, -1, *s, FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED);
}
int Random(int Range)
{
return (rand() >> 3)%Range;
}
class Point
{
public:
Point(int x_, int y_) : x(x_), y(y_)
{}
Point() : x(0), y(0) {}
int x;
int y;
};
enum ObjTypeEnum
{
Path, // Must be 0 due to defintion of Maze[][]
Free = Path,
Wall, // Must be 1 due to defintion of Maze[][]
Man,
Sharp,
BombTreasure,
Bomb,
Dot
};
class ObjectBaseClass
{
public:
ObjectBaseClass(int x, int y, int freq, ObjTypeEnum Type) : ObjType(Type)
{
XPos = x;
YPos = y;
Period = FREQ/freq;
Tick = 0;
}
virtual ~ObjectBaseClass() {} ;
virtual bool Trigger() = 0;
virtual bool IsAt(int x, int y)
{
return XPos == x && YPos == y;
}
virtual bool IsA(ObjTypeEnum type)
{
return ObjType == type;
}
int GetXPos() {return XPos;}
int GetYPos() {return YPos;}
protected:
friend class ObjectListClass;
int Period;
int Tick;
int XPos, YPos;
const ObjTypeEnum ObjType;
};
class ObjectListClass : private std::list<ObjectBaseClass *>
{
public:
void Add(ObjectBaseClass *Obj)
{
push_back(Obj);
if(Obj->IsA(Man))
ManObj = (class ManObjectClass *)Obj;
else if(Obj->IsA(Sharp))
NumSharp++;
}
bool RemoveObject(int x, int y, ObjTypeEnum Type)
{
for(iterator i = begin(); i != end(); i++)
{
if((*i)->IsAt(x, y) && (*i)->IsA(Type))
{
if((*i)->IsA(Man))
ManObj = 0;
else if((*i)->IsA(Sharp))
NumSharp--;
delete *i;
erase(i);
return true;
}
}
return false;
}
class ManObjectClass *FindMan()
{
return ManObj;
}
bool Trigger()
{
iterator idx = begin();
while(idx != end())
{
if((*idx)->Tick++ >= (*idx)->Period)
{
(*idx)->Tick = 0;
if(!((*idx)->Trigger()))
{
if((*idx)->IsA(Sharp))
NumSharp--;
else if((*idx)->IsA(Man))
ManObj = 0;
delete *idx;
idx = erase(idx);
}
else
idx++;
}
else
idx++;
}
return ManObj ? true : false;
}
int GetNumSharp()
{
return NumSharp;
}
private:
class ManObjectClass *ManObj;
int NumSharp;
};
ObjectListClass ObjectList;
class TimedObjectClass : public ObjectBaseClass
{
public:
TimedObjectClass(int x, int y, ObjTypeEnum objType, int timeout, char ch, WORD attr) :
ObjectBaseClass(x, y, 10, objType)
{
Timeout = timeout;
Ch = ch;
Attrib = attr;
Counter = 0;
DrawMe(true);
}
virtual bool Trigger()
{
return Counter++ < Timeout ? true : false;
}
virtual ~TimedObjectClass()
{
DrawMe(false);
}
protected:
virtual void DrawMe(bool on)
{
OutCharXY(XPos, YPos, on ? Ch : ' ', Attrib);
}
WORD Attrib;
int Timeout;
int Counter;
char Ch;
};
class BombObjectClass : public TimedObjectClass
{
public:
BombObjectClass(int x, int y) : TimedObjectClass(x, y, Bomb, 150, ' ', FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_INTENSITY)
{
Maze[YPos][XPos] = Bomb;
DrawMe(true);
}
virtual bool Trigger()
{
DrawMe(true);
return TimedObjectClass::Trigger();
}
virtual ~BombObjectClass()
{
Maze[YPos][XPos] = Free;
}
private:
virtual void DrawMe(bool on)
{
OutCharXY(XPos, YPos, on ? (char )(Counter & 1 ? 149 : 162) : ' ', Attrib);
}
};
class ManObjectClass : public ObjectBaseClass
{
public:
ManObjectClass(int x, int y) : ObjectBaseClass(x, y, 10, Man)
{
DrawMe(true);
Maze[YPos][XPos] = Man;
NumBombs = 2;
Energy = 60;
}
virtual ~ManObjectClass()
{
DrawMe(false);
Maze[YPos][XPos] = Free;
ShowStatus(Energy, NumBombs);
}
virtual bool Trigger()
{
int dx = 0, dy = 0;
if(IsKeyPressed(VK_UP) && Maze[YPos - 1][XPos] != Wall)
{
dy = -1;
}
else if(IsKeyPressed(VK_DOWN) && Maze[YPos + 1][XPos] != Wall)
{
dy = 1;
}
else if(IsKeyPressed(VK_LEFT) && Maze[YPos][XPos - 1] != Wall)
{
dx = -1;
}
else if(IsKeyPressed(VK_RIGHT) && Maze[YPos][XPos + 1] != Wall)
{
dx = 1;
}
if(dx || dy)
{
DrawMe(false);
Maze[YPos][XPos] = Free;
if(IsKeyPressed(VK_SPACE) && NumBombs)
{
NumBombs--;
ObjectList.Add(new BombObjectClass(XPos, YPos));
}
XPos += dx;
YPos += dy;
if(Maze[YPos][XPos] == BombTreasure)
{
ObjectList.RemoveObject(XPos, YPos, BombTreasure);
NumBombs++;
}
else if(Maze[YPos][XPos] == Dot)
{
ObjectList.RemoveObject(XPos, YPos, Dot);
Energy++;
}
else if(Maze[YPos][XPos] == Bomb)
{
ObjectList.RemoveObject(XPos, YPos, Bomb);
Energy -= 20;
}
else if(Maze[YPos][XPos] == Sharp)
{
ObjectList.RemoveObject(XPos, YPos, Sharp);
Energy -= 50;
}
Maze[YPos][XPos] = Man;
DrawMe(true);
}
ShowStatus(Energy, NumBombs);
return Energy > 0;
}
void KilledSharp()
{
Energy += 10;
ShowStatus(Energy, NumBombs);
}
void HitSharp()
{
Energy -= 50;
Maze[YPos][XPos] = Man;
DrawMe(true);
ShowStatus(Energy, NumBombs);
}
private:
void DrawMe(bool on)
{
OutCharXY(XPos, YPos, on ? '@' : ' ', FOREGROUND_BLUE | FOREGROUND_INTENSITY);
}
int NumBombs;
int Energy;
};
class SharpObjectClass : public ObjectBaseClass
{
public:
SharpObjectClass(int x, int y, int level) : ObjectBaseClass(x, y, 3 + level, Sharp)
{
DrawMe(true);
Counter = 0;
Maze[YPos][XPos] = Sharp;
}
virtual ~SharpObjectClass()
{
}
virtual bool Trigger(void);
private:
static const Point Dir[4];
unsigned int FindPath(int x, int y, unsigned int level, Point *Path, unsigned int &MinDist);
unsigned int Counter;
unsigned int Shadow[Y_SIZE][X_SIZE];
void DrawMe(bool on)
{
OutCharXY(XPos, YPos, on ? '#' : ' ', FOREGROUND_RED | FOREGROUND_INTENSITY);
}
};
class BombTreasureObjectClass : public TimedObjectClass
{
public:
BombTreasureObjectClass(int x, int y) : TimedObjectClass(x, y, BombTreasure, 200, '!', FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_INTENSITY)
{
Maze[YPos][XPos] = BombTreasure;
}
virtual ~BombTreasureObjectClass()
{
Maze[YPos][XPos] = Free;
}
};
const Point SharpObjectClass::Dir[4] = {Point(-1, 0), Point(1, 0), Point(0, -1), Point(0, 1)};
unsigned int SharpObjectClass::FindPath(int x, int y, unsigned int level, Point *BestPath, unsigned int &MinDist)
{
level++;
if(Shadow[y][x] <= level || level >= MAX_DEPTH)
return UINT_MAX;
else
Shadow[y][x] = level;
unsigned int Max[4] = {UINT_MAX, UINT_MAX, UINT_MAX, UINT_MAX};
int i;
for(i = 0; i < 4; i++)
{
if(Maze[y + Dir[i].y][x + Dir[i].x] != Wall && Maze[y + Dir[i].y][x + Dir[i].x] != Man && Maze[y + Dir[i].y][x + Dir[i].x] != Sharp)
{
Max[i] = FindPath(x + Dir[i].x, y + Dir[i].y, level, BestPath, MinDist);
}
else if(Maze[y + Dir[i].y][x + Dir[i].x] == Man)
{
if(level < MinDist)
{ // The shortest path up to now!
MinDist = level;
BestPath[level].x = x + Dir[i].x;
BestPath[level].y = y + Dir[i].y;
}
Max[i] = level;
}
}
unsigned int n, m = UINT_MAX;
for(n = 0; n < 4; n++)
if(Max[n] < m)
{
m = Max[n];
}
if(m == MinDist)
{
BestPath[level - 1].x = x;
BestPath[level - 1].y = y;
}
return m;
}
bool SharpObjectClass::Trigger(void)
{
memset(Shadow, 0xFF, sizeof(Shadow));
Point MinPath[MAX_DEPTH*2];
unsigned int MinDist = UINT_MAX;
if(FindPath(XPos, YPos, 0, MinPath, MinDist) > MAX_DEPTH)
return true;
Maze[YPos][XPos] = Free;
DrawMe(false);
XPos = MinPath[1].x;
YPos = MinPath[1].y;
if(Maze[YPos][XPos] == Bomb)
{
ObjectList.RemoveObject(XPos, YPos, Bomb);
ManObjectClass *Man = ObjectList.FindMan();
if(Man)
Man->KilledSharp();
return false;
}
else if(Maze[YPos][XPos] == BombTreasure)
{
ObjectList.RemoveObject(XPos, YPos, BombTreasure);
}
else if(Maze[YPos][XPos] == Dot)
{
ObjectList.RemoveObject(XPos, YPos, Dot);
}
else if(Maze[YPos][XPos] == Man)
{
ManObjectClass *Man = ObjectList.FindMan();
if(Man)
Man->HitSharp();
return false;
}
Maze[YPos][XPos] = Sharp;
DrawMe(true);
return true;
}
class DotObjectClass : public TimedObjectClass
{
public:
DotObjectClass(int x, int y) : TimedObjectClass(x, y, Dot, 200, '.', FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_INTENSITY)
{
Maze[y][x] = Dot;
}
};
Point GetFreeSpot()
{
Point p;
do
{
p.x = Random(X_SIZE);
p.y = Random(Y_SIZE);
}
while(Maze[p.y][p.x] != Free);
return p;
}
Point GetSharpPoint(bool right)
{
return Point(right ? X_SIZE - 2 : 1, 1);
}
int main(void)
{
StdOut = GetStdHandle(STD_OUTPUT_HANDLE);
StdIn = GetStdHandle(STD_INPUT_HANDLE);
if(GetYSize() < 25 || GetXSize() < 60)
{
printf("The Window is to small, you have to increase the size of the window,n I need at least 30 linesn");
GetChar();
return EXIT_FAILURE;
}
YOffset = GetYOffset() + 1;
ClearScreen();
Intro();
ShowCaret(false);
ShowStatus(0, 0);
srand(time(0));
int y, x;
for(y = 0; y < Y_SIZE; y++)
{
for(x = 0; x < X_SIZE; x++)
{
if(Maze[y][x] == 1)
OutCharXY(x, y, 0xB0, FOREGROUND_GREEN | FOREGROUND_INTENSITY);
else
OutCharXY(x, y, ' ', FOREGROUND_GREEN | FOREGROUND_INTENSITY);
}
}
ObjectList.Add(new ManObjectClass(1, 1));
ObjectList.Add(new SharpObjectClass(21, 1, 0));
bool Run;
int N = 3;
do
{
Run = ObjectList.Trigger();
if(Run)
{
if(++Score%(FREQ*50) == 0)
N++;
if(!Random(FREQ*5))
{
Point p = GetFreeSpot();
ObjectList.Add(new BombTreasureObjectClass(p.x, p.y));
}
if(ObjectList.GetNumSharp() <= ((N - 3)/2) ||
(ObjectList.GetNumSharp() < N && !Random(35*FREQ)) ||
!Random(75*FREQ))
{
ManObjectClass *Man = ObjectList.FindMan();
if(Man)
{ // If man is on the left half, create the sharp on the right half
Point p = GetSharpPoint(Man->GetXPos() < X_SIZE/2);
ObjectList.Add(new SharpObjectClass(p.x, p.y, N - 3));
}
}
if(!Random(2*FREQ))
{
Point p = GetFreeSpot();
ObjectList.Add(new DotObjectClass(p.x, p.y));
}
}
if(Run)
Sleep(1000/FREQ);
}
while(Run && !IsKeyPressed('Q'));
while(KeyHit())
GetChar();
ShowCaret(true);
ClearScreen();
if(!Run)
{
printf("Your score was %dn", Score);
HighScoreClass HighScore("HighScore.dat");
HighScore.CheckInsert(Score);
HighScore.PrintHighScore();
}
return 0;
}
void GotoXY(int x, int y)
{
COORD c;
c.X = (short )x;
c.Y = (short )y;
SetConsoleCursorPosition(StdOut, c);
}
void GetXY(int &x, int &y)
{
CONSOLE_SCREEN_BUFFER_INFO ConsoleScreenBufferInfo;
GetConsoleScreenBufferInfo(StdOut, &ConsoleScreenBufferInfo);
x = ConsoleScreenBufferInfo.dwCursorPosition.X;
y = ConsoleScreenBufferInfo.dwCursorPosition.Y;
}
int GetYOffset()
{
CONSOLE_SCREEN_BUFFER_INFO ConsoleScreenBufferInfo;
GetConsoleScreenBufferInfo(StdOut, &ConsoleScreenBufferInfo);
return ConsoleScreenBufferInfo.srWindow.Top;
}
int GetYSize()
{
CONSOLE_SCREEN_BUFFER_INFO ConsoleScreenBufferInfo;
GetConsoleScreenBufferInfo(StdOut, &ConsoleScreenBufferInfo);
return ConsoleScreenBufferInfo.srWindow.Bottom - ConsoleScreenBufferInfo.srWindow.Top + 1;
}
int GetXSize()
{
CONSOLE_SCREEN_BUFFER_INFO ConsoleScreenBufferInfo;
GetConsoleScreenBufferInfo(StdOut, &ConsoleScreenBufferInfo);
return ConsoleScreenBufferInfo.srWindow.Right - ConsoleScreenBufferInfo.srWindow.Left + 1;
}
WORD GetChar()
{
DWORD NumEventsRead;
INPUT_RECORD InputRecord;
while(1)
{
if(!ReadConsoleInput(StdIn, &InputRecord, 1, &NumEventsRead))
return 0;
if(InputRecord.EventType & KEY_EVENT && InputRecord.Event.KeyEvent.bKeyDown)
{
if(InputRecord.Event.KeyEvent.wVirtualKeyCode != VK_CONTROL &&
InputRecord.Event.KeyEvent.wVirtualKeyCode != VK_MENU &&
InputRecord.Event.KeyEvent.wVirtualKeyCode != VK_SHIFT)
{
return InputRecord.Event.KeyEvent.wVirtualKeyCode;
}
}
}
}
BOOL KeyHit()
{
DWORD NumEvents, NumEventsRead;
INPUT_RECORD *InputRecord;
DWORD i;
GetNumberOfConsoleInputEvents(StdIn, &NumEvents);
InputRecord = (INPUT_RECORD *)malloc(sizeof(INPUT_RECORD)*NumEvents);
PeekConsoleInput(StdIn, InputRecord, NumEvents, &NumEventsRead);
for(i = 0; i < NumEventsRead; i++)
{
if(InputRecord[i].EventType & KEY_EVENT && InputRecord[i].Event.KeyEvent.bKeyDown)
{
if(InputRecord[i].Event.KeyEvent.wVirtualKeyCode != VK_CONTROL &&
InputRecord[i].Event.KeyEvent.wVirtualKeyCode != VK_MENU &&
InputRecord[i].Event.KeyEvent.wVirtualKeyCode != VK_SHIFT)
{
free(InputRecord);
return TRUE;
}
}
}
free(InputRecord);
return FALSE;
}
void OutCharXY(int x, int y, char ch, WORD attr)
{
COORD Coord;
Coord.X = short(x);
Coord.Y = short(y + YOffset);
DWORD NumWritten;
WriteConsoleOutputCharacter(StdOut, &ch, 1, Coord, &NumWritten);
WriteConsoleOutputAttribute(StdOut, &attr, 1, Coord, &NumWritten);
}
BOOL IsKeyPressed(int Key)
{
return GetAsyncKeyState(Key) & 0x8000 ? TRUE : FALSE;
}
void ShowCaret(BOOL on)
{
CONSOLE_CURSOR_INFO ConsoleCursorInfo;
GetConsoleCursorInfo(StdOut, &ConsoleCursorInfo);
ConsoleCursorInfo.bVisible = on;
SetConsoleCursorInfo(StdOut, &ConsoleCursorInfo);
}
void Intro()
{
GotoXY(0, YOffset);
printf("You are the @ trying to escape from the dreadful #'sn");
printf("Collect a ! to get a bumb, . to get eneryn");
printf("Drop a bomb by hitting space WHILE moving, to kill a #n");
printf("Hit any key to start:");
fflush(stdout);
GetChar();
ClearScreen();
}
void ClearScreen()
{
short i;
CONSOLE_SCREEN_BUFFER_INFO ConsoleScreenBufferInfo;
GetConsoleScreenBufferInfo(StdOut, &ConsoleScreenBufferInfo);
SMALL_RECT Pos = ConsoleScreenBufferInfo.srWindow;
DWORD D;
for(i = Pos.Top; i <= Pos.Bottom; i++)
{
COORD C;
C.X = Pos.Left;
C.Y = i;
FillConsoleOutputCharacter(StdOut, ' ', Pos.Right - Pos.Left, C, &D);
FillConsoleOutputAttribute(StdOut, 0, Pos.Right - Pos.Left, C, &D);
}
GotoXY(0, 0);
}