海战棋 V0.1.2

海战棋 V0.1.2!

  • 首先感谢我的同学 qsy 为我提供的游戏,此游戏为 qsy 设计,由我编程。
  • 玩法:两人共同游玩,注意一个人操作时另一个人不能看。

V0.1

V0.1.0 (2023/11/25)

  • 基础代码,仍待完善,可能存在大量的 BUG。
  • 教程还没写,等什么时候有时间了再写。

V0.1.1.3

  • 把忘了写的潜艇写了,改了航母的飞机 BUG。
  • 胜利判定和初始化都补上了。
  • 改了距离的判定,舍弃了 \(\sqrt{dis^2}\le x\) 的判定,而是改用 \(dis^2\le x^2\) 的判定,提高精确度

V0.1.2

  • 加入防空,仅驱逐舰(D)可以防空。

上代码!

#include <bits/stdc++.h>
#include <windows.h>
#define pw2(x) ((x) * (x))
#define KEY_DOWN(VK_NONAME) ((GetAsyncKeyState(VK_NONAME) & 0x8000) ? 1 : 0)
using namespace std;
int retime[] = {0, 0, 2, 1, 2, 3, 1, 3, 1}, reload[] = {0, 0, 1, 2, 2, 1, 1, 1, 1};
int type[] = {0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 6, 8, 7, 7, 7};
int zt[] = {0, 0}, nowt, seed;
int plstk[2][30], stktop[2], plfnum[2], pltnum[2];
int retop[2];
bool isz[] = {0, 0};
bool isup[256];

struct node {
    int whichteam, which;
    node(int t = 0, int w = 0) {
        whichteam = t, which = w;
    }
} mp[45][95];

struct boat {
    int health, pos[2], which, speed;
    int hidedis, attdis, finddis;
    char name[100];
    int retime[10], reload[10];
    int damage[5];
    int num[5];
    int plnum[2];
    bool isattacted[10];

    boat() {
        memcpy(name, "  ", sizeof "  ");
        memset(isattacted, 0, sizeof isattacted);
        health = which = 0;
    }

    void init(int hp, int rel[10], char nm[100], int op[2], int wh, int v, int da[5], int nu[5]) {
        health = hp, which = wh, speed = v;
        memcpy(pos, op, sizeof pos);
        memcpy(reload, rel, sizeof reload);
        memcpy(name, nm, sizeof name);
        memcpy(damage, da, sizeof damage);
        memcpy(num, nu, sizeof num);
    }
    
    void plinit(int pfnum, int ptnum) {
    	plnum[0] = pfnum;
    	plnum[1] = ptnum;
	}

    void disinit(int hd, int ad, int fd) {
        hidedis = hd, attdis = ad, finddis = fd;
    }
} boats[25], theboat[2][100], empty;
// 1-6 boat; 11-16 otherboat; 17-40 plane; 41-64 otherplane

struct point {
    int x, y;
    point(int a = 1, int b = 1) {
        x = a, y = b;
    }
    bool operator <(const point &a)const {
        return y > a.y;
    }
} replstk[2][30];

void color(int a), gto(int x, int y), gto_board(int x, int y);
void start(), choose(int x), put(int x), jiaocheng(), init();
void mpout(int x), move(int x), detection(int x);
void attack(int x), shoot(boat A, boat &B, int num, int x);
void airdef(int x);
int distance(boat a, point b), distance(boat a, boat b);
int choosetheboat(int x), thecolor(int x, int whi), rnd(int x);
int getp(int x, int whi), rgetp(int x, int whi);
bool movetheboat(int x, int whi), findcheck(boat x, boat other);
bool atttheboat(int x, int whi), AattackB(boat &A, boat &B, int x);
bool check_died(int x);
float shootcheck(int a, int b);

void color(int a) {
    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), a);
}

void gto(int x, int y) {
    COORD pos;
    pos.X = y;
    pos.Y = x;
    SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), pos);
}

void gto_board(int x, int y) {
    gto(x * 2 - 1, y * 3 - 2);
}

