1

我正在制作一个处理继承的烫手山芋游戏。我有土豆班、球员班和裁判班。

在我的裁判类中调用 toss 函数时,我一直收到同样的错误,我似乎无法弄清楚为什么:终止调用抛出异常中止陷阱:6

我通过并发现在 umpire::start() 中,我的 for 循环中对 Players.at(randU)->toss(*m) 的调用导致出现此错误。但在我看来一切都很好。

谁能帮我吗?谢谢!

裁判.cc

#include <iostream>
#include <string>
#include "potato.h"
#include "player.h"
#include "umpire.h"
#include "PRNG.h"
using namespace std;

// Declare globally
int gamecount=1;

// GLOBAL VARIABLES
bool first=false; // False if set has not started
PRNG rplayer;

// UMPIRE CONSTRUCTOR-------------------------------------------------------------------
Umpire::Umpire( Player::PlayerList &players ){
   Players=players;
   cout<<"\tMashed POTATO will go off after ";
   cout.flush();
   m=new Mashed(Players.size()-1);
   cout << " tosses" << endl;
   cout.flush();
   cout <<"\tFried POTATO will go off after 5 tosses" << endl;  
   cout.flush();
   f=new Fried(5);}

// UMPIRE DESTRUCTOR-------------------------------------------------------------------
Umpire::~Umpire(){  
    delete m;
    delete f;}


// UMPIRE START------------------------------------------------------------------------
void Umpire::start(){
int randU;
int gameCount=1; // Keeps track of sets

// Check if you are at the end of the list.
if(Players.size()==1){
    // Who won?
    cout << Players.at(0)->getId() << "wins the Match!" << endl;
    cout.flush();}
else{

// Print output for sets----------------------------------------------------------------
// See which potato is being used in the set
if(gameCount%2!=0){ 
    cout << "Set " << gameCount << "-\tUser (mashed) [";
    cout.flush();}
else{ 
    cout << "Set " << gameCount << "-\tUser (fried) [";
    cout.flush();}
gameCount++; // increase gamecount
// Outputting players left in the set
for(unsigned int i=0;i<Players.size();i++){
    cout<<Players.at(i)->getId();}
cout <<"]: ";
cout.flush();

//Start Tossing--------------------------------------------------------------------------
    randU=rplayer(Players.size()-1);
    // Output A(id) or R(id)
    if (randU%2==0){
        cout<<"A("<<randU<<"), ";
        cout.flush();}
    else{
        cout<<"R("<<randU<<"), ";
        cout.flush();}
    if(first==false){
        for(unsigned int i=0; i<Players.size(); i++){
            if(Players.at(i)->getId()==Players.at(randU)->toss(*m)){
                Players.erase(Players.begin()+i);
                cout << "Eliminated: "<< i << endl;
                cout.flush();}
        }
        first=true;
        f->reset();
        start();
    }
    else{
        for(unsigned int i=0; i<Players.size(); i++){
            if(Players.at(i)->getId()==Players.at(randU)->toss(*f)){
                Players.erase(Players.begin()+i);
                cout << "Eliminated: "<< i << endl;
                cout.flush();}
        } 
        first=false;
        m->reset();
        start();
        }
    }
}

播放器.cc

#include <iostream>
#include "player.h"
#include "potato.h"
#include "PRNG.h"
using namespace std;

// GLOBAL DECLARATIONS--------------------------------------------------------------------
PRNG randP;

// PLAYER CONSTRUCTOR---------------------------------------------------------------------
Player::Player(unsigned int id, Player::PlayerList &players){
    pid=id;
    Players=players;
    lrpFLAG=false;}

// getId() returns the player's id--------------------------------------------------------
unsigned int Player::getId(){
        return pid;}

// RNPlayer Constructor-------------------------------------------------------------------
RNPlayer::RNPlayer( unsigned int id, Player::PlayerList &players ) : Player(id,players){}

