예제 소스
인베이더 게임으로 배우는 휴리스틱과 AI 브리지 · 파일 17개
tcpvlmclient.h
#pragma once
#include <QAtomicInt>
#include <QByteArray>
#include <QImage>
#include <QObject>
#include <QString>
class QTcpSocket;
/** 인베이더용 TCP 클라이언트 (omook TcpVlmClient 와 동일한 RPLY/LACK 응답 형식).
*
* INV3: PNG + 격자 → RPLY 성공 시 row 바이트 = PlayerAction(0..3), col=0
* INVL: 한 틱 로그 (추론 없음) → LACK
*/
namespace TcpVlmClient {
class Worker : public QObject {
Q_OBJECT
public:
explicit Worker(QObject *parent = nullptr);
~Worker() override;
bool isBusy() const;
bool isConnected() const;
public slots:
void doPing(QString host, quint16 port, int timeoutMs);
/// rows=kGridRows, cols=kGridCols 고정 직렬화 보드.
void requestMove(QImage boardImage, QByteArray boardPacked, int rows, int cols, QString host,
quint16 port, int timeoutMs);
/// action: 0=L 1=R 2=Fire 3=None / actor: 0 human 1 ai 2 vlm
void requestLog(int rows, int cols, int action, int actor, int playMode, int status, int seq,
QByteArray boardPacked, QString host, quint16 port, int timeoutMs);
void cancel();
void closeConnection();
signals:
void moveReady(bool success, int actionOrRow, int unusedCol, QString errorMessage);
void pingReady(bool success, QString errorMessage);
void connectionStateChanged(bool connected, QString endpoint);
private:
bool ensureConnected(const QString &host, quint16 port, int timeoutMs, QString *errorOut);
bool readBytes(QByteArray *dst, qint64 nbytes, int deadlineMs);
bool writeAll(const QByteArray &data, int timeoutMs);
void closeSocketLocked(const QString &reason);
void emitConnState();
QTcpSocket *m_socket = nullptr;
QString m_curHost;
quint16 m_curPort = 0;
QAtomicInt m_cancel{0};
QAtomicInt m_busy{0};
};
} // namespace TcpVlmClient