Untitled

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

class Team;
class obstacle ;
class character;
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 placeCharacter(const vector<character*>& members, int i);
    void cleanCharacter(character& character);
    
    void placeCharacterSingle(const character& character);
};

class character {
protected:
    //名字、原始血量、目前血量、攻擊、防禦、速度
    char symbol;
    string name;
    int origin_healthPoints;
    int current_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 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);
    //傷害
    void takeDamage(int damage);
    //攻擊
//    void attack();
    // 移動角色
    void move(Map& chessBoard);
    // 確認是否在攻擊範圍內
    bool checkDistance(character& character) const;
    
    void heal(int amount);
    
//    void checkObstacle(vector<obstacle>& allObstacles);
};

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 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 Team {
private:
    vector<character*> members;
	bool teamMark;
	
public:

    ~Team() {
        for (character* member : members) {
            delete member;
        }
    }
    
    Team(){
        teamMark = false;
    };

    void setTeamMark(){teamMark = true; return;}

        // 獲得隊伍的大小
    size_t getSize() const {
        return members.size();
    }
    
    const vector<character*>& getMembers() const {
        return members;
    }

    void addClassWizard(int x, int y) {
        members.push_back(new Wizard(x, y));
    }

    void addClassKnight(int x, int y) {
        members.push_back(new Knight(x, y));
    }
    
    void addClassArcher(int x, int y) {
        members.push_back(new Knight(x, y));
    }
    
    void addClassTank(int x, int y) {
        members.push_back(new Tank(x, y));
    }

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

void character::displayInfo(const vector<character*>& team){
    cout << "Name: " << name << endl;
    cout << "HP: " << current_healthPoints << endl;
    cout << "Attack: " << attackPoints << endl;
    cout << "Defence: " << defensePoints << endl;


//    待修 不確定要不要在character內建一個存此角色可以攻擊的對象的index
//    vector<size_t> tempAttackIndex;
//    for(size_t i = 0; i < team.size(); i++){
//
//        if(this->getSymbol() != team[i].getSymbol() && checkDistance(*(team[i])) == true){
//            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 << team[tempAttackIndex[i]]->getName() << " ";
//        }
//        cout << '\n';
//        return;
//    }
}

//void character::attack() {
//    bool checkAttack() = false;
//    string dowhat;
//    getline(cin, dowhat);
// }

void character::takeDamage(int damage) {
    current_healthPoints -= damage;
    if (current_healthPoints < 0) {
        current_healthPoints = 0;
        cout << name << " 被擊敗了!" << endl;
    }
    else {
        cout << name << " 受到 " << damage << " 點傷害,剩餘生命值:" << 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 << " 回复了 " << current_healthPoints-old_healthPoints << " 點生命值,當前生命值:" << current_healthPoints << endl;
	}

void character::move(Map& chessBoard) {
    string input;
    int moveX, moveY;
    bool validMove = false;

    while (!validMove) {
        try {
            cout << "Your Move (Enter 'attack' to attack or 'move' to move): ";
            getline(cin, input);

            if (input == "attack") {
//                attack();  // 呼叫 attack 方法
                validMove = true;  // 攻擊完成後退出循環
            } 
            else if (input == "move") {
                chessBoard.cleanCharacter(*this);  // 將原先位置設為空格
                cout << "Enter move X and Y: ";
                if (!(cin >> moveX >> moveY)) {
                    throw runtime_error("Invalid input for movement coordinates.");
                }
                cin.ignore();

                x += moveX;
                y += moveY;
                chessBoard.placeCharacterSingle(*this);  // 嘗試放置到新位置
                validMove = true;  // 如果成功,退出循環 
            } else {
                cout << "Invalid command. Please enter 'attack' or 'move'." << endl;
            }
        } catch (const runtime_error& e) {
            cout << "Error: " << e.what() << ". Please enter again!" << endl;
            cin.clear();  // 清除錯誤標誌
            cin.ignore(numeric_limits<streamsize>::max(), '\n');  // 忽略錯誤輸入直到下一行

            // 重置上一有效位置
            x -= moveX;
            y -= moveY;
        }
    }
}

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::placeCharacterSingle(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();
    }else {
    	throw runtime_error("the obstacle is out of map bounds");
	}	
    
}

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


Leave a Comment