📄 reversiboard.cpp
字号:
#include <monapi.h>#include "ReversiBoard.h"using namespace MonAPI;/** * コンストラクタ */ReversiBoard::ReversiBoard() { init();}/** * 回年された娥が茸烫惧にいくつあるかを眶える * @param piece <code>ReversiBoard.WHITE, ReversiBoard.BLACK, ReversiBoard.EMPTY</code> * @return 娥の改眶 */int ReversiBoard::countPieces(int piece) { int result = 0; // 娥の改眶を眶える for (int x = 0; x < BOARDW; x++) { for (int y = 0; y < BOARDH; y++) { if (this->board[x][y] == piece) result++; } } return result;}/** * 回年された疤弥の娥を手す * @param x (x, y) 娥の疤弥 * @param y (x, y) 娥の疤弥 * @return 娥 茸烫の认跋嘲の眷圭は<code>ReversiBoard.EMPTY</code> */int ReversiBoard::getPiece(int x, int y) { // x, yの认跋をチェック if (!checkRange(x, y)) return EMPTY; // 娥を手す return board[x][y];}/** * 回年された疤弥の娥を手す * @param point 娥の疤弥 * @return 娥 茸烫の认跋嘲の眷圭は<code>ReversiBoard.EMPTY</code> */int ReversiBoard::getPiece(Point* point) { return getPiece(point->x, point->y);}/** * 附哼の缄戎のプレイヤ〖を手す<code>ReversiBoard.EMPTY</code>を手したときは尽砷の疯缅がついている觉轮<BR> * @return 附哼の缄戎のプレイヤ〖 <code>ReversiBoard.BLACK, WHITE, EMPTY</code> */int ReversiBoard::getCurrentHand() const { return this->currentHand;}/** * 回年された疤弥に娥を弥く。<BR> * 娥が弥けた眷圭、弥いた眷疥を绩す。<BR> * <code>Point</code>がnotifyObserversで<BR> * 雌浑傅に奶梦される * @param x (x, y) 娥の疤弥 * @param y (x, y) 娥の疤弥 * @param piece 弥く娥 * @return 娥が弥けたら<code>true</code>, 娥が弥けなかったら<code>false</code> */bool ReversiBoard::setPiece(int x, int y, int piece) { int numReversiblePieces; // 微手すことのできる娥眶 // 附哼の缄と救圭 if (currentHand != piece) return false; // 涟缄が窗链に姜位したかどうかをチェック if (existNotReversedPieces()) return false; // そこに弥けるかどうかを拇べる numReversiblePieces = countReversiblePieces(x, y, piece); if (numReversiblePieces <= 0) return false; // pieceを(x, y)に弥いたときに、微手す娥をすべて淡脖 recordReversiblePieces(x, y, piece); // 娥を弥く board[x][y] = piece; // タ〖ンを淡脖 allTurns->add(new Point3D(x, y, piece)); // 恃构をObserverに奶梦 this->setChanged(); this->notifyObservers(new Point(x, y)); this->clearChanged(); return true;}/** * <code>setPiece()</code>した稿に、微手してない娥が赂哼するかを手す<BR> * <pre> * 蝗脱数恕 * board.setPiece(3, 5, OthlloBoard::BLACK); * while (existNotReversedPieces()) { * reverseNext(); * // 闪茶脱借妄 * } * </pre> * @return 微手してない娥が赂哼する眷圭<code>true</code> */bool ReversiBoard::existNotReversedPieces() { return allNotReversedPieces->size() > 0;}/** * 肌の娥を微手す<BR> * 微手した眷疥を绩す<code>Point</code>がnotifyObserversで雌浑傅に奶梦される * existNotReversedPieces()の蝗脱数恕を徊救 */void ReversiBoard::reverseNext() { // 微手す疤弥を艰评 Point* point = allNotReversedPieces->get(0); // 微手す reversePiece(point->x, point->y); // 恃构を奶梦 this->setChanged(); notifyObservers(new Point(point)); this->clearChanged(); // 微手したので疤弥を久殿 allNotReversedPieces->removeAt(0); return;}/** * 附哼タ〖ンを手す * @return 附哼タ〖ン */int ReversiBoard::getTurn() const { return this->turn;}/** * undo怠墙 * 1缄提る */void ReversiBoard::undo() { // 1缄涟に提れない眷圭 if (getTurn() < 1) return; // 茸烫介袋步 initBoard(); // 茸烫事べなおし for (int i = 0; i < allTurns->size() -1; i++) { // 娥を弥く Point3D* p = allTurns->get(i); setPiece(p->x, p->y, p->z); while (existNotReversedPieces()) { reverseNext(); } } // 呵稿のタ〖ンを久殿 allTurns->removeAt(allTurns->size() -1); return;}/** * 回年された疤弥に娥を弥いたときに、いくつ娥が微手せるかを手す * @param x * @param y * @param piece 弥く娥 * @return 微手せる娥眶 */int ReversiBoard::countReversiblePieces(int x, int y, int piece) { int result = 0; // x, yの认跋をチェック if (!checkRange(x, y)) return 0; // すでに娥が弥かれているかをチェック if (board[x][y] != EMPTY) return 0; // (x, y)にpieceを弥いた眷圭に微手すことのできる娥を8数羹に玫瑚 result += countReversiblePieceToOneAngle(x, y, 1, 0, piece, false); result += countReversiblePieceToOneAngle(x, y, 1, 1, piece, false); result += countReversiblePieceToOneAngle(x, y, 0, 1 ,piece, false); result += countReversiblePieceToOneAngle(x, y, -1, 1, piece, false); result += countReversiblePieceToOneAngle(x, y, -1, 0, piece, false); result += countReversiblePieceToOneAngle(x, y, -1, -1, piece, false); result += countReversiblePieceToOneAngle(x, y, 0, -1, piece, false); result += countReversiblePieceToOneAngle(x, y, 1, -1, piece, false); return result;}/** * リバ〖シ茸をリセットする */void ReversiBoard::resetBoard() { delete (this->allTurns); this->allTurns = new HList<Point3D*>(); initBoard(); // 恃构を奶梦 this->setChanged(); this->notifyObservers(NULL); this->clearChanged(); return;}/** * ReversiBoard栏喇と介袋步を乖う */void ReversiBoard::init() { // 茸烫介袋步 initBoard(); // すべてのタ〖ンを淡脖するVector介袋步 allTurns = new HList<Point3D*>(); return;}/** * 茸烫介袋步乖う */void ReversiBoard::initBoard() { // 附哼タ〖ンを肋年 this->turn = 0; // 黎缄は辊 this->currentHand = BLACK; // 茸烫を鄂にする for (int x = 0; x < BOARDW; x++) { for (int y = 0; y < BOARDH; y++) board[x][y] = EMPTY; } // 介袋觉轮で弥かれている娥をセット board[3][3] = BLACK; board[4][4] = BLACK; board[4][3] = WHITE; board[3][4] = WHITE; // 微手すべき娥のすべて疤弥を淡脖するList介袋步 allNotReversedPieces = new HList<Point*>(); return;}/** * 回年した娥を微手す */void ReversiBoard::reversePiece(int x, int y) { // x, yの认跋をチェック if (!checkRange(x, y)) return; // 娥を微手す帳もし鄂なら部もしない board[x][y] = turnColor(board[x][y]); return;}/** * 掐蜗された猛が茸烫惧に赂哼するかチェックする */bool ReversiBoard::checkRange(int x, int y) { // 茸烫惧にあるという掘凤 bool xRange = x >= 0 && x < BOARDW; bool yRange = y >= 0 && y < BOARDH; // 茸烫惧にある if (xRange && yRange) return true; // 茸烫惧にない return false;}/** * 回年されたベクトル(toX, toY)の数羹へ微手せる娥眶を眶える * reordFlagがtrueの箕は疤弥を淡脖 */int ReversiBoard::countReversiblePieceToOneAngle(int x, int y, int toX,int toY , int piece, bool recordFlag) { int result = 0; // 钨の娥へ败瓢 x += toX; y += toY; // 茸烫の眉まで玫瑚を鲁ける while (x >= 0 && y >= 0 && x < BOARDW && y < BOARDH) { // 玫瑚面の娥が微手しの咖なら微手せる if (board[x][y] == turnColor(piece)) { // 微手せる娥の疤弥を淡脖 if (recordFlag) allNotReversedPieces->add(new Point(x, y)); // 娥眶インクリメント result++; } // 票じ咖だったら、そこまであった微手し咖を微手すことができる else if (board[x][y] == piece) return result; // 鄂なら微手せない else if (board[x][y] == EMPTY) { if (recordFlag) { // 淡脖していた娥の疤弥 for (int i = 0; i < result; i++) { allNotReversedPieces->removeAt(allNotReversedPieces->size() - 1); } } return 0; } // さらに钨の娥へ败瓢 x += toX; y += toY; } if (recordFlag) { // 淡脖していた娥の疤弥 for (int i = 0; i < result; i++) { allNotReversedPieces->removeAt(allNotReversedPieces->size() - 1); } } return 0;}/** * 微手した咖を手す */int ReversiBoard::turnColor(int piece) { return piece * -1;}/** * pieceを(x, y)に弥いたときに、微手す娥をすべて淡脖 */bool ReversiBoard::recordReversiblePieces(int x, int y, int piece) { // x, yの认跋をチェック if (!checkRange(x, y)) return false; // すでに娥が弥かれているかをチェック if (board[x][y] != EMPTY) return false; // 娥疤弥淡脖オブジェクトを介袋步 delete allNotReversedPieces; allNotReversedPieces = new HList<Point*>(); // 微手せる疤弥を淡脖 countReversiblePieceToOneAngle(x, y, 1, 0, piece, true); countReversiblePieceToOneAngle(x, y, 1, 1, piece, true); countReversiblePieceToOneAngle(x, y, 0, 1 ,piece, true); countReversiblePieceToOneAngle(x, y, -1, 1, piece, true); countReversiblePieceToOneAngle(x, y, -1, 0, piece, true); countReversiblePieceToOneAngle(x, y, -1, -1, piece, true); countReversiblePieceToOneAngle(x, y, 0, -1, piece, true); countReversiblePieceToOneAngle(x, y, 1, -1, piece, true); return true;}// 肌缄のプレイヤ〖を冉们void ReversiBoard::setNextHand() { if (isTherePlace(turnColor(currentHand))) { currentHand = turnColor(currentHand); } else if (isTherePlace(currentHand)) { // 鲁けてもう1缄 } else { // 尉プレイヤ〖鼎に弥く眷疥がない currentHand = EMPTY; } return;}// 茸烫惧に回年されたpieceをおくことができるかを冉们bool ReversiBoard::isTherePlace(int piece) { int result = 0; // 娥の改眶を眶える for (int x = 0; x < BOARDW; x++) { for (int y = 0; y < BOARDH; y++) { result += countReversiblePieces(x, y, piece); } } return result > 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -