Subversion Repositories QTron

Compare Revisions

Ignore whitespace Rev 36 → Rev 37

/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")