Untitled

mail@pastecode.io avatar
unknown
plain_text
7 months ago
15 kB
2
Indexable
Never
#include <iostream>
#include <vector>
#include <cmath>
#include <string> 
#include <cstdlib> 
using namespace std;

class Map;
class Team;
class character {
protected:
    //名字、血量、攻擊、防禦、速度
    char symbol;
    string name;
    int origin_healthPoints;
    int current_healthPoints;
    //int healthPoints;
    int attackPoints;
    int defensePoints;
    int speedPoints;
    int x;  // 角色在方格地圖上的x、y座標 
    int y;
    vector<size_t> canAttackIndex;


public:
    //Constructor
    character() : symbol('N'), name("None"), origin_healthPoints(0),current_healthPoints(0), attackPoints(0), defensePoints(0), speedPoints(0), x(0), y(0) {}
    character(const char charSymbol, const string& charName, int origin_HP, int current_HP, int charAttack,int charDefense, int charSpeed, int x, int y) : symbol(charSymbol), name(charName), origin_healthPoints(origin_HP),current_healthPoints(current_HP),attackPoints(charAttack), defensePoints(charDefense), speedPoints(charSpeed), x(x), y(y) {}

    //取得基本資料函數
    char getSymbol() const { return symbol; }
    string getName() const { return name; }
    int get_current_HP() const { return current_healthPoints; }
    int get_origin_HP() const { return origin_healthPoints; }
    //int getHealthPoints() const { return healthPoints; }
    int getAttackPoints() const { return attackPoints; }
    int getDefensePoints() const { return defensePoints; }
    int getSpeedPoints() const { return speedPoints; }
    int getX() const { return x; }
    int getY() const { return y; }

    // 顯示基本資料
    void displayInfo(const vector<character*>& team, int index);
    // 傷害
    void takeDamage(Map& chessBoard, int damage, int index, Team& temp);
    // 攻擊
    void attack(int index, Team& temp, Map& chessBoard);
    // 移動角色
    void move(Map& chessBoard, Team& otherTeam);
    // 確認是否在攻擊範圍內
    bool checkDistance(character& character) const;
    // 待修
    void heal(int amount);
    // 發送可供attack的對象的prompt
    void chooseToAttack(const vector<character*>& team); 
//   void checkObstacle(vector<obstacle>& allObstacles);
};

class Map {
private:
    int rows;   // 地圖的行數
    int cols;   // 地圖的列數
    vector<vector<char> > map;  // 地圖的表示

public:
    Map() {}
    Map(int rows, int cols)
        : rows(rows), cols(cols), map(rows, vector<char>(cols, '.')) {}

    void draw() const;
    void cleanCharacter(character& character);
    void placeCharacter(const character* character);
    
    bool isCellOccupied(int x, int y) const {

        return (map[x][y] != '.');
    }
};


class Wizard : public character {
private:

public:
    Wizard(int x, int y): character('W', "Wizard", 80, 80, 25, 5, 8, x, y) {}

};

class Knight : public character {
private:

public:
    Knight(int x, int y): character('K', "Knight", 100, 100, 15, 3, 5, x, y){}
};

class Archer : public character {
private:

public:
	Archer(int x, int y): character('A', "Archer", 50,50, 40, 1, 7, x, y){}
};

class Tank : public character {
private:

public:
	Tank(int x, int y): character('T', "Tank", 300 ,300, 5, 10, 10, x, y){}
};

class obstacle{
	private:
		char symbol;
		string name;
		int x;
		int y;
	public:
		obstacle(const char symbol ,const string& name, int X , int Y) :  symbol(symbol), name(name), x(X), y(Y) {}; 
		char getSymbol() const { return symbol; }
		int getX() const {return x; }
		int getY() const {return y; }
//		void applyEffect(character& someone);
};

class Team{
private:
    vector<character*> members;
    bool teamMark;
public:
    Team(){
        teamMark = false;
    };
    ~Team(){

        for (character* member : members) {
            delete member;
        }

    }
    // 獲得隊伍的大小
    size_t getSize() const {
        return members.size();
    }

    character& operator[](size_t index) const {
        if (index < members.size()) {
            return *members[index];
        } else {
            //越界處理,待修
            return *members[0];
        }
    }

    // 提供 const vector<character*> 的方法
    const vector<character*>& getMembers() const {
        return members;
    }
    void setTeamMark(){teamMark = true; return;}
    // addClassWarrior();
    void addClassWizard(int x, int y);
    void addClassArcher(int x, int y);
    void addClassTank(int x, int y);
    // addClassBishop();
    void addClassKnight(int x, int y);
    // 確認是否為第一隊 
    bool getteamMark(){return teamMark;}

    bool allMembersDead() const;
};

void Team::addClassWizard(int x, int y) {
    character* newWizard = new Wizard(x, y);  // 假設 Wizard 類別有符合的建構函式
    members.push_back(newWizard);
    
}

