/bike.h |
---|
File deleted |
/QTron.pro |
---|
File deleted |
/mainwindow.h |
---|
File deleted |
/main.cpp |
---|
File deleted |
/bike.cpp |
---|
File deleted |
/mainwindow.cpp |
---|
File deleted |
/src/client.cpp |
---|
0,0 → 1,333 |
#include <QtCore/QCryptographicHash> |
#include <QtCore/QStringList> |
#include <QtNetwork/QHostAddress> |
#include "client.hpp" |
#include <iostream> |
using namespace std; |
Client::Client(int sd) : |
QThread() |
{ |
connected = true; |
socket = new QTcpSocket(this); |
socket->setSocketDescriptor(sd); |
peerAddress = socket->peerAddress().toString(); |
colourRed = -1; |
colourGreen = -1; |
colourBlue = -1; |
playing = false; |
playedGo = false; |
} |
Client::~Client() |
{ |
cout << ":: Deleted Connection: " << peerAddress.toStdString() << endl; |
if (connected) |
{ |
socket->disconnectFromHost(); |
} |
delete socket; |
} |
bool Client::isConnected() |
{ |
return connected; |
} |
void Client::run() |
{ |
cout << ":: Running Thread" << endl; |
doGo(); |
} |
bool Client::doGo() |
{ |
playedGo = false; |
bool p = false; |
checkDisconnected(); |
if (connected) |
{ |
if (playing && !crashed) |
{ |
int start = time(0); |
updatePos(); |
crashed = hasCollided(clients); |
sendText("G"); |
if (socket->waitForReadyRead(2000)) |
{ |
p = checkReadyRead(); |
if (!playedGo) |
{ |
socket->disconnectFromHost(); |
} |
} |
else |
{ |
p = true; |
socket->disconnectFromHost(); |
} |
int finish = time(0); |
int delta = finish - start; |
cout << ":: " << name.toStdString() << ": " << delta << endl; |
} |
else |
{ |
while (socket->canReadLine()) |
{ |
checkReadyRead(); |
} |
checkPlayable(); |
p = true; |
} |
} |
playedGo = p; |
return true; |
} |
void Client::checkDisconnected() |
{ |
if (socket->state() == QAbstractSocket::UnconnectedState) |
{ |
connected = false; |
} |
else |
{ |
if (socket->waitForDisconnected(10)) |
{ |
connected = false; |
} |
} |
} |
bool Client::checkReadyRead() |
{ |
bool playedGo = false; |
if (socket->canReadLine()) |
{ |
QByteArray data = socket->readLine(); |
QString line = data.trimmed(); |
cout << ":: " << name.toStdString() << ": " << line.toStdString() << endl; |
if (line == "DISCONNECT") |
{ |
socket->disconnectFromHost(); |
} |
else if (line.startsWith("NAME ")) |
{ |
name = line.remove(0, 5); |
} |
else if (line.startsWith("CHAT ")) |
{ |
QString text = line.remove(0, 5); |
emit chat(name, text); |
playedGo = true; |
} |
else if (line.startsWith("COLOUR ")) |
{ |
QStringList list = line.split(" "); |
if (list.count() == 4) |
{ |
colourRed = list[1].toInt(); |
colourGreen = list[2].toInt(); |
colourBlue = list[3].toInt(); |
} |
} |
else if (line == "N") |
{ |
playedGo = true; |
} |
else if (line == "L") |
{ |
angle -= 90; |
playedGo = true; |
} |
else if (line == "R") |
{ |
angle -= 90; |
playedGo = true; |
} |
else if (line == "A") |
{ |
//if (speed < 2.0) |
//{ |
// speed += 0.1; |
//} |
playedGo = true; |
} |
else if (line == "D") |
{ |
//if (speed > 0.2) |
//{ |
// speed -= 0.1; |
//} |
playedGo = true; |
} |
} |
return playedGo; |
} |
void Client::checkPlayable() |
{ |
if (!name.isEmpty()) |
{ |
if (colourRed != -1) |
{ |
if (colourGreen != -1) |
{ |
if (colourBlue != -1) |
{ |
playing = true; |
} |
} |
} |
} |
} |
void Client::updatePos() |
{ |
if (angle >= 360) |
{ |
angle -= 360; |
} |
if (angle <= -90) |
{ |
angle += 360; |
} |
if (angle == 0) |
{ |
y -= speed; |
} |
else if (angle == 180) |
{ |
y += speed; |
} |
else if (angle == 90) |
{ |
x += speed; |
} |
else if (angle == 270) |
{ |
x -= speed; |
} |
linePoints.append(QPoint(x, y)); |
} |
void Client::reset() |
{ |
x = rand() % 800; |
y = rand() % 600; |
int a = rand() % 4; |
angle = a * 90; |
speed = 1.0; |
linePoints.clear(); |
linePoints.append(QPoint(x, y)); |
crashed = false; |
sendText("RESET"); |
} |
bool Client::hasCollided(QList<Client *> clients) |
{ |
int i = linePoints.count() - 1; |
if(linePoints[i-1].x() < 0 || linePoints[i-1].x() > 800 || linePoints[i-1].y() < 0 || linePoints[i-1].y() > 600) |
return true; |
if(linePoints[i].x() < 0 || linePoints[i].x() > 800 || linePoints[i].y() < 0 || linePoints[i].y() > 600) |
return true; |
int j; |
foreach (Client *bike, clients) |
{ |
for(j = 0; j < bike->linePoints.count() - 2; j++) |
{ |
if(!(bike->linePoints[j].x() == bike->linePoints[j+1].x() && linePoints[i].x() == linePoints[i-1].x()) && !(bike->linePoints[j].y() == bike->linePoints[j+1].y() && linePoints[i].y() == linePoints[i-1].y())) |
{ |
// If not parallel |
if(bike->linePoints[j].x() == bike->linePoints[j+1].x()) |
{ |
// x equal |
if (((linePoints[i-1].x() > bike->linePoints[j].x()) && (linePoints[i].x() < bike->linePoints[j].x())) || ((linePoints[i-1].x() < bike->linePoints[j].x()) && (linePoints[i].x() > bike->linePoints[j].x()))) |
{ |
if((sign(linePoints[i-1].y() - bike->linePoints[j].y()) != sign(linePoints[i-1].y() - bike->linePoints[j+1].y()))) |
return true; |
} |
} |
else if(bike->linePoints[j].y() == bike->linePoints[j+1].y()) |
{ |
if (((linePoints[i-1].y() > bike->linePoints[j].y()) && (linePoints[i].y() < bike->linePoints[j].y())) || ((linePoints[i-1].y() < bike->linePoints[j].y()) && (linePoints[i].y() > bike->linePoints[j].y()))) |
{ |
if((sign(linePoints[i-1].x() - bike->linePoints[j].x()) != sign(linePoints[i-1].x() - bike->linePoints[j+1].x()))) |
return true; |
} |
} |
} |
} |
} |
return false; |
} |
void Client::sendText(QByteArray text) |
{ |
if (connected) |
{ |
write(text); |
write("\n"); |
} |
} |
void Client::write(QByteArray text) |
{ |
if (connected) |
{ |
socket->write(text); |
socket->flush(); |
} |
} |
int sign(float x) |
{ |
if (x > 0) |
{ |
return 1; |
} |
if (x < 0) |
{ |
return -1; |
} |
return 0; |
} |
/src/client.hpp |
---|
0,0 → 1,67 |
#ifndef CLIENT_H |
#define CLIENT_H |
#include <QtCore/QObject> |
#include <QtCore/QList> |
#include <QtCore/QString> |
#include <QtCore/QPoint> |
#include <QtCore/QThread> |
#include <QtNetwork/QTcpSocket> |
class Client : public QObject |
{ |
Q_OBJECT |
public: |
Client(int sd); |
~Client(); |
bool isConnected(); |
void run(); |
bool doGo(); |
bool checkReadyRead(); |
void checkDisconnected(); |
void checkPlayable(); |
void updatePos(); |
void reset(); |
bool hasCollided(QList<Client *> clients); |
void sendText(QByteArray text); |
void write(QByteArray text); |
QString name; |
int colourRed; |
int colourGreen; |
int colourBlue; |
double x; |
double y; |
int angle; |
double speed; |
bool playing; |
bool crashed; |
QList<QPoint> linePoints; |
QList<Client *> clients; |
bool playedGo; |
QString peerAddress; |
private: |
QTcpSocket *socket; |
bool connected; |
signals: |
void chat(QString name, QString data); |
}; |
int sign(float x); |
#endif // CLIENT_H |
/src/main.cpp |
---|
0,0 → 1,12 |
#include <QtCore/QCoreApplication> |
#include "server.hpp" |
int main(int argc, char *argv[]) |
{ |
QCoreApplication a(argc, argv); |
Server s; |
s.start(); |
return a.exec(); |
} |
/src/server.cpp |
---|
0,0 → 1,183 |
#include <QtNetwork/QHostAddress> |
#include "server.hpp" |
#include <iostream> |
using namespace std; |
Server::Server() : |
QObject() |
{ |
srand(time(NULL)); |
server = new QTcpServer(this); |
} |
Server::~Server() |
{ |
delete server; |
} |
void Server::start() |
{ |
int port = 4567; |
cout << ":: Starting server on port " << port << endl; |
if (!server->listen(QHostAddress::Any, port)) |
{ |
cout << "!! Could not start Server: " << server->errorString().toStdString() << endl; |
} |
bool running = true; |
while (running) |
{ |
checkClients(); |
checkConnections(); |
doGo(); |
} |
} |
void Server::checkClients() |
{ |
for (int i = clients.size() - 1; i >= 0; i--) |
{ |
Client *client = clients[i]; |
if (!client->isConnected()) |
{ |
delete client; |
clients.removeAt(i); |
} |
} |
} |
void Server::checkConnections() |
{ |
while (server->waitForNewConnection(10)) |
{ |
QTcpSocket *socket = server->nextPendingConnection(); |
Client *client = new Client(socket->socketDescriptor()); |
connect(client, SIGNAL(chat(QString, QString)), this, SLOT(chat(QString, QString))); |
clients.append(client); |
cout << ":: New Connection: " << socket->peerAddress().toString().toStdString() << endl; |
reset(); |
} |
} |
void Server::doGo() |
{ |
for (int i = clients.size() - 1; i >= 0; i--) |
{ |
Client *client = clients[i]; |
if (client->isConnected()) |
{ |
if (client->playing) |
{ |
sendClientInfo(client); |
} |
client->clients = clients; |
client->start(); |
} |
} |
bool goDone = false; |
while (!goDone) |
{ |
bool turnsDone = true; |
for (int i = clients.size() - 1; i >= 0; i--) |
{ |
Client *client = clients[i]; |
if (client->isConnected() && client->playing) |
{ |
if (!client->playedGo) |
{ |
turnsDone = false; |
} |
} |
} |
goDone = turnsDone; |
} |
bool allCrashed = true; |
for (int i = clients.size() - 1; i >= 0; i--) |
{ |
Client *client = clients[i]; |
if (client->isConnected()) |
{ |
if (!client->crashed) |
{ |
allCrashed = false; |
} |
} |
} |
if (allCrashed) |
{ |
reset(); |
} |
} |
void Server::sendClientInfo(Client *client) |
{ |
foreach (Client *c, clients) |
{ |
if (c->isConnected()) |
{ |
if (c->crashed) |
{ |
client->write("DIED "); |
client->write(c->name.toAscii()); |
client->write("\n"); |
} |
else |
{ |
client->write("BIKE "); |
client->write(c->name.toAscii()); |
client->write(" "); |
client->write(QByteArray::number(QByteArray::number(c->x).toInt())); |
client->write(" "); |
client->write(QByteArray::number(QByteArray::number(c->y).toInt())); |
client->write(" "); |
client->write(QByteArray::number(c->colourRed)); |
client->write(" "); |
client->write(QByteArray::number(c->colourGreen)); |
client->write(" "); |
client->write(QByteArray::number(c->colourBlue)); |
client->write("\n"); |
} |
} |
else |
{ |
client->write("DISCO "); |
client->write(c->name.toAscii()); |
client->write("\n"); |
} |
} |
} |
void Server::reset() |
{ |
foreach (Client *c, clients) |
{ |
c->reset(); |
} |
} |
void Server::chat(QString name, QString data) |
{ |
QByteArray array = "CHAT "; |
array.append(name.toAscii()); |
array.append(" "); |
array.append(data.toAscii()); |
array.append("\n"); |
foreach (Client *c, clients) |
{ |
c->write(array); |
} |
} |
/src/server.hpp |
---|
0,0 → 1,34 |
#ifndef SERVER_H |
#define SERVER_H |
#include <QtCore/QList> |
#include <QtNetwork/QTcpServer> |
#include "client.hpp" |
class Server : public QObject |
{ |
Q_OBJECT |
public: |
Server(); |
~Server(); |
void start(); |
void checkClients(); |
void checkConnections(); |
void doGo(); |
void sendClientInfo(Client *client); |
void reset(); |
private: |
QList<Client *> clients; |
QTcpServer *server; |
private slots: |
void chat(QString name, QString data); |
}; |
#endif // SERVER_H |
/tmake.tml |
---|
0,0 → 1,22 |
MinimumVersion(2) |
Project("QTron Server") |
Language("C++") |
Type("APPLICATION") |
LIBRARIES = { QT_LIB, QT_NETWORK_LIB } |
HEADERS = { "server.hpp", "client.hpp" } |
QtMoc(HEADERS) |
SOURCES = { "main.cpp", "server.cpp", "client.cpp", QT_MOC_S } |
Compile(SOURCES) |
Link("qtron-server", SOURCES, LIBRARIES) |
Install("qtron-server") |
Uninstall("qtron-server") |
CleanExec("rm -rf src/moc_server.cpp") |
CleanExec("rm -rf src/moc_client.cpp") |