void init() {
    fill(isup, isup + 255, 1);
    memset(mp, 0, sizeof mp);
    memset(replstk, 0, sizeof replstk);
    for (int i = 0; i <= 1; i++) {
        for (int l = 1; l <= 99; l++) {
            theboat[i][l] = empty;
        }
    }
    zt[0] = zt[1] = 0;
    isz[0] = isz[1] = 0;
    retop[0] = retop[1] = nowt = 0;
    seed = rand();
    stktop[0] = stktop[1] = 0;
    plfnum[0] = plfnum[1] = 0;
    pltnum[0] = pltnum[1] = 0;
    for (int i = 40; i >= 17; i--) {
        plstk[0][++stktop[0]] = i;
        plstk[1][++stktop[1]] = i;
    }
    int rel[10], da[5], op[2] = {1, 1}, nu[5];
    char nm[100];
    memset(rel, 0, sizeof rel);
    memset(da, 0, sizeof da);
    memset(nm, 0, sizeof nm);
    memset(nu, 0, sizeof nu);
    da[1] = 200, nu[1] = 3;
    memcpy(nm, "DA", sizeof "DA");
    boats[1].init(2000, rel, nm, op, 1, 20, da, nu);
    boats[1].disinit(2, 2, 5);
    da[1] = 300, nu[1] = 4;
    memcpy(nm, "DB", sizeof "DB");
    boats[2].init(2500, rel, nm, op, 2, 15, da, nu);
    boats[2].disinit(2, 2, 5);
    da[1] = 200, nu[1] = 4;
    memcpy(nm, "DC", sizeof "DC");
    boats[3].init(3000, rel, nm, op, 3, 15, da, nu);
    boats[3].disinit(2, 2, 5);
    da[1] = 100, nu[1] = 5;
    memcpy(nm, "DD", sizeof "DD");
    boats[4].init(2500, rel, nm, op, 4, 15, da, nu);
    boats[4].disinit(2, 2, 5);
    da[1] = 333, nu[1] = 3;
    memcpy(nm, "XA", sizeof "XA");
    boats[5].init(4000, rel, nm, op, 5, 15, da, nu);
    boats[5].disinit(2, 3, 4);
    da[1] = 400, nu[1] = 4;
    memcpy(nm, "XB", sizeof "XB");
    boats[6].init(5500, rel, nm, op, 6, 10, da, nu);
    boats[6].disinit(2, 3, 4);
    da[1] = 767, nu[1] = 3;
    memcpy(nm, "XC", sizeof "XC");
    boats[7].init(5000, rel, nm, op, 7, 10, da, nu);
    boats[7].disinit(2, 3, 4);
    da[1] = 750, nu[1] = 2;
    memcpy(nm, "XD", sizeof "XD");
    boats[8].init(6000, rel, nm, op, 8, 10, da, nu);
    boats[8].disinit(2, 3, 4);
    da[1] = 750, nu[1] = 4;
    memcpy(nm, "BA", sizeof "BA");
    boats[9].init(8000, rel, nm, op, 9, 6, da, nu);
    boats[9].disinit(4, 6, 2);
    da[1] = 1000, nu[1] = 2;
    memcpy(nm, "BB", sizeof "BB");
    boats[10].init(10000, rel, nm, op, 10, 6, da, nu);
    boats[10].disinit(4, 6, 2);
    da[1] = 1133, nu[1] = 3;
    memcpy(nm, "BC", sizeof "BC");
    boats[11].init(14000, rel, nm, op, 11, 6, da, nu);
    boats[11].disinit(4, 6, 2);
    da[1] = 1333, nu[1] = 3;
    memcpy(nm, "BD", sizeof "BD");
    boats[12].init(12000, rel, nm, op, 12, 6, da, nu);
    boats[12].disinit(4, 6, 2);
    da[1] = 0;
    nu[1] = 2, nu[2] = 2;
    memcpy(nm, "CA", sizeof "CA");
    boats[13].init(10500, rel, nm, op, 13, 8, da, nu);
    boats[13].disinit(4, -1, 3);
    boats[13].plinit(2, 2);
    nu[1] = 3, nu[2] = 1;
    memcpy(nm, "CB", sizeof "CB");
    boats[14].init(12000, rel, nm, op, 14, 8, da, nu);
    boats[14].disinit(4, -1, 3);
    boats[14].plinit(3, 1);
    nu[1] = 3, nu[2] = 0;
    memcpy(nm, "CF", sizeof "CF");
    boats[15].init(13000, rel, nm, op, 15, 8, da, nu);
    boats[15].disinit(4, -1, 3);
    boats[15].plinit(3, 0);
    nu[1] = 3;
    memcpy(nm, "CT", sizeof "CT");
    boats[16].init(14000, rel, nm, op, 16, 8, da, nu);
    boats[16].disinit(4, -1, 3);
    boats[16].plinit(0, 3);
    da[1] = 500;
    nu[1] = 4;
    memcpy(nm, "SA", sizeof "SA");
    boats[17].init(1500, rel, nm, op, 17, 5, da, nu);
    boats[17].disinit(2, -1, 2);
    nu[1] = 3;
    memcpy(nm, "SB", sizeof "SB");
    boats[18].init(2000, rel, nm, op, 18, 5, da, nu);
    boats[18].disinit(2, -1, 2);
    nu[1] = 2;
    memcpy(nm, "SC", sizeof "SC");
    boats[19].init(3000, rel, nm, op, 19, 5, da, nu);
    boats[19].disinit(2, -1, 2);
    nu[1] = 1, da[1] = 800;
    memcpy(nm, "PF", sizeof "PF");
    boats[20].init(1, rel, nm, op, 20, 20, da, nu);
    boats[20].disinit(0, 3, 5);
    nu[1] = 1, da[1] = 1200;
    memcpy(nm, "PT", sizeof "PT");
    boats[21].init(1, rel, nm, op, 21, 20, da, nu);
    boats[21].disinit(0, 5, 3);
    da[1] = 500;
    nu[1] = 4;
    memcpy(nm, "HA", sizeof "HA");
    boats[22].init(1500, rel, nm, op, 22, 3, da, nu);
    boats[22].disinit(2, 4, 5);
    nu[1] = 3;
    memcpy(nm, "HB", sizeof "HB");
    boats[23].init(2000, rel, nm, op, 23, 3, da, nu);
    boats[23].disinit(2, 4, 5);
    nu[1] = 2;
    memcpy(nm, "HC", sizeof "HC");
    boats[24].init(3000, rel, nm, op, 24, 3, da, nu);
    boats[24].disinit(2, 4, 5);
}

