c++ - 类 draw() 方法在直接调用时有效,但在被另一个对象调用时崩溃

标签 c++ tic-tac-toe

<分区>

我正在制作一个九板井字游戏版本。 (每一步决定了对方玩家必须移动的棋盘)

我的标准 Board 可以很好地绘制: gameplay->board->draw(w, h, d);

但是当我尝试绘制一组 3x3 的 Board 来制作整个游戏在其上运行的 SuperBoard 时,单个 Boards 给 EXC_BAD_ACCESS on: gameplay->superBoard->drawBig(w, h, d);

我哪里错了?

代码:

游戏板.h:

struct Location {
  int col;
  int row;
  int err;
};

class Board {
public:
  // ctor
  Board();
  ~Board();

  // func
  void draw(float w, float h, float d);
  void draw(float x, float y, float w, float h, float d);
  int move(int col, int row, int player);
  int getWinCount(int player);
  bool isFull();

private:
  int squares[3][3];
};

class SuperBoard {
public:
  // ctor
  SuperBoard();
  ~SuperBoard();

  // func
  void drawBig(float w, float h, float d);
  int getWinCount(int player);
  Location move(int col, int row, int player);

  // vars
  Board* boards[3][3];
};

游戏板.cpp:

#include "gameBoard.h"
#import "ProjectHeader.h"

Board::Board() {
  // init vars
  winCountPlayer1 = winCountPlayer2 = 0;
  // init board
  for (int i=0; i<3; i++) {
    for (int j=0; j<3; j++) {
      squares[i][j] = 0;
    }
  }
}

Board::~Board() {

}

void Board::draw(float x, float y, float w, float h, float d) {
  ofPushMatrix();
  ofTranslate(x, y);
  // first, draw the basic board:
  float border = SCREEN_BORDER * (w / ofGetWidth());
  // vert
  ofLine(w/2 - d/6, h/2 - (d/2 - border), w/2 - d/6, h/2 + (d/2 - border));
  ofLine(w/2 + d/6, h/2 - (d/2 - border), w/2 + d/6, h/2 + (d/2 - border));

  // horiz
  ofLine(w/2 - (d/2 - border), h/2 - d/6, w/2 + (d/2 - border), h/2 - d/6);
  ofLine(w/2 - (d/2 - border), h/2 + d/6, w/2 + (d/2 - border), h/2 + d/6);


  // then draw the moved moves:
  for (int i=0; i<3; i++) {
    for (int j=0; j<3; j++) {
      if (squares[i][j] == 1) { // X
        ofSetColor(player1color);
        // descending stroke:
        ofLine(i*d/3 + (w/2 - d/2),
               j*d/3 + (h/2 - d/2),
               i*d/3 + w/2 - d/2 + d/3,
               j*d/3 + h/2 - d/2 + d/3);
        // ascending stroke:
        ofLine(i*d/3 + w/2 - d/2, 
               j*d/3 + h/2 - d/2 + d/3, 
               i*d/3 + w/2 - d/2 + d/3, 
               j*d/3 + h/2 - d/2);
      } else if (squares[i][j] == 2) { // O
        ofSetColor(player2color);
        ofCircle(i*d/3 + w/2 - d/3, j*d/3 + h/2 - d/3, d/6);
      }
    }
  }

  // then draw a line through any wins:
  ofSetLineWidth(d*0.03);
  for (int i=0; i<3; i++) {
    // check rows
    if (squares[i][0] == squares[i][1] && squares[i][1] == squares[i][2] && squares[i][2] != 0) {
      ofSetColor(squares[i][0] == 1 ? player1win : player2win);
      ofLine(w/2 - d/3 + i*(d/3), h/2 - d/2, w/2 - d/3 + i*(d/3), h/2 + d/2);
    }
    // check columns
    if (squares[0][i] == squares[1][i] && squares[1][i] == squares[2][i] && squares[2][i] != 0) {
      ofSetColor(squares[0][i] == 1 ? player1win : player2win);
      ofLine(w/2 - d/2, h/2 - d/3 + i*(d/3), w/2 + d/2, h/2 - d/3 + i*(d/3));

    }
    // check diagonals
    if (squares[0][0] == squares[1][1] && squares[1][1] == squares[2][2] && squares[2][2] != 0) {
      ofSetColor(squares[0][0] == 1 ? player1win : player2win);
      ofLine(w/2 - d/2, h/2 - d/2, w/2 + d/2, h/2 + d/2);
    }
    if (squares[0][2] == squares[1][1] && squares[1][1] == squares[2][0] && squares[2][0] != 0) {
      ofSetColor(squares[0][2] == 1 ? player1win : player2win);
      ofLine(w/2 - d/2, h/2 + d/2, w/2 + d/2, h/2 - d/2);
    }
  }
  ofPopMatrix();
}

void Board::draw(float w, float h, float d) {
  ofSetColor(0);
  ofNoFill();
  ofSetLineWidth(d*0.02);
  ofSetCircleResolution(100);

  draw(0, 0, w, h, d);
}

