I'm making a snake console game but I want to be able to save the state of the game (where the snake is, where the mice are, where the power-ups are, and where the mongoose is). I've looked at quite a few sites on Google but none of them have helped me much. This is so that I can load the file and then play on from where it was left.
If anyone knows it would be greatly appreciated, here is my code:
#include <iostream> //for output and input: cout <<, cin >>
#include <iomanip> //for output manipulators
#include <conio.h> //for getch()
#include <string> //for string
#include <vector> // for vectors
#include <ctime> // for random
#include <cstdlib> // for rand_max
#include <fstream> // for text files
using namespace std;
#include "ConsoleUtils.h" //for Clrscr, Gotoxy, etc.
const int SIZEY(10); const int SIZEX(10); const char SNAKE('O'); const char BODY('o'); const char MOUSE('@'); const char TUNNEL(' '); const char WALL('#'); const char PILL('+'); const char MONGOOSE('M'); const int UP(72); const int DOWN(80); const int RIGHT(77); const int LEFT(75); const char QUIT('Q'); const char CHEAT('C'); const char LOAD('L'); const char SAVE('S');
#define FPS 5
struct Item {
int x, y;
char symbol;
};
int main()
{
void initialiseGame(char g[][SIZEX + 1], char m[][SIZEX + 1], vector<Item>& snake, Item& mouse, Item& pill, int& score, bool& pillActive, int& moveCount, Item& mongoose);
void paintGame(const char g[][SIZEX + 1], string& mess, bool isCheatOn, int& score, const int target, string name, int highScore, int pillScore, bool setInvincibility, int invCount);
bool wantsToQuit(const int key);
bool isArrowKey(const int k);
int getKeyPress();
void moveSnake(char g[][SIZEX + 1], vector<Item>& snake, const int key, string& mess, Item& m, int& score, bool& isAlive, bool& hasWon,
const int target, int& highScore, bool& isCheatOn, Item& pill, bool& pillActive, int& moveCount, int& pillScore, bool& setInvincibility, int& invCount, bool& mongooseActive, int& lastDirection);
void updateGrid(char g[][SIZEX + 1], const char m[][SIZEX + 1], const vector<Item> snake, Item& mouse, Item& pill, int& score, bool& pillActive, int& moveCount, Item& mongoose, bool& mongooseActive, bool& isAlive);
void getName(string& name);
void endProgram();
void invincibility(bool& setInvincibility, int& invCount);
bool isCheatKey(const int k);
bool wantsToLoad(const int k);
bool wantsToSave(const int k);
void cheatMode(const vector<Item>& snake, int& score);
char grid[SIZEY + 1][SIZEX + 1]; char maze[SIZEY + 1][SIZEX + 1];
bool isCheatOn = false;
bool isAlive = true;
bool hasWon = false;
bool pillActive = false;
bool mongooseActive = false;
bool setInvincibility = false;
int lastDirection = UP;
const int target = 10;
int moveCount = 0;
int invCount = 0;
int score = 0;
int pillScore = 0;
int highScore = 0;
std::string name;
Item snakehead = { (SIZEX / 2) + 1, (SIZEY / 2) + 1, SNAKE }; Item body = { BODY };
Item body1 = { (SIZEX / 2), (SIZEY / 2), BODY };
Item body2 = { (SIZEX / 2) - 1, (SIZEY / 2) - 1, BODY };
Item body3 = { (SIZEX / 2) - 2, (SIZEY / 2) - 2, BODY };
Item mouse = { (SIZEX / 2) - 1, (SIZEY / 2) - 2, MOUSE };
vector<Item> snake = { snakehead, body1, body2, body3 };
vector<int> bestScores[6];
Item pill = { 0, 0, PILL };
Item mongoose = { 0, 0, MONGOOSE };
string message("LET'S START...");
getName(name);
Clrscr();
initialiseGame(grid, maze, snake, mouse, pill, score, pillActive, moveCount, mongoose); paintGame(grid, message, isCheatOn, score, target, name, highScore, pillScore, setInvincibility, invCount);
ofstream fout;
fout.open((name + ".txt"), ios::out);
ofstream bestScore;
bestScore.open(("bestScores.txt"), ios::out);
int key(getKeyPress()); while (!wantsToQuit(key) && isAlive&&!hasWon) {
if (isArrowKey(key))
{
invincibility(setInvincibility, invCount);
moveSnake(grid, snake, key, message, mouse, score, isAlive, hasWon, target, highScore, isCheatOn, pill, pillActive, moveCount, pillScore, setInvincibility, invCount, mongooseActive, lastDirection); updateGrid(grid, maze, snake, mouse, pill, score, pillActive, moveCount, mongoose, mongooseActive, isAlive);
}
else{
if (isCheatKey(key)){ if (!isCheatOn){
int size = snake.size();
cheatMode(snake, score); message = "Cheat mode activated!";
cout << '\a' << '\a' << '\a';
snake.resize(4);
isCheatOn = true;
}
else{
message = "Cheat mode deactivated!";
cout << '\a' << '\a' << '\a';
isCheatOn = false;
}
}
if (wantsToLoad(key))
{
}
if (wantsToSave(key))
{
}
else
message = "INVALID KEY!"; }
paintGame(grid, message, isCheatOn, score, target, name, highScore, pillScore, setInvincibility, invCount); key = getKeyPress(); }
if (hasWon)
{
SelectBackColour(clBlue);
Gotoxy(40, 8);
cout << '\a';
cout << "You win!!" << endl;
}
fout << highScore; endProgram(); return 0;
}
void initialiseGame(char grid[][SIZEX + 1], char maze[][SIZEX + 1], vector<Item>& snake, Item& mouse, Item& pill, int& score, bool& pillActive, int& moveCount, Item& mongoose)
{ void setInitialMazeStructure(char g[][SIZEX + 1]);
void setInitialSnakeCoordinates(vector<Item>& snake);
void setMaze(char g[][SIZEX + 1], const char m[][SIZEX + 1]);
void placeSnake(char g[][SIZEX + 1], const vector<Item> snake);
void placeMouse(char g[][SIZEX + 1], Item& m);
void positionMouse(char g[][SIZEX + 1], Item& m);
void positionPill(char g[][SIZEX + 1], Item& p, int& score, bool& pillActive, int& moveCount);
setInitialMazeStructure(maze); setMaze(grid, maze); setInitialSnakeCoordinates(snake); placeSnake(grid, snake); positionMouse(grid, mouse);
placeMouse(grid, mouse);
positionPill(grid, pill, score, pillActive, moveCount);
}
void setInitialMazeStructure(char maze[][SIZEX + 1])
{ char initialMaze[SIZEY + 1][SIZEX + 1] = { { 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X' },
{ 'X', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#' },
{ 'X', '#', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '#' },
{ 'X', '#', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '#' },
{ 'X', '#', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '#' },
{ 'X', '#', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '#' },
{ 'X', '#', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '#' },
{ 'X', '#', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '#' },
{ 'X', '#', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '#' },
{ 'X', '#', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '#' },
{ 'X', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#' } };
for (int row(1); row <= SIZEY; ++row) for (int col(1); col <= SIZEX; ++col) maze[row][col] = initialMaze[row][col];
}
void setInitialSnakeCoordinates(vector<Item>& snake)
{ snake[0].y = 3; snake[0].x = 5;
snake[1].y = 4;
snake[1].x = 5;
snake[2].y = 5;
snake[2].x = 5;
snake[3].y = 6;
snake[3].x = 5;
}
void updateGrid(char grid[][SIZEX + 1], const char maze[][SIZEX + 1], const vector<Item> snake, Item& mouse, Item& pill, int& score, bool& pillActive, int& moveCount, Item& mongoose, bool& mongooseActive, bool& isAlive)
{ void setMaze(char g[][SIZEX + 1], const char m[][SIZEX + 1]);
void placeSnake(char g[][SIZEX + 1], const vector<Item> snake);
void placeMouse(char g[][SIZEX + 1], Item& m);
void positionPill(char g[][SIZEX + 1], Item& p, int& score, bool& pillActive, int& moveCount);
void placeMongoose(char g[][SIZEX + 1], Item& mn, int score, bool& mongooseActive, bool& isAlive);
setMaze(grid, maze);
placeSnake(grid, snake); placeMouse(grid, mouse);
positionPill(grid, pill, score, pillActive, moveCount);
placeMongoose(grid, mongoose, score, mongooseActive, isAlive);
}
void setMaze(char grid[][SIZEX + 1], const char maze[][SIZEX + 1])
{ for (int row(1); row <= SIZEY; ++row) for (int col(1); col <= SIZEX; ++col) grid[row][col] = maze[row][col];
}
void placeSnake(char g[][SIZEX + 1], const vector<Item> s)
{ for (int i(0); i < s.size(); ++i)
{
g[s[i].y][s[i].x] = s[i].symbol;
}
}
void positionMouse(char g[][SIZEX + 1], Item& m)
{
srand(static_cast<int>(time(0)));
int randMaxX = 7;
int randMaxY = 6;
int y = rand() % randMaxY;
int x = rand() % randMaxX;
m.y = y + 1; m.x = x + 1; while (g[m.y][m.x] != TUNNEL) {
int randMaxX = 7;
int randMaxY = 6;
int y = rand() % randMaxY;
int x = rand() % randMaxX;
m.y = y + 1;
m.x = x + 1;
}
}
void placeMouse(char g[][SIZEX + 1], Item& m) {
g[m.y][m.x] = m.symbol;
}
void positionPill(char g[][SIZEX + 1], Item& p, int& score, bool& pillActive, int& moveCount)
{
srand(static_cast<int>(time(0)));
if ((score % 2 == 0) && (score != 0) && (!pillActive) && (moveCount <= 15))
{
pillActive = true;
++moveCount;
int randMaxX = 7;
int randMaxY = 6;
int y = rand() % randMaxY;
int x = rand() % randMaxX;
p.y = y + 1;
p.x = x + 1;
while (g[p.y][p.x] != TUNNEL)
{
int randMaxX = 7;
int randMaxY = 6;
int y = rand() % randMaxY;
int x = rand() % randMaxX;
p.y = y + 1;
p.x = x + 1;
}
}
if (moveCount > 5)
{
p.x = 0;
p.y = 0;
moveCount = 0;
}
g[p.y][p.x] = p.symbol;
}
void placePill(char g[][SIZEX + 1], Item& p)
{
g[p.y][p.x] = p.symbol;
}
void moveSnake(char grid[][SIZEX + 1], vector<Item>& s, const int key, string& mess, Item& m, int& score, bool& isAlive, bool& hasWon, const int target,
int& highScore, bool& isCheatOn, Item& pill, bool& pillActive, int& moveCount, int& pillScore, bool& setInvinciblity, int& invCount, bool& mongooseActive, int& lastDirection)
{ void setKeyDirection(int k, int& dx, int& dy, int& lastDirection); void moveSnakeBody(vector<Item>& s, int& dx, int& dy);
void positionMouse(char g[][SIZEX + 1], Item& m);
void endProgram();
int dx(0), dy(0);
setKeyDirection(key, dx, dy, lastDirection); bool stopGrowCheat = false;
switch (grid[s[0].y + dy][s[0].x + dx])
{ case TUNNEL: moveSnakeBody(s, dx, dy);
if (pillActive)
{
++moveCount;
}
break;
case WALL: if (setInvinciblity == false){
cout << '\a'; mess = "You Lose!";
isAlive = false;
}
else{
if (dx == 1){
cout << '\a';
s[0].y += dy; s[0].x += (dx - (SIZEX - 2)); }
else{
if (dx == -1){
cout << '\a';
s[0].y += dy; s[0].x += (dx + (SIZEX - 2)); }
else{
if (dy == -1){
cout << '\a';
s[0].y += (dy + (SIZEY - 2)); s[0].x += dx; }
else{
if (dy == 1){
cout << '\a';
s[0].y += (dy - (SIZEY - 2)); s[0].x += dx; }
}
}
}
}
break;
case BODY:
if (setInvinciblity == false){
cout << '\a'; mess = "You Lose!";
isAlive = false;
}
else{
cout << '\a';
}
break;
case MOUSE:
if (isCheatOn == false){
s.push_back(s[s.size() - 1]);
s.push_back(s[s.size() - 1]);
}
++score;
moveSnakeBody(s, dx, dy);
positionMouse(grid, m);
if (score == target){
hasWon = true;
}
if (score >= highScore){
highScore = score;
moveCount = 0;
pillActive = false;
}
break;
case PILL:
s.resize(4);
moveSnakeBody(s, dx, dy);
pill.x = 0;
pill.y = 0;
pillActive = false;
pillScore++;
setInvinciblity = true;
invCount = 20;
break;
case MONGOOSE:
if (setInvinciblity == false){
cout << '\a'; mess = "Killed by mongoose, you Lose!";
isAlive = false;
}
}
}
void moveSnakeBody(vector<Item>& s, int& dx, int& dy)
{
int snakeSize = s.size();
for (int i(snakeSize - 1); i > 0; --i)
{
s[i].x = s[i - 1].x;
s[i].y = s[i - 1].y;
}
s[0].y += dy; s[0].x += dx;
}
void setKeyDirection(const int key, int& dx, int& dy, int& lastDirection)
{
switch (key) {
case LEFT: lastDirection = LEFT;
dx = -1; dy = 0;
break;
case RIGHT: lastDirection = RIGHT;
dx = +1; dy = 0;
break;
case UP: lastDirection = UP;
dx = 0;
dy = -1; break;
case DOWN: lastDirection = DOWN;
dx = 0;
dy = +1; break;
}
}
int getKeyPress()
{ int keyPressed;
keyPressed = _getch(); while (keyPressed == 224) keyPressed = _getch();
return toupper(keyPressed); }
bool isArrowKey(const int key)
{ return (key == LEFT) || (key == RIGHT) || (key == UP) || (key == DOWN);
}
bool wantsToQuit(const int key)
{ return toupper(key) == QUIT;
}
bool isCheatKey(const int key)
{
return toupper(key) == CHEAT;
}
bool wantsToLoad(const int key)
{
return toupper(key) == LOAD;
}
bool wantsToSave(const int key)
{
return toupper(key) == SAVE;
}
void paintGame(const char gd[][SIZEX + 1], string& mess, bool isCheatOn, int& score, const int target, string name, int highScore, int pillScore, bool setInvincibility, int invCount)
{ void paintGrid(const char g[][SIZEX + 1]);
Clrscr();
SelectTextColour(clYellow);
Gotoxy(0, 0);
cout << "___SNAKE GAME___\n" << endl;
SelectBackColour(clWhite);
SelectTextColour(clRed);
Gotoxy(40, 0);
cout << "FoP Group Z3 - Connor Newton,";
Gotoxy(40, 1);
cout << "Kieran Cousens, Jordan Rhodes";
paintGrid(gd);
SelectBackColour(clRed);
SelectTextColour(clYellow);
Gotoxy(40, 3);
cout << "TO MOVE USE KEYBOARD ARROWS ";
Gotoxy(40, 4);
cout << "TO QUIT ENTER 'Q' ";
Gotoxy(40, 5);
cout << "PRESS 'C' TO ENTER CHEAT MODE";
if (isCheatOn){
Gotoxy(40, 6);
cout << "Cheat mode on";
}
else{
Gotoxy(40, 6);
cout << "Cheat mode off";
}
Gotoxy(40, 10);
cout << "Score : " << score << " out of " << target;
Gotoxy(40, 11);
cout << "Pills eaten : " << pillScore;
Gotoxy(40, 9);
cout << "Player's name: " << name;
Gotoxy(40, 12);
if (setInvincibility == true){
SelectBackColour(clBlue);
SelectTextColour(clWhite);
cout << "Invinciblity ON";
}
Gotoxy(40, 12);
if (setInvincibility == false){
SelectBackColour(clRed);
SelectTextColour(clYellow);
cout << "Invincibility OFF";
}
Gotoxy(40, 13);
{
SelectBackColour(clRed);
SelectTextColour(clYellow);
cout << "To save - S, To load - L";
}
SelectBackColour(clWhite);
SelectTextColour(clRed);
Gotoxy(40, 2);
time_t now = time(0);
tm *ltm = localtime(&now);
cout << setfill('0') << setw(2);
cout << ltm->tm_mday << "/"; cout << setfill('0') << setw(2);
cout << 1 + ltm->tm_mon << "/"; cout << 1900 + ltm->tm_year << " ";
cout << setfill('0') << setw(2);
cout << 1 + ltm->tm_hour << ":"; cout << setfill('0') << setw(2);
cout << 1 + ltm->tm_min << ":"; cout << setfill('0') << setw(2);
cout << 1 + ltm->tm_sec;
SelectBackColour(clBlack);
SelectTextColour(clWhite);
Gotoxy(40, 8);
cout << mess; mess = ""; }
void paintGrid(const char g[][SIZEX + 1])
{ SelectBackColour(clBlack);
SelectTextColour(clWhite);
Gotoxy(0, 2);
for (int row(1); row <= SIZEY; ++row) {
for (int col(1); col <= SIZEX; ++col) cout << g[row][col]; cout << endl;
}
}
void endProgram()
{
SelectBackColour(clRed);
SelectTextColour(clYellow);
Gotoxy(40, 15);
cout << "\n";
system("pause");
}
void cheatMode(const vector<Item>& snake, int& score)
{
score = 0;
}
void getName(string& name){
SelectTextColour(clWhite);
Gotoxy(20, 10);
cout << "Enter Player Name:";
SelectTextColour(clYellow);
cin >> name;
while (name.length() > 20)
{
Clrscr();
SelectTextColour(clWhite);
Gotoxy(20, 11);
cout << "Invalid length, try again! (20 characters max)";
Gotoxy(20, 10);
SelectTextColour(clYellow);
cout << "Enter Player Name:";
cin >> name;
}
}
void invincibility(bool& setInvincibility, int& invCount){
if (setInvincibility == true)
invCount--;
if (invCount == 0)
{
setInvincibility = false;
}
}
void placeMongoose(char g[][SIZEX + 1], Item& mn, int score, bool& mongooseActive, bool& isAlive)
{
srand(static_cast<int>(time(0)));
if (mongooseActive == true){
int tempx;
int tempy;
tempx = mn.x;
tempy = mn.y;
int randMaxX = 3;
int randMaxY = 3;
int ym = rand() % randMaxY - 1;
int xm = rand() % randMaxX - 1;
mn.y += ym;
mn.x += xm;
int i = 0;
while (g[mn.y][mn.x] != TUNNEL)
{
mn.x = tempx;
mn.y = tempy;
int randMaxX = 3;
int randMaxY = 3;
int ym = rand() % randMaxY - 1;
int xm = rand() % randMaxX - 1;
mn.y += ym;
mn.x += xm;
}
g[mn.y][mn.x] = mn.symbol;
}
if ((score >= 3) && (mongooseActive == false))
{
int randMaxX = 7;
int randMaxY = 6;
int y = rand() % randMaxY;
int x = rand() % randMaxX;
mn.y = y + 1;
mn.x = x + 1;
while (g[mn.y][mn.x] != TUNNEL)
{
int randMaxX = 7;
int randMaxY = 6;
int y = rand() % randMaxY;
int x = rand() % randMaxX;
mn.y = y + 1;
mn.x = x + 1;
}
g[mn.y][mn.x] = mn.symbol;
mongooseActive = true;
}
}
What I have tried:
I've tried looking on cplusplus and stackoverflow