- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
我知道这个问题在这些论坛上被评估过很多次,但大多数时候它们确实是针对特定案例的。
这是一个类(class)项目(同样使用 C++),该项目的目的是重制经典棋盘游戏 Reversi。
我辛苦编写了几个小时的代码,终于编写了一个可以运行的程序,至少我是这么认为的!
我遇到的大问题似乎来自于我的解构器,因为它给了我这个我们许多人都见过的错误。我的代码发布在下面,根据我自己的调试代码(使用有用的 cout 消息),我确定该程序设法运行到 Game.cpp 类的末尾。只是,它在解构器上偶然发现并崩溃,然后才最终“很好地结束”。
棋盘.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
板.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;
播放器.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
播放器.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;
}
人类玩家.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
人类玩家.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
电脑播放器.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;
随机播放器.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
随机播放器.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));
}
游戏.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
游戏.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();
}
对于过多的代码,我深表歉意,但在这一点上,我不知道要修复什么。我知道这里也可能存在不良的编码习惯,所以如果您发现任何问题,我很乐意提出建设性的批评。
预先感谢您的所有帮助!!
最佳答案
这可能是因为您在 Game
类中有这些声明:
Board b;
Player *p1;
Player *p2;
以及析构函数中的这段代码:
delete &b;
delete &p1;
delete &p2;
首先,Board
成员b
不是指针,因此不应删除。其次,您使用地址运算符获取指针的地址 (它将是 Player**
类型的值),您不要分配。删除 &
。
关于c++ - 调试断言失败!表达式 : _BLOCK_TYPE_IS_VALID(pHead->nBlockUse),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20279293/
我遇到了这个问题: 调试断言失败! 文件:f:\dd\vctools\crt_bld\self_x86\crt\dbgdel.cpp 第 52 行 表达式“_BLOCK_TYPE_IS_VALID(p
我在这里查看了类似的问题,但仍然无法意识到我做错了什么。请帮忙。 我需要为大小有限的字符串类制作模板(就像在 Pascal 中一样)代码如下:http://pastebin.com/syZf3yM8
我打算写一个程序,使用虚函数做多边形计算,但是当我完成这个程序后,出现 BLOCK_TYPE_IS_VALID(pHead -> nBlockUse) 错误 // pointers to base c
首先,我将向您展示我的代码。 std::ifstream file("accounts/22816.txt"); if(file){ char *str[50]; int count=0;
我有一个错误“_BLOCK_TYPE_IS_VALID(pHead->nBlockUse)”,我不知道该怎么办.. person.h #ifndef _person_H #define _person
这个问题在这里已经有了答案: What is The Rule of Three? (8 个答案) 关闭 8 年前。 我知道这是一个常见错误,所以我尝试创建一个最小示例。我认为这是因为我试图释放堆栈
我在下面代码的最后一行遇到错误“_BLOCK_TYPE_IS_VALID(pHead->nBlockUse)”: pixelCoorindateAndThreePoint* tempSpace = n
这个问题在这里已经有了答案: What is the behavior of "delete" with stack objects? [duplicate] (1 个回答) 关闭 6 年前。 我是
我正在尝试修复一个非常严重的内存泄漏,但不知何故我无法在不触发此断言的情况下删除对象。 我已通过 Google 搜索了解决方案,并已阅读有关此错误的 Stackoverflow 上的问题,但我仍然无法
我一直在从事一个新项目,但遇到了一个我不知道为什么会失败的问题。 当我执行此行删除 textY 时,给我错误 _Block_Type_Is_Valid (pHead->nBlockUse)。那我做错了
我想弄清楚为什么我的程序在运行时会失败。到目前为止,当我运行我的程序时,它对我失败了。我调试了错误,它把我带到了 dbgdel.cpp。第 32 行“_ASSERTE(_BLOCK_TYPE_IS_V
我不知道为什么我总是收到 _Block_Type_Is_Valid (pHead->nBlockUse) 错误。我知道这通常是因为我双重删除了一些东西但我只在代码中使用了一次删除。以下是代码。 Box
我知道有几篇关于此错误的帖子,但它们都是针对特定情况的。我正在制作一个文件拆分/连接器,它具有以下要求:-用户必须输入文件名/输入路径和输出文件夹。我用将原始文件拆分为 N 部分(用户必须输入)的基本
我现在很迷茫。我做了一个 vector 类。一切都按照我希望的方式工作,直到最后。当调用析构函数时,我收到一条错误消息:调试断言失败 BLOCK_TYPE_IS_VALID(pHead->nblock
通过引用“_BLOCK_TYPE_IS_VALID(pHead->nBlockUse)”添加参数后调试断言失败。 class Stack { private: const std::uint3
我知道这个问题在这些论坛上被评估过很多次,但大多数时候它们确实是针对特定案例的。 这是一个类(class)项目(同样使用 C++),该项目的目的是重制经典棋盘游戏 Reversi。 我辛苦编写了几个小
此错误发生在运行时,我不确定是什么原因导致的 - 代码对我来说看起来是正确的。 #include #include using namespace std; struct Room { i
我想弄清楚为什么会出现此错误。我已经看到很多关于相同的问题/答案,但我只是没有看到任何可能导致我的代码出现此错误的原因。 根据我一直在做的研究,这个错误的可能原因是: 1 - 我不止一次删除对象 2
我有一段简单的代码: struct A { char* str; A() : str(NULL) {} ~A() { delete[] str;
当此函数运行时,我收到调试断言错误,如 sprite = spr; 行标题中所述.如果我添加 sprite.reset();在此之前,它在 sprite.reset(); 线上崩溃.指针存储在别处,在
我是一名优秀的程序员,十分优秀!