我知道这些问题在这些论坛上经过多次评估,但它们在大多数情况下都是独特的。
这是一个类的项目(在C ++上也不少),项目的重点是重制经典的棋盘游戏Reversi。
我已经通过代码工作了几个小时,最后制作了一个可以工作的程序,或者我想到了!
我遇到的一个大问题似乎来自我的解构主义者,因为它给了我许多人看到的这个错误。我的代码发布在下面,来自我自己的调试代码(使用有用的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();
}
我为极端数量的代码道歉,但在这一点上,我不知道该解决什么问题。我知道这里可能还有不良的编码习惯,所以如果你看到了,我会喜欢建设性的批评。
提前感谢您的帮助!!
答案 0 :(得分:3)
这可能是 因为你在Game
类中有这些声明:
Board b;
Player *p1;
Player *p2;
和析构函数中的代码:
delete &b;
delete &p1;
delete &p2;
首先,Board
成员b
不是指针,因此不应删除。其次,您正在使用address-of运算符来获取指针的地址(它将是Player**
类型的值),您不会分配它。放下&
。