Revision 3042
Date2026-05-19T16:27:14+02:00
Committercu1017
Download
| // Copyright 2024, University of Freiburg
// Chair of Algorithms and Data Structures
// Author: Hannah Bast <bast@cs.uni-freiburg.de>,
#include "./Snake.h"
#include <unistd.h>
// ____________________________________________________________________________
void Snake::play() {
drawBorder(TerminalManager::Green);
drawSnake(TerminalManager::Red);
terminalManager_->refresh();
// Initial speed in pixels per second.
double speed = 10;
// Acceleration in pixel per second squared.
double acceleration = 2;
// The absolute distance moved since the last call to moveSnake(). If it
// becomes > 1 we have to move the snake by one pixel.
double distance = 0;
while (true) {
// Let the game run until the snake has moved by at least one pixel.
while (true) {
UserInput userInput = terminalManager_->getUserInput();
if (userInput.isEscape()) {
return;
}
handleKey(userInput);
usleep(1000);
distance += speed / 1000;
speed += acceleration / 1000;
if (distance >= 1.0) {
distance -= 1.0;
break;
}
}
// Move the snake to the next position (leave a trail of white pixels).
drawSnake(TerminalManager::White);
moveSnake();
drawSnake(TerminalManager::Red);
terminalManager_->refresh();
// If the snake collides with the border, quit after three seconds.
if (collidesWithBorder()) {
usleep(3'000'000);
return;
}
}
}
// ____________________________________________________________________________
Snake::Snake(TerminalManager *terminalManager)
: terminalManager_(terminalManager) {
posRow_ = terminalManager_->numRows() / 2;
posCol_ = terminalManager_->numCols() / 2;
dirRow_ = 0;
dirCol_ = 1;
}
// ____________________________________________________________________________
void Snake::drawBorder(int color) {
for (int row = 0; row < terminalManager_->numRows(); row++) {
terminalManager_->drawPixel(row, 0, color);
terminalManager_->drawPixel(row, terminalManager_->numCols() - 1, color);
}
for (int col = 0; col < terminalManager_->numCols(); col++) {
terminalManager_->drawPixel(0, col, color);
terminalManager_->drawPixel(terminalManager_->numRows() - 1, col, color);
}
}
// ____________________________________________________________________________
void Snake::drawSnake(int color) {
terminalManager_->drawPixel(posRow_, posCol_, color);
}
// ____________________________________________________________________________
bool Snake::collidesWithBorder() {
return posRow_ <= 0 || posRow_ >= terminalManager_->numRows() - 1 ||
posCol_ <= 0 || posCol_ >= terminalManager_->numCols() - 1;
}
// ____________________________________________________________________________
void Snake::moveSnake() {
posRow_ = posRow_ + dirRow_;
posCol_ = posCol_ + dirCol_;
}
// ____________________________________________________________________________
void Snake::handleKey(UserInput userInput) {
if (userInput.isKeyDown()) {
if (dirRow_ != -1) {
dirRow_ = 1;
dirCol_ = 0;
}
} else if (userInput.isKeyUp()) {
if (dirRow_ != 1) {
dirRow_ = -1;
dirCol_ = 0;
}
} else if (userInput.isKeyLeft()) {
if (dirCol_ != 1) {
dirRow_ = 0;
dirCol_ = -1;
}
} else if (userInput.isKeyRight()) {
if (dirCol_ != -1) {
dirRow_ = 0;
dirCol_ = 1;
}
}
}
|