snake-sfml/squared.cpp

154 lines
4.4 KiB
C++

#include <SFML/Graphics.hpp>
#include <iostream>
#include <vector>
#define SCALE 20
using namespace std;
using namespace sf;
enum direction {
STOP = 0,
UP,
RIGHT,
DOWN,
LEFT
} dir;
void generateFood(vector<vector<int>>*, int, int);
void printBoard(RenderWindow*, vector<vector<int>>*, int, int, int);
int main (int argc, char* argv[]) {
srand(time(0));
const int height = 600 / SCALE;
const int width = 800 / SCALE;
vector<vector<int>> board = {}; // x = 1st dim; y = 2nd;
int headX = width / 2,
headY = height / 2,
length = 1;
for (int i = 0; i < width; i ++) {
board.push_back({});
for (int j = 0; j < height; j ++) {
board[i].push_back(0);
}
}
RenderWindow win(VideoMode(width * SCALE, height * SCALE), "Snake");
dir = STOP;
win.setFramerateLimit(10);
win.display();
generateFood(&board, width, height);
while (win.isOpen()) {
board[headX][headY] = length;
printBoard(&win, &board, width, height, length);
Event e;
while (win.pollEvent(e)) {
switch (e.type) {
case Event::Closed:
win.close();
break;
case Event::KeyPressed:
switch (e.key.code) {
case Keyboard::W:
if(board[headX][headY - 1] <= 0)
dir = UP;
break;
case Keyboard::D:
if(board[headX + 1][headY] <= 0)
dir = RIGHT;
break;
case Keyboard::S:
if(board[headX][headY + 1] <= 0)
dir = DOWN;
break;
case Keyboard::A:
if(board[headX - 1][headY] <= 0)
dir = LEFT;
break;
}
break;
}
}
for (int i = 0; i < width; i ++) {
for (int j = 0; j < height; j ++) {
if (board[i][j] > 0) board[i][j] --;
}
}
switch (dir) {
case UP:
headY -= 1;
break;
case RIGHT:
headX += 1;
break;
case DOWN:
headY += 1;
break;
case LEFT:
headX -= 1;
break;
}
if (headX >= width // collide with board or itself
|| headX <= -1
|| headY <= -1
|| headY >= height
|| (board[headX][headY] > 0 && board[headX][headY] < length)) {
printf("Game over! Score: %i\n", length);
return 0;
}
if (board[headX][headY] == -1) { // collide with eat
length ++;
generateFood(&board, width, height);
}
}
return 0;
}
void generateFood(vector<vector<int>>* board, int width, int height) {
int appleX = rand() % width,
appleY = rand() % height;
while((*board)[appleX][appleY] != 0){
appleX = rand() % width;
appleY = rand() % height;
}
(*board)[appleX][appleY] = -1;
}
void printBoard(RenderWindow* win, vector<vector<int>>* board, int width, int height, int length) {
for (int i = 0; i < (*board).size(); i ++) {
for (int j = 0; j < (*board)[0].size(); j ++) {
if ((*board)[i][j] < -1 || (*board)[i][j] == 0 ) continue;
RectangleShape* rectangle = new RectangleShape();
rectangle->setPosition(Vector2f(i * SCALE, j * SCALE));
rectangle->setSize(Vector2f(SCALE - 1, SCALE - 1));
rectangle->setFillColor(Color::Red);
if ((*board)[i][j] > 0 && (*board)[i][j] < length) {
if((*board)[i][j] % 2 == 0) {
rectangle->setFillColor(Color::Green);
} else {
rectangle->setFillColor(Color::Cyan);
}
}
if ((*board)[i][j] == length) {
rectangle->setFillColor(Color::Yellow);
}
if ((*board)[i][j] == -1) {
rectangle->setFillColor(Color::Red);
}
win->draw(*rectangle);
delete rectangle;
}
}
win->display();
win->clear(Color::Black);
}