int Board::move(int _c, int _r, int player) {
  // first, see if we can legally move here:
  if (squares[_c][_r] == 0) {
    squares[_c][_r] = player;
    // then, see if the move caused a win:
    int wincount = getWinCount(player);
    // return the player who won, or zero if no win yet
    if (wincount > 0) {
      return player;
    } else return GAME_STATE_NORMAL;
    // otherwise return an error:
  } else if (squares[_c][_r] == player) {
    return ERROR_SQUARE_TAKEN_BY_PLAYER;
  } else {
    return ERROR_SQUARE_TAKEN_BY_OPPONENT;
  }
}

int Board::getWinCount(int player) {
  cout << "Board state:" << endl;
  for (int i=0; i<3; i++) {
    for (int j=0; j<3; j++) {
      cout << squares[j][i] << " ";
    }
    cout << endl;
  } cout << endl;

  // For multi-board games this now handles more than one win per board.
  int wincount = 0;
  for (int i=0; i<3; i++) {
    // check rows
    if (squares[i][0] == squares[i][1] && 
        squares[i][1] == squares[i][2] && 
        squares[i][2] == player) wincount++;
    // check columns
    if (squares[0][i] == squares[1][i] && 
        squares[1][i] == squares[2][i] && 
        squares[2][i] == player) wincount++;
  }
  // check diagonals
  if (squares[0][0] == squares[1][1] && 
      squares[1][1] == squares[2][2] && 
      squares[2][2] == player) wincount++;
  if (squares[0][2] == squares[1][1] && 
      squares[1][1] == squares[2][0] && 
      squares[2][0] == player) wincount++;

  return wincount;
}

bool Board::isFull() {
  for (int i=0; i<3; i++) {
    for (int j=0; j<3; j++) {
      if (squares[i][j] == 0) return false;
    }
  }
  return true;
}

//---------------------------------------- // super 板代码: //--------------------------------------------

SuperBoard::SuperBoard() {
  for (int i=0; i<3; i++) {
    for (int j=0; j<3; j++) {
      boards[j][i] = new Board();
    }
  }
}

SuperBoard::~SuperBoard() {

}

void SuperBoard::drawBig(float w, float h, float d) {
  ofSetColor(0);
  ofSetLineWidth(d*0.02);
  // first, draw the big board dividing lines:
  float border = SCREEN_BORDER;
  // vert
  ofLine(w/2 - d/6, h/2 - (d/2 - border), w/2 - d/6, h/2 + (d/2 - border));
  ofLine(w/2 + d/6, h/2 - (d/2 - border), w/2 + d/6, h/2 + (d/2 - border));

  // horiz
  ofLine(w/2 - (d/2 - border), h/2 - d/6, w/2 + (d/2 - border), h/2 - d/6);
  ofLine(w/2 - (d/2 - border), h/2 + d/6, w/2 + (d/2 - border), h/2 + d/6);

  // then, draw each of our small boards in place:
  float _d = d/3;
  float _w = w/3;
  float _h = h/3;
  for (int i=0; i<3; i++) {
    for (int j=0; i<3; j++) {
      float _x = (w/2 - d/2) + i * _d;
      float _y = (h/2 - d/2) + j * _d;
      boards[i][j]->draw(_x, _y, _w, _h, _d);
    }
  }
}

int SuperBoard::getWinCount(int player) {
  int winCount;
  for (int i=0; i<3; i++) {
    for (int j=0; i<3; j++) {
      winCount += boards[i][j]->getWinCount(player);
    }
  }
  return winCount;
}

Location SuperBoard::move(int col, int row, int player) {
  int result;
  for (int i=0; i<3; i++) {
    for (int j=0; i<3; j++) {
      if (boards[j][i]->isActive()) {
        result = boards[j][i]->move(col, row, player);
      }
      boards[j][j]->setIsActive(false);
    }
  }
  Location loc;
  if (result >= 0) {
    loc.col = col;
    loc.row = row;
    boards[col][row]->setIsActive(true);
    loc.err = 0;
  } else {
    loc.err = result;
  }

  return loc;
}

最佳答案

这条线看起来很可疑

for (int j=0; i<3; j++)

也许应该是

对于 (int j=0; j<3; j++)

关于c++ - 类 draw() 方法在直接调用时有效,但在被另一个对象调用时崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7387988/

相关文章:

c++ - 如何调整 Eclipse 的 C++ 索引器?

c++ - 自定义字符串类实现建议?

javascript - 无法从函数打印字符串(在 React tictactoe 教程中)

java - 极小极大井字游戏 : Computer sometimes losing when Player goes first; works otherwise

Java - 使用多个堆栈允许 'undo' 方法

c - TicTacToe 的 Minimax 算法无法正常工作

c++ - vector 的 vector ,保留

c++ - 调试断言失败_BLOCK_TYPE_IS_VALID(pHead->nBlockUse)

c++ - 由于下载由 libcurl 接收的 utf8 编码的 xml 数据而导致字符串损坏

Python turtle 井字游戏