void jiaocheng() {
    system("cls");
}

int choosetheboat(int x) {
    int isk = 1, lst = 1, page = 1, lstpage = 1;
A:
    system("cls");
    printf("第 %d 艘船:\n", x);
    int now;
    if (page == 3 && isk >= 6) {
        isk = lst = 1;
    }
    for (int i = 1; i <= 7; i++) {
        if (page == 3 && i >= 6) break;
        if (i == isk) color(13);
        gto(i * 2, 0);
        now = (page - 1) * 7 + i;
        printf("%s  HP:%d  WeaponNum:%d  HurtPerWea:%d",
            boats[now].name, boats[now].health, boats[now].num[1], boats[now].damage[1]);
        if (boats[now].num[2]) {
            gto(i * 2 + 1, 14);
            printf("WeaponNum:%d  HurtPerWea:%d", boats[now].num[2], boats[now].damage[2]);
        }
        if (i == isk) color(7);
    }
    color(7);
    gto(29, 39);
    while (1) {
        Sleep(30);
        if (!KEY_DOWN(40)) isup[40] = 1;
        if (!KEY_DOWN(38)) isup[38] = 1;
        if (!KEY_DOWN(37)) isup[37] = 1;
        if (!KEY_DOWN(39)) isup[39] = 1;
        if (!KEY_DOWN(27)) isup[27] = 1;
        if (isup[40] && KEY_DOWN(40)) isup[40] = 0, isk = min(7, isk + 1), Sleep(30);
        if (isup[38] && KEY_DOWN(38)) isup[38] = 0, isk = max(1, isk - 1), Sleep(30);
        if (isup[39] && KEY_DOWN(39)) isup[39] = 0, page = min(3, page + 1), Sleep(30);
        if (isup[37] && KEY_DOWN(37)) isup[37] = 0, page = max(1, page - 1), Sleep(30);
        if (isk != lst || page != lstpage) {
            lst = isk;
            lstpage = page;
            goto A;
        }
        if (KEY_DOWN(13)) {
            return (page - 1) * 7 + isk;
        }
    }
}

void choose(int x) {
    system("mode con cols=50 lines=30");
    system("cls");
    if (x) printf("蓝");
    else printf("红");
    printf("方从船坞中选择船只:\n");
    Sleep(1000);
    for (int i = 1; i <= 6; i++) {
        int h = choosetheboat(i);
        theboat[x][i] = boats[h];
        system("cls");
        printf("第 %d 艘船:%s\n", i, boats[h].name);
        plfnum[x] += boats[h].plnum[0];
        pltnum[x] += boats[h].plnum[1];
        Sleep(1000);
    }
}

void put(int x) {
    system("mode con cols=185 lines=50");
    system("cls");
    if (x == 0) printf("红方进行放置");
    else printf("蓝方进行放置");
    Sleep(1000);
    if (x == 1) {
        x = 1;
    }
    system("cls");
    int sx = 1, sy = 1, op[2];
    if (x == 1) sy = 80;
    boat now;
    for (int i = 1; i <= 6; i++) {
        gto(45, 20);
        now = theboat[x][i];
        printf("%s  HP:%d  WeaponNum:%d  HurtPerWea:%d    ",
            now.name, now.health, now.num[1], now.damage[1]);
        if (now.num[2]) {
            gto(47, 34);
            printf("WeaponNum:%d  HurtPerWea:%d    ", now.num[2], now.damage[2]);
        } else {
            gto(47, 34), printf("                             ");
        }
        while (1) {
            int nowwh = theboat[x][mp[sx][sy].which].which;
            if (KEY_DOWN(37) && (x == 0 ? sy > 1 : sy > 80)) {
                gto(sx, sy * 2), printf("%s", boats[nowwh].name), sy--;
                gto(sx, sy * 2), color(13), printf("%s", now.name), color(7);
            }
            if (KEY_DOWN(38) && sx > 1) {
                gto(sx, sy * 2), printf("%s", boats[nowwh].name), sx--;
                gto(sx, sy * 2), color(13), printf("%s", now.name), color(7);
            }
            if (KEY_DOWN(39) && (x == 0 ? sy < 10 : sy < 90)) {
                gto(sx, sy * 2), printf("%s", boats[nowwh].name), sy++;
                gto(sx, sy * 2), color(13), printf("%s", now.name), color(7);
            }
            if (KEY_DOWN(40) && sx < 40) {
                gto(sx, sy * 2), printf("%s", boats[nowwh].name), sx++;
                gto(sx, sy * 2), color(13), printf("%s", now.name), color(7);
            }
            if (KEY_DOWN(13) && mp[sx][sy].which == 0) {
                mp[sx][sy] = {x, i};
                op[0] = sx;
                op[1] = sy;
                memcpy(theboat[x][i].pos, op, sizeof op);
                break;
            }
            Sleep(50);
        }
        Sleep(1000);
    }
}

