Update
Added:
-Highscores (uses a file to save them)
-Starting Menu
- Play
- Highscore (check the file that has them)
- Options (change snake speed)
- Exit
Every game you finish, the score will be saved and compared to others and added to the list (this if there's a lower score then that one (top 10)).
Speed snake is changed by changing the Sleep(xxx) speed.
Code:
//
// mainLogic.cpp
// UniqueSnake
//
// Created by Bruno Monteiro on 2010. (Aka Brinuz @ mpgh.net)
//
#include <iostream>
#include <windows.h>
#include <fstream>
#include "snake.h"
using namespace std;
int menu();
void play(CSnake *snake);
void highscore(CSnake *snake);
void options(CSnake *snake);
void sortFileScore(CSnake *snake);
int main()
{
CSnake snake(10,10);
HANDLE console = GetStdHandle(STD_OUTPUT_HANDLE);
do
{
switch(menu())
{
case 1:
snake.clearAllSnake(console);
snake.resetSnake();
snake.drawArena(console);
play(&snake);
sortFileScore(&snake);
break;
case 2:
highscore(&snake);
break;
case 3:
options(&snake);
break;
case 0:
return 0;
break;
}
system("cls");
}
while(true);
return 0;
}
int menu()
{
cout << "~v~ Menu ~v~" << endl;
cout << "1- Play" << endl;
cout << "2- Highscores" << endl;
cout << "3- Options" << endl;
cout << "0- Exit" << endl;
int op = 0;
do
{
cout << "Choose a valid option:" << endl; cin >> op;
}
while(op < 0 || op > 3);
system("cls");
return op;
}
void options(CSnake *snake)
{
cout << "~v~ Speed ~v~" << endl;
cout << "1- Fast" << endl;
cout << "2- Normal" << endl;
cout << "3- Slow" << endl;
cout << "Your current is: " << snake->gameSpeed << endl;
int op = 0;
do
{
cout << "Choose a valid option:" << endl; cin >> op;
}
while(op < 1 || op > 3);
switch(op)
{
case 1: snake->gameSpeed = 30;
break;
case 2: snake->gameSpeed = 50;
break;
case 3: snake->gameSpeed = 70;
break;
}
system("cls");
}
void highscore(CSnake *snake)
{
ifstream fScore;
fScore.open("score.snk");
int i = 0; int aux;
cout << "Top Ten Scores:" << endl;
while (fScore >> aux) //top 10
{
cout << aux << endl;
i++;
}
fScore.close();
system("pause");
system("cls");
}
void play(CSnake *snake)
{
bool started = false;
HANDLE console = GetStdHandle(STD_OUTPUT_HANDLE);
COORD lastCoord = {0,0};
COORD scoreCoord = {3, 23};
CTimer timer;
unsigned foodInterval = 5;
//for(int i = 0; i < 5; i++) //starts with Head + 5 on tail
// snake->add2Tail();
snake->setCursorAndDraw(console);
timer.start();
while(GetAsyncKeyState(VK_ESCAPE) == 0)
{
if(timer.elapsedTime() >= foodInterval)
{
if(snake->foodExist)
snake->clearFood(console);
snake->createFood(console);
snake->foodExist = true;
timer.start();
}
else
{
snake->clearAllSnake(console);
if(GetAsyncKeyState(VK_LEFT) != 0) {
snake->setTalePositions();
snake->add2Coords(-1, 0);
lastCoord.X = -1; lastCoord.Y = 0; started = true;
}
else if(GetAsyncKeyState(VK_RIGHT) != 0) {
snake->setTalePositions();
snake->add2Coords(1, 0);
lastCoord.X = 1; lastCoord.Y = 0; started = true;
}
else if(GetAsyncKeyState(VK_UP) != 0) {
snake->setTalePositions();
snake->add2Coords(0, -1);
lastCoord.X = 0; lastCoord.Y = -1; started = true;
}
else if(GetAsyncKeyState(VK_DOWN) != 0) {
snake->setTalePositions();
snake->add2Coords(0, 1);
lastCoord.X = 0; lastCoord.Y = 1; started = true;
}
else {
if(started)
snake->setTalePositions();
snake->add2Coords(lastCoord.X, lastCoord.Y);
}
if(snake->detectAreacollision() || snake->detectBodycollision())
{
lastCoord.X = 0;
lastCoord.Y = 0;
snake->clearAllSnake(console);
started = false;
snake->resetSnake();
snake->drawArena(console);
}
else
{
snake->setCursorAndDraw(console);
snake->detectFoodcollision();
}
SetConsoleCursorPosition(console, scoreCoord);
cout << "Score: " << snake->score << " || Lives: " << snake->lifes << " ";
if(snake->lifes <= 0)
break;
Sleep(snake->gameSpeed);
}
}
cout << "Game Over :) ";
system("pause");
system("cls");
}
void sortFileScore(CSnake *snake)
{
int scores[11]; int aux;
int i = 0;
ifstream fScoreRead;
fScoreRead.open("score.snk");
while(fScoreRead >> aux)
{
scores[i] = aux;
i++;
}
scores[i] = snake->score;
int auxSort;
for(int i = 0; i < 11; i++)
{
for(int j = 0; j < 11; j++)
{
if(scores[i] > scores[j])
{
auxSort = scores[i];
scores[i] = scores[j];
scores[j] = auxSort;
}
}
}
ofstream fScoreWrite;
fScoreWrite.open("score.snk");
for(int i = 0; i < 10; i++)
{
fScoreWrite << scores[i] << "\n";
}
}
Code:
//
// snake.h
// UniqueSnake
//
// Created by Bruno Monteiro on 2010. (Aka Brinuz @ mpgh.net)
//
#include <iostream>
#include <windows.h>
#include <time.h>
//console size: 25x80
//snake base struct
struct tagSnakeBody{
COORD snakePart;
char character;
struct tagSnakeBody* pNext;
};
class CTimer {
private:
unsigned startingTime;
public:
void start();
unsigned elapsedTime();
};
void CTimer::start() {
startingTime = clock();
}
unsigned CTimer::elapsedTime() {
return ((unsigned) clock() - startingTime) / CLOCKS_PER_SEC;
}
//snake class
class CSnake {
private:
//snake it self
struct tagSnakeBody *pHead;
public:
//constructor
CSnake(int, int);
//global vars
int lifes;
int score;
COORD food;
bool foodExist;
DWORD gameSpeed;
//functions
void add2Tail();
void setCursorAndDraw(HANDLE);
void add2Coords(int x, int y);
void clearAllSnake(HANDLE console);
void setTalePositions();
void createFood(HANDLE console);
void clearFood(HANDLE console);
void detectFoodcollision();
void drawArena(HANDLE console);
bool detectAreacollision();
void resetSnake();
bool detectBodycollision();
};
//contructor
CSnake::CSnake(int x, int y) {
struct tagSnakeBody *pNew;
pHead = NULL;
//new Snake Head
pNew = (tagSnakeBody*)malloc(sizeof(struct tagSnakeBody));
pNew->pNext = NULL;
pNew->character = '@';
pNew->snakePart.X = x;
pNew->snakePart.Y = y;
pHead = pNew;
score = 0;
lifes = 3;
gameSpeed = 50;
}
//adds a new bodypart to tail
void CSnake::add2Tail() {
struct tagSnakeBody *pNew;
struct tagSnakeBody *pAux;
//new Snake Body Part
pNew = (tagSnakeBody*)malloc(sizeof(struct tagSnakeBody));
pNew->pNext = NULL;
pNew->character = '*';
if(pHead == NULL)
pHead = pNew;
else
{
pAux = pHead;
while(pAux->pNext != NULL)
pAux = pAux->pNext;
pNew->snakePart.X = pAux->snakePart.X - 1;
pNew->snakePart.Y = pAux->snakePart.Y;
pAux->pNext = pNew;
}
}
//Places the cursor on console at the same coords as Snake Head is
void CSnake::setCursorAndDraw(HANDLE console) {
struct tagSnakeBody *pAux;
if(pHead == NULL)
return;
else
{
pAux = pHead;
while(pAux != NULL)
{
SetConsoleCursorPosition(console, pAux->snakePart);
std::cout << pAux->character;
pAux = pAux->pNext;
}
}
}
//make it move
void CSnake::add2Coords(int x, int y) {
pHead->snakePart.X += x;
pHead->snakePart.Y += y;
}
//clears the last place where the snake has been at
void CSnake::clearAllSnake(HANDLE console) {
struct tagSnakeBody *pAux;
if(pHead == NULL)
return;
else
{
pAux = pHead;
while(pAux != NULL)
{
SetConsoleCursorPosition(console, pAux->snakePart);
std::cout << " ";
pAux = pAux->pNext;
}
}
}
//makes tale to move with the head
void CSnake::setTalePositions() {
struct tagSnakeBody *pAux;
struct tagSnakeBody *beforeAux;
if(pHead == NULL)
return;
else
{
pAux = pHead;
while(pAux->pNext != NULL)
pAux = pAux->pNext;
while(pAux != pHead)
{
beforeAux = pHead;
while(beforeAux->pNext != pAux)
beforeAux = beforeAux->pNext;
pAux->snakePart = beforeAux->snakePart;
pAux = beforeAux;
}
}
}
//creates a piece of food at the console
void CSnake::createFood(HANDLE console) {
food.X = rand()%77+1;
food.Y = rand()%19+1;
SetConsoleCursorPosition(console, food);
std::cout << "&";
}
//clears the food if not eaten
void CSnake::clearFood(HANDLE console) {
SetConsoleCursorPosition(console, food);
std::cout << " ";
}
//food collision
void CSnake::detectFoodcollision() {
if(pHead->snakePart.X == food.X && pHead->snakePart.Y == food.Y)
{
foodExist = false;
score++;
add2Tail();
}
}
//draw snake arena
void CSnake::drawArena(HANDLE console) {
COORD auxCoord;
for(int i = 0; i < 80; i++)
{
for(int j = 0; j < 22; j++)
{
auxCoord.X = i;
auxCoord.Y = j;
if(j == 0 || j == 21 || i == 0 || i == 79)
{
SetConsoleCursorPosition(console, auxCoord);
std::cout << "#";
}
}
}
}
//detect area collision
bool CSnake::detectAreacollision() {
if(pHead->snakePart.X == 0 || pHead->snakePart.X == 79
|| pHead->snakePart.Y == 0 || pHead->snakePart.Y == 21)
{
lifes--;
return true;
}
return false;
}
//reset snake
void CSnake::resetSnake() {
struct tagSnakeBody *pNew;
pHead = NULL;
//new Snake Head
pNew = (tagSnakeBody*)malloc(sizeof(struct tagSnakeBody));
pNew->pNext = NULL;
pNew->character = '@';
pNew->snakePart.X = 10;
pNew->snakePart.Y = 10;
pHead = pNew;
for(int i = 0; i < 5; i++) //starts with Head + 5 on tail
add2Tail();
}
//detect collision with own body
bool CSnake::detectBodycollision() {
struct tagSnakeBody *pAux;
if(pHead == NULL)
return false;
else
{
pAux = pHead->pNext;
while(pAux != NULL)
{
if(pHead->snakePart.X == pAux->snakePart.X && pHead->snakePart.Y == pAux->snakePart.Y)
{
lifes--;
return true;
}
pAux = pAux->pNext;
}
}
return false;
}
enjoy