2013-11-29 97 views
2

我知道這個問題在這些論壇上進行了多次評估,但它們在大多數情況下都是獨特的。調試斷言失敗!表達式:_BLOCK_TYPE_IS_VALID(pHead-> nBlockUse)

這是一個類的一個項目(在C++不會少),並且該項目的點爲重拍經典棋盤遊戲黑白棋。

我已經努力了幾個小時的代碼,並最終做出了一個可以工作的程序,所以我想!

我遇到的最大的問題似乎是來自我的解構,因爲它是給我這個錯誤我們很多人都看到了。我的代碼發佈在下面,並且來自我自己的調試代碼(使用有用的cout消息)我已經確定程序設法運行到Game.cpp類的末尾。只有它在解構器上磕磕絆絆,並在最終「很好地結束」之前崩潰。

Board.h

#include <iostream> 
#include <cstdlib> 
#include <vector> 
#ifndef BOARD_H 
#define BOARD_H 
using namespace std; 

enum Piece {LIGHT, DARK, EMPTY, BORDER}; 
typedef int Move; 
Move const NullMove = -1; 
int const MAX_SQUARES = 100; 
enum Direction {N=0, NE=1, E=2, SE=3, S=4, SW=5, W=6, NW=7}; 


class Board 
{ 
public: 
    Board(); 
    void reset(); 
    void display(); 
    void makeMove(Piece, Move); 
    bool isLegal(Piece, Move); 
    Piece getWinner(); 
    Piece getPlayer(); 
    void genMoves(); 
    int numMoves(); 
    Move getMove(int) const; 
    bool gameOver; 

private: 
    Piece board[MAX_SQUARES]; 
    int lightPieces; 
    int darkPieces; 
    vector<Move> goodMoves; 
    static Piece currentPlayer; 
    vector <int> offset; 
}; 

#endif 

Board.cpp

#include <iostream> 
#include <cstdlib> 
#include <vector> 
#include "Board.h" 
using namespace std; 


Board::Board() 
{ 
    reset(); 
    for(int i=0;i<MAX_SQUARES;++i) 
    { 
     if(i<11 || i>88 || i%10==0 || i%10==9) 
      board[i]=BORDER; 
    } 

    offset.push_back(10); 
    offset.push_back(11); 
    offset.push_back(1); 
    offset.push_back(-9); 
    offset.push_back(-10); 
    offset.push_back(-11); 
    offset.push_back(-1); 
    offset.push_back(9); 

    board[44] = LIGHT; 
    board[45] = DARK; 
    board[54] = DARK; 
    board[55] = LIGHT; 

    gameOver=false; 
} 

void Board::reset() 
{ 
    for(int i=0; i<MAX_SQUARES;++i) 
     board[i] = EMPTY; 
} 

void Board::display() 
{ 
    for(int i=0;i<MAX_SQUARES;++i) 
    { 
     switch(board[i]) 
     { 
      case LIGHT: 
       cout << "|LG|"; 
       break; 
      case DARK: 
       cout << "|DR|"; 
       break; 
      case EMPTY: 
       cout << "| |"; 
       break; 
      case BORDER: 
       if(i<9) 
        cout << "<0" << i << ">"; 
       else if(i==9) 
        cout << "<09>\n----------------------------------------\n"; 
       else if(i%10==9) 
        cout << "<$$>\n----------------------------------------\n"; 
       else if(i%10==0) 
        cout << "<" << i << ">"; 
       else if(i<11 || i>90) 
        cout << "<$$>"; 
       break; 
     } 

    } 
} 