void mpout(int x) {
    system("cls");
    int thec;
    for (int i = 1; i <= 64; i++) {
        thec = thecolor(x, i);
        boat now = theboat[x][i];
        if (now.health <= 0) continue;
        color(thec), gto(now.pos[0], now.pos[1] * 2);
        printf("%s", now.name), color(7);
    }
}

int distance(boat a, boat b) {
    return pw2(a.pos[0] - b.pos[0]) + pw2(a.pos[1] - b.pos[1]);
}

int distance(boat a, point b) {
    return pw2(a.pos[0] - b.x) + pw2(a.pos[1] - b.y);
}

int thecolor(int x, int whi) {
    if ((7 <= whi && whi <= 16) || whi >= 41) return 7;
    bool flag1, flag2;
    flag1 = flag2 = 1;
    boat now = theboat[x][whi];
    for (int k = 1; k <= now.num[1]; k++) {
        if (now.reload[k] || now.isattacted[k]) flag1 = 0;
        else flag2 = 0;
    }
    for (int k = 1; k <= now.num[2]; k++) {
        if (now.reload[now.num[1] + k] || now.isattacted[now.num[1] + k]) flag1 = 0;
        else flag2 = 0;
    }
    if (flag1) return 10;
    else if (flag2) return 12;
    else return 6;
}

bool movetheboat(int x, int whi) {
    boat now = theboat[x][whi];
    int rx = now.pos[0], ry = now.pos[1], rc = thecolor(x, whi);
    int sx = rx, sy = ry, dis = now.speed, nowwh, thec;
    if (isz[x]) {
    	if (now.which == 21 || now.which == 20) dis = 1.5 * dis;
    	else dis = 0.7 * dis;
	}
    while (1) {
        Sleep(30);
        if (!KEY_DOWN(13)) isup[13] = 1;
        nowwh = 0;
        for (int i = 1; i <= 70; i++) {
            if (theboat[x][i].pos[0] == sx && theboat[x][i].pos[1] == sy) {
                nowwh = i;
            }
        }
        if (nowwh) thec = thecolor(x, nowwh);
        else thec = 7;
        if (KEY_DOWN(37) && sy > 1 && distance(now, (point){sx, sy - 1}) <= pw2(dis)) {
            color(thec);
            gto(sx, sy * 2), printf("%s", theboat[x][nowwh].name);
            sy--, color(rc);
            gto(sx, sy * 2), printf("%s", now.name), color(7);
        }
        if (KEY_DOWN(38) && sx > 1 && distance(now, (point){sx - 1, sy}) <= pw2(dis)) {
            color(thec);
            gto(sx, sy * 2), printf("%s", theboat[x][nowwh].name);
            sx--, color(rc);
            gto(sx, sy * 2), printf("%s", now.name), color(7);
        }
        if (KEY_DOWN(39) && sy < 90 && distance(now, (point){sx, sy + 1}) <= pw2(dis)) {
            color(thec);
            gto(sx, sy * 2), printf("%s", theboat[x][nowwh].name);
            sy++, color(rc);
            gto(sx, sy * 2), printf("%s", now.name), color(7);
        }
        if (KEY_DOWN(40) && sx < 40 && distance(now, (point){sx + 1, sy}) <= pw2(dis)) {
            color(thec);
            gto(sx, sy * 2), printf("%s", theboat[x][nowwh].name);
            sx++, color(rc);
            gto(sx, sy * 2), printf("%s", now.name), color(7);
        }
        if (KEY_DOWN(13) && isup[13] == 1 && (!mp[sx][sy].which || (sx == rx && sy == ry))) {
            isup[13] = 0;
            theboat[x][whi].pos[0] = sx;
            theboat[x][whi].pos[1] = sy;
            mp[rx][ry] = {0, 0};
            mp[sx][sy] = {x, whi};
            return (sx != rx || sy != ry);
        }
    }
}

int getp(int x, int whi) {
	for (int i = 1; i <= 6; i++) {
		boat now = theboat[x][i];
		if (now.health <= 0) continue;
		if (now.plnum[whi]) return i;
	}
	return 0;
}

int rgetp(int x, int whi) {
	for (int i = 1; i <= 6; i++) {
		boat now = theboat[x][i];
		if (now.health <= 0) continue;
		if (now.plnum[whi] < boats[now.which].plnum[whi]) return i;
	}
	return 0;
}

