This commit is contained in:
Love 2024-09-06 17:17:53 +02:00
commit de44ead6db
23 changed files with 1001 additions and 0 deletions

12
.gitignore vendored Executable file
View File

@ -0,0 +1,12 @@
*~
.DS_Store
*.pro.user.*
*.pro.user
build-*/
*.app
*.exe
build

2
README.md Executable file
View File

@ -0,0 +1,2 @@
# robots

26
Robots.pro Executable file
View File

@ -0,0 +1,26 @@
TEMPLATE = app
QT += widgets
HEADERS += src/mainwindow.h \
src/utilities.h \
src/constants.h \
src/Unit.h \
src/Junk.h \
src/Hero.h \
src/Robot.h \
src/GameState.h \
src/qgameoverwindow.h \
src/qresetbutton.h
SOURCES += src/mainwindow.cpp \
src/robotsmain.cpp \
src/utilities.cpp \
src/Unit.cpp \
src/Junk.cpp \
src/Hero.cpp \
src/Robot.cpp \
src/GameState.cpp \
src/qgameoverwindow.cpp \
src/qresetbutton.cpp
QMAKE_CXXFLAGS += -std=c++11
macx {
cache()
}

119
src/GameState.cpp Executable file
View File

@ -0,0 +1,119 @@
/**
* Copyright (C) David Wolfe, 1999. All rights reserved.
* Ported to Qt and adapted for TDDD86, 2015.
* Updated for TDDD86, 2021.
*/
#include "GameState.h"
#include "utilities.h"
#include "constants.h"
#include <iostream>
GameState::GameState(int numberOfRobots) {
for (int i = 0; i < numberOfRobots; i++) {
Robot robot;
while(!isEmpty(robot)){
robot = Robot();
}
robots.push_back(robot);
}
teleportHero();
}
void GameState::draw(QGraphicsScene *scene) const {
scene->clear();
hero.draw(scene);
for (const Robot& robot: robots)
robot.draw(scene);
for (const Junk& junk: junks)
junk.draw(scene);
}
void GameState::teleportHero() {
do hero.teleport();
while (!isEmpty(hero));
}
void GameState::moveRobots() {
for(Robot& robot: robots)
robot.moveTowards(hero.asPoint());
}
void GameState::updateCrashes() {
for(unsigned i=0; i < robots.size(); ++i){
for(unsigned j=0; j < junks.size(); ++j){
if(robots[i].at(junks[j])){
robots[i].doCrash();
}
}
for(unsigned o=i+1; o < robots.size(); ++o){
if(robots[i].at(robots[o])){
robots[i].doCrash();
robots[o].doCrash();
}
}
}
}
int GameState::countToBeJunked()const{
int numberDestroyed =0;
for(unsigned i=0; i < robots.size(); ++i)
if(robots[i].isToBeJunked())
numberDestroyed++;
return numberDestroyed;
}
void GameState::junkTheCrashed(){
for(unsigned i=0; i < robots.size(); ++i){
if (robots[i].isToBeJunked()) {
junks.push_back(Junk(robots[i].asPoint()));
robots[i] = robots[robots.size()-1];
robots.pop_back();
}
}
}
bool GameState::someRobotsAlive() const {
for(unsigned i=0; i < robots.size(); ++i)
if(robots[i].isAlive())
return true;
return false;
}
bool GameState::heroDead() const {
for(const Robot& robot: robots){
if(hero.at(robot)){
return true;
}
}
for(const Junk& junk: junks){
if(hero.at(junk)){
return true;
}
}
return false;
}
void GameState::moveHeroTowards(const Point& dir) {
hero.moveTowards(dir);
}
Point GameState::getHeroAsPoint() const {return hero.asPoint();}
/*
* Free of robots and junk
*/
bool GameState::isEmpty(const Unit& unit) const {
for(const Robot& robot: robots)
if(robot.at(unit))
return false;
for(const Junk& junk: junks)
if(junk.at(unit))
return false;
return true;
}

91
src/GameState.h Executable file
View File

