Skip to content

Commit

Permalink
Merge branch 'TeeworldsBotLib:master' into master
Browse files Browse the repository at this point in the history
  • Loading branch information
ChillerDragon authored May 20, 2024
2 parents 627d484 + 0361029 commit bf06995
Show file tree
Hide file tree
Showing 10 changed files with 242 additions and 32 deletions.
5 changes: 4 additions & 1 deletion .github/workflows/clang-tidy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ jobs:
run: |
mkdir clang-tidy
cd clang-tidy
cmake -G Ninja -DCMAKE_CXX_CLANG_TIDY="clang-tidy;-warnings-as-errors=*" -DCMAKE_C_CLANG_TIDY="clang-tidy;-warnings-as-errors=*" -DCMAKE_BUILD_TYPE=Debug -Werror=dev ..
cmake -G Ninja -DCMAKE_CXX_CLANG_TIDY="clang-tidy;-warnings-as-errors=*" -DCMAKE_C_CLANG_TIDY="clang-tidy;-warnings-as-errors=*" \
-DCMAKE_BUILD_TYPE=Debug \
-DTWBL_DEBUG=ON \
-Werror=dev ..
cmake --build . --config Debug
2 changes: 2 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ FILE(GLOB BOT_SOURCE_FILES

add_library(twbl STATIC ${BOT_SOURCE_FILES})

target_compile_options(twbl PRIVATE -std=gnu++17)

include_directories(src)

include(CTest)
Expand Down
70 changes: 63 additions & 7 deletions src/bots/base.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,74 @@

namespace TWBL {

void CBaseBot::DirRaw(int Dir)
void PushRingStr(const char **ppBuffer, const char *pNew, size_t MaxEntries)
{
for(int i = MaxEntries - 1; i > 0; i--)
ppBuffer[i] = ppBuffer[i - 1];
ppBuffer[0] = pNew;
}

void PushRingInt(int *pBuffer, int New, size_t MaxEntries)
{
for(int i = MaxEntries - 1; i > 0; i--)
pBuffer[i] = pBuffer[i - 1];
pBuffer[0] = New;
}

#define GetStrBufSize(buf) sizeof(buf) / sizeof(const char *)
#define GetIntBufSize(buf) sizeof(buf) / sizeof(int)

void CBaseBot::_AimRaw(int TargetX, int TargetY) const
{
m_pStateOut->m_TargetX = TargetX;
m_pStateOut->m_TargetY = TargetY;
}

void CBaseBot::_Aim(int TargetX, int TargetY, const char *pComment, const char *pFunction, const char *pFile, int Line) const
{
_AimRaw(TargetX, TargetY);
PushRingStr(m_pStateOut->m_apAimComments, pComment, GetStrBufSize(m_pStateOut->m_apAimComments));
PushRingStr(m_pStateOut->m_apAimFunctions, pFunction, GetStrBufSize(m_pStateOut->m_apAimFunctions));
PushRingStr(m_pStateOut->m_apAimFiles, pFile, GetStrBufSize(m_pStateOut->m_apAimFiles));
PushRingInt(m_pStateOut->m_aAimLines, Line, GetIntBufSize(m_pStateOut->m_aAimLines));
}
void CBaseBot::_DirRaw(int Dir) const
{
m_pStateOut->m_Direction = Dir;
}

void CBaseBot::Dir(int Dir, const char *pComment, const char *pFunction, const char *pFile, int Line)
void CBaseBot::_Dir(int Dir, const char *pComment, const char *pFunction, const char *pFile, int Line) const
{
DirRaw(Dir);
m_pStateOut->m_pDirComment = pComment;
m_pStateOut->m_pDirFunction = pFunction;
m_pStateOut->m_pDirFile = pFile;
m_pStateOut->m_DirLine = Line;
_DirRaw(Dir);
PushRingStr(m_pStateOut->m_apDirComments, pComment, GetStrBufSize(m_pStateOut->m_apDirComments));
PushRingStr(m_pStateOut->m_apDirFunctions, pFunction, GetStrBufSize(m_pStateOut->m_apDirFunctions));
PushRingStr(m_pStateOut->m_apDirFiles, pFile, GetStrBufSize(m_pStateOut->m_apDirFiles));
PushRingInt(m_pStateOut->m_aDirLines, Line, GetIntBufSize(m_pStateOut->m_aDirLines));
}

void CBaseBot::_HookRaw(int Value) const
{
m_pStateOut->m_Hook = Value;
}

void CBaseBot::_Hook(int Value, const char *pComment, const char *pFunction, const char *pFile, int Line) const
{
_HookRaw(Value);
PushRingStr(m_pStateOut->m_apHookComments, pComment, GetStrBufSize(m_pStateOut->m_apHookComments));
PushRingStr(m_pStateOut->m_apHookFunctions, pFunction, GetStrBufSize(m_pStateOut->m_apHookFunctions));
PushRingStr(m_pStateOut->m_apHookFiles, pFile, GetStrBufSize(m_pStateOut->m_apHookFiles));
PushRingInt(m_pStateOut->m_aHookLines, Line, GetIntBufSize(m_pStateOut->m_aHookLines));
}

void CBaseBot::_JumpRaw(int Value) const
{
m_pStateOut->m_Jump = Value;
}
void CBaseBot::_Jump(int Value, const char *pComment, const char *pFunction, const char *pFile, int Line) const
{
}

#undef GetStrBufSize
#undef GetIntBufSize

} // namespace TWBL
44 changes: 35 additions & 9 deletions src/bots/base.h
Original file line number Diff line number Diff line change
@@ -1,10 +1,20 @@
#ifndef TWBL_SRC_BOTS_BASE_H
#define TWBL_SRC_BOTS_BASE_H

#include <cstddef>

#include "shared/types.h"

namespace TWBL {

// 0 is newest
// MaxEntries-1 is oldest
void PushRingStr(const char **ppBuffer, const char *pNew, size_t MaxEntries);

// 0 is newest
// MaxEntries-1 is oldest
void PushRingInt(int *pBuffer, int New, size_t MaxEntries);

// TODO: this is horrible
// can we somehow include the vec2 type from the tw codebase?
typedef class CTwblVec2
Expand Down Expand Up @@ -33,26 +43,42 @@ class CBaseBot
}

vec2 GetPos() const { return vec2(m_pStateIn->m_PosX, m_pStateIn->m_PosY); }
void DirRaw(int Dir);
void Dir(int Dir, const char *pComment, const char *pFunction, const char *pFile, int Line);
vec2 GetVel() const { return vec2(m_pStateIn->m_VelX, m_pStateIn->m_VelY); }

// it is recommended to use the macros instead

void _AimRaw(int TargetX, int TargetY) const;
void _Aim(int TargetX, int TargetY, const char *pComment, const char *pFunction, const char *pFile, int Line) const;

void _DirRaw(int Dir) const;
void _Dir(int Dir, const char *pComment, const char *pFunction, const char *pFile, int Line) const;

void _HookRaw(int Value) const;
void _Hook(int Value, const char *pComment, const char *pFunction, const char *pFile, int Line) const;

void _JumpRaw(int Value) const;
void _Jump(int Value, const char *pComment, const char *pFunction, const char *pFile, int Line) const;

void Tick(){};
};