void Team::addClassKnight(int x, int y){
    character* newKnight = new Knight(x, y);
    members.push_back(newKnight);
}

void Team::addClassArcher(int x, int y) {
    character* newArcher = new Archer(x, y);
    members.push_back(newArcher);
}
    
void Team::addClassTank(int x, int y) {
    character* newTank = new Tank(x, y);
    members.push_back(newTank);
}

bool Team::allMembersDead() const{
    for (const character* member : members) {
        if (member->get_current_HP() > 0) {
            return false;  // 如果有任何一個成員血量不為 0,返回 false
        }
    }
    return true; 
}

void character::attack(int index, Team& temp, Map& chessBoard){
    temp[index].takeDamage(chessBoard, attackPoints, index, temp);
}

// 確認傳入之角色是否於九宮格內
bool character::checkDistance(character& character) const{
    
	if(abs(x - character.getX()) == 1 && abs(y - character.getY()) == 0 || abs(y - character.getY()) == 1 && abs(x - character.getX()) == 0 || (abs(x - character.getX()) == 1 && abs(y - character.getY()) == 1)){
        return true;
    }
    return false;
    
}

void character::chooseToAttack(const vector<character*>& team){
    vector<size_t> tempAttackIndex;
    for(size_t i = 0; i < team.size(); i++){
        if(checkDistance(*(team[i])) == true){
            if(team[i]->get_current_HP() == 0){
                continue;
            }
            else{
                tempAttackIndex.push_back(i);
            }
        }
    }
    // 如果此vector為空(沒人可以打)
    if(tempAttackIndex.empty() == true){
        return;
    }
    else{
        cout << "You can attack: ";
        canAttackIndex = tempAttackIndex;
        for(size_t i = 0; i < tempAttackIndex.size(); i++){
            cout << tempAttackIndex[i] << ',' << team[tempAttackIndex[i]]->getName() << " ";
        }
        cout << '\n';
        return;
    }
}

void character::displayInfo(const vector<character*>& team, int index){
    cout << "Name: " << index << ',' << name << endl;
    cout << "HP: " << current_healthPoints << "/" << origin_healthPoints << endl;
    cout << "Attack: " << attackPoints << endl;
    cout << "Defence: " << defensePoints << endl;
}

void character::takeDamage(Map& chessBoard, int damage, int index, Team& temp) {
    current_healthPoints -= damage;
    if (current_healthPoints <= 0) {
        current_healthPoints = 0;
        chessBoard.cleanCharacter(*this);
        cout << index << ',' << name << " is DEAD! " << endl;

    }
    else {
        cout << index << ',' << name << " received damage points: " << damage << " Current Health Point: " << current_healthPoints << endl;
    }
}

void character::heal(int amount) {
		
		int old_healthPoints = current_healthPoints;
	    int new_healthPoints = current_healthPoints + amount;
	    // 确保生命值不超過最大值
	    current_healthPoints = min(new_healthPoints,origin_healthPoints);
	    cout << name << " restored health points: " << current_healthPoints-old_healthPoints << " Current Health Point:" << current_healthPoints << endl;
	}

void Map::cleanCharacter(character& character){
    int row = character.getY();
    int col = character.getX();

    // 檢查座標是否合法
    if (row >= 0 && row < rows && col >= 0 && col < cols) {
        map[row][col] = '.';
    }
}

void Map::placeCharacter(const character* character) {
    int row = character->getY();
    int col = character->getX();

    // 檢查座標是否合法
    if (row >= 0 && row < rows && col >= 0 && col < cols) {
        map[row][col] = character->getSymbol();
    }
}

void Map::draw() const{
    for (int i = 0; i < rows; i++) {
            for (int j = 0; j < cols; j++) {
                cout << map[i][j] << ' ';
            }
            cout << endl;
        }
}

void character::move(Map& chessBoard, Team& otherTeam) {
    string input;
    int attackIndex;
    int moveX;
    int moveY;
    cout << "Your Move(Enter your movement): " << endl;
    cin >> input;
    chessBoard.cleanCharacter(*this);  // 將原先位置設為空格

    if(input == "attack"){
        // call function "attack"
        cin >> attackIndex;
        attack(attackIndex, otherTeam, chessBoard);
        chessBoard.placeCharacter(this);
        return;
    }
    else if(input == "move"){
        bool validMove = false;
        string check;
        while(!validMove){
            cin >> moveX >> moveY;

            // 檢查目標位置是否有其他角色
            int targetX = x + moveX;
            int targetY = y + moveY;

            // 檢查座標是否合法
            if (chessBoard.isCellOccupied(targetX, targetY)) {
                cout << "Cannot move to a cell that is already occupied !!!" << endl;
                cout << "Please select a target cell again : " << endl;
                
            } else {
                while(check != "y" && check != "n"){
                    cout << "Press y to continue or Press n to cancel : " << endl;
                    cin >> check;
                }

                if(check == "y") {
                    x = targetX;
                    y = targetY;
                    chessBoard.placeCharacter(this);  // 更新新位置
                    cout << x << " " << y << endl;
                    validMove = true;
                }
                else if(check == "n") {
                    cout << "Please enter a new target cell : " << endl;
                }
                
            }

        }
    }
}