@ -0,0 +1,91 @@
/**
* Copyright (C) David Wolfe, 1999. All rights reserved.
* Ported to Qt and adapted for TDDD86, 2015.
*
* Maintains the game state: Location of all robots, junk and hero.
*/
#ifndef GAMESTATE_H
#define GAMESTATE_H
#include <string>
#include <vector>
#include <QGraphicsScene>
#include "Unit.h"
#include "Robot.h"
#include "Junk.h"
#include "Hero.h"
class GameState {
public:
/*
* Create a GameState with randomly placed, but not
* overlapping hero and numberOfRobots robots
*/
GameState(int numberOfRobots);
~GameState() = default;
/*
* Clear and redraw entire playing field
*/
void draw(QGraphicsScene* scene) const; // Clear and redraw entire playing field
/*
* Teleport hero to random location
*/
void teleportHero();
/*
* Move robots one step towards hero
*/
void moveRobots();
/*
* Identify crashed robots
*/
void updateCrashes();
/*
* Count identified crashed robots
*/
int countToBeJunked()const;
/*
* Replace each identified crashed robot with a junk
*/
void junkTheCrashed();
/*
* Are there still robots that did not crash?
*/
bool someRobotsAlive() const;
/*
* Is hero in same place as robot or junk?
*/
bool heroDead() const;
/*
* Move hero towards dir
*/
void moveHeroTowards (const Point& dir);
/*
* Return hero
*/
Point getHeroAsPoint () const;
private:
std::vector<Robot> robots; // the robots
std::vector<Junk> junks; // robots that have turned to junk
Hero hero; // the hero
// private helpers
bool isEmpty(const Unit& unit) const;
};
#endif // GAMESTATE_H

16
src/Hero.cpp Executable file
View File

@ -0,0 +1,16 @@
/**
* Copyright (C) David Wolfe, 1999. All rights reserved.
* Ported to Qt and adapted for TDDD86, 2015.
*/
#include "Hero.h"
#include "constants.h"
void Hero::draw(QGraphicsScene *scene) const {
Point corner = asPoint();
scene->addRect(QRectF(corner.x * UNIT_WIDTH, corner.y * UNIT_HEIGHT,
UNIT_WIDTH, UNIT_HEIGHT), Qt::NoPen, QBrush(HERO_COLOR));
}

23
src/Hero.h Executable file
View File

@ -0,0 +1,23 @@
/**
* Copyright (C) David Wolfe, 1999. All rights reserved.
* Ported to Qt and adapted for TDDD86, 2015.
*/
#ifndef HERO_H
#define HERO_H
#include "Unit.h"
#include <QGraphicsScene>
class Hero : public Unit {
public:
/*
* Draws this hero onto the given QGraphicsScene.
*/
void draw(QGraphicsScene *scene) const;
};
#endif // HERO_H

16
src/Junk.cpp Executable file
View File

@ -0,0 +1,16 @@
/**
* Copyright (C) David Wolfe, 1999. All rights reserved.
* Ported to Qt and adapted for TDDD86, 2015.
*/
#include "Junk.h"
#include "constants.h"
void Junk::draw(QGraphicsScene *scene) const {
Point corner = asPoint();
scene->addEllipse(QRectF(corner.x * UNIT_WIDTH, corner.y * UNIT_HEIGHT,
JUNK_RADIUS, JUNK_RADIUS), QPen(), QBrush(JUNK_COLOR));
}

22
src/Junk.h Executable file
View File

@ -0,0 +1,22 @@
/**
* Copyright (C) David Wolfe, 1999. All rights reserved.
* Ported to Qt and adapted for TDDD86, 2015.
*/
#ifndef JUNK_H
#define JUNK_H
#include "Unit.h"
#include <QGraphicsScene>
class Junk : public Unit {
public:
Junk(const Point& p): Unit(p){}
/*
* Draws this junk onto the given QGraphicsScene.
*/
void draw(QGraphicsScene* scene) const;
};
#endif // JUNK_H

29
src/Robot.cpp Executable file
View File

@ -0,0 +1,29 @@
/**
* Copyright (C) David Wolfe, 1999. All rights reserved.
* Ported to Qt and adapted for TDDD86, 2015.
*/
#include "Robot.h"
#include "constants.h"
bool Robot::isAlive() const{
return !toBeJunked;
}
void Robot::doCrash(){
toBeJunked = true;
}
bool Robot::isToBeJunked() const{
return toBeJunked;
}
void Robot::draw(QGraphicsScene *scene) const {
Point corner = asPoint();
scene->addEllipse(QRectF(corner.x * UNIT_WIDTH, corner.y * UNIT_HEIGHT,
JUNK_RADIUS, JUNK_RADIUS), QPen(), QBrush(ROBOT_COLOR));
}