void move(int x) {
    system("cls");
    if (x) printf("蓝方");
    else printf("红方");
    if (isz[x]) {
        printf("是否保持战备状态?(Y/N)");
        Sleep(50);
    } else {
        printf("是否进入战备状态?(Y/N)");
    }
    while (1) {
        Sleep(30);
        if (KEY_DOWN('Y')) {
            if (!isz[x]) {
                isz[x] = 1;
                zt[x] = nowt;
            }
            break;
        } else if (KEY_DOWN('N')) {
            if (isz[x]) {
                isz[x] = 0;
                zt[x] = nowt;
            }
            break;
        }
    }
    bool ismoved[100], isud[100];
    memset(ismoved, 0, sizeof ismoved);
    memset(isud, 0, sizeof isud);
    system("cls");
    if (x == 0) printf("红方移动");
    else printf("蓝方移动");
    Sleep(1000);
    int isk;
    for (int i = 1; i <= 6; i++) {
        if (theboat[x][i].health > 0) {
            isk = i;
            break;
        }
    }
A:
    mpout(x);
    boat now = theboat[x][isk];
    gto(45, 5), printf("PLF: %d", plfnum[x]);
    gto(46, 5), printf("PLT: %d", pltnum[x]);
    gto(now.pos[0], now.pos[1] * 2), color(13), printf("%s", now.name), color(7);
    gto(45, 20);
    printf("%s  HP:%d  WeaponNum:%d  HurtPerWea:%d",
        now.name, now.health, now.num[1], now.damage[1]);
    if (now.num[2]) {
        gto(47, 34);
        printf("WeaponNum:%d  HurtPerWea:%d", now.num[2], now.damage[2]);
    }
    while (1) {
        Sleep(30);
        if (!KEY_DOWN(9)) isup[9] = 1;
        if (!KEY_DOWN(32)) isup[32] = 1;
        if (!KEY_DOWN(13)) isup[13] = 1;
        if (KEY_DOWN(9) && isup[9] == 1) {
            isup[9] = 0;
            do {
                isk++;
                if (isk > 6 && isk < 17) isk = 17;
                if (isk > 40) isk = 1;
            } while (theboat[x][isk].health <= 0);
            goto A;
        }
        if (KEY_DOWN(32) && isup[32] == 1 && !ismoved[isk]) {
            isup[32] = 0;
            ismoved[isk] = movetheboat(x, isk);
            goto A;
        }
        if (KEY_DOWN('F') && plfnum[x] > 0) {
        	int a = getp(x, 0);
            theboat[x][plstk[x][stktop[x]]] = boats[20];
            memcpy(theboat[x][plstk[x][stktop[x]]].pos, theboat[x][a].pos, sizeof theboat[x][a].pos);
            theboat[x][a].plnum[0]--;
            isk = plstk[x][stktop[x]];
            stktop[x]--;
            plfnum[x]--;
            ismoved[isk] = movetheboat(x, isk);
            goto A;
        }
        if (KEY_DOWN('T') && pltnum[x] > 0) {
        	int a = getp(x, 1);
            theboat[x][plstk[x][stktop[x]]] = boats[21];
            memcpy(theboat[x][plstk[x][stktop[x]]].pos, theboat[x][a].pos, sizeof theboat[x][a].pos);
            theboat[x][a].plnum[1]--;
            isk = plstk[x][stktop[x]];
            stktop[x]--;
            pltnum[x]--;
            ismoved[isk] = movetheboat(x, isk);
            goto A;
        }
        if (KEY_DOWN('W') && type[theboat[x][isk].which] == 7 && !isud[isk]) {
            isud[isk] = 1;
            boat newboat = theboat[x][isk];
            newboat.which -= 5;
            newboat.speed = 5;
            newboat.disinit(2, -1, 2);
            newboat.reload[5] = newboat.retime[5] * 2 / 3 + 1;
            newboat.retime[5] = 0;
            newboat.name[0] = 'S';
            theboat[x][isk] = newboat;
            goto A;
        }
        if (KEY_DOWN('S') && type[theboat[x][isk].which] == 5 && !isud[isk]) {
        	isud[isk] = 0;
            if (theboat[x][isk].reload[5]) continue;
            isud[isk] = 1;
            boat newboat = theboat[x][isk];
            newboat.which += 5;
            newboat.speed = 3;
            newboat.disinit(2, 4, 5);
            newboat.retime[5] = 0;
            newboat.name[0] = 'H';
            theboat[x][isk] = newboat;
            goto A;
        }
        if (KEY_DOWN(13) && isup[13] == 1) {
            isup[13] = 0;
            break;
        }
    }
}

int rnd(int x) {
    int a = rand() % 1145 + 1;
    x *= a;
    x ^= x << 13;
    x ^= x >> 7;
    x ^= x << 17;
    x /= a;
    return x;
}

