Я делаю игру с горячим картофелем, которая касается наследования. У меня есть класс картофеля, класс игрока и класс судьи.
При вызове функции toss в моем классе судьи я продолжаю получать ту же ошибку, и я не могу понять, почему: прекратить вызывать, выбрасывая ловушку exceptionAbort: 6
Я прошел и обнаружил, что в umpire :: start (), вызов Players.at (randU) -> toss (* m) в цикле for вызывает эту ошибку. Но все выглядит хорошо для меня.
Может кто-нибудь мне помочь? Спасибо!
Umpire.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();
}
}
}
Player.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();
}
Main.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 до #.
ТАКЖЕ:
Проблема возникает, когда я вызываю свою функцию броска. Я не за пределами диапазона, потому что когда я пытаюсь вызвать Players.at (randU) -> getID (), я не получаю никаких ошибок вообще. Может ли быть так, что я не могу достичь функции броска для этого игрока? Я думаю, что это связано с чем-то, на что я указываю, или памятью. Сначала я делаю игроков PlayerList в моем main.cc и push_back-проигрывателях, чередующихся между ними. Но каждый игрок также занимает в списке. Может быть, я сталкиваюсь с ошибками, связанными с этим?
Спасибо! Любая помощь высоко ценится 🙂
Выданное исключение должно быть std :: out_of_range. Случайное число, которое вы генерируете, должно быть больше, чем количество элементов в векторе.
randU
должен быть восстановлен после Players.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)
}
}