41
src/Robot.h Executable file
View File

@ -0,0 +1,41 @@
/**
* Copyright (C) David Wolfe, 1999. All rights reserved.
* Ported to Qt and adapted for TDDD86, 2015.
*/
#ifndef ROBOT_H
#define ROBOT_H
#include "Unit.h"
#include <QGraphicsScene>
class Robot : public Unit {
bool toBeJunked = false;
public:
/*
* did not crash yet
*/
bool isAlive() const;
/*
* Crashes and remembers it
*/
void doCrash();
/*
* Return whether the robot crashed
*/
bool isToBeJunked() const;
/*
* Draws this robot onto the given QGraphicsScene.
*/
void draw(QGraphicsScene* scene) const;
};
#endif // ROBOT_H

59
src/Unit.cpp Executable file
View File

@ -0,0 +1,59 @@
/**
* Copyright (C) David Wolfe, 1999. All rights reserved.
* Ported to Qt and adapted for TDDD86, 2015.
*/
#include "Unit.h"
#include "constants.h"
#include "utilities.h"
#include <cstdlib>
#include <cmath>
Unit::Unit() {
teleport();
}
Unit::Unit(const Point& p) {
x = p.x;
y = p.y;
}
Point Unit::asPoint() const {
return Point{x, y};
}
bool Unit::at(const Unit& u) const {
return (x == u.x && y == u.y);
}
void Unit::moveTowards(const Point& p) {
if (x > p.x) x--;
if (x < p.x) x++;
if (y > p.y) y--;
if (y < p.y) y++;
checkBounds();
}
void Unit::teleport() {
x = rand_int (MIN_X, MAX_X);
y = rand_int (MIN_Y, MAX_Y);
}
double Unit::distanceTo(const Unit& u) const {
double dx = u.x - x;
double dy = u.y - y;
return sqrt(dx * dx + dy * dy);
}
/*
* Put this unit inside playing field if outside
*/
void Unit::checkBounds() {
if (x < MIN_X) x = MIN_X;
if (x > MAX_X) x = MAX_X;
if (y < MIN_Y) y = MIN_Y;
if (y > MAX_Y) y = MAX_Y;
}

65
src/Unit.h Executable file
View File

@ -0,0 +1,65 @@
/**
* Copyright (C) David Wolfe, 1999. All rights reserved.
* Ported to Qt and adapted for TDDD86, 2015.
* Updated for TDDD86, 2021.
*/
#ifndef UNIT_H
#define UNIT_H
#include "utilities.h"
#include <QGraphicsScene>
/* Root class for all pieces on the board.
* Subclasses are Robot, Hero and Junk.
*/
class Unit {
public:
/*
* Create a unit at a random position
*/
Unit();
/*
* Create unit at given point
*/
Unit(const Point& p);
virtual ~Unit(){}
/*
* Return Point representation of Unit
*/
Point asPoint() const;
/*
* Am I in the same square as u?
*/
bool at(const Unit& u) const;
/*
* Take one step closer to point
*/
void moveTowards(const Point&);
/*
* Teleport. Does not check for collision
*/
void teleport();
/*
* Euclidean distance to u
*/
double distanceTo(const Unit& u) const;
private:
int x; // x position of this unit
int y; // y position of this unit
// private helpers
void checkBounds();
};
#endif // UNIT_H

32
src/constants.h Executable file
View File

@ -0,0 +1,32 @@
/**
* Copyright (C) David Wolfe, 1999. All rights reserved.
* Ported to Qt and adapted for TDDD86, 2015.
*/
#ifndef CONSTANTS_H
#define CONSTANTS_H
#include <QColor>
// GUI constants
const int MIN_X = 0;
const int MIN_Y = 0;
const int MAX_X = 39;
const int MAX_Y = 39;
const int UNIT_WIDTH = 10;
const int UNIT_HEIGHT = 10;
static const int SCENE_WIDTH = 400;
static const int SCENE_HEIGHT = 400;
const int JUNK_RADIUS = 9;
const QColor JUNK_COLOR = QColor(0, 0, 0);
const QColor ROBOT_COLOR = QColor(245, 95, 60);
const QColor HERO_COLOR = QColor(237, 207, 114);
// game constants
const int MIN_ROBOTS = 10;
const int MAX_ROBOTS = 80;
const int ROBOTS_INC = 5; // Additional robots per round
const int POINTS_PER_ROBOT = 10;
const int WAIT_BONUS = 20; // Per robot
#endif // CONSTANTS_H