void toContinue();
void addToTeam(Team& temp, int& teamCnt);

int main() {
    // 初始化地圖
    Map chessBoard(20, 20);
    int teamCnt = 0;

    // 丟入Team中之vector<character*> members
    Team team1;
    team1.setTeamMark();
    addToTeam(team1, teamCnt);
    // 丟入Team中之vector<character*> members  
    Team team2;
    cout << "You cannot use team1's members' locations!!!!!!!" << endl;
    addToTeam(team2, teamCnt);


    // 放置隊伍進地圖
    for(size_t i = 0; i < team1.getSize(); i++) {
        chessBoard.placeCharacter(&team1[i]);
    }

    for(size_t i = 0; i < team2.getSize(); i++)
    {
        chessBoard.placeCharacter(&team2[i]);
    }

    //遊戲剛開始時地圖
    cout << "Initial Chess Board:" << endl;
    chessBoard.draw();


    // Team loop
    while(!team1.allMembersDead() && !team2.allMembersDead()){
        string check;
        for(size_t i = 0 ; i < team1.getSize(); i++) { 
            if(team1[i].get_current_HP() == 0){
                continue;
            }
            else{
                cout << "Your team : Team1" << endl;
                    // 顯示角色基本資料
                team1[i].displayInfo(team1.getMembers(), i);
                
                // 可攻擊誰
                team1[i].chooseToAttack(team2.getMembers());


                // 移動角色
                team1[i].move(chessBoard, team2);
                
                //toContinue();

                cout << "\n\n\n\n\n\n\n\n\n\n";
                cout << "Chess Board after moving player:" << endl;
                chessBoard.draw();
            }
        }

        for(size_t i = 0 ; i < team1.getSize(); i++) { 
            if(team2[i].get_current_HP() == 0){
                continue;
            }
            else{
                cout << "Your team : Team2" << endl;
                // 顯示角色基本資料
                team2[i].displayInfo(team1.getMembers(), i);

                // 可攻擊誰 如果有敵方的人在周圍即可選擇
                team2[i].chooseToAttack(team1.getMembers());

                // 移動角色
                team2[i].move(chessBoard, team1);

                //toContinue();


                cout << "\n\n\n\n\n\n\n\n\n\n";
                cout << "Chess Board after moving player:" << endl;
                chessBoard.draw();
            }
        }
    }
    return 0;
}

void toContinue(){
    string check;
    while(check != "y"){
        cout << "Press y to continue :" << endl;
        cin >> check;
    }
    return;
}

void addToTeam(Team& temp, int& teamCnt){
    while(temp.getSize() < 3)
    {
        string characterName;
        int quantity = 0;
        int x;
        int y;
        int space = 3 - temp.getSize();
        if(teamCnt == 0){
            cout << "Which character do  you want to add in team1? ( Wizard , Knight , Archer , Tank )" << endl;
        }
        else if(teamCnt == 1){
            cout << "Which character do  you want to add in team2? ( Wizard , Knight , Archer , Tank )" << endl;
        }
            
            
        
        
        cin >> characterName;
        if(characterName == "Wizard")
        {
            cout << "You can at most add " << space << " characters" << endl;
            cout << "Quantity:";
            cin >> quantity;

            for(int i = 0; i < quantity; i++)
            {
                cout << "Location:";
                cin >> x >> y;
                temp.addClassWizard(x, y);
            }
        }
        else if(characterName == "Knight")
        {
            cout << "You can at most add " << space << " characters" << endl;
            cout << "Quantity:";
            cin >> quantity;

            for(int i = 0; i < quantity; i++)
            {
                cout << "Location:";
                cin >> x >> y;
                temp.addClassKnight(x, y);
            }
        }
        else if (characterName == "Archer"){
        	cout << "You can at most add " << space << " characters" << endl;
            cout << "Quantity:";
            cin >> quantity;

            for(int i = 0; i < quantity; i++)
            {
                cout << "Location:";
                cin >> x >> y;
                temp.addClassArcher(x, y);
                
            }
    	}
            
        else if (characterName == "Tank"){
        	cout << "You can at most add " << space << " characters" << endl;
            cout << "Quantity:";
            cin >> quantity;

            for(int i = 0; i < quantity; i++)
            {
                cout << "Location:";
                cin >> x >> y;
                temp.addClassTank(x, y);
                
            }	
		}

    }

    teamCnt++;
}
Leave a Comment