Add puzzle_modules_solved to gamestate updates

This commit is contained in:
redfast00 2021-02-01 15:59:46 +01:00
parent 57a2712587
commit 393b1c94ce
No known key found for this signature in database
GPG key ID: 5946E0E34FD0553C
7 changed files with 43 additions and 32 deletions

View file

@ -50,8 +50,9 @@ class Message:
timeleft = self.payload[1] << 0x18 | self.payload[2] << 0x10 | self.payload[3] << 0x08 | self.payload[4]
strikes = self.payload[5]
max_strikes = self.payload[6]
solved_puzzle_modules = self.payload[7]
return f'{timeleft/1000:3.2f} {strikes:02}/{max_strikes:02}'
return f'{timeleft/1000:3.2f} {strikes:02}/{max_strikes:02} [{solved_puzzle_modules:02}]'
def parse_message(self):
sender_type = self.sender_type()

View file

@ -57,13 +57,13 @@ Types for controller:
- 3 state (every x ms e.g. in the middle of each second)
[ X B B B B B B B ]
-------- - - -
time left ↓ ↓ reserved
time left ↓ ↓ #solved puzzle modules
#strikes #max strikes
- 4-6 solved, timeout, strikeout
[ X B B B B B B B ]
-------- - - -
end time ↓ ↓ reserved
end time ↓ ↓ #solved puzzle modules
#strikes #max strikes
- 7 info start

View file

@ -114,13 +114,14 @@ bool receive(struct message *msg) {
break;
case OBUS_PAYLDTYPE_GAMESTATUS:
if (receive_frame.can_dlc < 7) {
Serial.println(F("W Received illegal gamestatus msg: payload <7"));
if (receive_frame.can_dlc < 8) {
Serial.println(F("W Received illegal gamestatus msg: payload <8"));
return false;
}
msg->gamestatus.time_left = unpack_4b_into_u32(&(receive_frame.data[1]));
msg->gamestatus.strikes = receive_frame.data[5];
msg->gamestatus.max_strikes = receive_frame.data[6];
msg->gamestatus.time_left = unpack_4b_into_u32(&(receive_frame.data[1]));
msg->gamestatus.strikes = receive_frame.data[5];
msg->gamestatus.max_strikes = receive_frame.data[6];
msg->gamestatus.puzzle_modules_solved = receive_frame.data[7];
break;
case OBUS_PAYLDTYPE_COUNT:
@ -186,7 +187,8 @@ void send(struct message *msg) {
pack_u32_into_4b(&(send_frame.data[1]), msg->gamestatus.time_left);
send_frame.data[5] = msg->gamestatus.strikes;
send_frame.data[6] = msg->gamestatus.max_strikes;
length = 7;
send_frame.data[7] = msg->gamestatus.puzzle_modules_solved;
length = 8;
break;
case OBUS_PAYLDTYPE_COUNT:

View file

@ -51,6 +51,7 @@ struct payld_gamestatus {
uint32_t time_left;
uint8_t strikes;
uint8_t max_strikes;
uint8_t puzzle_modules_solved;
};
struct payld_infomessage {
uint8_t len;
@ -128,12 +129,13 @@ inline struct message _msg(struct module from, bool priority, uint8_t msg_type)
*/
inline void _send_payld_gamestatus(
struct module from, bool priority, uint8_t msg_type,
uint32_t time_left, uint8_t strikes, uint8_t max_strikes) {
uint32_t time_left, uint8_t strikes, uint8_t max_strikes, uint8_t puzzle_modules_solved) {
struct message msg = _msg(from, priority, msg_type);
msg.gamestatus.time_left = time_left;
msg.gamestatus.strikes = strikes;
msg.gamestatus.max_strikes = max_strikes;
msg.gamestatus.puzzle_modules_solved = puzzle_modules_solved;
send(&msg);
}
@ -163,44 +165,44 @@ inline void send_c_hello(struct module from) {
* Send a controller "game start" OBUS message
*/
inline void send_c_gamestart(
struct module from, uint32_t time_left, uint8_t strikes, uint8_t max_strikes) {
struct module from, uint32_t time_left, uint8_t strikes, uint8_t max_strikes, uint8_t puzzle_modules_solved) {
assert(from.type == OBUS_TYPE_CONTROLLER);
_send_payld_gamestatus(
from, false, OBUS_MSGTYPE_C_GAMESTART, time_left, strikes, max_strikes);
from, false, OBUS_MSGTYPE_C_GAMESTART, time_left, strikes, max_strikes, puzzle_modules_solved);
}
/**
* Send a controller "state" OBUS message
*/
inline void send_c_state(
struct module from, uint32_t time_left, uint8_t strikes, uint8_t max_strikes) {
struct module from, uint32_t time_left, uint8_t strikes, uint8_t max_strikes, uint8_t puzzle_modules_solved) {
assert(from.type == OBUS_TYPE_CONTROLLER);
_send_payld_gamestatus(
from, false, OBUS_MSGTYPE_C_STATE, time_left, strikes, max_strikes);
from, false, OBUS_MSGTYPE_C_STATE, time_left, strikes, max_strikes, puzzle_modules_solved);
}
/**
* Send a controller "solved" OBUS message
*/
inline void send_c_solved(
struct module from, uint32_t time_left, uint8_t strikes, uint8_t max_strikes) {
struct module from, uint32_t time_left, uint8_t strikes, uint8_t max_strikes, uint8_t puzzle_modules_solved) {
assert(from.type == OBUS_TYPE_CONTROLLER);
_send_payld_gamestatus(
from, false, OBUS_MSGTYPE_C_SOLVED, time_left, strikes, max_strikes);
from, false, OBUS_MSGTYPE_C_SOLVED, time_left, strikes, max_strikes, puzzle_modules_solved);
}
/**
* Send a controller "timeout" OBUS message
*/
inline void send_c_timeout(
struct module from, uint32_t time_left, uint8_t strikes, uint8_t max_strikes) {
struct module from, uint32_t time_left, uint8_t strikes, uint8_t max_strikes, uint8_t puzzle_modules_solved) {
assert(from.type == OBUS_TYPE_CONTROLLER);
_send_payld_gamestatus(
from, false, OBUS_MSGTYPE_C_TIMEOUT, time_left, strikes, max_strikes);
from, false, OBUS_MSGTYPE_C_TIMEOUT, time_left, strikes, max_strikes, puzzle_modules_solved);
}
/**
@ -216,11 +218,11 @@ inline void send_c_infostart(struct module from) {
* Send a controller "strikeout" OBUS message
*/
inline void send_c_strikeout(
struct module from, uint32_t time_left, uint8_t strikes, uint8_t max_strikes) {
struct module from, uint32_t time_left, uint8_t strikes, uint8_t max_strikes, uint8_t puzzle_modules_solved) {
assert(from.type == OBUS_TYPE_CONTROLLER);
_send_payld_gamestatus(
from, false, OBUS_MSGTYPE_C_STRIKEOUT, time_left, strikes, max_strikes);
from, false, OBUS_MSGTYPE_C_STRIKEOUT, time_left, strikes, max_strikes, puzzle_modules_solved);
}

