154 lines
4.4 KiB
C++
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);
|
|
} |