201
src/mainwindow.cpp Executable file
View File

@ -0,0 +1,201 @@
/**
* TDDD86 Robots
* This file contains the implementation of the mainwindow class.
* See mainwindow.h for comments about each member.
*/
#include <algorithm>
#include "mainwindow.h"
#include "Hero.h"
#include "Robot.h"
#include "Junk.h"
MainWindow::MainWindow(QWidget *parent) :
QWidget(parent) {
// set default size and color
scene = new QGraphicsScene(0, 0, SCENE_WIDTH, SCENE_HEIGHT);
scene->setBackgroundBrush(QBrush(QColor(204, 192, 179)));
view = new QGraphicsView(scene);
// create the main layout
mainLayout = new QVBoxLayout();
setLayout(mainLayout);
// add game board to layout
mainLayout->insertWidget(0, view);
// start new game and draw state
gameState.draw(scene);
// create label layout
labelLayout = new QHBoxLayout();
// create the score widget
scoreLabel = new QLabel(QString("SCORE: %1").arg(score));
scoreLabel->setStyleSheet("QLabel { color: rgb(235,224,214); font: 16pt; }");
scoreLabel->setFixedHeight(35);
// create the level widget
levelLabel = new QLabel(QString("LEVEL: %1").arg(level));
levelLabel->setStyleSheet("QLabel { color: rgb(235,224,214); font: 16pt; }");
levelLabel->setFixedHeight(35);
// add score and level widgets to board
labelLayout->insertWidget(0, levelLabel, 0, Qt::AlignLeft);
labelLayout->insertWidget(1, scoreLabel, 0, Qt::AlignRight);
mainLayout->insertLayout(1, labelLayout);
// style sheet of the game board
setStyleSheet("MainWindow { background-color: rgb(187,173,160) }");
// no resizing of game window
setFixedSize(sizeHint());
connect(gameOverWindow.getResetBtn(), SIGNAL(clicked()), this, SLOT(resetGame()));
}
MainWindow::~MainWindow() {
delete scoreLabel;
delete levelLabel;
delete labelLayout;
delete scene;
delete view;
delete mainLayout;
}
/*
* Listens to key press events from the graphical subsystem,
* and handles the events appropriately:
* - '[n]' moves hero in direction [n],
* where n = 1, 2, 3, 4, 6, 7, 8, 9 on the numeric keypad
* - '5' on the numeric keypad makes the hero wait one turn
* - 'T' teleports hero
*/
void MainWindow::keyPressEvent(QKeyEvent *e)
{
if (!gameOver) { // only process key presses while game is not over
Point pt = gameState.getHeroAsPoint();
bool actionTaken = false;
bool waiting = false;
if ((e->modifiers() == Qt::NoModifier) || (e->modifiers() == Qt::KeypadModifier)) {
switch (e->key()) {
case Qt::Key_B:
case Qt::Key_1:
actionTaken = tryMoveHeroTowards(Point{pt.x - 1, pt.y + 1});
break;
case Qt::Key_N:
case Qt::Key_2:
actionTaken = tryMoveHeroTowards(Point{pt.x, pt.y + 1});
break;
case Qt::Key_M:
case Qt::Key_3:
actionTaken = tryMoveHeroTowards(Point{pt.x + 1, pt.y + 1});
break;
case Qt::Key_H:
case Qt::Key_4:
actionTaken = tryMoveHeroTowards(Point{pt.x - 1, pt.y});
break;
case Qt::Key_K:
case Qt::Key_6:
actionTaken = tryMoveHeroTowards(Point{pt.x + 1, pt.y});
break;
case Qt::Key_Y:
case Qt::Key_7:
actionTaken = tryMoveHeroTowards(Point{pt.x - 1, pt.y - 1});
break;
case Qt::Key_U:
case Qt::Key_8:
actionTaken = tryMoveHeroTowards(Point{pt.x, pt.y - 1});
break;
case Qt::Key_I:
case Qt::Key_9:
actionTaken = tryMoveHeroTowards(Point{pt.x + 1, pt.y - 1});
break;
case Qt::Key_J:
case Qt::Key_5:
actionTaken = true;
waiting = true;
break;
case Qt::Key_T:
gameState.teleportHero();
actionTaken = true;
break;
default:
QWidget::keyPressEvent(e);
}
}
if (actionTaken) { // process results of viable move
processMove(waiting);
}
} else { // game is over - do not process key press
QWidget::keyPressEvent(e);
}
}
/*
* Try to move hero to unit
*/
bool MainWindow::tryMoveHeroTowards(const Point& point) {
if (!outsideBorder(point)) {
gameState.moveHeroTowards(point);
return true;
}
return false;
}
/*
* Process results of viable move
*/
void MainWindow::processMove(bool waiting) {
gameState.moveRobots();
gameState.updateCrashes();
score += gameState.countToBeJunked() * (POINTS_PER_ROBOT +
(waiting ? WAIT_BONUS : 0));
gameState.junkTheCrashed();
gameState.draw(scene);
displayScore();
if (gameState.heroDead()) { // game over
gameOver = true;
gameOverWindow.show();
}else if(!gameState.someRobotsAlive()) { // won level
numberOfRobots = std::min(MAX_ROBOTS, numberOfRobots + ROBOTS_INC);
gameState = GameState(numberOfRobots);
gameState.draw(scene);
++level;
displayLevel();
}
}
/*
* Is point outside of playing field?
*/
bool MainWindow::outsideBorder(Point const& point) const {
return point.x > MAX_X
|| point.y > MAX_Y
|| point.x < MIN_X
|| point.y < MIN_Y;
}
void MainWindow::displayScore() const {
scoreLabel->setText(QString("SCORE: %1").arg(score));
}
void MainWindow::displayLevel() const {
levelLabel->setText(QString("LEVEL: %1").arg(level));
}
void MainWindow::resetGame() {
score = 0;
level = 1;
numberOfRobots = MIN_ROBOTS;
gameState = GameState(numberOfRobots);
gameState.draw(scene);
displayScore();
displayLevel();
gameOver = false;
gameOverWindow.hide();
}

