init
This commit is contained in:
commit
f96baa9e89
12
.gitignore
vendored
Executable file
12
.gitignore
vendored
Executable file
@ -0,0 +1,12 @@
|
||||
*~
|
||||
|
||||
.DS_Store
|
||||
|
||||
*.pro.user.*
|
||||
*.pro.user
|
||||
|
||||
build-*/
|
||||
*.app
|
||||
*.exe
|
||||
|
||||
build
|
26
Robots.pro
Executable file
26
Robots.pro
Executable 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
119
src/GameState.cpp
Executable 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
91
src/GameState.h
Executable 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
16
src/Hero.cpp
Executable 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
23
src/Hero.h
Executable 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
16
src/Junk.cpp
Executable 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
22
src/Junk.h
Executable 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
29
src/Robot.cpp
Executable 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
41
src/Robot.h
Executable 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
59
src/Unit.cpp
Executable 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
65
src/Unit.h
Executable 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
32
src/constants.h
Executable 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
201
src/mainwindow.cpp
Executable 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
58
src/mainwindow.h
Executable 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
42
src/qgameoverwindow.cpp
Executable 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
35
src/qgameoverwindow.h
Executable 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
18
src/qresetbutton.cpp
Executable 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
28
src/qresetbutton.h
Executable 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
21
src/robotsmain.cpp
Executable 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
18
src/utilities.cpp
Executable 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
27
src/utilities.h
Executable 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
|
Loading…
x
Reference in New Issue
Block a user