C++ゲームシリーズ6:自分で動く

24161 ワード

詳細:C++ゲームシリーズカタログ
知識点:(1)オブジェクト配列は、自動的に複数の「プレイヤー」(キャラクタクラスのオブジェクト)を生成し、自動的に遊ぶ.(2)ファイルを使う:武器はファイルから読み、遊ぶ過程で、ファイルに書き込まれる.不足(改善すべき点):(1)乱数が発生した場合、繰り返しを避けることができず、自分で自分を攻撃する場合がある--血を加えても減らしても、変化がなく、同じ武器が複数ある--棒だが、棒を2本持っていてもいい.(2)自動生成されたキャラクターをプレイさせるだけで、自分は参加していませんが、実は、指定されたオブジェクト配列の0番目のオブジェクトが自分(ランダムに動作者を選択する場合、ランダム数は最小1)で、メニューを追加して、動作を選択すればいいのです.
【アイテム-プレイヤー自身を動かす】(前のバージョンに比べてmain.cppで主に変化)1.game.h:クラス宣言
#ifndef GAME_H_INCLUDED
#define GAME_H_INCLUDED
#include <string>
using namespace std;
const int N=5; //           
const int M=30;  //        
const int NOWEAPON=-1;  //       
const int SIZE=100;  //           ,  100   

class Point     //Point   
{
public: //    
    Point(int x=0, int y=0);
    int getX();
    int getY();
    double distance(const Point &p);  //       p     
    void moveTo(int x, int y); //      
    void move(int dx, int dy); //       
private:
    int x, y;  //  
};

class Weapon
{
public:
    Weapon(){};
    Weapon(string wnam, int f, double k);
    Weapon(const Weapon&);
    string getWname();
    int getForce();         //     
    double getKillRange();  //      
    void setWeapon(string,int,double);
private:
    string wname;   //  
    int force;       //   
    double killRange;   //    
};

class Role
{
public:
    Role():weaponNum(0),holdWeapon(NOWEAPON){};
    Role(string nam, int b, Point l, Weapon w[], int n); //    
    ~Role(); //    
    void eat(int d); //   , d (           )
    void attack(Role &r); //    ,    ,         。           
    void beAttack(int f); //     ,  f       
    double distance(Role &r); //          
    bool isAlived(); //    
    void moveTo(int x, int y); //      
    void move(int dx, int dy); //       
    void changeWeapon(int wno); //      
    void show(); //  
    void setBaseInfo(string, int);//         
    void setLocation(int,int);//    
    void addWeapon(Weapon);//     
    string getName();
    int getWeaponNum();
    string getCurWeapon();
private:
    string name;  //    
    int blood;    //    
    bool life;    //    
    Point location;  //  
    Weapon weapons[N];  //  
    int weaponNum;      //    
    int holdWeapon;     //         (   NOWEAPON,     )
};

#endif // GAME_H_INCLUDED

2.point.cpp、ポイントクラスを定義し、位置を表す
#include "game.h"
#include <cmath>

Point::Point(int x, int y): x(x), y(y) { }
int Point::getX()
{
    return x;
}
int Point::getY()
{
    return y;
}
//      
void Point::moveTo(int x, int y)
{
    this->x=x;
    this->y=y;
}
//       
void Point::move(int dx, int dy)
{
    this->x+=dx;
    this->y+=dy;
}
double Point::distance(const Point& p)
{
    double dx = this->x - p.x;
    double dy = this->y - p.y;
    return (sqrt(dx * dx + dy * dy));
}

3.weapon.cpp、武器類の定義
#include "game.h"
Weapon::Weapon(string wnam, int f, double k):wname(wnam),force(f),killRange(k) {}
Weapon::Weapon(const Weapon &w):wname(w.wname),force(w.force),killRange(w.killRange) {}
string Weapon::getWname()
{
    return wname;
}
//     
int Weapon::getForce()
{
    return force;
}
//      
double Weapon::getKillRange()
{
    return killRange;
}
void Weapon::setWeapon(string name,int f,double r)
{
    wname=name;
    force=f;
    killRange=r;
}

4.role.cpp、キャラクタクラスを定義し、ゲームに参加するキャラクタを表す
#include <iostream>
#include "game.h"
using namespace std;

Role::Role(string nam, int b, Point l, Weapon w[], int n)
    :name(nam),blood(b),location(l),weaponNum(n),holdWeapon(NOWEAPON)
{
    if(blood>0)
        life=true;
    else
        life=false;
    for(int i=0; i<n; i++)
        weapons[i]=w[i];
}
Role::~Role()
{
    cout<<name<<"    ..."<<endl;
}

//   , d (           )
void Role::eat(int d) //   , d (     ,    ,     )
{
    blood+=d;
    if(blood>0)
        life=true;
}

//    ,    ,         ,           
//              
void Role::attack(Role &r)
{
    if(isAlived()&&holdWeapon>NOWEAPON&&weapons[holdWeapon].getKillRange()>this->distance(r)) //         
    {
        blood+=weapons[holdWeapon].getForce();
        r.beAttack(weapons[holdWeapon].getForce());
    }
}

//     ,  f       
void Role::beAttack(int f)
{
    blood-=f;
    if(blood<=0)
        life=false;
}