bool findcheck(boat x, boat other) {
    if (distance(x, other) > pw2(x.finddis + other.hidedis)) return 0;
    int ty = type[x.which];
    int a = seed = rnd(seed) % 100 + 1;
    if (ty == 1 && a <= 70) return 1;
    if (ty == 2 && a <= 60) return 1;
    if (ty == 3 && a <= 30) return 1;
    if (ty == 4 && a <= 50) return 1;
    if (ty == 5 && a <= 10) return 1;
    if ((ty == 6 || ty == 8) && a <= 90 && type[other.which] != 7) return 1;
    if (ty == 7) return 1;
    return 0;
}

void detection(int x) {
    for (int i = 11; i <= 16; i++) {
        theboat[x][i] = empty;
    }
    for (int i = 41; i <= 64; i++) {
        theboat[x][i] = empty;
    }
    boat now, other;
    int pltop = 41, bttop = 11;
    bool isfind[100];
    memset(isfind, 0, sizeof isfind);
    for (int i = 1; i <= 40; i++) {
        if (i == 7) i = 17;
        now = theboat[x][i];
        if (now.health <= 0) continue;
        for (int l = 1; l <= 6; l++) {
            other = theboat[x ^ 1][l];
            if (other.health <= 0 || isfind[l]) continue;
            if (findcheck(now, other)) {
            	isfind[l] = 1;
                theboat[x][bttop] = other;
                bttop++;
            }
        }
        for (int l = 17; l <= 40; l++) {
            other = theboat[x ^ 1][l];
            if (other.health <= 0 || isfind[l]) continue;
            if (findcheck(now, other)) {
            	isfind[l] = 1;
                theboat[x][pltop] = other;
                pltop++;
            }
        }
    }
}

float shootcheck(int a, int b) {
    int x = seed = rnd(seed);
    if (a == 3) {
        if (b == 1 || b == 2 || b == 5) {
            if (x <= 50) return 0;
            else return 0.4;
        } else if (b == 3 || b == 4) {
            if (x <= 10) return 0;
            if (x <= 20) return 0.2;
            if (x <= 80) return 0.5;
            if (x <= 90) return 1;
            return 0.4;
        }
    } else if (a == 1) {
        if (b == 2 || b == 3 || b == 4) {
            if (x <= 10) return 0;
            if (x <= 30) return 0.1;
            if (x <= 50) return 0.2;
            if (x <= 90) return 0.5;
            return 1;
        } else if (b == 1 || b == 5) {
            if (x <= 40) return 0;
            if (x <= 90) return 0.5;
            return 0.4;
        }
    } else if (a == 2) {
        if (b == 1 || b == 5) {
            if (x <= 10) return 0;
            if (x <= 20) return 0.2;
            if (x <= 70) return 0.5;
            if (x <= 90) return 1;
            return 0.4;
        } else if (b == 2 || b == 3 || b == 4) {
            if (x <= 20) return 0.1;
            if (x <= 40) return 0.2;
            if (x <= 80) return 0.5;
            if (x <= 90) return 1;
            return 0.4;
        }
    } else if (a == 6) return 1;
    else if (a == 7 || a == 8) {
        if (x <= 80) return 1;
        return 1.5;
    }
    return 0;
}

void shoot(boat A, boat &B, int num, int x) {
    int daofone = A.damage[1];
    int tya = type[A.which], tyb = type[B.which];
    for (int i = 1; i <= num; i++) {
        B.health -= shootcheck(tya, tyb) * daofone;
    }
    if (B.health <= 0 && type[B.which] == 4) {
        if (B.which == 13) {
            plfnum[x] -= 2;
            pltnum[x] -= 2;
        } else if (B.which == 14) {
            plfnum[x] -= 3;
            pltnum[x] -= 1;
        } else if (B.which == 15) {
            plfnum[x] -= 3;
        } else {
            pltnum[x] -= 3;
        }
    }
}

bool AattackB(boat &A, boat &B, int x) {
    int num, cnt, lst;
    num = cnt = A.num[1];
    for (int i = 1; i <= num; i++) {
        if (A.reload[i] || A.isattacted[i]) cnt--;
    }
    num = cnt, lst = cnt = 1;
G:
    gto(45, 70), printf("发射数量:%d ", cnt);
    while (1) {
        Sleep(30);
        if (!KEY_DOWN(38)) isup[38] = 1;
        if (!KEY_DOWN(40)) isup[40] = 1;
        if (!KEY_DOWN(27)) isup[27] = 1;
        if (KEY_DOWN(40) && isup[40]) {
            isup[40] = 0;
            cnt = min(num, cnt + 1);
        }
        if (KEY_DOWN(38) && isup[38]) {
            isup[38] = 0;
            cnt = max(1, cnt - 1);
        }
        if (cnt != lst) {
            lst = cnt;
            goto G;
        }
        if (KEY_DOWN(13) && isup[13]) {
            isup[13] = 0;
            shoot(A, B, cnt, x ^ 1);
            for (int i = 1; i <= A.num[1]; i++) {
                if (!A.reload[i] && !A.isattacted[i]) {
                    A.retime[i]++;
                    A.isattacted[i] = 1;
                }
                if (A.retime[i] >= retime[type[A.which]]) {
                    A.retime[i] = 0;
                    A.reload[i] = reload[type[A.which]] + 1;
                }
            }
            return 1;
        }
        if (KEY_DOWN(27) && isup[27]) {
            isup[27] = 0;
            return 0;
        }
    }
}