View file

@ -105,14 +105,15 @@ void empty_callback_info(uint8_t info_id, uint8_t infomessage[7]) {
(void)infomessage;
}
void empty_callback_state(uint32_t time_left, uint8_t strikes, uint8_t max_strikes) {
void empty_callback_state(uint32_t time_left, uint8_t strikes, uint8_t max_strikes, uint8_t puzzle_modules_solved) {
// Mark arguments as not used
(void)time_left;
(void)strikes;
(void)max_strikes;
(void)puzzle_modules_solved;
}
bool loopPuzzle(obus_can::message* message, void (*callback_game_start)(), void (*callback_game_stop)(), void (*callback_info)(uint8_t info_id, uint8_t infomessage[7]), void (*callback_state)(uint32_t time_left, uint8_t strikes, uint8_t max_strikes)) {
bool loopPuzzle(obus_can::message* message, void (*callback_game_start)(), void (*callback_game_stop)(), void (*callback_info)(uint8_t info_id, uint8_t infomessage[7]), void (*callback_state)(uint32_t time_left, uint8_t strikes, uint8_t max_strikes, uint8_t puzzle_modules_solved)) {
// TODO this can be more efficient by only enabling error interrupts and
// reacting to the interrupt instead of checking if the flag is set in a loop
// We will need to fork our CAN library for this, because the needed functions are private.
@ -151,7 +152,7 @@ bool loopPuzzle(obus_can::message* message, void (*callback_game_start)(), void
case OBUS_MSGTYPE_C_ACK:
break;
case OBUS_MSGTYPE_C_STATE:
callback_state(message->gamestatus.time_left, message->gamestatus.strikes, message->gamestatus.max_strikes);
callback_state(message->gamestatus.time_left, message->gamestatus.strikes, message->gamestatus.max_strikes, message->gamestatus.puzzle_modules_solved);
break;
default:
break;
@ -168,7 +169,7 @@ bool loopPuzzle(obus_can::message* message, void (*callback_game_start)(), void
return received_message;
}
bool loopNeedy(obus_can::message* message, void (*callback_game_start)(), void (*callback_game_stop)(), void (*callback_info)(uint8_t info_id, uint8_t infomessage[7]), void (*callback_state)(uint32_t time_left, uint8_t strikes, uint8_t max_strikes)) {
bool loopNeedy(obus_can::message* message, void (*callback_game_start)(), void (*callback_game_stop)(), void (*callback_info)(uint8_t info_id, uint8_t infomessage[7]), void (*callback_state)(uint32_t time_left, uint8_t strikes, uint8_t max_strikes, uint8_t puzzle_modules_solved)) {
// For now this is the same function
return loopPuzzle(message, callback_game_start, callback_game_stop, callback_info, callback_state);
}

View file

@ -13,11 +13,11 @@ namespace obus_module {
void setup(uint8_t type, uint8_t id);
void empty_callback_info(uint8_t info_id, uint8_t infomessage[7]);
void empty_callback_state(uint32_t time_left, uint8_t strikes, uint8_t max_strikes);
void empty_callback_state(uint32_t time_left, uint8_t strikes, uint8_t max_strikes, uint8_t puzzle_modules_solved);
bool loopPuzzle(obus_can::message* message, void (*callback_game_start)(), void (*callback_game_stop)(), void (*callback_info)(uint8_t info_id, uint8_t infomessage[7]) = empty_callback_info, void (*callback_state)(uint32_t time_left, uint8_t strikes, uint8_t max_strikes) = empty_callback_state);
bool loopPuzzle(obus_can::message* message, void (*callback_game_start)(), void (*callback_game_stop)(), void (*callback_info)(uint8_t info_id, uint8_t infomessage[7]) = empty_callback_info, void (*callback_state)(uint32_t time_left, uint8_t strikes, uint8_t max_strikes, uint8_t puzzle_modules_solved) = empty_callback_state);
bool loopNeedy(obus_can::message* message, void (*callback_game_start)(), void (*callback_game_stop)(), void (*callback_info)(uint8_t info_id, uint8_t infomessage[7]) = empty_callback_info, void (*callback_state)(uint32_t time_left, uint8_t strikes, uint8_t max_strikes) = empty_callback_state);
bool loopNeedy(obus_can::message* message, void (*callback_game_start)(), void (*callback_game_stop)(), void (*callback_info)(uint8_t info_id, uint8_t infomessage[7]) = empty_callback_info, void (*callback_state)(uint32_t time_left, uint8_t strikes, uint8_t max_strikes, uint8_t puzzle_modules_solved) = empty_callback_state);
bool loopInfo(obus_can::message* message, int (*info_generator)(uint8_t*));

View file

@ -28,6 +28,7 @@ uint8_t state = STATE_INACTIVE;
struct obus_can::module connected_modules_ids[OBUS_MAX_MODULES];
uint8_t nr_connected_modules;
uint8_t nr_connected_puzzles;
uint8_t nr_solved_puzzles;
uint8_t strikes;
// Bitvector for checking if game is solved or not
@ -86,6 +87,9 @@ void add_puzzle_to_bit_vector(uint8_t module_id) {
void solve_puzzle_in_bit_vector(uint8_t module_id) {
uint8_t byte_index = module_id >> 3;
uint8_t bit_index = module_id & 0x07;
if (unsolved_puzzles[byte_index] & (0x1 << bit_index)) {
nr_solved_puzzles++;
}
unsolved_puzzles[byte_index] &= ~(0x1 << bit_index);
}
@ -176,6 +180,7 @@ void receive_hello() {
void initialize_game() {
strikes = 0;
nr_solved_puzzles = 0;
game_start = millis();
last_draw = 0;
@ -185,7 +190,7 @@ void initialize_game() {
Serial.println(" Game started");
draw_display(millis(), OBUS_GAME_DURATION_MS);
obus_can::send_c_gamestart(this_module, OBUS_GAME_DURATION_MS, strikes, OBUS_MAX_STRIKES);
obus_can::send_c_gamestart(this_module, OBUS_GAME_DURATION_MS, strikes, OBUS_MAX_STRIKES, nr_solved_puzzles);
}
@ -241,14 +246,14 @@ void game_loop() {
if (check_solved()) {
Serial.println(" Game solved");
obus_can::send_c_solved(this_module, time_left, strikes, OBUS_MAX_STRIKES);
obus_can::send_c_solved(this_module, time_left, strikes, OBUS_MAX_STRIKES, nr_solved_puzzles);
state = STATE_GAMEOVER;
tm.displayText("dISArmEd");
return;
}
if (time_left == 0) {
Serial.println(" Time's up");
obus_can::send_c_timeout(this_module, time_left, strikes, OBUS_MAX_STRIKES);
obus_can::send_c_timeout(this_module, time_left, strikes, OBUS_MAX_STRIKES, nr_solved_puzzles);
state = STATE_GAMEOVER;
tm.displayText(" boo t");
// m
@ -258,7 +263,7 @@ void game_loop() {
}
if (strikes >= OBUS_MAX_STRIKES) {
Serial.println(" Strikeout");
obus_can::send_c_strikeout(this_module, time_left, strikes, OBUS_MAX_STRIKES);
obus_can::send_c_strikeout(this_module, time_left, strikes, OBUS_MAX_STRIKES, nr_solved_puzzles);
state = STATE_GAMEOVER;
tm.displayText(" boo S");
// m
@ -270,7 +275,7 @@ void game_loop() {
draw_display(current_time, time_left);
if (last_update + OBUS_UPDATE_INTERVAL <= current_time) {
obus_can::send_c_state(this_module, time_left, strikes, OBUS_MAX_STRIKES);
obus_can::send_c_state(this_module, time_left, strikes, OBUS_MAX_STRIKES, nr_solved_puzzles);
last_update = current_time;
}
}