-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
move code from the original repository and add a README file
- Loading branch information
0 parents
commit 2d6bb17
Showing
11 changed files
with
1,736 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
cmake_minimum_required(VERSION 3.1) | ||
|
||
project(MIMUW_SIK_BOMBERMAN) | ||
|
||
set(CMAKE_CXX_STANDARD 20) | ||
set(CMAKE_CXX_FLAGS "-Wall -Wextra -Wconversion -O2 -Werror") | ||
|
||
find_package(Boost 1.74.0 COMPONENTS program_options system) | ||
find_package(Threads) | ||
|
||
include_directories(include) | ||
|
||
add_executable(robots-client robots-client.cpp) | ||
target_link_libraries(robots-client Boost::program_options Boost::system Threads::Threads) | ||
|
||
add_executable(robots-server robots-server.cpp) | ||
target_link_libraries(robots-server Boost::program_options Boost::system Threads::Threads) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
# A bomberman implementation |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
#ifndef BOMBERMAN_COMMON_HPP | ||
#define BOMBERMAN_COMMON_HPP | ||
|
||
#include <charconv> // std::from_chars | ||
#include <concepts> // std::unsigned_integral | ||
#include <stdexcept> // std::runtime_error | ||
#include <system_error> // std::errc | ||
|
||
#include <boost/asio.hpp> | ||
|
||
#include "streamable-buffer.hpp" | ||
|
||
// The maximal size of data in a UDP packet is the maximal size of an UDP | ||
// packet (1 << 16 bytes) decreased by the size of an IP header (20 bytes) | ||
// and an UDP header (8 bytes). | ||
constexpr size_t MAX_UDP_MESSAGE_SIZE = (1 << 16) - 20 - 8; | ||
|
||
using port_t = uint16_t; | ||
|
||
class invalid_number : public std::runtime_error { | ||
using std::runtime_error::runtime_error; | ||
}; | ||
|
||
// Parse unsigned, base-10 integral from the given C string. | ||
// Throw invalid_number on any non-standardiness such as a leading sign. | ||
template <std::unsigned_integral T> | ||
T parse_uint(const char* first, const char* last) { | ||
T result; | ||
std::from_chars_result conv = std::from_chars( | ||
first, | ||
last, | ||
result | ||
); | ||
|
||
if (conv.ec != std::errc {}) { | ||
throw invalid_number("Invalid format for an unsigned integer"); | ||
} | ||
|
||
return result; | ||
} | ||
|
||
// to nie powinno byc w cpp - to powinno byc jako template z tcp/udp | ||
|
||
void send(streamable_buffer& stream, boost::asio::ip::tcp::socket& sock) { | ||
auto buffer = stream.get_buffer(); | ||
const std::vector<unsigned char>& data { buffer.begin(), buffer.end() }; | ||
sock.send(boost::asio::buffer(data)); | ||
stream.clear(); | ||
} | ||
|
||
std::vector<uint8_t> read(boost::asio::ip::tcp::socket& sock, size_t n) { | ||
std::vector<uint8_t> buffer (n); | ||
size_t rec = boost::asio::read(sock, boost::asio::buffer(buffer)); | ||
assert(rec == n); | ||
return buffer; | ||
} | ||
|
||
#endif // BOMBERMAN_COMMON_HPP | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
/** This file contains debugging helpers for the project. | ||
* Most notably, it contains std::ostream operator<< overloads for most | ||
* common types such as selected STL containers and this projects' | ||
* message formats for the client-server-gui communication. | ||
*/ | ||
|
||
#ifndef BOMBERMAN_DEBUG_HPP | ||
#define BOMBERMAN_DEBUG_HPP | ||
|
||
#include <deque> | ||
#include <iostream> | ||
#include <map> | ||
#include <utility> | ||
#include <vector> | ||
|
||
#include "streamable-buffer.hpp" | ||
#include "messages.hpp" | ||
|
||
template<typename u, typename v> | ||
std::ostream& operator<< (std::ostream& out, const std::pair<u, v>& x) { | ||
out << '<' << x.first << ", " << x.second << '>'; | ||
return out; | ||
} | ||
|
||
template<typename u> | ||
std::ostream& operator<< (std::ostream& out, const std::vector<u>& x) { | ||
out << '['; | ||
if (x.size() > 0) { | ||
for (size_t i=0; i < x.size() - 1; ++i) { out << x[i] << ", "; } | ||
out << x[x.size() - 1]; | ||
} | ||
out << ']'; | ||
return out; | ||
} | ||
|
||
template<typename u> | ||
std::ostream& operator<< (std::ostream& out, const std::deque<u>& x) { | ||
out << '['; | ||
if (x.size() > 0) { | ||
for (size_t i=0; i < x.size() - 1; ++i) { out << x[i] << ", "; } | ||
out << x[x.size() - 1]; | ||
} | ||
out << ']'; | ||
return out; | ||
} | ||
|
||
template<typename u, typename v> | ||
std::ostream& operator<< (std::ostream& out, const std::map<u, v>& x) { | ||
out << '['; | ||
if (x.size() > 0) { | ||
for (auto it=x.begin(); it != prev(x.end()); ++it) { | ||
out << *it << ", "; | ||
} | ||
out << *std::prev(x.end()); | ||
} | ||
out << ']'; | ||
return out; | ||
} | ||
|
||
std::ostream& operator<<(std::ostream& os, const streamable_buffer& s) { | ||
os << s.buffer; | ||
return os; | ||
} | ||
|
||
std::ostream& operator<<(std::ostream& os, const Position& pos) { | ||
return os << std::make_pair(pos.x, pos.y); | ||
} | ||
|
||
std::ostream& operator<<(std::ostream& os, const Bomb& bomb) { | ||
return os << std::make_pair(bomb.position, bomb.timer); | ||
} | ||
|
||
std::ostream& operator<< (std::ostream& os, const Player& player) { | ||
return os << std::make_pair(player.name, player.address); | ||
} | ||
|
||
template<typename T, typename ... Args> | ||
void print(T t, Args ... args) { | ||
std::cout << t; | ||
((std::cout << ' ' << args), ...); | ||
} | ||
|
||
template<typename ... Args> | ||
void println([[maybe_unused]]Args ... args) { | ||
print(args...); | ||
print('\n'); | ||
} | ||
|
||
template<typename ... Args> | ||
void debug([[maybe_unused]]Args ... args) { | ||
#ifndef NDEBUG | ||
println(args...); | ||
#endif | ||
} | ||
|
||
#endif // BOMBERMAN_DEBUG_HPP |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,206 @@ | ||
/* This file contains definitions of types and message formats used through- | ||
* out the project in communication between client, server and GUI server. | ||
* The order of members of the structs below and the order of these types | ||
* in related std::variants is important: | ||
* -the order of members determines the order in which they will be | ||
* serialized. | ||
* -the order of types corresponds directly to the message ids which they | ||
* will be assigned | ||
* Name of the 'msg_id' member is not to be changed - objects are tested | ||
* for presence of such a member in the serialization code | ||
*/ | ||
|
||
#ifndef BOMBERMAN_MESSAGES_HPP | ||
#define BOMBERMAN_MESSAGES_HPP | ||
|
||
#include <cstdint> // uint8_t, ... | ||
#include <string> | ||
#include <vector> | ||
#include <map> | ||
#include <variant> | ||
|
||
// Definitions of the most primitive types --------------------------------- | ||
using bomb_id_t = uint32_t; | ||
using bomb_timer_t = uint16_t; | ||
// we could use an enum, but this is just more convenient for serialization | ||
using direction_t = uint8_t; | ||
using explosion_radius_t = uint16_t; | ||
using game_length_t = uint16_t; | ||
using initial_blocks_t = uint16_t; | ||
using msg_id_t = uint8_t; | ||
using player_id_t = uint8_t; | ||
using players_count_t = uint8_t; | ||
using pos_t = uint16_t; | ||
using score_t = uint32_t; | ||
using server_name_t = std::string; | ||
using strlen_t = uint8_t; | ||
using turn_duration_t = uint64_t; | ||
using turn_t = uint16_t; | ||
|
||
struct Position { | ||
pos_t x; | ||
pos_t y; | ||
auto operator<=>(const Position&) const = default; | ||
}; | ||
|
||
struct Bomb { | ||
Position position; | ||
bomb_timer_t timer; | ||
}; | ||
|
||
struct Player { | ||
std::string name; | ||
std::string address; | ||
}; | ||
|
||
// Definitions of events --------------------------------------------------- | ||
struct EventBombPlaced { | ||
static constexpr uint8_t msg_id = 0; | ||
bomb_id_t bomb_id; | ||
Position position; | ||
}; | ||
|
||
struct EventBombExploded { | ||
static constexpr uint8_t msg_id = 1; | ||
bomb_id_t bomb_id; | ||
std::vector<player_id_t> robots_destroyed; | ||
std::vector<Position> blocks_destroyed; | ||
}; | ||
|
||
struct EventPlayerMoved { | ||
static constexpr uint8_t msg_id = 2; | ||
player_id_t player_id; | ||
Position position; | ||
}; | ||
|
||
struct EventBlockPlaced { | ||
static constexpr uint8_t msg_id = 3; | ||
Position position; | ||
}; | ||
|
||
using Event = std::variant< | ||
EventBombPlaced, | ||
EventBombExploded, | ||
EventPlayerMoved, | ||
EventBlockPlaced | ||
>; | ||
|
||
// Definitions of messages from client to server --------------------------- | ||
struct ClientMessageJoin { | ||
static constexpr uint8_t msg_id = 0; | ||
std::string name; | ||
}; | ||
|
||
struct ClientMessagePlaceBomb { | ||
static constexpr uint8_t msg_id = 1; | ||
}; | ||
|
||
struct ClientMessagePlaceBlock { | ||
static constexpr uint8_t msg_id = 2; | ||
}; | ||
|
||
struct ClientMessageMove { | ||
static constexpr uint8_t msg_id = 3; | ||
direction_t direction; | ||
}; | ||
|
||
using ClientMessage = std::variant< | ||
ClientMessageJoin, | ||
ClientMessagePlaceBomb, | ||
ClientMessagePlaceBlock, | ||
ClientMessageMove | ||
>; | ||
|
||
// Definitions of messages from server to client --------------------------- | ||
struct ServerMessageHello { | ||
static constexpr uint8_t msg_id = 0; | ||
std::string server_name; | ||
players_count_t players_count; | ||
pos_t size_x; | ||
pos_t size_y; | ||
game_length_t game_length; | ||
explosion_radius_t explosion_radius; | ||
bomb_timer_t bomb_timer; | ||
}; | ||
|
||
struct ServerMessageAcceptedPlayer { | ||
static constexpr uint8_t msg_id = 1; | ||
player_id_t player_id; | ||
Player player; | ||
}; | ||
|
||
struct ServerMessageGameStarted { | ||
static constexpr uint8_t msg_id = 2; | ||
std::map<player_id_t, Player> players; | ||
}; | ||
|
||
struct ServerMessageTurn { | ||
static constexpr uint8_t msg_id = 3; | ||
game_length_t turn; | ||
std::vector<Event> events; | ||
}; | ||
|
||
struct ServerMessageGameEnded { | ||
static constexpr uint8_t msg_id = 4; | ||
std::map<player_id_t, score_t> scores; | ||
}; | ||
|
||
using ServerMessage = std::variant< | ||
ServerMessageHello, | ||
ServerMessageAcceptedPlayer, | ||
ServerMessageGameStarted, | ||
ServerMessageTurn, | ||
ServerMessageGameEnded | ||
>; | ||
|
||
// Definitions of messages from client to GUI server ----------------------- | ||
struct DrawMessageLobby { | ||
static constexpr uint8_t msg_id = 0; | ||
std::string server_name; | ||
players_count_t players_count; | ||
pos_t size_x; | ||
pos_t size_y; | ||
game_length_t game_length; | ||
explosion_radius_t explosion_radius; | ||
bomb_timer_t bomb_timer; | ||
std::map<player_id_t, Player> players; | ||
}; | ||
|
||
struct DrawMessageGame { | ||
static constexpr uint8_t msg_id = 1; | ||
std::string server_name; | ||
pos_t size_x; | ||
pos_t size_y; | ||
game_length_t game_length; | ||
turn_t turn; | ||
std::map<player_id_t, Player> players; | ||
std::map<player_id_t, Position> player_positions; | ||
std::vector<Position> blocks; | ||
std::vector<Bomb> bombs; | ||
std::vector<Position> explosions; | ||
std::map<player_id_t, score_t> scores; | ||
}; | ||
|
||
using DrawMessage = std::variant<DrawMessageLobby, DrawMessageGame>; | ||
|
||
// Definitions of messages from GUI server to client ----------------------- | ||
struct InputMessagePlaceBomb { | ||
static constexpr uint8_t msg_id = 0; | ||
}; | ||
|
||
struct InputMessagePlaceBlock { | ||
static constexpr uint8_t msg_id = 1; | ||
}; | ||
|
||
struct InputMessageMove { | ||
static constexpr uint8_t msg_id = 2; | ||
direction_t direction; | ||
}; | ||
|
||
using InputMessage = std::variant< | ||
InputMessagePlaceBomb, | ||
InputMessagePlaceBlock, | ||
InputMessageMove | ||
>; | ||
|
||
#endif // BOMBERMAN_MESSAGES_HPP |
Oops, something went wrong.