58
src/mainwindow.h Executable file
View File

@ -0,0 +1,58 @@
/**
* TDDD86 Robots
* This file contains the declaration of the mainwindow class.
* See mainwindow.cpp for implementation of each member.
*/
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QWidget>
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QGraphicsView>
#include <QGraphicsScene>
#include <QLabel>
#include <QKeyEvent>
#include "qgameoverwindow.h"
#include "constants.h"
#include "GameState.h"
class MainWindow : public QWidget {
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
signals:
protected:
void keyPressEvent(QKeyEvent *k);
public slots:
void resetGame();
private:
QVBoxLayout* mainLayout = nullptr; // main layout
QHBoxLayout* labelLayout = nullptr; // label layout
QGraphicsView* view = nullptr; // playing field widget
QGraphicsScene* scene = nullptr; // scene for playing field
QLabel* scoreLabel = nullptr; // score widget
QLabel* levelLabel = nullptr; // level widget
QGameOverWindow gameOverWindow; // game over widget
int score = 0; // current score
int level = 1; // current level
int numberOfRobots = MIN_ROBOTS; // current no. of robots
GameState gameState = GameState(numberOfRobots); // current state of game
bool gameOver = false;
// private helpers
bool tryMoveHeroTowards(const Point &point);
void processMove(bool waiting);
bool outsideBorder(const Point &point) const;
void displayScore() const;
void displayLevel() const;
};
#endif // MAINWINDOW_H

42
src/qgameoverwindow.cpp Executable file
View File

@ -0,0 +1,42 @@
/**
* TDDD86 Robots
* This file contains the implementation of the QGameOverWindow class.
*/
#include "qgameoverwindow.h"
#include "qresetbutton.h"
#include <QVBoxLayout>
#include <QLabel>
QGameOverWindow::QGameOverWindow(QWidget *parent) :
QWidget(parent) {
setStyleSheet("QGameOverWindow { background: rgb(237,224,200); }");
setFixedSize(425, 205);
QVBoxLayout *layout = new QVBoxLayout(this);
// game over label
QLabel* gameover = new QLabel("Game Over!", this);
gameover->setStyleSheet("QLabel { color: rgb(119,110,101); font: 40pt; font: bold;} ");
// reset button
reset = new QResetButton(this);
reset->setFixedHeight(50);
reset->setFixedWidth(100);
// add game over label to window
layout->insertWidget(0, gameover, 0, Qt::AlignCenter);
// add reset button to window
layout->insertWidget(1, reset, 0, Qt::AlignCenter);
}
QGameOverWindow::~QGameOverWindow() {
delete reset;
delete gameover;
delete layout;
}
QResetButton* QGameOverWindow::getResetBtn() const {
return reset;
}

