打飞机
·once·
·
·
个人记录
//转自:https://www.luogu.com.cn/discuss/30357?page=59
#include <stdio.h>
#include <conio.h>
#include <windows.h>
#include <time.h>
#include <stdlib.h>
#define T 10
#define R 23
#define C 49
#define KEY_DOWN(VK_NONAME) ((GetAsyncKeyState(VK_NONAME) & 0x8000) ? 1:0)
int difficulty = 1, tim, score, HP, asd;
char ch;
int xx, yy, cnt, p1, p2, q1, q2;
bool bul[R+5][C+5], Bul[R+5][C+5];
int occ[R+5][C+5];
char board[R+5][80], last[R+5][80];
int llast;
bool ls, t2, t3;
void gotoxy(int x, int y) {
COORD coord = {y, x};
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);
}
void printxy(int x, int y, char ch) {
COORD coord = {x, y};
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);
putchar(ch);
}
int max(int a, int b) {
return a > b ? a : b;
}
int min(int a, int b) {
return a > b ? b : a;
}
struct enemy {
bool dead;
int x, y;
int type;
int blood;
}enemies[1000010];
int gtt, gtx, gty;
int rand_gt_type(void) {
switch (rand() % 5) {
case 0: case 1: {
switch (rand() % 10) {
case 0: case 1: {
return 3;
break;
}
case 2: case 3: case 4: {
return 2;
break;
}
case 5: case 6: case 7: case 8: case 9: {
return 1;
break;
}
}
break;
}
case 2: case 3: {
switch (rand() % 3) {
case 0: case 1: {
return 4;
break;
}
case 2: {
return 5;
break;
}
}
break;
}
case 4: {
return 6;
break;
}
}
}
void draw_gt(int x, int y, int type) {
if (type == 0) return;
if (gtx >= 0) for (int i = 0; i <= 4; i++) board[x][y+i] = '-';
for (int i = 0; i <= 4; i++) board[x+2][y+i] = '-';
if (gtx >= -1)board[x+1][y] = board[x+1][y+4] = '|';
if (gtx >= -1) switch (type) {
case 1: case 2: case 3: {
board[x+1][y+1] = '+';
board[x+1][y+2] = 49 + (1 << (type - 1));
board[x+1][y+3] = '0';
break;
}
case 4: case 5: {
board[x+1][y+1] = '^';
board[x+1][y+2] = 'x';
board[x+1][y+3] = 46 + type;
break;
}
case 6: {
board[x+1][y+1] = '1';
board[x+1][y+2] = 'U';
board[x+1][y+3] = 'P';
break;
}
}
}
void RND(void) {
srand(time(0));
int ASDFGHJKL = rand();
while (ASDFGHJKL--) srand(rand());
}
void start(void) {
system("cls");
tim = score = HP = asd = ch = xx = yy = cnt = p1 = p2 = q1 = q2 = llast = ls = t2 = t3 = 0;
memset(bul, 0, sizeof(bul));
memset(Bul, 0, sizeof(Bul));
memset(occ, 0, sizeof(occ));
memset(board, 0, sizeof(board));
memset(last, 0, sizeof(last));
memset(enemies, 0, sizeof(enemies));
system("cls");
for (int i = 0; i <= R+1; i++) {
for (int j = 0; j <= 78; j++) {
if (i == 0 || j == 0 || i == R+1 || j == 78) putchar('#');
else putchar(32);
}
if (i != R+1) putchar(10);
}
gotoxy(7, 34);
printf("请选择难度");
gotoxy(10,35);
printf("简单模式");
gotoxy(13,35);
printf("中等模式");
gotoxy(16,35);
printf("困难模式");
gotoxy(difficulty * 3 + 7, 33);
putchar('>');
while ((ch = getch()) != 10 && ch != 13) {
if (ch == -32) {
ch = getch();
if (ch == 72) if (difficulty != 1) {
gotoxy(difficulty * 3 + 7, 33);
putchar(' ');
gotoxy((--difficulty) * 3 + 7, 33);
putchar('>');
}
if (ch == 80) if (difficulty != 3) {
gotoxy(difficulty * 3 + 7, 33);
putchar(' ');
gotoxy((++difficulty) * 3 + 7, 33);
putchar('>');
}
}
}
switch(difficulty) {
case 1: {
tim = 12;
p1 = 7;
q1 = 1;
p2 = 5;
q2 = 1;
break;
}
case 2: {
tim = 10;
p1 = 6;
q1 = 1;
p2 = 4;
q2 = 1;
break;
}
case 3: {
tim = 8;
p1 = 5;
q1 = 1;
p2 = 3;
q2 = 1;
break;
}
}
system("cls");
}
int length(int type) {
return 2 + (1 << (type - 1));
}
int width(int type) {
return 3 + (1 << type);
}
int blood(int type) {
if (type == 3) return 5;
return type;
}
bool GAMEOVER(void) {
for (int i = yy-2; i <= yy+2; i++) {
if (occ[xx+1][i] || Bul[xx+1][i]) return 1;
}
for (int i = yy-1; i <= yy+1; i++) {
if (occ[xx+2][i] || Bul[xx+2][i]) return 1;
}
return 0;
}
bool create_enemy(int pos, int type) {
for (int i = max(pos, 1); i <= min(pos + width(type) - 1, C); i++) if (occ[1][i]) return 0;
cnt++;
enemies[cnt].x = 2 - length(type);
enemies[cnt].y = pos;
enemies[cnt].dead = 0;
enemies[cnt].type = type;
enemies[cnt].blood = blood(type);
return 1;
}
void attack_enemy(int a) {
enemies[a].blood--;
}
void paint(int x, int y, int xx, int yy, char ch) {
x = max(x, 1);
y = max(y, 1);
xx = min(xx, R);
yy = min(yy, C);
for (int i = x; i <= xx; i++) {
for (int j = y; j <= yy; j++) {
board[i][j] = ch;
}
}
}
void draw_plane(int x, int y) {
board[x][y] = '|';
paint(x+1, y-2, x+1, y+2, '*');
board[x+2][y] = '*';
board[x+1][y-3] = board[x+2][y-1] = '\\';
board[x+1][y+3] = board[x+2][y+1] = '/';
}
void draw_enemy(int x, int y, int type, bool broken) {
paint(x, y, x, y, '/');
paint(x+length(type)-1, y+width(type)-1, x+length(type)-1, y+width(type)-1, '/');
paint(x+length(type)-1, y, x+length(type)-1, y, '\\');
paint(x, y+width(type)-1, x, y+width(type)-1, '\\');
paint(x, y+1, x, y+width(type)-2, '-');
paint(x+length(type)-1, y+1, x+length(type)-1, y+width(type)-2, '-');
paint(x+1, y, x+length(type)-2, y, '|');
paint(x+1, y+width(type)-1, x+length(type)-2, y+width(type)-1, '|');
paint(x+1, y+1, x+length(type)-2, y+width(type)-2, ' ');
if (broken) {
if (type == 2) {
paint(x, y+2, x, y+2, 'v');
paint(x, y+4, x, y+4, 'v');
paint(x+1, y, x+1, y, '>');
paint(x+1, y+4, x+1, y+4, '*');
paint(x+2, y+2, x+2, y+2, '*');
paint(x+2, y+6, x+2, y+6, '<');
paint(x+3, y+2, x+3, y+2, '^');
paint(x+3, y+4, x+3, y+4, '^');
} else {
paint(x, y+2, x, y+2, 'v');
paint(x, y+5, x, y+5, 'v');
paint(x, y+8, x, y+8, 'v');
paint(x+1, y, x+1, y, '>');
paint(x+3, y, x+3, y, '>');
paint(x+1, y+8, x+1, y+8, '*');
paint(x+2, y+2, x+2, y+2, '*');
paint(x+2, y+6, x+2, y+6, '*');
paint(x+3, y+4, x+3, y+4, '*');
paint(x+3, y+8, x+3, y+8, '*');
paint(x+4, y+2, x+4, y+2, '*');
paint(x+2, y+10, x+2, y+10, '<');
paint(x+4, y+10, x+4, y+10, '<');
paint(x+5, y+2, x+5, y+2, '^');
paint(x+5, y+5, x+5, y+5, '^');
paint(x+5, y+8, x+5, y+8, '^');
}
}
}
void kill_enemy(void) {
for (int i = 1; i <= cnt; i++) {
if (!enemies[i].dead && enemies[i].blood <= 0) score += blood(enemies[i].type), asd++;
if (!enemies[i].dead && (enemies[i].blood <= 0 || enemies[i].x == R+1)) enemies[i].dead = 1;
}
}
void show_enemy(void) {
memset(occ, 0, sizeof(occ));
for (int i = 1; i <= cnt; i++) {
if (!enemies[i].dead) {
for (int x = max(enemies[i].x, 1); x <= min(enemies[i].x + length(enemies[i].type) - 1, R); x++) {
for (int y = max(enemies[i].y, 1); y <= min(enemies[i].y + width(enemies[i].type) - 1, C); y++) {
occ[x][y] = i;
}
}
}
}
}
void move_enemy() {
for (int i = 1; i <= cnt; i++) {
if (!enemies[i].dead) {
enemies[i].x++;
if (enemies[i].type == 1) {
if (rand() % 30 == 0) Bul[enemies[i].x + 3][enemies[i].y + 2] = 1;
}
if (enemies[i].type == 2) {
if (rand() % 20 == 0) Bul[enemies[i].x + 4][enemies[i].y + 3] = 1;
}
if (enemies[i].type == 3) {
if (rand() % 10 == 0) Bul[enemies[i].x + 6][enemies[i].y + 4] = 1;
if (rand() % 10 == 0) Bul[enemies[i].x + 6][enemies[i].y + 6] = 1;
}
}
}
}
void draw_score(void) {
board[3][58] = -75;
board[3][59] = -61;
board[3][60] = -73;
board[3][61] = -42;
board[3][62] = -93;
board[3][63] = -70;
int arr[10];
memset(arr, 0, sizeof(arr));
if (score == 0) board[3][64] = '0';
else {
int t = 0;
int s = score;
while (s) {
arr[++t] = s % 10;
s /= 10;
}
for (int i = t; i >= 1; i--) {
board[3][64+t-i] = 48 + arr[i];
}
}
board[6][58] = -61;
board[6][59] = -4;
board[6][60] = -54;
board[6][61] = -3;
board[6][62] = -93;
board[6][63] = -70;
int c = HP+1;
while (c--) board[6][c+64] = 3;
}
void draw_line(void) {
for (int i = 0; i <= R+1; i++) board[i][0] = board[i][C+1] = board[i][78] = '#';
for (int i = 0; i <= 78; i++) board[0][i] = board[R+1][i] = '#';
for (int i = C+2; i <= 78; i++) board[9][i] = '#';
}
void draw(void) {
memcpy(last, board, sizeof(board));
memset(board, 32, sizeof(board));
draw_plane(xx, yy);
for (int i = 1; i <= cnt; i++) {
if (!enemies[i].dead) draw_enemy(enemies[i].x, enemies[i].y, enemies[i].type, (enemies[i].type != 1 && enemies[i].blood <= enemies[i].type * 2 - 3));
}
for (int i = 1; i <= R; i++) {
for (int j = 1; j <= C; j++) {
if (bul[i][j]) board[i][j] = '^';
if (Bul[i][j]) board[i][j] = 'v';
}
}
draw_gt(gtx, gty, gtt);
draw_score();
draw_line();
}
void create_gt(void) {
gtt = rand_gt_type();
gtx = -1;
gty = rand() % (C-4) + 1;
}
bool in_gt(int x, int y) {
return (x >= gtx && x <= gtx + 2 && y >= gty && y <= gty + 4);
}
bool get_gt(void) {
if (in_gt(xx, yy)) return 1;
for (int i = yy-1; i <= yy+1; i++) if (in_gt(xx+1, i)) return 1;
for (int i = yy-1; i <= yy+1; i++) if (in_gt(xx+2, i)) return 1;
return 0;
}
void use_gt(void) {
switch(gtt) {
case 1: {
score += 20;
break;
}
case 2: {
score += 30;
break;
}
case 3: {
score += 50;
break;
}
case 4: {
score += 10;
t2 = 1;
break;
}
case 5: {
score += 10;
t3 = 1;
break;
}
case 6: {
score += 10;
HP++;
break;
}
}
gtt = 0;
}
void move_gt(void) {
gtx++;
if (gtx == R+1) gtt = 0;
}
void print(void) {
for (int i = 0; i <= R+1; i++) {
for (int j = 0; j <= 79; j++) {
if (board[i][j] != last[i][j]) {
printxy(j, i, board[i][j]);
}
}
}
}
bool end(void) {
system("cls");
for (int i = 0; i <= R+1; i++) {
for (int j = 0; j <= 78; j++) {
if (i == 0 || j == 0 || i == R+1 || j == 78) putchar('#');
else putchar(32);
}
if (i != R+1) putchar(10);
}
gotoxy(5, 35);
switch(difficulty) {
case 1: {
printf("简单模式");
break;
}
case 2: {
printf("中等模式");
break;
}
case 3: {
printf("困难模式");
break;
}
}
gotoxy(8, 35);
printf("得分:%d", score);
gotoxy(11, 34);
printf("击落敌机%d架", asd);
gotoxy(14, 33);
printf("继续游戏?(Y/N)");
while (1) {
switch(getch()) {
case 'Y': case 'y': {
return 1;
break;
}
case 'N': case 'n': {
return 0;
break;
}
}
}
}
void game(void) {
xx = 21;
yy = 25;
int t = 0;
HP = 4 - difficulty;
draw();
for (int i = 0; i <= R+1; i++) {
for (int j = 0; j <= 78; j++) {
putchar(board[i][j]);
}
if (i != R+1) putchar(10);
}
while (HP--) {
xx = 21;
yy = 25;
t = 0;
llast = 0;
ls = 0;
while (!GAMEOVER()) {
t++;
if (KEY_DOWN(VK_MENU)) {
exit(0);
}
if (KEY_DOWN(VK_CONTROL)) {
getch();
}
if (t - llast >= 3) {
if (KEY_DOWN(VK_RIGHT) && yy != 46) yy++, llast = t;
if (KEY_DOWN(VK_LEFT) && yy != 4) yy--, llast = t;
}
if (t - llast >= 6) {
if (KEY_DOWN(VK_DOWN) && xx != 21) xx++, llast = t;
if (KEY_DOWN(VK_UP) && xx != 1) xx--, llast = t;
}
if (KEY_DOWN(VK_SPACE)) {
if (!ls)
if (t3) bul[xx][yy] = bul[xx][yy-2] = bul[xx][yy+2] = 1;
else if (t2) bul[xx][yy-1] = bul[xx][yy+1] = 1;
else bul[xx][yy] = 1;
ls = 1;
} else ls = 0;
for (int i = 1; i <= R; i++) {
for (int j = 1; j <= C; j++) {
if (i != 1) bul[i-1][j] = bul[i][j];
bul[i][j] = 0;
if (bul[i-1][j]) {
if (occ[i-1][j]) {
attack_enemy(occ[i-1][j]);
bul[i-1][j] = 0;
} else if (occ[i][j]) {
attack_enemy(occ[i][j]);
bul[i-1][j] = 0;
}
}
}
}
if (get_gt()) use_gt();
kill_enemy();
show_enemy();
draw();
print();
if (t % (tim>>1) == 0) {
for (int i = R; i >= 1; i--) {
for (int j = 1; j <= C; j++) {
if (i != R) Bul[i+1][j] = Bul[i][j];
Bul[i][j] = 0;
}
}
}
if (t % tim == 0) {
if (gtt) move_gt();
move_enemy();
if (rand() % p1 < q1) {
int type;
switch(rand() % 13) {
case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7: case 8: {
type = 1;
break;
}
case 9: case 10: case 11: {
type = 2;
break;
}
default: {
type = 3;
break;
}
}
create_enemy(1 + rand() % (C - width(type) + 1), type);
}
show_enemy();
if (rand() % p2 < q2) {
int type;
switch(rand() % 13) {
case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7: case 8: {
type = 1;
break;
}
case 9: case 10: case 11: {
type = 2;
break;
}
default: {
type = 3;
break;
}
}
create_enemy(1 + rand() % (C - width(type) + 1), type);
}
}
if (t % (1000 * (difficulty + 2)) == 0) create_gt();
Sleep(10);
}
gtx = gty = gtt = 0;
t2 = t3 = 0;
draw();
if (occ[xx][yy] || Bul[xx][yy]) board[xx][yy] = '+';
for (int i = yy-3; i <= yy+3; i++) if (occ[xx+1][i] || Bul[xx+1][i]) board[xx+1][i] = '+';
for (int i = yy-1; i <= yy+1; i++) if (occ[xx+2][i] || Bul[xx+2][i]) board[xx+2][i] = '+';
print();
Sleep(500);
memset(occ, 0, sizeof(occ));
memset(enemies, 0, sizeof(enemies));
memset(bul, 0, sizeof(bul));
memset(Bul, 0, sizeof(Bul));
cnt = 0;
draw();
print();
}
}
void work(void) {
HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
CONSOLE_CURSOR_INFO CursorInfo;
GetConsoleCursorInfo(handle, &CursorInfo);
CursorInfo.bVisible = false;
SetConsoleCursorInfo(handle, &CursorInfo);
RND();
do {
start();
game();
} while (end());
}
int main() {
work();
}