[OOP]hw003 Adventure

Story


Adventure is a CLI game. The player has to explore in the castle with many levels and a lot of rooms. The task of the player is to find a room where the princess is prinsoned and take her leave the castle. There are many types of rooms, and each type of room has different types of exits. Note that there's a monster in one of the rooms, which the exact location is not able to be aware. But once the player meets a monster, the game is over.


When the game starts, the player is at the lobby of the castle. Then the program shows information about the lobby:name of the room, how many exits are there, and names of all exits (e.g.: "east", "south", "up"), like:


Welcome to the lobby. There are 3 exits as: east, west and up.
Enter your command:
The player then can input "go" followed by the name of one exit to enter the room connected with that door, like:
go east
The player goes into the room to the east. The program shows the information about that room, like what happened in the lobby just now. And the player may input command to choose another room.
Once the player enters a room with a monster, the program shows a message and game over. Once the player enters the room of princess, the program shows a message about the princess, and the process is going to leave with the player. The player then has to find their way out the castle. The only way to leave the castle is via the lobby.


All printed messages and user input are in English to simplify the code.

Requirement


At least three different kinds of room;
At least five rooms;

The room with monster or princess is randomly set.


这个程序非常疯狂,我实现了一个无限房间的游戏

编译需要-std=c++11


// name: room.h
// author: Amrzs
// date: 2014/03/29

#ifndef ROOM_H
#define ROOM_H

#include <string>
#include <map>

using namespace std;

class Room {

public:
    Room(string name, vector<string> exitNames, bool safe = false); 
    ~Room();

private:
    string name;
    map<string, Room*> exitMap; 
    bool princess, monster;
    
public:
    bool hasPrincess();
    bool hasMonster();
    bool existExit(string exitName);
    Room *goExit(string exitName);
    void printInfo();
    
    void setExit(string exitName, Room*);
};

#endif //ROOM_H

// name: room.cpp
// author: Amrzs
// date: 2014/03/29

#include <iostream>
#include <string>
#include <map>
#include <vector>
#include <cstdlib>

#include "room.h"

using namespace std;

Room::Room(string name, vector<string> exitNames, bool safe):
    name(name){

    srand(time(NULL));

    if(safe){
        princess = monster = false; // this room don't have a princess or monster
    }else{
        princess = (0 == rand()%5);
        monster = (0 == rand()%5); // 1/5 is the probability
    }

    vector<string>::iterator it;
    for(it = exitNames.begin(); it != exitNames.end(); it++){
        if(0 != rand()%3)
            exitMap[*it] = NULL; // 2/3 is the probability
    }
}

Room::~Room(){

    cout << "Room: " << name << " gone" << endl;
}


bool Room::hasPrincess(){
    
    return princess;
}

bool Room::hasMonster(){

    return monster;
}

bool Room::existExit(string exitName){

    return 1 == exitMap.count(exitName);
}

Room *Room::goExit(string exitName){

    return exitMap[exitName]; //it's dangerous, it must after existExit()
}

void Room::printInfo(){

    cout << "Welcome come to the "
        << name << "." <<endl;
    cout << "There are " << exitMap.size()
        << " exits as: ";

    map<string, Room*>::iterator it;
    for(it = exitMap.begin(); it != exitMap.end(); it++){
        cout << (*it).first << " ";
    }
    cout << endl;

    cout << "Please enter your command: ";
}


void Room::setExit(string exitName, Room *room){

    exitMap[exitName] = room; //dangerous and after existExit()
}

// name: castle.h
// author: Amrzs
// date: 2014/03/29

#ifndef CASTLE_H
#define CASTLE_H

#include <string>
#include <vector>

#include "room.h"

using namespace std;

class Castle {

public:
    Castle();
    ~Castle();

private:
    vector<Room*> rooms;
    bool princess = false; 

public:
    Room *addRoom(string name);

    void printInfo();
    void run();

//static functions and variables
private:
    string static oppoExit(string exitName);

    vector<string> static exitNames;
};

#endif //CASTLE_H

// name: castle.cpp
// author: Amrzs
// date: 2014/03/29

#include <iostream>
#include <string>
#include <vector>

#include "castle.h"

using namespace std;

Castle::Castle(){

    Room *room = new Room("lobby", exitNames, true);
    rooms.push_back(room);
}

Castle::~Castle(){

    while(!rooms.empty()){
        vector<Room*>::iterator it = rooms.end();
        rooms.pop_back();
        delete (*it);        
    }
    cout << "The castle gone!" << endl;
}