// TOSS FUNCTION--------------------------------------------------------------------------
unsigned int RNPlayer::toss( Potato &potato ){
unsigned int randnum;
if(potato.countdown()){ return getId(); }
    for(;;){    
        randnum=randP(Players.size()-1);
        if (randnum%2==0){
            cout<<"A("<<randnum<<"), ";
            cout.flush();}
        else{
            cout<<"R("<<randnum<<"), ";
            cout.flush();}
        // If our randomly selected player is not the current player...
        if(Players.at(randnum)->getId()!=getId()){
            break;}
    }   
return Players.at(randnum)->toss(potato);
}

// LRPlayer Constructor-------------------------------------------------------------------
LRPlayer::LRPlayer( unsigned int id, Player::PlayerList &players ) : Player(id,players){}

// TOSS FUNCTION
unsigned int LRPlayer::toss( Potato &potato ){
    unsigned int current; // current player
    // Find who our current player is
    for(unsigned int i=0; i<Players.size(); i++){
        if(Players.at(i)->getId()==getId()){
            current=i;
            cout<<"A("<<i<<"), ";}
    }
    // if timer hasn't gone off yet...
    if(potato.countdown()!=true){
    // if this is the FIRST toss, we want to toss left
        if(lrpFLAG==false){
            if(current==0){
                lrpFLAG=true;
                (Players.at(Players.size()-1))->toss(potato);}
            else{
                lrpFLAG=true;
                (Players.at(current-1))->toss(potato);}
            }
        else{
            if(current==Players.size()-1){
                lrpFLAG=false;
                (Players.at(0))->toss(potato);}
            else{
                lrpFLAG=false;
                (Players.at(current+1))->toss(potato);}
            }
        }
    return (Players.at(current))->getId();
}

主.cc

#include <iostream>
#include <vector>
#include <time.h>
#include "potato.h"
#include "player.h"
#include "umpire.h"
#include "PRNG.h"
using namespace std;

int main(int argc, char *argv[] ){
    int p = 5;
    int tmp;
    unsigned int s;
    PRNG prng1;
    prng1.seed(1234567890);
    // Parse the command line arguments
    switch ( argc ) {
        case 3:
            tmp=atoi(argv[1]);
            s=atoi(argv[2]);
            prng1.seed(s);
            if(tmp<2 || tmp>20){
                cout << "Player must be between 2 and 20 inclusive" << endl;
                    return 0;}
            else{
                p = atoi(argv[1]);}
        }
    // Creating list of players.
    Player::PlayerList players;
    for(int i=0; i<p; i++){
        if(i%2==0){
            players.push_back(new LRPlayer(i,players));}
        else{               
            players.push_back(new RNPlayer(i,players));}
        }

//for (int i=0;i<players.size();i++){
//  cout << "Player at " << i << " id: " << players.at(i)->getId() << endl;}

// How many players?----------------------------------------------------------------------
cout << p << " players in the match" << endl;

// Construct an UMPIRE--------------------------------------------------------------------
Umpire u(players);

// Start the game!------------------------------------------------------------------------
u.start();

}

另请注意:PRNG.h 是一个生成随机数的类。所以 PRNG prng1; int rand=prng1(#) 生成一个介于 0 和 # 之间的随机数。

另外: 当我调用我的 toss 函数时,问题就出现了。我没有超出范围,因为当我尝试调用 Players.at(randU)->getID() 时,我根本没有收到任何错误。难道是我无法达到那个玩家的投掷功能吗?我认为这与我指向的东西或记忆有关。我首先在我的 main.cc 中创建一个 PlayerList 播放器,并在两者之间交替使用 push_back 播放器。但是每个玩家也需要一份名单。也许我遇到了与此有关的错误?

谢谢!任何帮助深表感谢 :)

4

2 回答 2

0

randUPlayers.erase()调用后必须重新生成。否则会超出范围。
或者您应该将循环中断为:

for(unsigned int i=0; i<Players.size(); i++){
            if(Players.at(i)->getId()==Players.at(randU)->toss(*f)){
                Players.erase(Players.begin()+i);
                cout << "Eliminated: "<< i << endl;
                cout.flush();
                break; // BREAK HERE as randU now can be greater than (Players.size() - 1)
            }
        } 
于 2012-11-21T04:39:57.747 回答
0

抛出的异常必须是 std::out_of_range。您生成的随机数必须高于向量中的元素数。

于 2012-11-21T04:33:33.347 回答