//          
double Role::distance(Role &r)
{
    return location.distance(r.location);
}
//      
void Role::changeWeapon(int wno)
{
    if(wno<weaponNum)
        holdWeapon=wno;
}
//    
bool Role::isAlived()
{
    return life;
}
//      
void Role::moveTo(int x, int y)
{
    if(isAlived())  //       
        location.moveTo(x,y);
}
//       
void Role::move(int dx, int dy)
{
    if(isAlived())
        location.move(dx,dy);
}
//  
void Role::show()
{
    cout<<name<<" has "<<blood<<" blood, hold ";
    if(holdWeapon==NOWEAPON)
        cout<<"no weapon";
    else
        cout<<weapons[holdWeapon].getWname();
    cout<<"(";
    for(int i=0; i<weaponNum; i++)
        cout<<weapons[i].getWname()<<",";
    cout<<"\b)";
    cout<<". He is in ("<<location.getX()<<", "<<location.getY()<<") and ";
    if(isAlived())
        cout<<"alived.";
    else
        cout<<"dead.";
    cout<<endl;
}
//         
void Role::setBaseInfo(string nam, int b)
{
    name=nam;
    blood=b;
    if(blood>0)
        life=true;
}
//    
void Role::setLocation(int x,int y)
{
    location.moveTo(x,y);
}
//     
void Role::addWeapon(Weapon w)
{
    if(weaponNum<N)
    {
        weapons[weaponNum]=w;
        weaponNum++;
    }
}

//    
string Role::getName()
{
    return name;
}

    int Role::getWeaponNum()
    {
        return weaponNum;
    }
string Role::getCurWeapon()
{
    return weapons[holdWeapon].getWname();
}

5.main.cpp、テスト関数、位置を表す
#include <iostream>
#include <fstream>
#include <cstdlib>
#include <ctime>
#include "game.h"
using namespace std;
void initializeRoles(Role roles[]); //     ,        
int readWeaponInfo(Weapon WeaponBase[]); //          
int randBetween(int low, int high); //           
void play(Role roles[], int n);

//   
int main( )
{
    srand(time(0));
    Role roles[M];
    initializeRoles(roles);
    play(roles, 1000);
    return 0;
}

//     
void initializeRoles(Role roles[])
{
    Weapon weaponBase[SIZE]; //               
    int weaponNum = readWeaponInfo(weaponBase); //                ,        
    char cno[5]; //    
    int wn; //      
    int wno; //         (weaponBase    )
    for(int i=0; i<M; i++) //  M     ,       
    {
        itoa(i,cno,10);
        roles[i].setBaseInfo(string("Soldier")+cno,randBetween(10, 100));
        roles[i].setLocation(randBetween(0,1000),randBetween(0, 1000));
        wn=randBetween(1,N);
        for(int j=0; j<wn; j++) //  wn   
        {
            wno=randBetween(0,weaponNum);
            roles[i].addWeapon(weaponBase[wno]);
        }
        roles[i].changeWeapon(randBetween(0,wn));//       
    }
}

//      
int readWeaponInfo(Weapon WeaponBase[])
{
    ifstream infile("weapon.txt",ios::in);
    int n=0;
    string wn;
    int wf;
    double wr; //       、   、    
    if(!infile)
    {
        cerr<<"open error!"<<endl;
        exit(1);
    }
    while(infile>>wn>>wf>>wr)
    {
        WeaponBase[n++].setWeapon(wn,wf,wr);
    }
    infile.close();
    return n;
}
//        low,  high       
int randBetween(int low, int high)
{
    return low+rand()%(high-low);
}

// n   ,          
//       、  、   、 
//     ,   log.txt   
void play(Role roles[], int n)
{
    int i;
    int rno,rno2; //      
    int action; //  0-  ,1-  ,2-   ,3-   
    int newx, newy, newWeapon, eatd;
    ofstream outfile("log.txt",ios::out);  //       
    if(!outfile)                    //      ,outfile  0 
    {
        cerr<<"open error!"<<endl;
        exit(1);
    }

    cout<<"   ...."<<endl;
    for(i=0; i<M; i++)
        roles[i].show();
    cout<<"    ,          ...."<<endl<<endl;
    for(i=0; i<n; i++)
    {
        rno=randBetween(0,M);
        outfile<<" "<<i<<" : "<<roles[rno].getName();
        action=randBetween(0,4);
        switch(action)
        {
        case 0: //  
            rno2=randBetween(0,M);
            outfile<<"  "<<roles[rno2].getName();
            roles[rno].attack(roles[rno2]);
            break;
        case 1: //  
            newx=randBetween(0,1000);
            newy=randBetween(0, 1000);
            outfile<<"   ("<<newx<<","<<newy<<")";
            roles[rno].moveTo(newx,newy);
            break;
        case 2: //   
            newWeapon=randBetween(0,roles[rno].getWeaponNum());
            roles[rno].changeWeapon(newWeapon);
            outfile<<"     : "<<roles[rno].getCurWeapon();
            break;
        case 3: // 
            eatd=randBetween(0,100);
            roles[rno].eat(eatd);
            outfile<<"  : "<<eatd;
            break;
        }
        outfile<<". "<<endl;
    }
    outfile<<endl;
            outfile.close();
    cout<<"     ...."<<endl;
    for(i=0; i<M; i++)
        roles[i].show();

}