void TwblDirRaw(CServerBotStateOut *pStateOut, int Dir);
void TwblDir(CServerBotStateOut *pStateOut, int Dir, const char *pComment, const char *pFunction, const char *pFile, int Line);

} // namespace TWBL

// These macros can only be used within the scope of a CBaseBot

#ifdef TWBL_DEBUG
#define DIR(value, comment) Dir(value, comment, __func__, __FILE__, __LINE__)
#define Aim(TargetX, TargetY, comment) _Aim(TargetX, TargetY, comment, __func__, __FILE__, __LINE__)
#define Dir(value, comment) _Dir(value, comment, __func__, __FILE__, __LINE__)
#define Hook(value, comment) _Hook(value, comment, __func__, __FILE__, __LINE__)
#define Jump(value, comment) _Jump(value, comment, __func__, __FILE__, __LINE__)
#else
#define DIR(value, comment) DirRaw(value)
#define Aim(TargetX, TargetY, comment) _AimRaw(TargetX, TargetY)
#define Dir(value, comment) _DirRaw(value)
#define Hook(value, comment) _HookRaw(value)
#define Jump(value, comment) _JumpRaw(value)
#endif

#define Left(comment) DIR(-1, comment)
#define Right(comment) DIR(1, comment)
#define Left(comment) Dir(-1, comment)
#define Right(comment) Dir(1, comment)