bool atttheboat(int x, int whi) {
    boat &now = theboat[x][whi];
    if (thecolor(x, whi) == 12) return 0;
    bool res = 0;
    point btk[10];
    int bttop, isk = 1, sx, sy;
A:
    gto(45, 70);
    printf("                      ");
    bttop = 0;
    for (int i = 11; i <= 16; i++) {
        if (theboat[x][i].health <= 0) continue;
        if (distance(theboat[x][i], now) <= pw2(now.attdis)) {
            btk[++bttop] = {theboat[x][i].pos[0], theboat[x][i].pos[1]};
        }
    }
    if (bttop == 0) return res;
    if (isk > bttop) isk = 1;
    sx = btk[isk].x, sy = btk[isk].y;
    boat &other = theboat[x ^ 1][mp[sx][sy].which];
    gto(other.pos[0], other.pos[1] * 2);
    color(12), printf("%s", other.name), color(7);
    while (1) {
        Sleep(30);
        if (!KEY_DOWN(9)) isup[9] = 1;
        if (!KEY_DOWN(32)) isup[32] = 1;
        if (!KEY_DOWN(13)) isup[13] = 1;
        if (KEY_DOWN(9) && isup[9]) {
            isup[9] = 0;
            gto(other.pos[0], other.pos[1] * 2);
            printf("%s", other.name);
            isk++;
            if (isk > bttop) isk = 1;
            goto A;
        }
        if (KEY_DOWN(32) && isup[32] && thecolor(x, whi) != 12) {
            isup[32] = 0;
            if (type[now.which] != 7 && type[other.which] == 7) continue;
            res = AattackB(now, other, x);
            gto(other.pos[0], other.pos[1] * 2);
            printf("%s", other.name);
            goto A;
        }
        if (KEY_DOWN(13) && isup[13]) {
            isup[13] = 0;
            break;
        }
    }
    return res;
}

void attack(int x) {
    system("cls");
    if (x == 0) printf("红方攻击");
    else printf("蓝方攻击");
    Sleep(1000);
    int isk;
    for (int i = 1; i <= 6; i++) {
        if (theboat[x][i].health > 0) {
            isk = i;
            break;
        }
    }
    bool flag = 1;
A:
    mpout(x);
    boat now = theboat[x][isk];
    gto(now.pos[0], now.pos[1] * 2), color(13), printf("%s", now.name), color(7);
    gto(45, 20);
    printf("%s  HP:%d  WeaponNum:%d  HurtPerWea:%d",
        now.name, now.health, now.num[1], now.damage[1]);
    if (now.num[2]) {
        gto(47, 34);
        printf("WeaponNum:%d  HurtPerWea:%d", now.num[2], now.damage[2]);
    }
    while (1) {
        Sleep(30);
        if (!KEY_DOWN(9)) isup[9] = 1;
        if (!KEY_DOWN(32)) isup[32] = 1;
        if (!KEY_DOWN(13)) isup[13] = 1;
        if (KEY_DOWN(9) && isup[9] == 1) {
            isup[9] = 0;
            do {
                isk++;
                if (isk > 6 && isk < 17) isk = 17;
                if (isk > 40) isk = 1;
            } while (theboat[x][isk].health <= 0);
            goto A;
        }
        if (KEY_DOWN(32) && isup[32] == 1 && type[now.which] != 4 && type[now.which] != 5) {
            isup[32] = 0;
            if (atttheboat(x, isk)) {
                flag = 0;
            }
            goto A;
        }
        if (KEY_DOWN(13) && isup[13] == 1) {
            isup[13] = 0;
            break;
        }
        if (KEY_DOWN(27) && flag) {
            move(x);
            break;
        }
    }
}