vector<string> Castle::exitNames = {
    "up", "down",
    "east", "west"
};


Room *Castle::addRoom(string name){
    
    Room *room = new Room(name, exitNames);
    rooms.push_back(room);
    return room;
}

void Castle::printInfo(){

    cout << "Welcome to my castle, "
        << "enjoy your time!" << endl;
} 

void Castle::run(){

    Room *nowRoom = rooms[0];

    string go, exitName, roomName;

    while(1){ //don't like for(;;)
        nowRoom->printInfo();
        cin >> go >> exitName;
        if(!nowRoom->existExit(exitName)){
            cout << "There isn't a exit named "
                << exitName << "." << endl;
            continue;
        }

        Room *newRoom = nowRoom->goExit(exitName);
        if(!newRoom){
            cout << "Please enter a new room name: ";
            cin >> roomName;
            newRoom = addRoom(roomName);
            nowRoom->setExit(exitName, newRoom);
            newRoom->setExit(oppoExit(exitName), nowRoom);
        }
        nowRoom = newRoom;

        if(nowRoom->hasMonster()){
            cout << "You meet the monster and game over!" << endl;
            return; //dead
        }

        if(nowRoom->hasPrincess()){
            if(!princess){
                princess = true;
                cout << "You get the princess, return back quickly!" << endl;
            }
        }

        if(princess && nowRoom==rooms[0]){
            cout << "You win!" << endl
                << "Return back to the lobby and get the princess." << endl;
            return; //win
        }
    }
}

string Castle::oppoExit(string exitName){

    //make sure you can get the princess and return in original path

//    if("up" == exitName || "down" == exitName){
//        oppoExitName = ("up" == exitName) ? "down" : "up";
//    }
//    if("east" == exitName || "west" == exitName){
//        oppoExitName = ("east" == exitName) ? "west" : "east";
//    }
    
    vector<string>::iterator it;
    for(it = exitNames.begin(); it != exitNames.end(); it += 2){
        
        if((*it) == exitName)
            return *(it+1);

        if(*(it+1) == exitName)
            return *it;
    }

    cout << "No oppoExit!" << endl;

    return string("error"); 
}


// name: main.cpp
// author: Amrzs
// date: 2014/03/30

#include "castle.h"

int main(){

    Castle castle;
    castle.run();

    return 0;
}


编译命令:

g++ -std=c++11 main.cpp room.cpp castle.cpp

错的Makefile,我不知道怎么把-std=c++11优雅的加入

等我找到办法的时候我会改回来

CPP = g++
FLAGS = -o
TARGET = a.out
OBJS = main.o castle.o room.o

$(TARGET): $(OBJS)
	$(CPP) $(FLAGS) $(TARGET) $(OBJS)
main.o: main.cpp castle.o room.o
castle.o: castle.cpp
room.o: room.cpp

.PHONY: clean
clean:
	-rm $(TARGET) $(OBJS)



下面一段是游戏过程:

Welcome come to the lobby.
There are 1 exits as: up 
Please enter your command: go ee
There isn't a exit named ee.
Welcome come to the lobby.
There are 1 exits as: up 
Please enter your command: go up
Please enter a new room name: 001
You get the princess, return back quickly!
Welcome come to the 001.
There are 3 exits as: down east west 
Please enter your command: go down
You win!
Return back to the lobby and get the princess.
Room: 001 gone
The castle gone!
运气真好,第一个就是公主的房间


程序小结:

1. 在一个城堡中开始游戏,当遇见怪兽或者安全把公主带回来游戏结束

2.城堡第一个保证没公主和怪兽,名字且为lobby

3.在类的静态变量里存了各个方向(我的定义在C++98里是错的!),相邻两个为反方向,这样使得找到公主后可以原路返回

4.每次进入一个没有进入的房间就会随机生成一个房间,1/5是公主或者怪兽(当然每个城堡只有一个公主和怪兽),每个出口方向是1/3概率,其实我想设置为可变概率,这样在城堡里可以传参数进入

5.每次生成房间需要输入房间名字,蛋疼,也不知道怎么改好

6.如果能记录步数以及路径,这样会对玩家更友好点

7.游戏结束释放内存,析构函数会输出 ××room gone,我觉得这样挺好

8.研究了stl容器,发现还挺好玩的,以后好好用上

9.vector等容器我应该重新定义类型,这样可以在不改变的代码的情况下随意改动vector变成deque, list等等

10.容器的访问存在安全隐患,我下次去问问老师,怎么做比较好

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值