diff --git a/utils.c b/utils.c index efc4e66..017de19 100644 --- a/utils.c +++ b/utils.c @@ -44,25 +44,24 @@ short get_first_night_zone() { } -// TODO обновить метод для работы с двумя роботами // вернет можно ли ехать и главное куда ехать, если можно (нельзя если вернулось значение < 0) // -1 вернет что перемещать нельзя short can_move(struct barrel *bar, char robot_id) { if (robot_id != 1 && robot_id != 2) { - return -1; + return -3; } // сразу отсекаем варианты, при которых невозможно переместить барабан if (!bar->flags.is_exist) { - return -1; + return -3; } if (bar->software_timer > 0) { - return -1; + return -2; } if (bar->flags.robot != 0) { - return -2; + return -3; } // проверка ночного режима @@ -70,8 +69,6 @@ short can_move(struct barrel *bar, char robot_id) { if (bar->flags.is_night && !bar->flags.is_empty) { return -1; } - } else { - } // дальше нужно проверить, что можно передвигать бочку @@ -705,3 +702,81 @@ void create_operation(struct robot_code *code, short barrel_id, const short star #endif code->PC = 0; } + +char increment_zone(short zone) { + if (zone == ROBOT_ZONE_ETCH) { + if ((hla_disabled_zones & DISABLED_ETCH) == DISABLED_ETCH) { + etching_zone = -1; + return 0; + } else { + if ((hla_disabled_zones & DISABLED_ETCH) == 0) { + // если обе зоны активны + if (etching_zone < 0) { + etching_zone = 0; + } else { + if (etching_zone == 0) { + etching_zone = 1; + } else { + etching_zone = 0; + } + } + } else { + // если только одна зона + if (hla_disabled_zones & DISABLED_ETCH_1) { + etching_zone = 1; + } else { + etching_zone = 0; + } + } + + return 1; + } + } else if (zone == ROBOT_ZONE_GAL) { + // с зонами цинкования все несколько сложнее... + // сначала надо посчитать кол-во включенных зон + short enabled_zones = 0; + for (short z = DISABLED_GAL_1; z & DISABLED_GAL; z <<= 1) { + if ((hla_disabled_zones & z) == 0) { + enabled_zones++; + } + } + + if (enabled_zones == 0) { + // таких зон нет... + galvanizing_zone = -1; + return 0; + } else if (enabled_zones == 1) { + // зона одна, ее только найти надо и установить + for (short z = 0; z < 8; z++) { + if ((hla_disabled_zones & (DISABLED_GAL_1 << z)) == 0) { + galvanizing_zone = z; + break; + } + } + } else { + // зон несколько, поэтому берем текущую, пробегаемся по битам и ищем другую + // всего может быть 7 зон, куда мы еще посмотрим + short bit_id = galvanizing_zone + 1; + if (galvanizing_zone < 0) { + bit_id = 0; + } + for (short i = 0; i < 7 + (galvanizing_zone < 0 ? 1 : 0); i++) { + if (bit_id >= 8) { + bit_id = 0; + } + if ((hla_disabled_zones & (DISABLED_GAL_1 << bit_id)) == 0) { + // свободная зона + galvanizing_zone = bit_id; + break; + } + + bit_id++; + } + } + + return 1; + } else { + // неверный аргумент + return 0; + } +} diff --git a/utils.h b/utils.h index 7e86c36..c9a374e 100644 --- a/utils.h +++ b/utils.h @@ -182,6 +182,12 @@ extern short hla_time_reagent; extern short hla_time_washing_1; extern short hla_time_washing_2; +// выбор зоны промежуточной с панели +extern short hla_exchange_zone; + +// выбор отключенных зон +extern short hla_disabled_zones; + extern char hla_robot1_en; extern char hla_robot2_en; @@ -220,6 +226,9 @@ extern char scheduler_start_signal; #define hla_time_washing_1 _c_hla_time_washing_1 #define hla_time_washing_2 _c_hla_time_washing_2 +#define hla_exchange_zone _c_hla_exchange_zone +#define hla_disabled_zones _c_hla_disabled_zones + #define hla_robot1_en _c_hla_robot1_en #define hla_robot2_en _c_hla_robot2_en @@ -281,6 +290,22 @@ extern const short NIGHT_ZONES[9]; #define ROBOT_CMD_INC_ZONE(arg) ((ROBOT_CMD_INC_ZONE_code) | (short)(arg)) +/* ======================== DISABLED ZONES DEFS ======================== */ + +#define DISABLED_ETCH_1 0x0001 +#define DISABLED_ETCH_2 0x0002 +#define DISABLED_ETCH 0x0003 + +#define DISABLED_GAL_1 0x0004 +#define DISABLED_GAL_2 0x0008 +#define DISABLED_GAL_3 0x0010 +#define DISABLED_GAL_4 0x0020 +#define DISABLED_GAL_5 0x0040 +#define DISABLED_GAL_6 0x0080 +#define DISABLED_GAL_7 0x0100 +#define DISABLED_GAL_8 0x0200 +#define DISABLED_GAL 0x03FC + /* ======================== IO DEFS ======================== */ #define ROBOT1_X 1 @@ -294,9 +319,6 @@ extern const short NIGHT_ZONES[9]; /* ======================== ROBOT DEFS ======================== */ - - - #define MB_CMD_WRITE_FLAG 5 #define MB_CMD_WRITE_REG 6 @@ -350,6 +372,13 @@ char remove_barrel_from_zone(short zone); void create_operation(struct robot_code *code, const short barrel_id, const short start_zone, const short dest_zone, const short current_zone, const short robot_id); +/** + * Инкрементировать зону цинкования или зону травления. + * @param zone ROBOT_ZONE_ETCH или ROBOT_ZONE_GAL. Для других значений функция вернет false. + * @return true, если существует хотя бы одна зона, куда можно положить баран. При любых ошибках вернет false. + */ +char increment_zone(short zone); + #ifdef EMULATOR void debug_print_robot_code(const struct robot_code *code, const short robot_id, int fd); #endif