void load(int x) {
    for (int i = 1; i <= 6; i++) {
        boat &now = theboat[x][i];
        if (now.health <= 0) continue;
        for (int l = 1; l <= now.num[1]; l++) {
            now.reload[l] = max(0, now.reload[l] - 1);
        }
        if (type[now.which] == 7) {
            now.retime[5]++;
            if (now.retime[5] == 3) {
                now.retime[5] = 0;
                boat newboat = now;
                newboat.which -= 5;
                newboat.speed = 5;
                newboat.disinit(2, -1, 2);
                newboat.reload[5] = 3;
                newboat.retime[5] = 0;
                newboat.name[0] = 'S';
                now = newboat;
            }
        }
        if (type[now.which] == 5) now.reload[5]--;
    }
    for (int i = 17; i <= 40; i++) {
        boat &now = theboat[x][i];
        if (now.health <= 0) continue;
        if (now.reload[1] || now.retime[2]) {
            replstk[x][++retop[x]] = {(type[now.which] == 6 ? 0 : 1), now.retime[2] + 2};
            plstk[x][++stktop[x]] = i;
            theboat[x][i] = empty;
        } else {
            now.retime[2]++;
        }
    }
    sort(replstk[x] + 1, replstk[x] + retop[x] + 1);
    for (int i = 1; i <= retop[x]; i++) {
        replstk[x][i].y--;
    }
    while (retop[x] && replstk[x][retop[x]].y == 0) {
    	int whi = replstk[x][retop[x]].x;
    	int a = rgetp(x, whi);
    	theboat[x][a].plnum[whi]++;
        if (whi == 0) plfnum[x]++;
        else pltnum[x]++;
        retop[x]--;
    }
}

bool check_died(int x) {
    bool flag = 0;
    for (int i = 1; i <= 6; i++) {
        if (theboat[x][i].health > 0) {
            flag = 1;
            break;
        }
    }
    return !flag;
}

void airdef(int x) {
	for (int i = 1; i <= 6; i++) {
		boat now = theboat[x][i];
		if (now.health <= 0) continue;
		if (type[now.which] != 1) continue;
		for (int l = 17; l <= 40; l++) {
			boat &otpl = theboat[x ^ 1][l];
			if (otpl.health <= 0) continue;
			if (distance(now, otpl) > pw2(3)) continue;
			int a = seed = rnd(seed);
			a %= 100;
			if (a <= (isz[x] ? 50 : 30)) otpl = empty;
		}
	}
}

void game() {
    choose(0), choose(1), put(0), put(1);
    bool flag = 0;
    while (1) {
        nowt++;
        move(0), move(1);
        airdef(0), airdef(1);
        detection(0), detection(1);
        if (isz[0] && !isz[1]) {
            attack(0);
            if (check_died(1)) {
            	flag = 0;
                break;
            }
            attack(1);
            if (check_died(0)) {
            	flag = 1;
                break;
            }
        } else if (isz[1] && isz[0]) {
            attack(1);
            if (check_died(0)) {
            	flag = 1;
                break;
            }
            attack(0);
            if (check_died(1)) {
            	flag = 0;
                break;
            }
        } else if (isz[0] && isz[1]) {
            if (zt[0] < zt[1]) {
                attack(0);
                if (check_died(1)) {
                	flag = 0;
                    break;
                }
                attack(1);
                if (check_died(0)) {
                	flag = 1;
                    break;
                }
            } else {
                attack(1);
                if (check_died(0)) {
                	flag = 1;
                    break;
                }
                attack(0);
                if (check_died(1)) {
                	flag = 0;
                    break;
                }
            }
        } else {
            if (zt[0] < zt[1]) {
                attack(1);
                if (check_died(0)) {
                	flag = 1;
                    break;
                }
                attack(0);
                if (check_died(1)) {
                	flag = 0;
                    break;
                }
            } else {
                attack(0);
                if (check_died(1)) {
                	flag = 0;
                    break;
                }
                attack(1);
                if (check_died(0)) {
                	flag = 1;
                    break;
                }
            }
        }
        load(0), load(1);
    }
    system("cls");
    gto(25, 50);
    if (flag) printf("蓝");
    else printf("红");
    printf("方胜利!!!");
    system("pause");
}

void start() {
A:
    init();
    system("cls");
    system("mode con cols=40 lines=30");
    int isk = 1, lst = 0;
    gto(7, 10), printf("海战棋      v0.1.2");
B:
    gto(13, 25), printf("开始教程!");
    gto(15, 25), printf("新游戏!");
    color(13);
    if (isk == 1) {
        gto(13, 25), printf("开始教程!");
    } else if (isk == 2) {
        gto(15, 25), printf("新游戏!");
    }
    color(7);
    gto(29, 39);
    while (1) {
        Sleep(30);
        if (!KEY_DOWN(40)) isup[40] = 1;
        if (!KEY_DOWN(38)) isup[38] = 1;
        if (!KEY_DOWN(27)) isup[27] = 1;
        if (isup[40] && KEY_DOWN(40)) isup[40] = 0, isk = min(2, isk + 1), Sleep(30);
        if (isup[38] && KEY_DOWN(38)) isup[38] = 0, isk = max(1, isk - 1), Sleep(30);
        if (isk != lst) {
            lst = isk;
            goto B;
        }
        if (KEY_DOWN(13)) {
            if (isk == 1) {
                jiaocheng();
                goto A;
            } else {
                game();
                goto A;
            }
        }
        if (isup[27] && KEY_DOWN(27)) {
            isup[27] = 0;
            break;
        }
    }
    return ;
}

int main() {
    srand((unsigned)time(0));
    seed = rand();
    start();
    return 0;
}
posted @ 2024-02-27 19:40  wswwhcs  阅读(9)  评论(0编辑  收藏  举报