void Board::makeMove(Piece p, Move m) 
{ 
    genMoves(); //generate valid moves 
    cout << "generated moves\n"; 
    int good = numMoves(); //gets number of moves 
    if(good>0) //if there are valid moves 
    { 
     cout << "more than 0\n"; 
     for(int i=0;i<goodMoves.size();++i) //checking the valid move list 
     { 
      if(m==goodMoves[i]) //if our move is in the list 
      { 
       cout << "move was in list\n"; 
       board[m]=p; //change square 
       if(board[m]==DARK) 
        cout << "ITS DARK\n"; 
       else if(board[m]==LIGHT) 
        cout << "ITS LIGHT\n"; 
       else if(board[m]==EMPTY) 
        cout << "ITS EMPTY WTF WTF WTF\n"; 
       for(int i=0;i<8;++i) //checking directions 
       { 
        Piece opp =(p==LIGHT)? DARK : LIGHT; //Making an opposite piece 
        cout << "made opp\n"; 
        int counter=0; 
        int toCheck = m+offset[i]; //making the next square to check 
        if(board[toCheck]==opp) //if it's the opposite colour from player 
        { 
         cout << "it was the opposite piece\n"; 
         while(board[toCheck]!=BORDER && board[toCheck]!=EMPTY) //while it's a piece 
         { 
          cout << "there was a piece to check\n"; 
          if(board[toCheck]==p && counter>0) //if it's player's piece and counter is higher than 0 
          { 
           cout << "this should flip stuff\n"; 
           for(int k=m;k!=toCheck;k = k+offset[i]) 
           { 
            board[k]=p; 
            cout << k; 
           } 
           break; 
          } 
          else 
          { 
           cout << "found nothing, keep trying..\n"; 
           toCheck += offset[i]; //if not, step in direction 
           counter++; 
          } 
         } 
        } 
       } 
      } 
      cout << "move wasn't in list\n"; 
     } 
    } 
    currentPlayer=(p==LIGHT)? DARK : LIGHT; 
} 

bool Board::isLegal(Piece p, Move m) 
{ 
    Piece opp =(p==LIGHT)? DARK : LIGHT; //Making an opposite piece 
    if(board[m]==EMPTY) //Checking that the space we're going is empty 
    { 
     for(int i=0;i<8;++i) //checking directions 
     { 
      int toCheck = m+offset[i]; //making the next square to check 
      if(board[toCheck]==opp) //if it's the opposite colour from player 
      { 
       while(board[toCheck]!=BORDER && board[toCheck]!=EMPTY) //while it's a piece 
       { 
        if(board[toCheck]==p) //if it's player's piece 
         return true; // if move is valid 
        else 
         toCheck += offset[i]; //if not, step in direction 
       } 
      } 
     } 
     return false; // if there's no valid direction moves 
    } 
    else // if it's not empty 
     return false; 
} 

Piece Board::getWinner() 
{ 
    bool gameDone = true; 

    for(int i=0;i<MAX_SQUARES;++i) 
    { 
     if(board[i]==EMPTY) 
      gameDone = false; 
    } 

    if(gameDone==false) 
     return EMPTY; 
    else if(lightPieces>darkPieces) 
     return LIGHT; 
    else 
     return DARK; 
} 

Piece Board::getPlayer() 
{ 
    return currentPlayer; 
} 

void Board::genMoves() 
{ 
    goodMoves.clear(); 
    cout << "generating shit\n"; 
    for(int i=0;i<MAX_SQUARES;++i) 
    { 
     if(isLegal(currentPlayer, i)) 
      {goodMoves.push_back(i); 
     cout << i << " twas a good move\n";} 
    } 
    if(goodMoves.size()==0) 
     gameOver=true; 
} 

int Board::numMoves() 
{ 
    return goodMoves.size(); 
} 

Move Board::getMove(int i) const 
{ 
    return goodMoves[i]; 
} 

Piece Board::currentPlayer=DARK; 

Player.h

#include <iostream> 
#include <cstdlib> 
#ifndef PLAYER_H 
#define PLAYER_H 
#include "Board.h" 
using namespace std; 



