# FINAL 參考解答
## 1. Fraction Arithmetic
:::spoiler frac.h
```clike=
#ifndef FRAC_H
#define FRAC_H
#include <stdint.h>
int32_t frac_add(int32_t *x, int32_t *y, int32_t a, int32_t b, int32_t c, int32_t d);
int32_t frac_del(int32_t *x, int32_t *y, int32_t a, int32_t b, int32_t c, int32_t d);
int32_t frac_mul(int32_t *x, int32_t *y, int32_t a, int32_t b, int32_t c, int32_t d);
int32_t frac_div(int32_t *x, int32_t *y, int32_t a, int32_t b, int32_t c, int32_t d);
#endif
```
:::
:::spoiler frac.c
```clike=
#include "frac.h"
#include <stdlib.h>
#include <limits.h>
#include <stdio.h>
int64_t gcd64(int64_t a, int64_t b) {
while (b != 0) {
int64_t t = b;
b = a % b;
a = t;
}
return a;
}
static void reduce(int64_t *x, int64_t *y) {
int64_t g = gcd64(llabs(*x), llabs(*y));
*x /= g;
*y /= g;
if (*y < 0) {
*x = -*x;
*y = -*y;
}
}
int32_t frac_add(int32_t *x, int32_t *y, int32_t a, int32_t b, int32_t c, int32_t d) {
int64_t ad, bc, bd;
if (b == 0 || d == 0) return -1;
ad = (int64_t)a * d;
bc = (int64_t)b * c;
bd = (int64_t)b * d;
int64_t numerator = ad + bc;
reduce(&numerator, &bd);
if(numerator > INT32_MAX || numerator < INT32_MIN || bd > INT32_MAX || bd < INT32_MIN) return -1;
*x = (int32_t)numerator;
*y = bd;
return 0;
}
int32_t frac_del(int32_t *x, int32_t *y, int32_t a, int32_t b, int32_t c, int32_t d) {
if (b == 0 || d == 0) return -1;
// Perform the subtraction operation in a rearranged manner to avoid overflow
int64_t ad, bc, bd;
ad = (int64_t)a * d;
bc = (int64_t)b * c;
bd = (int64_t)b * d;
// Check for subtraction overflow
int64_t numerator = (int64_t)ad - bc;
reduce(&numerator, &bd);
if(numerator > INT32_MAX || numerator < INT32_MIN || bd > INT32_MAX || bd < INT32_MIN) return -1;
*x = (int32_t)numerator;
*y = bd;
return 0;
}
int32_t frac_mul(int32_t *x, int32_t *y, int32_t a, int32_t b, int32_t c, int32_t d) {
int64_t ac, bd;
if (b == 0 || d == 0) return -1;
ac = (int64_t)a * c;
bd = (int64_t)b * d;
reduce(&ac, &bd);
if(ac > INT32_MAX || ac < INT32_MIN || bd > INT32_MAX || bd < INT32_MIN) return -1;
*x = ac;
*y = bd;
return 0;
}
int32_t frac_div(int32_t *x, int32_t *y, int32_t a, int32_t b, int32_t c, int32_t d) {
int64_t ad, bc;
if (b == 0 || d == 0 || c == 0) return -1;
ad = (int64_t)a * d;
bc = (int64_t)b * c;
reduce(&ad, &bc);
if(ad > INT32_MAX || ad < INT32_MIN || bc > INT32_MAX || bc < INT32_MIN) return -1;
*x = ad;
*y = bc;
return 0;
}
```
:::
## 2. Minesweeper
:::spoiler mine.h
```c
#pragma once
#include <stdint.h>
#include <stdio.h>
#define N 16
#define M 30
int32_t hit( int32_t board[N][M], int32_t row, int32_t col );
```
:::
:::spoiler mine.c
```c
#include "mine.h"
int8_t dir_x[8] = {0, 1, 1, 1, 0, -1, -1, -1};
int8_t dir_y[8] = {1, 1, 0, -1, -1, -1, 0, 1};
int8_t get_mine(int32_t board[N][M], int32_t row, int32_t col ) {
int8_t count = 0;
for (int k = 0; k < 8; k++) {
int32_t x = row + dir_x[k];
int32_t y = col + dir_y[k];
if (x >= 0 && x < N && y >= 0 && y < M && board[x][y] == -2) {
count++;
}
}
return count;
}
void get_ans(int32_t board[N][M], int32_t ans_board[N][M]) {
for (int i = 0; i < N; i++) {
for (int j = 0; j < M; j++) {
if (board[i][j] == -2) {
ans_board[i][j] = -2;
}
else {
ans_board[i][j] = get_mine(board, i, j);
}
}
}
}
void diffusion(int32_t board[N][M], int32_t ans_board[N][M], int32_t visited[N][M], int32_t row, int32_t col) {
visited[row][col] = 1;
board[row][col] = ans_board[row][col];
if (board[row][col] != 0) {
return;
}
for (int k = 0; k < 8; k++) {
int32_t x = row + dir_x[k];
int32_t y = col + dir_y[k];
if (x >= 0 && x < N && y >= 0 && y < M && visited[x][y] == 0) {
diffusion(board, ans_board, visited, x, y);
}
}
}
int32_t hit(int32_t board[N][M], int32_t row, int32_t col) {
if (row < 0 || row >= N || col < 0 || col >= M) {
return -1;
}
for (int i = 0; i < N; i++) {
for (int j = 0; j < M; j++) {
if (board[i][j] < -2 || board[i][j] > 8) {
return -1;
}
}
}
int32_t ans_board[N][M] = {{0}};
get_ans(board, ans_board);
for (int i = 0; i < N; i++) {
for (int j = 0; j < M; j++) {
if ((board[i][j] != -2 && board[i][j] != -1) && board[i][j] != ans_board[i][j]) {
return -1;
}
}
}
if (board[row][col] == -2) {
return 1;
} else if (board[row][col] == -1 && ans_board[row][col] == 1) {
board[row][col] = ans_board[row][col];
return 0;
} else if(board[row][col] != -1 && board[row][col] != 0) {
return 0;
}
int32_t visited[N][M] = {{0}};
diffusion(board, ans_board, visited, row, col);
return 0;
}
```
:::
## 3. Firewall
:::spoiler firewall.c
```c
#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "firewall.h"
#define MAX_RULES 100
#define OFFSET 10
typedef int32_t (*RuleFunctionPointer)(const uint8_t *p_input_packet, const int32_t input_size, uint8_t **pp_output_packet, int32_t *p_output_size);
RuleFunctionPointer rules[MAX_RULES] = {NULL};
int32_t set_rule(int32_t idx, RuleFunctionPointer rule)
{
if (idx < 0 || idx >= MAX_RULES || rule == NULL)
{
return -1;
}
rules[idx] = rule;
return 0;
}
int32_t unset_rule(int32_t idx)
{
if (idx < 0 || idx >= MAX_RULES)
{
return -1;
}
rules[idx] = NULL;
return 0;
}
int32_t filter(const uint8_t *p_input_packets,
const int32_t input_size,
uint8_t **pp_output_packets,
int32_t *p_output_size)
{
if (p_input_packets == NULL || input_size <= 0)
{
return -1;
}
*p_output_size = 0;
for (int count = 0; count < input_size;)
{
const uint8_t *p_input_packet = &(p_input_packets[count]);
const uint32_t p_input_packet_size = ((uint16_t *)(p_input_packet))[4] + OFFSET; // data_size + offset
uint8_t *tmp_input_packet = malloc(p_input_packet_size * sizeof(uint8_t));
memcpy(tmp_input_packet, p_input_packet, p_input_packet_size * sizeof(uint8_t));
uint32_t tmp_input_size = p_input_packet_size;
int32_t result = 0;
for (int i = 0; i < MAX_RULES; i++)
{
if (rules[i] == NULL) continue;
uint8_t *tmp_output_packet = NULL;
int32_t tmp_output_size = 0;
result = rules[i](tmp_input_packet, tmp_input_size, &tmp_output_packet, &tmp_output_size);
if (result == 1) break;
else if (result == -1) continue;
free(tmp_input_packet);
tmp_input_packet = malloc(tmp_output_size * sizeof(uint8_t));
tmp_input_size = tmp_output_size;
memcpy(tmp_input_packet, tmp_output_packet, tmp_output_size * sizeof(uint8_t));
free(tmp_output_packet);
}
if(result != 1)
{
*pp_output_packets = realloc(*pp_output_packets, (*p_output_size + tmp_input_size) * sizeof(uint8_t));
memcpy(*pp_output_packets + (*p_output_size), tmp_input_packet, tmp_input_size * sizeof(uint8_t));
(*p_output_size) += tmp_input_size;
}
count += p_input_packet_size;
}
return 0;
}
```
:::
## 4. The Tank War Game
Credit: 61107020E 吳O霆
:::spoiler 60 pts(但只能拿到最高 50 分)
```c
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define SCREEN_HEIGHT 31
#define SCREEN_WIDTH 31
#define CP_CNT 3
#define CANNONBALL_LIFE_TIME 10
struct map_stat
{
int h, w;
int obstacle_cnt;
int *obstacle_x, *obstacle_y;
}map;
typedef struct player
{
int alive;
int x, y;
int muzzle_dir;
int cannonball_dir, cannonball_x, cannonball_y, cannonball_life;
}player;
player hp, cp[CP_CNT];
void init_map()
{
map.obstacle_cnt = map.h * map.w / 40;
map.obstacle_x = malloc(sizeof(int) * map.obstacle_cnt);
map.obstacle_y = malloc(sizeof(int) * map.obstacle_cnt);
srand(time(0));
for (int i=0;i<map.obstacle_cnt;i++)
{
map.obstacle_x[i] = rand() % map.h;
map.obstacle_y[i] = rand() % map.w;
}
hp.alive = 1;
hp.x = rand() % map.h;
hp.y = rand() % map.w;
hp.muzzle_dir = 0;
hp.cannonball_x = hp.cannonball_y = -1;
hp.cannonball_life = 0;
for (int i=0;i<CP_CNT;i++)
{
cp[i].alive = 1;
cp[i].x = rand() % map.h;
cp[i].y = rand() % map.w;
cp[i].muzzle_dir = 0;
cp[i].cannonball_x = cp[i].cannonball_y = -1;
cp[i].cannonball_life = 0;
}
}
void destroy_map()
{
free(map.obstacle_x);
free(map.obstacle_y);
}
int game_cont()
{
int cp_alive_cnt = 0;
for (int i=0;i<CP_CNT;i++) cp_alive_cnt += cp[i].alive;
return hp.alive && cp_alive_cnt;
}
const int dx[8] = {-1, -1, 0, 1, 1, 1, 0, -1};
const int dy[8] = {0, 1, 1, 1, 0, -1, -1, -1};
void shoot(player *p)
{
if (p->cannonball_x != -1) return;
p->cannonball_x = p->x + dx[p->muzzle_dir];
p->cannonball_y = p->y + dy[p->muzzle_dir];
p->cannonball_dir = p->muzzle_dir;
p->cannonball_life = CANNONBALL_LIFE_TIME;
}
void process_cannonball(player *p)
{
if (p->cannonball_life <= 0) return;
p->cannonball_x += dx[p->cannonball_dir];
p->cannonball_y += dy[p->cannonball_dir];
if (0 > p->cannonball_x || p->cannonball_x >= map.h || 0 > p->cannonball_y || p->cannonball_y >= map.w){
int ndir;
if (p->cannonball_dir % 2 == 0) ndir = (p->cannonball_dir + 4) % 8;
else
{
if ((0 > p->cannonball_x || p->cannonball_x >= map.h) && (0 > p->cannonball_y || p->cannonball_y >= map.w))
ndir = (p->cannonball_dir + 4) % 8;
else if (0 > p->cannonball_x)
{
if (p->cannonball_dir == 1) ndir = 3;
else ndir = 5;
}
else if (p->cannonball_x >= map.h)
{
if (p->cannonball_dir == 3) ndir = 1;
else ndir = 7;
}
else if (0 > p->cannonball_y)
{
if (p->cannonball_dir == 5) ndir = 3;
else ndir = 1;
}
else if (p->cannonball_y >= map.w)
{
if (p->cannonball_dir == 1) ndir = 7;
else ndir = 3;
}
}
if (0 > p->cannonball_x || p->cannonball_x >= map.h) p->cannonball_x -= dx[p->cannonball_dir] * 2;
if (0 > p->cannonball_y || p->cannonball_y >= map.w) p->cannonball_y -= dy[p->cannonball_dir] * 2;
p->cannonball_dir = ndir;
}
for (int i=0;i<map.obstacle_cnt;i++)
{
if (p->cannonball_x == map.obstacle_x[i] && p->cannonball_y == map.obstacle_y[i])
{
map.obstacle_x[i] = map.obstacle_y[i] = p->cannonball_x = p->cannonball_y = -1;
p->cannonball_life = 0;
}
}
if (hp.x == p->cannonball_x && hp.y == p->cannonball_y)
{
hp.alive = 0;
p->cannonball_x = p->cannonball_y = -1;
p->cannonball_life = 0;
}
for (int i=0;i<CP_CNT;i++)
{
if (p->cannonball_x == cp[i].x && p->cannonball_y == cp[i].y)
{
cp[i].alive = 0;
p->cannonball_x = p->cannonball_y = -1;
p->cannonball_life = 0;
}
}
p->cannonball_life--;
if (p->cannonball_life == 0)
{
p->cannonball_x = p->cannonball_y = -1;
}
}
int not_obstacle(int x, int y)
{
for (int i=0;i<map.obstacle_cnt;i++) if (map.obstacle_x[i] == x && map.obstacle_y[i] == y) return 0;
return 1;
}
void cp_action(player *p)
{
if (p->cannonball_x == -1)
{
shoot(p);
}
else
{
int i = rand() % 4;
if (i == 0)
{
if (p->x > 0 && not_obstacle(p->x - 1, p->y)) p->x--;
}
else if (i == 1)
{
if (p->y > 0 && not_obstacle(p->x, p->y - 1)) p->y--;
}
else if (i == 2)
{
if (p->x < map.h-1 && not_obstacle(p->x + 1, p->y)) p->x++;
}
else
{
if (p->y < map.w-1 && not_obstacle(p->x, p->y + 1)) p->y++;
}
}
}
void next_round()
{
hp.muzzle_dir = (hp.muzzle_dir + 1) % 8;
for (int i=0;i<CP_CNT;i++)
{
cp[i].muzzle_dir = (cp[i].muzzle_dir + 1) % 8;
}
process_cannonball(&hp);
for (int i=0;i<CP_CNT;i++)
{
process_cannonball(&cp[i]);
}
}
void add_to_map(char c, int x, int y, int lx, int ly, int rx, int ry, char map_data[][SCREEN_WIDTH+1])
{
if (lx <= x && x <= rx && ly <= y && y <= ry)
map_data[x-lx][y-ly] = c;
}
void print_map()
{
static char map_data[SCREEN_HEIGHT][SCREEN_WIDTH+1];
const int radius = SCREEN_HEIGHT / 2;
int lx = hp.x - radius, ly = hp.y - radius, rx = hp.x + radius, ry = hp.y + radius;
if (map.h < SCREEN_HEIGHT)
{
lx = 0;
rx = map.h - 1;
}
else if (lx < 0)
{
rx -= lx;
lx = 0;
}
else if (rx >= map.h)
{
lx += rx - map.h + 1;
rx = map.h - 1;
}
if (map.w < SCREEN_WIDTH)
{
ly = 0;
ry = map.w - 1;
}
else if (ly < 0)
{
ry -= ly;
ly = 0;
}
else if (ry >= map.w)
{
ly += ry - map.w + 1;
ry = map.w - 1;
}
for (int i=0;i<=rx-lx;i++)
{
for (int j=0;j<=ry-ly;j++)
{
map_data[i][j] = ' ';
}
map_data[i][ry - ly+1] = '\0';
}
if (hp.alive)
{
add_to_map('P', hp.x, hp.y, lx, ly, rx, ry, map_data);
add_to_map('I', hp.x + dx[hp.muzzle_dir], hp.y + dy[hp.muzzle_dir], lx, ly, rx, ry, map_data);
}
if (hp.cannonball_x != -1) add_to_map('o', hp.cannonball_x, hp.cannonball_y, lx, ly, rx, ry, map_data);
for (int i=0;i<CP_CNT;i++)
{
if (cp[i].alive)
{
add_to_map('C', cp[i].x, cp[i].y, lx, ly, rx, ry, map_data);
add_to_map('I', cp[i].x + dx[cp[i].muzzle_dir], cp[i].y + dy[cp[i].muzzle_dir], lx, ly, rx, ry, map_data);
}
if (cp[i].cannonball_x != -1) add_to_map('o', cp[i].cannonball_x, cp[i].cannonball_y, lx, ly, rx, ry, map_data);
}
for (int i=0;i<map.obstacle_cnt;i++)
{
add_to_map('R', map.obstacle_x[i], map.obstacle_y[i], lx, ly, rx, ry, map_data);
}
for (int i=0;i<ry-ly+3;i++) printf("-");
printf("\n");
for (int i=0;i<rx-lx+1;i++)
{
printf("|%s|\n", map_data[i]);
}
for (int i=0;i<ry-ly+3;i++) printf("-");
printf("\n");
}
int main()
{
printf("Please input the height of the map: ");
scanf("%d", &map.h);
printf("Please input the width of the map: ");
scanf("%d", &map.w);
init_map();
while (game_cont())
{
char act[2];
print_map();
printf("Please input the action: ");
scanf("%s", act);
if (act[0] == 'W')
{
if (hp.x > 0 && not_obstacle(hp.x - 1, hp.y)) hp.x--;
}
else if (act[0] == 'A')
{
if (hp.y > 0 && not_obstacle(hp.x, hp.y - 1)) hp.y--;
}
else if (act[0] == 'S')
{
if (hp.x < map.h-1 && not_obstacle(hp.x + 1, hp.y)) hp.x++;
}
else if (act[0] == 'D')
{
if (hp.y < map.w-1 && not_obstacle(hp.x, hp.y + 1)) hp.y++;
}
else if (act[0] == 'Q')
{
shoot(&hp);
}
for (int i=0;i<CP_CNT;i++)
{
if (cp[i].alive) cp_action(&cp[i]);
}
next_round();
}
print_map();
destroy_map();
}
```
:::
Credit: 41247001S 盧O安
少了一點點功能
:::spoiler 52 pts(但只能拿到最高 50 分)
```c
#include <math.h>
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <time.h>
static int64_t height = 0,width = 0,obstacles = 0,player_alive = 1,bot_left = 3;
static int64_t bot[3][2][2],player[2][2],frame = 1,bomb[2] = {0,0};
static int64_t bomblocation[4][2],bombdirection[4][2],botalive[3] = {1,1,1};
static char **map = NULL;
static char cmd;
void initial_map();
void initial_obstacle();
void initial_player();
void initial_bot();
void map_show();
void player_move();
void muzzle_change_place();
void bot_move();
int64_t touch_obstacle(int64_t x,int64_t y);
int64_t ad_move_touch_obstacle(int64_t x,int64_t y);
int64_t ws_move_touch_obstacle(int64_t x,int64_t y);
int64_t min(int64_t a,int64_t b){return a > b ? b : a;}
int64_t max(int64_t a,int64_t b){return a > b ? a : b;}
void throw_bomb(int64_t pbot,int64_t place);
void bomb_run();
void bombkill_detect();
void bot_bomb();
int main(){
srand(time(NULL));
printf("Please input the height of the map: ");
scanf("%ld",&height);
printf("Please input the width of the map: ");
scanf("%ld",&width);
cmd = getchar();
obstacles = height * width / 20;
initial_map();
initial_obstacle();
initial_player();
initial_bot();
while(player_alive && bot_left){
map_show();
printf("Please input the action: ");
scanf("%s",&cmd);
bombkill_detect();
map[player[0][1]][player[1][1]] = ' ';
for(int i=0;i<3;i++){
map[bot[i][0][1]][bot[i][1][1]] = ' ';
}
for(int i=0;i<4;i++){
map[bomblocation[i][0]][bomblocation[i][1]] = ' ';
}
frame += 1;
bomb[0] = bomb[0] == 0 ? 0 : bomb[0] - 1;
bomb[1] = bomb[1] == 0 ? 0 : bomb[1] - 1;
bomb_run();
if(bomb[1]==0){
bot_bomb(); }
bombkill_detect();
player_move();
bot_move();
bombkill_detect();
muzzle_change_place(frame);
}}
void bombkill_detect(){
for(int i=0;i<4;i++){
if(map[bomblocation[i][0]][bomblocation[i][1]]=='P'){
player_alive = 0;
printf("You Dead!\n");
}
}
for(int i=0;i<4;i++){
if(map[bomblocation[i][0]][bomblocation[i][1]]=='C'){
bot_left -= 1;
for(int j=0;j<3;j++){
if(bot[j][0][0]==bomblocation[i][0] && bot[j][1][0] == bomblocation[i][1]){
botalive[j] = 0;
bot[j][0][0] = 99999;
bot[j][1][0] = 99999;
}
}
}
}
}
void bomb_run(){
for(int i=0;i<2;i++){
if(bomb[i]==0) continue;
else{
if(!i){
bomblocation[i][0] += bombdirection[i][0];
bomblocation[i][1] += bombdirection[i][1];
if(bomblocation[i][0]>=0&&bomblocation[i][0]<height-1&&bomblocation[i][1]<width-1&&bomblocation[i][1]>=0){
map[bomblocation[i][0]][bomblocation[i][1]] = 'o';
}
else{
bombdirection[i][0] *= -1;
bombdirection[i][1] *= -1;
bomblocation[i][0] += bombdirection[i][0];
bomblocation[i][1] += bombdirection[i][1];
bomblocation[i][0] += bombdirection[i][0];
bomblocation[i][1] += bombdirection[i][1];
map[bomblocation[i][0]][bomblocation[i][1]] = 'o';
}
}
else{
for(int j=0;j<3;j++){
bomblocation[i+j][0] += bombdirection[i+j][0];
bomblocation[i+j][1] += bombdirection[i+j][1];
if(bomblocation[i+j][0]>=0&&bomblocation[i+j][0]<height-1&&bomblocation[i+j][1]<width-1&&bomblocation[i+j][1]>=0){
map[bomblocation[i+j][0]][bomblocation[i+j][1]] = 'o';
}
else{
bombdirection[i+j][0] *= -1;
bombdirection[i+j][1] *= -1;
bomblocation[i+j][0] += bombdirection[i+j][0];
bomblocation[i+j][1] += bombdirection[i+j][1];
bomblocation[i+j][0] += bombdirection[i+j][0];
bomblocation[i+j][1] += bombdirection[i+j][1];
map[bomblocation[i+j][0]][bomblocation[i+j][1]] = 'o';
}
}
}}
}
}
void bot_bomb(){
throw_bomb(frame%8,1);
}
void throw_bomb(int64_t pbot,int64_t place){
if(place==0){
if(pbot==0){
bomblocation[0][0] = player[0][0]-2;
bomblocation[0][1] = player[1][0];
bombdirection[0][0] = -1;
bombdirection[0][1] = 0;
}
if(pbot==1){
bomblocation[0][1] = player[1][0] + 2;
bomblocation[0][0] = player[0][0] -2;
bombdirection[0][0] = -1;
bombdirection[0][1] = +1;
}
if(pbot==2){
bomblocation[0][1] = player[1][0] + 2;
bomblocation[0][0] = player[0][0] ;
bombdirection[0][0] = 0;
bombdirection[0][1] = 1;
}
if(pbot==3){
bomblocation[0][1] = player[1][0] + 2;
bomblocation[0][0] = player[0][0] +2;
bombdirection[0][0] = 1;
bombdirection[0][1] = 1;
}
if(pbot==4){
bomblocation[0][1] = player[1][0] ;
bomblocation[0][0] = player[0][0] +2;
bombdirection[0][0] = 1;
bombdirection[0][1] = 0;
}
if(pbot==5){
bomblocation[0][1] = player[1][0] - 2;
bomblocation[0][0] = player[0][0] +2;
bombdirection[0][0] = 1;
bombdirection[0][1] = -1;
}
if(pbot==6){
bomblocation[0][1] = player[1][0] - 2;
bomblocation[0][0] = player[0][0] ;
bombdirection[0][0] = 0;
bombdirection[0][1] = -1;
}
if(pbot==7){
bomblocation[0][1] = player[1][0] - 2;
bomblocation[0][0] = player[0][0] -2;
bombdirection[0][0] = -1;
bombdirection[0][1] = -1;
}
bomb[0] = 10;
if(bomblocation[0][0]>=0&&bomblocation[0][0]<height-1&&bomblocation[0][1]<width-1&&bomblocation[0][1]>=0){
map[bomblocation[0][0]][bomblocation[0][1]] = 'o';
}
else{
int i = 0;
bombdirection[i][0] *= -1;
bombdirection[i][1] *= -1;
bomblocation[i][0] += bombdirection[i][0];
bomblocation[i][1] += bombdirection[i][1];
bomblocation[i][0] += bombdirection[i][0];
bomblocation[i][1] += bombdirection[i][1];
map[bomblocation[i][0]][bomblocation[i][1]] = 'o';
}
}
else{
for(int i=0;i<3;i++){
if(botalive[i]==0) continue;
if(pbot==0){
bomblocation[i+1][0] = bot[i][0][0]-2;
bomblocation[i+1][1] = bot[i][1][0];
bombdirection[i+1][0] = -1;
bombdirection[i+1][1] = 0;
}
if(pbot==1){
bomblocation[i+1][1] = bot[i][1][0] + 2;
bomblocation[i+1][0] = bot[i][0][0] -2;
bombdirection[i+1][0] = -1;
bombdirection[i+1][1] = +1;
}
if(pbot==2){
bomblocation[i+1][1] = bot[i][1][0] + 2;
bomblocation[i+1][0] = bot[i][0][0] ;
bombdirection[i+1][0] = 0;
bombdirection[i+1][1] = 1;
}
if(pbot==3){
bomblocation[i+1][1] = bot[i][1][0] + 2;
bomblocation[i+1][0] = bot[i][0][0] +2;
bombdirection[i+1][0] = 1;
bombdirection[i+1][1] = 1;
}
if(pbot==4){
bomblocation[i+1][1] = bot[i][1][0] ;
bomblocation[i+1][0] = bot[i][0][0] +2;
bombdirection[i+1][0] = 1;
bombdirection[i+1][1] = 0;
}
if(pbot==5){
bomblocation[i+1][1] = bot[i][1][0] - 2;
bomblocation[i+1][0] = bot[i][0][0] +2;
bombdirection[i+1][0] = 1;
bombdirection[i+1][1] = -1;
}
if(pbot==6){
bomblocation[i+1][1] = bot[i][1][0] - 2;
bomblocation[i+1][0] = bot[i][0][0] ;
bombdirection[i+1][0] = 0;
bombdirection[i+1][1] = -1;
}
if(pbot==7){
bomblocation[i+1][1] = bot[i][1][0] - 2;
bomblocation[i+1][0] = bot[i][0][0] +2;
bombdirection[i+1][0] = +1;
bombdirection[i+1][1] = -1;
}
bomb[1] = 10;
if(bomblocation[i+1][0]>=0&&bomblocation[i+1][0]<height-1&&bomblocation[i+1][1]<width-1&&bomblocation[i+1][1]>=0){
map[bomblocation[i+1][0]][bomblocation[i+1][1]] = 'o';
}
}
}
}
void muzzle_change_place(){
if(frame%8==0){
player[1][1] = player[1][0];
player[0][1] = player[0][0]-1;
for(int i=0;i<3;i++){
bot[i][0][1] = bot[i][0][0]-1;
bot[i][1][1] = bot[i][1][0];
}}
if(frame%8==1){
player[1][1] = player[1][0] + 1;
player[0][1] = player[0][0] -1;
for(int i=0;i<3;i++){
bot[i][0][1] = bot[i][0][0]-1;
bot[i][1][1] = bot[i][1][0]+1;
}}
if(frame%8==2){
player[1][1] = player[1][0] +1;
player[0][1] = player[0][0];
for(int i=0;i<3;i++){
bot[i][0][1] = bot[i][0][0];
bot[i][1][1] = bot[i][1][0]+1;
}}
if(frame%8==3){
player[1][1] = player[1][0] + 1;
player[0][1] = player[0][0] +1;
for(int i=0;i<3;i++){
bot[i][0][1] = bot[i][0][0]+1;
bot[i][1][1] = bot[i][1][0]+1;
}}
if(frame%8==4){
player[1][1] = player[1][0];
player[0][1] = player[0][0]+1;
for(int i=0;i<3;i++){
bot[i][0][1] = bot[i][0][0]+1;
bot[i][1][1] = bot[i][1][0];
}}
if(frame%8==5){
player[1][1] = player[1][0]-1;
player[0][1] = player[0][0]+1;
for(int i=0;i<3;i++){
bot[i][0][1] = bot[i][0][0]+1;
bot[i][1][1] = bot[i][1][0]-1;
}}
if(frame%8==6){
player[1][1] = player[1][0]-1;
player[0][1] = player[0][0];
for(int i=0;i<3;i++){
bot[i][0][1] = bot[i][0][0];
bot[i][1][1] = bot[i][1][0]-1;
}}
if(frame%8==7){
player[1][1] = player[1][0]-1;
player[0][1] = player[0][0]-1;
for(int i=0;i<3;i++){
bot[i][0][1] = bot[i][0][0]-1;
bot[i][1][1] = bot[i][1][0]-1;
}}
map[player[0][1]][player[1][1]] = 'I';
for(int i=0;i<3;i++){
map[bot[i][0][1]][bot[i][1][1]] = 'I';
}
}
void bot_move(){
for(int i=0;i<3;i++){
if(botalive[i]==0) continue;
int c = rand()%4;
if(c==0){
if(ws_move_touch_obstacle(bot[i][0][0]-1,bot[i][1][0])) continue;
bot[i][0][0] -= 1;
map[bot[i][0][0]][bot[i][1][0]] = 'C';
map[bot[i][0][0]+1][bot[i][1][0]] = ' ';
}
if(c==1){
if(ws_move_touch_obstacle(bot[i][0][0]+1,bot[i][1][0])) continue;
bot[i][0][0] += 1;
map[bot[i][0][0]][bot[i][1][0]] = 'C';
map[bot[i][0][0]-1][bot[i][1][0]] = ' ';
}
if(c==2){
if(ws_move_touch_obstacle(bot[i][0][0],bot[i][1][0]+1)) continue;
bot[i][1][0] += 1;
map[bot[i][0][0]][bot[i][1][0]] = 'C';
map[bot[i][0][0]][bot[i][1][0]-1] = ' ';
}
if(c==3){
if(ws_move_touch_obstacle(bot[i][0][0],bot[i][1][0]-1)) continue;
bot[i][1][0] -= 1;
map[bot[i][0][0]][bot[i][1][0]] = 'C';
map[bot[i][0][0]][bot[i][1][0]+1] = ' ';
}
}
}
void player_move(){
if(cmd=='W'||cmd=='w'){
if(ws_move_touch_obstacle(player[0][0]-1,player[1][0])) return;
player[0][0] -= 1;
map[player[0][0]][player[1][0]] = 'P';
map[player[0][0]+1][player[1][0]] = ' ';
}
if(cmd=='S'||cmd=='s'){
if(ws_move_touch_obstacle(player[0][0]+1,player[1][0])) return;
player[0][0] += 1;
map[player[0][0]][player[1][0]] = 'P';
map[player[0][0]-1][player[1][0]] = ' ';
}
if(cmd=='D'||cmd=='d'){
if(ad_move_touch_obstacle(player[0][0],player[1][0]+1)) return;
player[1][0] += 1;
map[player[0][0]][player[1][0]] = 'P';
map[player[0][0]][player[1][0]-1] = ' ';
}
if(cmd=='A'||cmd=='a'){
if(ad_move_touch_obstacle(player[0][0],player[1][0]-1)) return;
player[1][0] -= 1;
map[player[0][0]][player[1][0]] = 'P';
map[player[0][0]][player[1][0]+1] = ' ';
}
if(cmd=='Q'||cmd=='q'){
if(!bomb[0]) throw_bomb((frame)%8,0);
}
}
int64_t ad_move_touch_obstacle(int64_t x,int64_t y){
if(map[x][y]!=' '&&map[x][y]!='I')return 1;
if(y==0)return 1;
if(y==width-1)return 1;
if(x<=0) return 1;
if(x>=height - 1) return 1;
return 0;
}
int64_t ws_move_touch_obstacle(int64_t x,int64_t y){
if(map[x][y]!=' '&&map[x][y]!='I')return 1;
if(x<=0) return 1;
if(x>=height - 1) return 1;
if(y==0)return 1;
if(y==width-1)return 1;
return 0;
}
void map_show(){
int64_t map_x = 0,map_y = 0;
if(player[0][0] <= 9) map_x = 1;
else map_x = player[0][0] - 9;
if(player[1][0] <= 29)map_y = 1;
//else if(player[1] + 29 >=width)map_y = width - 58;
else map_y = player[1][0] - 29;
for(int i=-2;i<min(map_y+58,width-1)-map_y;i++)printf("-");
printf("\n");
for(int i=map_x;i<min(map_x + 18,height-1);i++){
printf("|");
for(int j=map_y;j<min(map_y+58,width-1);j++){
printf("%c",map[i][j]);
}
printf("|");
if(i==min(map_x + 18,height-1)-5){
printf("Enemie cooldown: %ld",bomb[1]);
}
if(i==min(map_x + 18,height-1)-4){
printf("Enemies left: %ld",bot_left);
}
if(i==min(map_x + 18,height-1)-3){
printf("Player X: %ld",player[0][0]);
}
else if(i==min(map_x + 18,height-1)-2){
printf("Player Y: %ld",player[1][0]);
}
else if(i==min(map_x + 18,height-1)-1){
printf("Bomb Cooldown: %ld",bomb[0]);
}
printf("\n");
}
for(int i=-2;i<min(map_y+58,width-1)-map_y;i++)printf("-");
printf("\n");
}
void initial_map(){
map = malloc(height*sizeof(char*));
for(int64_t i=0;i<height;i++){
map[i] = malloc(width);
map[i][0] = '|';
map[i][width-1] = '|';
for(int j=1;j<width-1;j++)map[i][j] = ' ';
}
for(int64_t i=0;i<width;i++){
map[0][i] = '-';
map[height-1][i] = '-';
}
//printf("!!!");
}
void initial_obstacle(){
for(int64_t i=0;i<obstacles;i++){
int64_t x = rand()%height,y = rand()%width;
while(map[x][y]!=' '){
x = rand()%height;
y = rand()%width;
}
map[x][y] = 'R';
}
}
void initial_player(){
int64_t x = rand()%height,y = rand()%width;
while(map[x][y]!=' '||map[x+1][y]!=' '||x+1==height){
x = rand()%height;
y = rand()%width;
}
map[x][y] = 'I';
map[x+1][y] = 'P';
player[0][0] = x+1;
player[1][0] = y;
player[0][1] = x;
player[1][1] = y;
}
void initial_bot(){
for(int i=0;i<3;i++){
int64_t x = rand()%height,y = rand()%width;
while(map[x][y]!=' '||map[x+1][y]!=' '||x+1==height){
x = rand()%height;
y = rand()%width;
}
map[x][y] = 'I';
map[x+1][y] = 'C';
bot[i][0][0] = x+1;
bot[i][1][0] = y;
bot[i][0][1] = x;
bot[i][1][1] = y;
}
}
```
:::