Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
Jochen Bauer
spn-relayserver
Commits
9569a7ed
Commit
9569a7ed
authored
Apr 11, 2018
by
Hubert Denkmair
Browse files
track food
parent
ca602b9c
Changes
4
Hide whitespace changes
Inline
Side-by-side
relayserver/CMakeLists.txt
View file @
9569a7ed
...
...
@@ -15,6 +15,7 @@ add_executable(
main.cpp
RelayServer.h RelayServer.cpp
TcpProtocol.h TcpProtocol.cpp
SpatialMap.h
)
target_link_libraries
(
...
...
relayserver/SpatialMap.h
0 → 100644
View file @
9569a7ed
#pragma once
#include <array>
#include <vector>
#include <functional>
#include <Eigen/Geometry>
typedef
double
real_t
;
typedef
Eigen
::
Matrix
<
real_t
,
2
,
1
>
Vector2D
;
template
<
class
T
>
class
SpatialMapRegion
;
template
<
class
T
,
size_t
TILES_X
,
size_t
TILES_Y
>
class
SpatialMap
{
public:
typedef
std
::
vector
<
T
>
TileVector
;
typedef
SpatialMapRegion
<
SpatialMap
<
T
,
TILES_X
,
TILES_Y
>>
Region
;
friend
class
SpatialMapRegion
<
SpatialMap
<
T
,
TILES_X
,
TILES_Y
>>
;
public:
SpatialMap
(
size_t
fieldSizeX
,
size_t
fieldSizeY
,
size_t
reserveCount
)
:
m_fieldSizeX
(
fieldSizeX
)
,
m_fieldSizeY
(
fieldSizeY
)
,
m_tileSizeX
(
fieldSizeX
/
TILES_X
)
,
m_tileSizeY
(
fieldSizeY
/
TILES_Y
)
,
m_fullRegion
(
*
this
,
0
,
0
,
TILES_X
-
1
,
TILES_Y
-
1
)
{
for
(
auto
&
v
:
m_tiles
)
{
v
.
reserve
(
reserveCount
);
}
}
void
clear
()
{
for
(
auto
&
v
:
m_tiles
)
{
v
.
clear
();
}
}
size_t
size
()
const
{
size_t
retval
=
0
;
for
(
auto
&
tile
:
m_tiles
)
{
retval
+=
tile
.
size
();
}
return
retval
;
}
void
addElement
(
const
T
&
element
)
{
getTileVectorForPosition
(
element
.
pos
()).
push_back
(
element
);
}
void
erase_if
(
std
::
function
<
bool
(
const
T
&
)
>
predicate
)
{
for
(
auto
&
tile
:
m_tiles
)
{
tile
.
erase
(
std
::
remove_if
(
tile
.
begin
(),
tile
.
end
(),
predicate
),
tile
.
end
());
}
}
Region
getRegion
(
const
Vector2D
&
center
,
real_t
radius
)
{
const
Vector2D
topLeft
=
center
-
Vector2D
{
radius
,
radius
};
const
Vector2D
bottomRight
=
center
+
Vector2D
{
radius
,
radius
};
return
{
*
this
,
static_cast
<
int
>
(
topLeft
.
x
()
/
m_tileSizeX
),
static_cast
<
int
>
(
topLeft
.
y
()
/
m_tileSizeY
),
static_cast
<
int
>
(
bottomRight
.
x
()
/
m_tileSizeX
),
static_cast
<
int
>
(
bottomRight
.
y
()
/
m_tileSizeY
)
};
}
typename
Region
::
Iterator
begin
()
{
return
m_fullRegion
.
begin
();
}
typename
Region
::
Iterator
end
()
{
return
m_fullRegion
.
end
();
}
private:
size_t
m_fieldSizeX
,
m_fieldSizeY
;
real_t
m_tileSizeX
,
m_tileSizeY
;
Region
m_fullRegion
;
std
::
array
<
TileVector
,
TILES_X
*
TILES_Y
>
m_tiles
;
TileVector
&
getTileVector
(
int
tileX
,
int
tileY
)
{
return
m_tiles
[
wrap
<
TILES_Y
>
(
tileY
)
*
TILES_X
+
wrap
<
TILES_X
>
(
tileX
)];
}
TileVector
&
getTileVectorNoWrap
(
int
tileX
,
int
tileY
)
{
return
m_tiles
[
tileY
*
TILES_X
+
tileX
];
}
TileVector
&
getTileVectorForPosition
(
const
Vector2D
&
pos
)
{
size_t
tileX
=
wrap
<
TILES_X
>
(
pos
.
x
()
/
m_tileSizeX
);
size_t
tileY
=
wrap
<
TILES_Y
>
(
pos
.
y
()
/
m_tileSizeY
);
return
m_tiles
[
tileY
*
TILES_X
+
tileX
];
}
template
<
size_t
SIZE
>
static
size_t
wrap
(
int
unwrapped
)
{
int
result
=
(
unwrapped
%
SIZE
);
if
(
result
<
0
)
{
result
+=
SIZE
;
}
return
static_cast
<
size_t
>
(
result
);
}
static
bool
needsWrapX
(
int
unwrapped
)
{
return
(
unwrapped
<
0
)
||
(
unwrapped
>=
TILES_X
);
}
static
bool
needsWrapY
(
int
unwrapped
)
{
return
(
unwrapped
<
0
)
||
(
unwrapped
>=
TILES_Y
);
}
};
template
<
class
T
>
class
SpatialMapRegion
{
public:
class
Iterator
{
public:
Iterator
(
SpatialMapRegion
*
region
,
bool
atEnd
)
:
m_region
(
region
)
,
m_needsWrap
(
region
->
m_needsWrap
)
,
m_atEnd
(
atEnd
)
{
if
(
m_atEnd
)
{
moveToEnd
();
}
else
{
m_tileX
=
m_region
->
m_x1
;
m_tileY
=
m_region
->
m_y1
;
skipEmptyTiles
();
}
}
Iterator
&
operator
++
()
{
if
(
m_atEnd
)
{
return
*
this
;
}
if
(
++
m_positionInTile
>=
getCurrentTile
().
size
())
{
m_positionInTile
=
0
;
m_tileX
++
;
skipEmptyTiles
();
}
return
*
this
;
}
bool
operator
!=
(
const
Iterator
&
other
)
{
if
(
m_atEnd
)
{
return
(
other
.
m_region
!=
m_region
)
||
(
!
other
.
m_atEnd
);
}
return
(
other
.
m_region
!=
m_region
)
||
(
other
.
m_atEnd
!=
m_atEnd
)
||
(
other
.
m_tileX
!=
m_tileX
)
||
(
other
.
m_tileY
!=
m_tileY
)
||
(
other
.
m_positionInTile
!=
m_positionInTile
);
}
auto
&
operator
*
()
{
return
getCurrentTile
()[
m_positionInTile
];
}
private:
SpatialMapRegion
*
m_region
;
const
bool
m_needsWrap
=
true
;
bool
m_atEnd
=
false
;
int
m_tileX
=
0
;
int
m_tileY
=
0
;
size_t
m_positionInTile
=
0
;
void
skipEmptyTiles
()
{
while
(
m_tileY
<=
m_region
->
m_y2
)
{
while
(
m_tileX
<=
m_region
->
m_x2
)
{
if
(
getCurrentTile
().
size
()
>
0
)
{
return
;
}
m_tileX
++
;
}
m_tileX
=
m_region
->
m_x1
;
m_tileY
++
;
}
moveToEnd
();
}
void
moveToEnd
()
{
m_atEnd
=
true
;
m_tileX
=
0
;
m_tileY
=
0
;
m_positionInTile
=
0
;
}
typename
T
::
TileVector
&
getCurrentTile
()
{
return
m_needsWrap
?
m_region
->
m_map
.
getTileVector
(
m_tileX
,
m_tileY
)
:
m_region
->
m_map
.
getTileVectorNoWrap
(
m_tileX
,
m_tileY
);
}
};
SpatialMapRegion
(
T
&
map
,
int
x1
,
int
y1
,
int
x2
,
int
y2
)
:
m_map
(
map
),
m_x1
(
x1
),
m_y1
(
y1
),
m_x2
(
x2
),
m_y2
(
y2
)
,
m_needsWrap
(
map
.
needsWrapX
(
x1
)
||
map
.
needsWrapX
(
x2
)
||
map
.
needsWrapY
(
y1
)
||
map
.
needsWrapY
(
y2
))
{
}
Iterator
begin
()
{
return
Iterator
(
this
,
false
);
}
Iterator
end
()
{
return
Iterator
(
this
,
true
);
}
private:
T
&
m_map
;
const
int
m_x1
,
m_y1
,
m_x2
,
m_y2
;
const
bool
m_needsWrap
;
};
relayserver/TcpProtocol.cpp
View file @
9569a7ed
...
...
@@ -65,32 +65,84 @@ void TcpProtocol::OnMessageReceived(std::vector<char> &data)
{
case
0x00
:
if
(
arr
.
size
<
5
)
{
return
;
}
std
::
cerr
<<
"size_x "
<<
arr
.
ptr
[
2
].
via
.
f64
<<
" size_y "
<<
arr
.
ptr
[
3
].
via
.
f64
<<
" decrate "
<<
arr
.
ptr
[
4
].
via
.
f64
<<
std
::
endl
;
OnWorldInfoReceived
(
arr
.
ptr
[
2
].
via
.
f64
,
arr
.
ptr
[
3
].
via
.
f64
,
arr
.
ptr
[
4
].
via
.
f64
)
;
break
;
case
0x01
:
std
::
cerr
<<
"world update"
<<
std
::
endl
;
break
;
case
0x10
:
std
::
cerr
<<
"tick"
<<
std
::
endl
;
break
;
case
0x20
:
std
::
cerr
<<
"bot spawn"
<<
std
::
endl
;
break
;
case
0x21
:
std
::
cerr
<<
"bot kill"
<<
std
::
endl
;
break
;
case
0x22
:
std
::
cerr
<<
"bot move"
<<
std
::
endl
;
break
;
case
0x30
:
std
::
cerr
<<
"food spawn"
<<
std
::
endl
;
if
(
arr
.
size
<
3
)
{
return
;
}
for
(
auto
&
item
:
arr
.
ptr
[
2
].
via
.
array
)
{
auto
&
fi
=
item
.
via
.
array
;
if
(
fi
.
size
<
3
)
{
continue
;
}
OnFoodSpawnReceived
({
static_cast
<
guid_t
>
(
fi
.
ptr
[
0
].
via
.
i64
),
// guid
{
fi
.
ptr
[
1
].
via
.
f64
,
fi
.
ptr
[
2
].
via
.
f64
},
// position
fi
.
ptr
[
3
].
via
.
f64
// value
});
}
break
;
case
0x31
:
std
::
cerr
<<
"food consume"
<<
std
::
endl
;
if
(
arr
.
size
<
3
)
{
return
;
}
for
(
auto
&
item
:
arr
.
ptr
[
2
].
via
.
array
)
{
auto
&
fi
=
item
.
via
.
array
;
if
(
fi
.
size
<
2
)
{
continue
;
}
OnFoodConsumedReceived
(
static_cast
<
guid_t
>
(
fi
.
ptr
[
0
].
via
.
i64
),
// food guid
static_cast
<
guid_t
>
(
fi
.
ptr
[
1
].
via
.
i64
)
// bot guid
);
}
break
;
case
0x32
:
std
::
cerr
<<
"food decay"
<<
std
::
endl
;
if
(
arr
.
size
<
3
)
{
return
;
}
for
(
auto
&
item
:
arr
.
ptr
[
2
].
via
.
array
)
{
OnFoodDecayedReceived
(
static_cast
<
guid_t
>
(
item
.
via
.
u64
));
}
break
;
}
}
void
TcpProtocol
::
OnWorldInfoReceived
(
real_t
size_x
,
real_t
size_y
,
real_t
decay_rate
)
{
_food
=
std
::
make_unique
<
FoodMap
>
(
size_x
,
size_y
,
1000
);
_foodDecayRate
=
decay_rate
;
}
void
TcpProtocol
::
OnFoodSpawnReceived
(
const
TcpProtocol
::
Food
&
food
)
{
if
(
_food
==
nullptr
)
{
return
;
}
_food
->
addElement
(
food
);
}
void
TcpProtocol
::
OnFoodConsumedReceived
(
guid_t
food_id
,
guid_t
bot_id
)
{
_food
->
erase_if
([
food_id
](
const
Food
&
food
)
{
return
food
.
guid
==
food_id
;
});
}
void
TcpProtocol
::
OnFoodDecayedReceived
(
guid_t
food_id
)
{
_food
->
erase_if
([
food_id
](
const
Food
&
food
)
{
return
food
.
guid
==
food_id
;
});
}
relayserver/TcpProtocol.h
View file @
9569a7ed
...
...
@@ -4,7 +4,10 @@
#include <functional>
#include <deque>
#include <vector>
#include <memory>
#include "SpatialMap.h"
typedef
std
::
uint64_t
guid_t
;
class
TcpProtocol
{
public:
...
...
@@ -13,9 +16,31 @@ class TcpProtocol
bool
Read
(
int
socket
);
private:
static
constexpr
const
size_t
SPATIAL_MAP_TILES_X
=
128
;
static
constexpr
const
size_t
SPATIAL_MAP_TILES_Y
=
128
;
static
constexpr
const
size_t
SPATIAL_MAP_RESERVE_COUNT
=
10
;
struct
Food
{
guid_t
guid
;
Vector2D
position
;
real_t
value
;
const
Vector2D
&
pos
()
const
{
return
position
;
}
};
typedef
SpatialMap
<
Food
,
SPATIAL_MAP_TILES_X
,
SPATIAL_MAP_TILES_Y
>
FoodMap
;
size_t
_awaitedSize
=
0
;
std
::
deque
<
char
>
_buf
;
MessageReceivedCallback
_messageReceivedCallback
;
std
::
unique_ptr
<
FoodMap
>
_food
;
real_t
_foodDecayRate
=
0
;
void
OnMessageReceived
(
std
::
vector
<
char
>&
data
);
void
OnWorldInfoReceived
(
real_t
size_x
,
real_t
size_y
,
real_t
decay_rate
);
void
OnFoodSpawnReceived
(
const
Food
&
food
);
void
OnFoodConsumedReceived
(
guid_t
food_id
,
guid_t
bot_id
);
void
OnFoodDecayedReceived
(
guid_t
food_id
);
};
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment