Untitled

 avatar
unknown
plain_text
6 months ago
5.4 kB
2
Indexable
#include <iostream>
#include <unordered_map>
#include <set>
#include <vector>
#include <string>
#include <algorithm>

#define MAX_N 25

using namespace std;

struct Country {
    string name;
    int numSoldier;
    int group;
    
    Country() : name(""), numSoldier(0), group(0) {}
    Country(string n, int s, int g) : name(n), numSoldier(s), group(g) {}
};

Country map[MAX_N][MAX_N];
unordered_map<string, int> mp;
vector<set<int>> groups;
vector<set<int>> enemy;
int cntGr;
int n;

const int dx[] = {-1, -1, -1, 0, 1, 1, 1, 0};
const int dy[] = {-1, 0, 1, 1, 1, 0, -1, -1};

string charToString(const char* str) {
    string result;
    if (str) {
        for (int i = 0; str[i] != '\0'; i++) {
            result += str[i];
        }
    }
    return result;
}

bool isValidPosition(int x, int y) {
    return x >= 0 && x < n && y >= 0 && y < n;
}

void init(int N, int mSoldier[25][25], char mMonarch[25][25][11]) {
    n = N;
    cntGr = 1;
    mp.clear();
    
    // Resize vectors to prevent out-of-bounds access
    groups.clear();
    enemy.clear();
    groups.resize(N * N + 1);
    enemy.resize(N * N + 1);

    for (int i = 0; i < N; i++) {
        for (int j = 0; j < N; j++) {
            string monarchName = charToString(mMonarch[i][j]);
            
            mp[monarchName] = i * N + j;
            map[i][j] = Country(monarchName, mSoldier[i][j], 0);
        }
    }
}

int ally(char mMonarchA[11], char mMonarchB[11]) {
    string sA = charToString(mMonarchA);
    string sB = charToString(mMonarchB);
    
    if (mp.find(sA) == mp.end() || mp.find(sB) == mp.end()) {
        return -2;  // Invalid monarch names
    }
    
    int posA = mp[sA];
    int posB = mp[sB];
    int rA = posA / n;
    int cA = posA % n;
    int rB = posB / n;
    int cB = posB % n;

    int grA = map[rA][cA].group;
    int grB = map[rB][cB].group;
    
    // Check if monarchs are already enemies
    if (grA > 0 && grB > 0 && !enemy[grA].empty() && 
        enemy[grA].find(grB) != enemy[grA].end()) {
        return -2;
    }

    if (grA == 0 && grB == 0) {
        map[rA][cA].group = cntGr;
        map[rB][cB].group = cntGr;
        groups[cntGr].insert(posA);
        groups[cntGr].insert(posB);
        cntGr++;
        return 1;
    } 
    else if (grA > 0 && grB == 0) {
        groups[grA].insert(posB);
        map[rB][cB].group = grA;
        return 1;
    } 
    else if (grB > 0 && grA == 0) {
        groups[grB].insert(posA);
        map[rA][cA].group = grB;
        return 1;
    } 
    else if (grB == grA) {
        return -1;
    }
    
    return -2;
}

int attack(char mMonarchA[11], char mMonarchB[11], char mGeneral[11]) {
    string sA = charToString(mMonarchA);
    string sB = charToString(mMonarchB);
    string sG = charToString(mGeneral);
    
    if (mp.find(sA) == mp.end() || mp.find(sB) == mp.end()) {
        return -2;
    }
    
    int posA = mp[sA];
    int posB = mp[sB];
    int rA = posA / n;
    int cA = posA % n;
    int rB = posB / n;
    int cB = posB % n;

    if (map[rA][cA].group == map[rB][cB].group && map[rA][cA].group != 0) {
        return -1;
    }

    vector<pair<int, int>> attackers, defenders;
    bool canAttack = false;

    // Find adjacent allies
    for (int k = 0; k < 8; k++) {
        int nx = rB + dx[k];
        int ny = cB + dy[k];
        
        if (isValidPosition(nx, ny)) {
            if (map[nx][ny].group == map[rA][cA].group && map[nx][ny].group != 0) {
                canAttack = true;
                attackers.push_back({nx, ny});
            } 
            else if (map[nx][ny].group == map[rB][cB].group && map[nx][ny].group != 0) {
                defenders.push_back({nx, ny});
            }
        }
    }

    if (!canAttack) return -2;

    // Calculate total forces
    int attackForce = 0;
    int defenseForce = map[rB][cB].numSoldier;
    
    for (const auto& pos : attackers) {
        int& soldiers = map[pos.first][pos.second].numSoldier;
        attackForce += soldiers / 2;
        soldiers -= soldiers / 2;
    }
    
    for (const auto& pos : defenders) {
        int& soldiers = map[pos.first][pos.second].numSoldier;
        defenseForce += soldiers / 2;
        soldiers -= soldiers / 2;
    }

    // Record enemies
    int grA = map[rA][cA].group;
    int grB = map[rB][cB].group;
    if (grA > 0 && grB > 0) {
        enemy[grA].insert(grB);
        enemy[grB].insert(grA);
    }

    // Resolve battle
    if (defenseForce >= attackForce) {
        map[rB][cB].numSoldier = defenseForce - attackForce;
        return 0;
    } else {
        map[rB][cB] = Country(sG, attackForce - defenseForce, grA);
        groups[grA].insert(posB);
        mp[sG] = posB;
        mp.erase(sB);
        return 1;
    }
}

int recruit(char mMonarch[11], int mNum, int mOption) {
    string s = charToString(mMonarch);
    
    if (mp.find(s) == mp.end() || mNum < 0) {
        return 0;
    }
    
    int pos = mp[s];
    int r = pos / n;
    int c = pos % n;
    
    if (mOption == 0) {
        map[r][c].numSoldier += mNum;
        return map[r][c].numSoldier;
    } 
    
    int gr = map[r][c].group;
    if (gr == 0) return 0;
    
    int totalSoldiers = 0;
    for (int pos : groups[gr]) {
        int row = pos / n;
        int col = pos % n;
        map[row][col].numSoldier += mNum;
        totalSoldiers += map[row][col].numSoldier;
    }
    
    return totalSoldiers;
}
Editor is loading...
Leave a Comment