class Player 
{ 
public: 
    Player(const string&, Piece); 
    Piece getPiece() const; 
    virtual void makeMove(Board&)=0; 
    void setName(string&); 
    string getName(); 
private: 
    string name; 
    Piece color; 
}; 

#endif 

Player.cpp

#include <iostream> 
#include <cstdlib> 
#include "Player.h" 
using namespace std; 

Player::Player(const string& n, Piece c) 
{ 
    name = n; 
    color = c; 
} 

Piece Player::getPiece() const 
{ 
    return color; 
} 

void Player::setName(string& n) 
{ 
    name = n; 
} 

string Player::getName() 
{ 
    return name; 
} 

HumanPlayer.h

#include <iostream> 
#include <cstdlib> 
#include "Player.h" 
#ifndef HUMANPLAYER_H 
#define HUMANPLAYER_H 
using namespace std; 

class HumanPlayer: public Player 
{ 
public: 
    HumanPlayer(const string&, Piece); 
    void makeMove(Board&); 
}; 

#endif 

HumanPlayer.cpp

#include <iostream> 
#include <cstdlib> 
#include "Player.h" 
#include "HumanPlayer.h" 
using namespace std; 

HumanPlayer::HumanPlayer(const string& n, Piece c): Player(n,c) 
{ 

} 

void HumanPlayer::makeMove(Board& b) 
{ 
    Move goTo; 
    cout << "Please enter the number for the square you would like to move: "; 
    cin >> goTo; 
    if(!b.gameOver) 
     b.makeMove(getPiece(),goTo); 
} 

ComputerPlayer.h

#include <iostream> 
#include <cstdlib> 
#include "Player.h" 
#ifndef COMPUTERPLAYER_H 
#define COMPUTERPLAYER_H 
using namespace std; 

class ComputerPlayer: public Player 
{ 
public: 
    ComputerPlayer(Piece p); 
private: 
    static int counter; 
    //string name; 
}; 

#endif 

ComputerPlayer.cpp

#include <iostream> 
#include <cstdlib> 
#include "ComputerPlayer.h" 
using namespace std; 

ComputerPlayer::ComputerPlayer(Piece p) : Player("", p) 
{ 
    string name = "ComputerPlayer" + char(65+counter); 
    setName(name); 
} 

int ComputerPlayer::counter=0; 

RandomPlayer.h

#include <iostream> 
#include <cstdlib> 
#include "ComputerPlayer.h" 
#ifndef RANDOMPLAYER_H 
#define RANDOMPLAYER_H 
using namespace std; 

class RandomPlayer : public ComputerPlayer 
{ 
public: 
    RandomPlayer(Piece); 
    void makeMove(Board&); 
}; 

#endif 

RandomPlayer.cpp

#include <iostream> 
#include <cstdlib> 
#include "RandomPlayer.h" 
using namespace std; 

RandomPlayer::RandomPlayer(Piece p) : ComputerPlayer(p) 
{ 

} 

void RandomPlayer::makeMove(Board& b) 
{ 
    cout << "Player 2 making move in stuff\n"; 
    b.genMoves(); 
    int temp1 = b.numMoves(); 
    cout << "This is temp1: " <<temp1 << '\n'; 
    int temp2; 
    if(temp1>0) 
    { 
     temp2 = rand()%temp1; 
    } 
    //cout << "This is temp2: " <<temp2 << '\n'; 
    if(!b.gameOver) 
     b.makeMove(getPiece(),b.getMove(temp2)); 
} 

Game.h

// Name: James St-Germain 
// Student #: 0270250 

#include <iostream> 
#include <cstdlib> 
#include "Board.h"; 
#include "HumanPlayer.h" 
#include "RandomPlayer.h" 
#ifndef GAME_H 
#define GAME_H 
using namespace std; 

class Game 
{ 
public: 
    Game(); 
    ~Game(); 
    void selectPlayers(); 
    Player* nextPlayer(); 
    void play(); 
    void announceWinner(); 
private: 
    Board b; 
    Player *p1; 
    Player *p2; 
    bool isRunning; 
}; 