35
src/qgameoverwindow.h Executable file
View File

@ -0,0 +1,35 @@
/**
* TDDD86 Robots
* This file contains the declaration of the QGameOverWindow class.
* See qgameoverwindow.cpp for implementation of each member.
*/
#ifndef QGAMEOVERWINDOW_H
#define QGAMEOVERWINDOW_H
#include <QWidget>
#include <QVBoxLayout>
#include <QLabel>
#include "qresetbutton.h"
class QGameOverWindow : public QWidget
{
Q_OBJECT
public:
explicit QGameOverWindow(QWidget *parent = 0);
~QGameOverWindow();
QResetButton* getResetBtn() const;
signals:
public slots:
private:
QVBoxLayout *layout = nullptr;
QLabel* gameover = nullptr;
QResetButton* reset = nullptr;
};
#endif // QGAMEOVERWINDOW_H

18
src/qresetbutton.cpp Executable file
View File

@ -0,0 +1,18 @@
/**
* TDDD86 Robots
* This file contains the implementation of the QResetButton class.
*/
#include "qresetbutton.h"
QResetButton::QResetButton( QWidget* parent) : QLabel(parent) {
setText("Try again!");
setAlignment(Qt::AlignCenter);
setStyleSheet("QResetButton { background-color: rgb(143,122,102); border-radius: 10px; font: bold; color: white; }");
}
void QResetButton::mousePressEvent(QMouseEvent* event) {
if (event) {
emit clicked();
}
}

28
src/qresetbutton.h Executable file
View File

@ -0,0 +1,28 @@
/**
* TDDD86 Robots
* This file contains the declaration of the QResetButton class.
* See qresetbutton.cpp for implementation of each member.
*/
#ifndef QRESETBUTTON_H
#define QRESETBUTTON_H
#include <QLabel>
class QResetButton : public QLabel
{
Q_OBJECT
public:
QResetButton( QWidget* parent = 0);
signals:
void clicked();
public slots:
protected:
void mousePressEvent(QMouseEvent* event);
};
#endif // QRESETBUTTON_H

21
src/robotsmain.cpp Executable file
View File

@ -0,0 +1,21 @@
/**
* TDDD86 Robots
* This client program contains the 'main' function to set up the overall
* program's graphical user interface.
* Your code should work properly with an unmodified version of this file.
*/
#include <QApplication>
#include "mainwindow.h"
#include "utilities.h"
int main(int argc, char *argv[]) {
QApplication a(argc, argv);
rand_seed(); // seed random number generator
MainWindow view; // create main window
view.show(); // display main window
return a.exec(); // start Qt event loop
}

18
src/utilities.cpp Executable file
View File

@ -0,0 +1,18 @@
/**
* Copyright (C) David Wolfe, 1999. All rights reserved.
* Ported to Qt and adapted for TDDD86, 2015.
*/
#include "utilities.h"
#include "constants.h"
#include <cstdlib>
#include <ctime>
void rand_seed() {
int seed = static_cast<int>(time(0));
srand(seed);
}
int rand_int(int a, int b) {
return a + rand() % (b - a + 1);
}

27
src/utilities.h Executable file
View File

@ -0,0 +1,27 @@
/**
* Copyright (C) David Wolfe, 1999. All rights reserved.
* Ported to Qt and adapted for TDDD86, 2015.
*/
#ifndef UTILITIES_H
#define UTILITIES_H
struct Point {
int x;
int y;
};
/**
* Sets the seed of the random number generator.
*/
void rand_seed();
/**
* Returns a random integer in a range.
* @param a the bottom of the range
* @param b the top of the range
* &return a random number x having a <= x and x <= b
*/
int rand_int(int a, int b);
#endif // UTILITIES_H