Skip to content

Commit

Permalink
Init
Browse files Browse the repository at this point in the history
  • Loading branch information
tigertv committed Jan 30, 2020
0 parents commit 5a0d322
Show file tree
Hide file tree
Showing 13 changed files with 1,105 additions and 0 deletions.
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
build/
.cproject
.project
.vscode/
12 changes: 12 additions & 0 deletions BorderFrame.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#include "BorderFrame.h"

BorderFrame::BorderFrame(int x, int y, int width, int height) {
this->x = x;
this->y = y;
this->width = width;
this->height = height;
}

void BorderFrame::update() {

}
15 changes: 15 additions & 0 deletions BorderFrame.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#ifndef BORDER_FRAME_H_
#define BORDER_FRAME_H_

class BorderFrame {
public:
int width;
int height;
int x;
int y;
BorderFrame(int x, int y, int width, int height);
virtual ~BorderFrame() {}
void update();
};

#endif
14 changes: 14 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
cmake_minimum_required (VERSION 2.6)

project (snake-game)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_EXTENSIONS OFF)
add_compile_options(-Wall -Wextra -pedantic)

find_package(Curses)

file(GLOB SRC_FILES "*.cpp")

add_executable(snake-game ${SRC_FILES})
target_link_libraries(snake-game ${CURSES_LIBRARIES})
28 changes: 28 additions & 0 deletions FoodBuilder.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#include "FoodBuilder.h"

FoodBuilder::FoodBuilder(BorderFrame* border) {
this->border = border;
}

Food* FoodBuilder::getFood() {
std::srand(std::time(nullptr)); // use current time as seed for random generator
int x = border->x + std::rand() % border->width;
int y = border->y + std::rand() % border->height;
if (x == border->x) x++;
if (y == border->y) y++;

if (this->food == nullptr) {
this->food = new Food(x, y);
} else {
this->food->x = x;
this->food->y = y;
}

return this->food;
}

FoodBuilder::~FoodBuilder() {
if (this->food != nullptr) {
delete this->food;
}
}
24 changes: 24 additions & 0 deletions FoodBuilder.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#ifndef FOOD_BUILDER_H_
#define FOOD_BUILDER_H_

#include <bits/stdc++.h>
#include "BorderFrame.h"

struct Food {
int x;
int y;
Food(int x, int y) : x(x), y(y) {}
};

class FoodBuilder{
private:
Food* food = nullptr;
BorderFrame* border;

public:
FoodBuilder(BorderFrame* border);
virtual ~FoodBuilder();
Food* getFood();
};

#endif
171 changes: 171 additions & 0 deletions Game.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
#include "Game.h"
#include <ncurses.h>
#include <unistd.h>

Game::Game() : foodBuilder(&borderFrame), borderFrame(0, 0, 64, 32) {

}

Game::~Game() {

}

void Game::run() {
this->init();
this->food = foodBuilder.getFood();
this->isPlaying = true;

while(this->isPlaying) {
// begin frame
std::clock_t c_start = std::clock();

this->processInput();
this->update();
this->render();

// end frame
std::clock_t c_end = std::clock();
std::clock_t diff = this->frame - c_end + c_start;

// delay
usleep(diff);
}

erase();
refresh();
endwin();
}

void Game::init() {
// init
initscr();
// TODO check for failing

cbreak(); // Character input doesnt require the <enter> key anymore
curs_set(0); // Makes the blinking cursor invisible
noecho(); // Wont print the keys received through input
nodelay(stdscr, TRUE); // Wont wait for input
keypad(stdscr, TRUE); // Support for extra keys (life F1, F2, ... )
//timeout(400);
//timeout(0);

// Ncurses' global variable meaning number of milliseconds
// to wait after the user presses ESC.
//
// VIM uses 25ms, so should you.
// Source: http://en.chys.info/2009/09/esdelay-ncurses/
ESCDELAY = 25;

refresh(); // Refresh the layout


//int max_y = 0, max_x = 0;

// Global var `stdscr` is created by the call to `initscr()`
//getmaxyx(stdscr, max_y, max_x);
}

void Game::processInput() {
int c = getch();

switch (c) {
case KEY_LEFT:
snake.changeDirection(Direction::LEFT);
break;

case KEY_DOWN:
snake.changeDirection(Direction::DOWN);
break;

case KEY_UP:
snake.changeDirection(Direction::UP);
break;

case KEY_RIGHT:
snake.changeDirection(Direction::RIGHT);
break;

case '1':
snake.grow();
break;

case 27: // KEY_ESC
// exit from loop
this->isPlaying = false;
break;
}
}

void Game::update() {
snake.update();

// collisions?
std::pair<int,int> head = snake.getHead();

// itself collision
std::list<std::pair<int, int>> *coords = snake.getCoordinates();
std::list<std::pair<int, int>>::iterator it = coords->begin();
for(it++; it != coords->end(); it++) {
if (it->first == head.first && it->second == head.second) {
// we have a collision
this->isPlaying = false;
// game over
return;
}
}

// border collision
if ((head.first == borderFrame.x && head.second >= borderFrame.y &&
head.second <= borderFrame.height) ||
(head.first == borderFrame.width && head.second >= borderFrame.y &&
head.second <= borderFrame.height) ||
(head.second == borderFrame.y && head.first >= borderFrame.x &&
head.first <= borderFrame.width) ||
(head.second == borderFrame.height && head.first >= borderFrame.x &&
head.first <= borderFrame.width)
) {
// you don't have to go out of the border space
this->isPlaying = false;
// game over
return;
}

// has eaten food?
if (head.first == food->x && head.second == food->y) {
snake.grow();
this->score += 10;
food = foodBuilder.getFood();
}
}

void Game::render() {
// clear screen
clear();

// render snake
std::list<std::pair<int, int>> *coords = snake.getCoordinates();
std::list<std::pair<int, int>>::iterator it = coords->begin();
// render head
mvprintw(it->second, it->first, "@");
// render body
for(it++; it != coords->end(); it++) {
mvprintw(it->second, it->first, "o");
}

// render boarders
for(int x = borderFrame.x; x <= borderFrame.width; x++) {
mvprintw(borderFrame.y, x, "x");
mvprintw(borderFrame.height, x, "x");
}
for(int y = borderFrame.y; y <= borderFrame.height; y++) {
mvprintw(y, borderFrame.x, "x");
mvprintw(y, borderFrame.width, "x");
}

// render food
mvprintw(this->food->y, this->food->x, "F");
}

int Game::getScore() {
return this->score;
}
30 changes: 30 additions & 0 deletions Game.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#ifndef GAME_H_
#define GAME_H_

#include "Snake.h"
#include "FoodBuilder.h"
#include "BorderFrame.h"

class Game {
private:
Snake snake;
int score = 0;
FoodBuilder foodBuilder;
Food* food = nullptr;
BorderFrame borderFrame;
const std::clock_t frame = 300000l;
bool isPlaying = false;

void init();
void processInput();
void update();
void render();

public:
Game();
virtual ~Game();
void run();
int getScore();
};

#endif
Loading

0 comments on commit 5a0d322

Please sign in to comment.