#endif 

Game.cpp

// Name: James St-Germain 
// Student #: 0270250 

#include "Game.h" 
#include <iostream> 
#include <cstdlib> 
#include <string> 
using namespace std; 

Game::Game(): b(), p1(NULL), p2(NULL), isRunning(true){} 

Game::~Game() 
{ 
    delete &b; 
    delete &p1; 
    delete &p2; 
} 

void Game::selectPlayers() 
{ 
    string choice[2]; 
    cout << "Is player 1 a human player or computer player? (H/C): \n"; 
    cin >> choice[0]; 
    cout << "Is player 2 a human player or computer player? (H/C): \n"; 
    cin >> choice[1]; 
    for(int i=0;i<2;++i) 
    { 
     if(choice[i]=="H") 
     { 
      string n; 
      char* c; 
      cout << "What is your name?: \n"; 
      cin >> n; 
      if(i==0) 
       p1 = new HumanPlayer(n, LIGHT); 
      else 
       p2 = new HumanPlayer(n, DARK); 
     } 
     if(choice[i]=="C") 
     { 
      if(i==0) 
       p1 = new RandomPlayer(LIGHT); 
      else 
       p2 = new RandomPlayer(DARK); 
     } 
    } 
    cout << "Player 1 is " << p1->getName() << '\n'; 
    cout << "Player 2 is " << p2->getName() << '\n'; 


} 

Player* Game::nextPlayer() 
{ 
    if(b.getPlayer()==LIGHT) 
     return p2; 
    else 
     return p1; 
} 

void Game::play() 
{ 
    while(isRunning) 
    { 
     b.display(); 
     Piece temp = b.getPlayer(); 
     if(temp==LIGHT) 
     { 
      cout << "Player 1 moves!\n"; 
      p1->makeMove(b); 
     } 
     else 
     { 
      cout << "Player 2 moves!\n"; 
      p2->makeMove(b); 
     } 

     if(b.gameOver==true) 
      break; 
    } 
} 

void Game::announceWinner() 
{ 
    Piece winner = b.getWinner(); 
    string name = (winner==LIGHT) ? p1->getName() : p2->getName(); 
    cout << "The winner is " << name << "! Congratulations!\n"; 
} 

的main.cpp

#include <iostream> 
#include <cstdlib> 
#include "Game.h" 
using namespace std; 

int main() 
{ 
    Game Reversi = Game(); 
    Reversi.selectPlayers(); 
    Reversi.play(); 
    Reversi.announceWinner(); 
} 

我很抱歉代碼太多,但在這一點上,我不知道該怎麼解決。我知道這裏也可能存在不好的編碼習慣,所以如果你看到任何問題,我都會喜歡這種建設性的批評。

非常感謝您的幫助!

+2

通向大量代碼的途徑!你應該儘量縮小它的範圍。一種方法是意識到這個錯誤通常是因爲你寫的超出了分配的內存。 –

回答

3

這是可能因爲你必須在Game類這些聲明:

Board b; 
Player *p1; 
Player *p2; 

這個代碼在析構函數:

delete &b; 
delete &p1; 
delete &p2; 

首先,在Board成員b不一個指針不應該被刪除。其次,您使用的是地址 - 運算符來獲取指針的地址(它將是類型Player**的值),您不分配該地址。丟掉&

+0

請解釋一下嗎? – JStGermain

+0

@JStGermain如果你有一個指針'p'並且使用'&p'中的運算符'&'的地址,你將得到一個指向指針的指針。如果'p'是'Player *'類型,那麼'&p'類型'Player **'。我希望你能發現差異。 –

+0

因此,而不是有 delete&b; 刪除&p1; 刪除&p2; 我應該有 刪除B; 刪除p1; 刪除p2; – JStGermain

相關問題