#endif
15 changes: 14 additions & 1 deletion src/bots/sample.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,21 @@ namespace TWBL {

void CSampleBot::Tick()
{
printf("pos x=%f \n", GetPos().x);
printf("pos x=%f tileX=%d \n", GetPos().x, (int)(GetPos().x / 32));
Right("yolo");
Left("hello");
Right("world");

Aim(10, -100, "up");
Aim(100, 1, "right");

Hook(0, "off");
Hook(1, "on");

if(GetPos().x < 10 * 32)
Right("go right till 10");
else
Left("go left till 10");
}

void SampleTick(const CServerBotStateIn *pStateIn, CServerBotStateOut *pStateOut)
Expand Down
7 changes: 5 additions & 2 deletions src/bots/sample.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,13 @@

namespace TWBL {

class CSampleBot : CBaseBot
class CSampleBot : public CBaseBot
{
public:
using CBaseBot::CBaseBot;
CSampleBot(const CServerBotStateIn *pStateIn, CServerBotStateOut *pStateOut) :
CBaseBot(pStateIn, pStateOut)
{
}

void Tick();
};
Expand Down
54 changes: 49 additions & 5 deletions src/shared/types.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
#ifndef TWBL_SRC_SHARED_TYPES_H
#define TWBL_SRC_SHARED_TYPES_H

#define TWBL_MAX_LOG_LEN 16

class CServerBotStateIn
{
public:
Expand All @@ -26,11 +28,53 @@ class CServerBotStateOut
bool m_Kill;

// debug
// TODO: make these a ring buffer
const char *m_pDirComment;
const char *m_pDirFunction;
const char *m_pDirFile;
int m_DirLine;
const char *m_apAimComments[TWBL_MAX_LOG_LEN];
const char *m_apAimFunctions[TWBL_MAX_LOG_LEN];
const char *m_apAimFiles[TWBL_MAX_LOG_LEN];
int m_aAimLines[TWBL_MAX_LOG_LEN];

const char *m_apDirComments[TWBL_MAX_LOG_LEN];
const char *m_apDirFunctions[TWBL_MAX_LOG_LEN];
const char *m_apDirFiles[TWBL_MAX_LOG_LEN];
int m_aDirLines[TWBL_MAX_LOG_LEN];

const char *m_apHookComments[TWBL_MAX_LOG_LEN];
const char *m_apHookFunctions[TWBL_MAX_LOG_LEN];
const char *m_apHookFiles[TWBL_MAX_LOG_LEN];
int m_aHookLines[TWBL_MAX_LOG_LEN];

const char *m_apJumpComments[TWBL_MAX_LOG_LEN];
const char *m_apJumpFunctions[TWBL_MAX_LOG_LEN];
const char *m_apJumpFiles[TWBL_MAX_LOG_LEN];
int m_aJumpLines[TWBL_MAX_LOG_LEN];

CServerBotStateOut()
{
#ifdef TWBL_DEBUG
for(int i = 0; i < TWBL_MAX_LOG_LEN; i++)
{
m_apAimComments[i] = "";
m_apAimFunctions[i] = "";
m_apAimFiles[i] = "";
m_aAimLines[i] = 0;

m_apDirComments[i] = "";
m_apDirFunctions[i] = "";
m_apDirFiles[i] = "";
m_aDirLines[i] = 0;

m_apHookComments[i] = "";
m_apHookFunctions[i] = "";
m_apHookFiles[i] = "";
m_aHookLines[i] = 0;

m_apJumpComments[i] = "";
m_apJumpFunctions[i] = "";
m_apJumpFiles[i] = "";
m_aJumpLines[i] = 0;
}
#endif
}
};

#endif
70 changes: 66 additions & 4 deletions src/test/test_sample.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,79 @@

using namespace TWBL;

int main()
static void TestPushStr()
{
InitTest("push str");

CServerBotStateOut Bot;

EXPECT_EQ(sizeof(Bot.m_apDirComments) / sizeof(const char *), TWBL_MAX_LOG_LEN);

EXPECT_STREQ(Bot.m_apDirComments[0], "");
EXPECT_STREQ(Bot.m_apDirComments[1], "");

PushRingStr(Bot.m_apDirComments, "hello", sizeof(Bot.m_apDirComments) / sizeof(const char *));
EXPECT_STREQ(Bot.m_apDirComments[0], "hello");
EXPECT_STREQ(Bot.m_apDirComments[1], "");

PushRingStr(Bot.m_apDirComments, "world", sizeof(Bot.m_apDirComments) / sizeof(const char *));
EXPECT_STREQ(Bot.m_apDirComments[0], "world");
EXPECT_STREQ(Bot.m_apDirComments[1], "hello");

PushRingStr(Bot.m_apDirComments, "", sizeof(Bot.m_apDirComments) / sizeof(const char *));
EXPECT_STREQ(Bot.m_apDirComments[0], "");
EXPECT_STREQ(Bot.m_apDirComments[1], "world");
EXPECT_STREQ(Bot.m_apDirComments[2], "hello");

PushRingStr(Bot.m_apDirComments, "foo", sizeof(Bot.m_apDirComments) / sizeof(const char *));
EXPECT_STREQ(Bot.m_apDirComments[0], "foo");
EXPECT_STREQ(Bot.m_apDirComments[1], "");
EXPECT_STREQ(Bot.m_apDirComments[2], "world");
EXPECT_STREQ(Bot.m_apDirComments[3], "hello");

for(int i = 0; i < TWBL_MAX_LOG_LEN * 2; i++)
PushRingStr(Bot.m_apDirComments, "max*2", sizeof(Bot.m_apDirComments) / sizeof(const char *));

EXPECT_STREQ(Bot.m_apDirComments[0], "max*2");
EXPECT_STREQ(Bot.m_apDirComments[TWBL_MAX_LOG_LEN - 1], "max*2");
}

static void TestBasic()
{
InitTest("basic");

CServerBotStateIn State;
State.m_PosX = 0;
State.m_PosY = 0;
State.m_VelX = 0;
State.m_VelY = 0;

CServerBotStateOut Bot;
SampleTick(&State, &Bot);

EXPECT_EQ(Bot.m_Direction, 1);

EXPECT_STREQ(Bot.m_pDirComment, "yolo");
EXPECT_STREQ(Bot.m_pDirFunction, "Tick");
EXPECT_EQ(Bot.m_DirLine, 12);
EXPECT_STREQ(Bot.m_apDirComments[0], "go right till 10");
EXPECT_STREQ(Bot.m_apDirComments[1], "world");
EXPECT_STREQ(Bot.m_apDirComments[2], "hello");
EXPECT_STREQ(Bot.m_apDirComments[3], "yolo");
EXPECT_STREQ(Bot.m_apDirFunctions[0], "Tick");
EXPECT_EQ(Bot.m_aDirLines[0], 23);

EXPECT_STREQ(Bot.m_apAimComments[0], "right");
EXPECT_EQ(Bot.m_TargetX, 100);
EXPECT_EQ(Bot.m_TargetY, 1);

EXPECT_STREQ(Bot.m_apHookComments[0], "on");
EXPECT_EQ(Bot.m_Hook, 1);

State.m_PosX = 20 * 32;
SampleTick(&State, &Bot);
EXPECT_STREQ(Bot.m_apDirComments[0], "go left till 10");
}

int main()
{
TestPushStr();
TestBasic();
}
3 changes: 2 additions & 1 deletion src/test/twbl_assert.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,14 @@ void _test_fail()
exit(1);
}

int _expect_streq(const char *Actual, const char *Expected)
int _expect_streq(const char *Actual, const char *Expected, int Line)
{
if(!strcmp(Actual, Expected))
{
_test_ok();
return 0;
}
fprintf(stderr, "assert failed in line %d\n", Line);
fprintf(stderr, "expected: \"%s\"\n", Expected);
fprintf(stderr, " got: \"%s\"\n", Actual);
_test_fail();
Expand Down
4 changes: 2 additions & 2 deletions src/test/twbl_assert.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@

void _test_ok();
void _test_fail();
int _expect_streq(const char *Actual, const char *Expected);
int _expect_streq(const char *Actual, const char *Expected, int Line);
int _expect_eq(int Actual, int Expected);
int _expect_float_eq(float Actual, float Expected);

#define EXPECT_STREQ(actual, expected) _expect_streq(actual, expected);
#define EXPECT_STREQ(actual, expected) _expect_streq(actual, expected, __LINE__);
#define EXPECT_EQ(actual, expected) _expect_eq(actual, expected);
#define EXPECT_FLOAT_EQ(actual, expected) _expect_float_eq(actual, expected);

Expand Down

0 comments on commit bf06995

Please sign in to comment.