void SceneGame::startClient(CCObject*obj) { if (Net::Connect("127.0.0.1")) { // 把棋子倒过来 for (int i = 0; i < 32; i++) { Stone* s = _s[i]; s->_row = 9 - s->_row; s->_col = 8 - s->_col; s->setPosition(s->fromPlate()); } // 开始接收 Net::RecvStart(); schedule(schedule_selector(SceneGame::CheckRecv)); Net::_isConnected = true; _bRedSide = false; CCMenuItemFont *font = (CCMenuItemFont *)obj; CCMenuItemFont *server = (CCMenuItemFont *)font->getUserObject(); server->setEnabled(false); font->setEnabled(false); } else { CCLog("Connect failure...."); } }
void SceneGame::doRegret() { // 游戏还没有开始不能悔棋 if (_steps.size() == 0) return; // 恢复最后一步 Step* step = *_steps.rbegin(); _steps.pop_back(); // 具体恢复工作 Stone* s = _s[step->moveid]; s->_row = step->rowFrom; s->_col = step->colFrom; s->setPosition(s->fromPlate()); Stone* kill; if (step->killid != -1) { kill = _s[step->killid]; kill->_dead = false; kill->setVisible(true); } _bRedTurn = !_bRedTurn; delete step; // 避免在选中棋子的情况下,悔棋 _selectid = -1; _selectSprite->setVisible(false); }
Group* StoneHandler::checkNeighbour(int x, int y, StoneColor color, Group *group, Matrix *m) //SL added eb 8 { // CHECK_PTR(group); // CHECK_PTR(m); //added eb 8 bool visible = false ; int size = boardHandler->board->getBoardSize(); //end add eb 8 Stone *tmp = stones->find(Matrix::coordsToKey(x, y)); // Okay, this is dirty and synthetic : // Because we use this function where the matrix can be NULL, we need to check this // Furthermore, since this has been added after the first code, we keep the 'stone->visible' test where one should only use the 'matrix' code if (m != NULL && x-1 >= 0 && x-1 < size && y-1 >= 0 && y-1 < size) //SL added eb 8 visible = (m->at(x - 1, y - 1) != stoneNone); //SL added eb 9 We do this in order not to pass a null matrix to the matrix->at function (seen in handicap games) // again we priviledge matrix over stone visibility (we might be browsing a game) if (tmp != NULL && tmp->getColor() == color && (tmp->isVisible()|| visible)) //SL added eb 8 { if (!group->contains(tmp)) { group->append(tmp); tmp->checked = true; } } return group; }
//判断在走的X,Y轴上,moveID和killID之间有多少个棋子 int GameScene::getStoneCountInSingleXY(int moveID, int killID, int tox, int toy){ int count = 0; Stone* moveStone = sts[moveID]; if (moveStone->getX() != tox && moveStone->getY() != toy){ return -1; } int m_x = moveStone->getX(); int m_y = moveStone->getY(); if (m_x == tox){ int y_min = m_y < toy ? m_y : toy; int y_max = m_y > toy ? m_y : toy; for (int i = y_min + 1; i < y_max; i++){ if (getStoneIDByXY(m_x, i) != -1){ count++; } } } else if (m_y == toy){ int x_min = m_x < tox ? m_x : tox; int x_max = m_x > tox ? m_x : tox; for (int i = x_min + 1; i < x_max; i++){ if (getStoneIDByXY(i, m_y) != -1){ count++; } } } else{ return -1; } return count; }
void GameClass::Stones_Init() { for (int i = 0; i < MAX_STONE_NUM; ++i) { Stone* stone = new Stone(); stone->width = 64; stone->height = 64; stone->foot = 32; stone->Set_img(L"GameMedia\\stone.png"); stone->out_of_map = false; stones[i] = stone; } map<int, Sprite*>::iterator iter; iter = stones.begin(); for (int i = 0; i < GAMEPANEL_HEIGHT; i++) { for (int j = 0; j < GAMEPANEL_WIDTH; j++) { if (WALL[i][j] == 2) { iter->second->world_Y = i; iter->second->world_X = j; if (iter == stones.end()) return; ++iter; } } } }
Stone* Stone::create(int id) { Stone* s = new Stone(); s->init(id); s->autorelease(); return s; };
bool Group::isAttachedTo(Stone *s) { CHECK_PTR(s); int stoneX = s->posX(); int stoneY = s->posY(); int x, y; StoneColor col = s->getColor(), c; Stone *tmp; if (isEmpty()) return false; for (unsigned int i=0; i<size(); i++) { tmp = at(i); x = tmp->posX(); y = tmp->posY(); c = tmp->getColor(); if (((stoneX == x && (stoneY == y-1 || stoneY == y+1)) || (stoneY == y && (stoneX == x-1 || stoneX == x+1))) && c == col) return true; } return false; }
bool GameScene::canMoveBING(int moveID, int killID, int tox, int toy){ Stone* moveStone = sts[moveID]; int m_x = moveStone->getX(); int m_y = moveStone->getY(); int xoff = abs(m_x - tox); int yoff = abs(m_y - toy); int checkXY = xoff * 10 + yoff; if (checkXY != 1 && checkXY != 10){ return false; } if (clickRed == moveStone->getisRed()){//棋盘的下半部分 if (toy < m_y){ return false; } if (m_y <= 4 && m_x != tox){//过河了 return false; } } else{//棋盘的上半部分 if (toy > m_y){ return false; } if (m_y >= 5 && m_x != tox){//过河了 return false; } } return true; }
bool GameScene::canMoveXIANG(int moveID, int killID, int tox, int toy){ Stone* moveStone = sts[moveID]; int m_x = moveStone->getX(); int m_y = moveStone->getY(); int xoff = abs(m_x - tox); int yoff = abs(m_y - toy); if (xoff != 2 || yoff != 2){ return false; } /*判断象眼位置*/ int mid_x = (m_x + tox) / 2; int mid_y = (m_y + toy) / 2; int mid_stone = getStoneIDByXY(mid_x, mid_y); if (mid_stone != -1){ return false; } //如果是在棋盘下面,y如果超过4,就越过楚河汉界了 if (clickRed == sts[moveID]->getisRed()){ if (toy > 4){ return false; } } else{ //如果是在棋盘上面,y如果小于5,就越过楚河汉界了 if (toy < 5){ return false; } } return true; }
bool GameScene::canMoveSHI(int moveID, int tox, int toy){ Stone* moveStone = sts[moveID]; int m_x = moveStone->getX(); int m_y = moveStone->getY(); int xoff = abs(m_x - tox); int yoff = abs(m_y - toy); if (xoff != 1 || yoff != 1){ return false; } /*判断将或帅是否走出9宫格*/ if (tox > 5 || tox < 3){ return false; } if (clickRed == sts[moveID]->getisRed()){ if (toy > 2 || toy < 0){ return false; } } else{ if (toy > 9 || toy < 7){ return false; } } return true; }
bool GameScene::canMoveJIANG(int moveID, int killID, int tox, int toy){ /*如果要杀的对面的将或帅,则直接按车的走法*/ if (killID != -1 && sts[killID]->getType() == Stone::JIANG){ return canMoveJU(moveID, killID, tox, toy); } /*判断是否走的一格*/ Stone* moveStone = sts[moveID]; int m_x = moveStone->getX(); int m_y = moveStone->getY(); int xoff = abs(m_x - tox); int yoff = abs(m_y - toy); int checkXY = xoff * 10 + yoff; if (checkXY != 1 && checkXY != 10){ return false; } /*判断将或帅是否走出9宫格*/ if (tox > 5 || tox < 3){ return false; } if (clickRed == sts[moveID]->getisRed()){ if (toy > 2 || toy < 0){ return false; } } else{ if (toy > 9 || toy < 7){ return false; } } return true; }
int StoneHandler::countLibertiesOnMatrix(Group *group, Matrix *m) { CHECK_PTR(group); CHECK_PTR(m); int liberties = 0; Q3ValueList<int> libCounted; // Walk through the horizontal and vertial directions, counting the // liberties of this group. for (unsigned int i=0; i<group->count(); i++) { Stone *tmp = group->at(i); CHECK_PTR(tmp); int x = tmp->posX(), y = tmp->posY(); // North checkNeighbourLibertyOnMatrix(x, y-1, libCounted, liberties, m); // West checkNeighbourLibertyOnMatrix(x-1, y, libCounted, liberties, m); // South checkNeighbourLibertyOnMatrix(x, y+1, libCounted, liberties, m); // East checkNeighbourLibertyOnMatrix(x+1, y, libCounted, liberties, m); } return liberties; }
bool StoneHandler::removeStone(int x, int y, bool hide) { if (!hasStone(x, y)) return false; if (!hide) { // We delete the killed stones only if we want to update the board (i.e. : not if we are browsing the game) if (boardHandler->getDisplay_incoming_move()) //SL added eb 9 if (!stones->remove(Matrix::coordsToKey(x, y))) { qWarning(" *** Key for stone %d, %d not found! ***", x, y); return false; } } else { Stone *s; if ((s = stones->find(Matrix::coordsToKey(x, y))) == NULL) { qWarning(" *** Key for stone %d, %d not found! ***", x, y); return false; } s->hide(); } return true; }
void SceneGame::CheckRecv(float) { if (Net::isRecvComplete()) { int len; char* data = Net::RecvData(len); unschedule(schedule_selector(SceneGame::CheckRecv)); // 悔棋 if (data[0] == 3) { doRegret2(); // 继续接收 Net::RecvStart(); schedule(schedule_selector(SceneGame::CheckRecv)); } // 选棋 else if (data[0] == 1) { _selectid = data[1]; _selectSprite->setPosition(_s[_selectid]->fromPlate()); _selectSprite->setVisible(true); // 继续接收 Net::RecvStart(); schedule(schedule_selector(SceneGame::CheckRecv)); } else if (data[0] == 2) { // 接受移动信息 Stone* s = _s[data[1]]; int row = 9 - data[2]; int col = 8 - data[3]; int killid = Common::getStoneFromRowCol(row, col, _s); // 记录走棋信息 recordStep(_selectid, killid, _s[_selectid]->_row, _s[_selectid]->_col, row, col); // 移动棋子 s->_row = row; s->_col = col; s->setPosition(s->fromPlate()); // 杀死棋子 if (killid != -1) { Stone* ks = _s[killid]; ks->_dead = true; ks->setVisible(false); } // 更新数据 _selectid = -1; _selectSprite->setVisible(false); _bRedTurn = !_bRedTurn; } } }
void Emerald::show() { Stone *p = head; while (p) { p->print(); p = p->next; } }
// 0 : no stone // -1 : hidden // 1 : shown int StoneHandler::hasStone(int x, int y) { Stone *s; if ((s = stones->find(Matrix::coordsToKey(x, y))) == NULL) return 0; if (s->isVisible()) return 1; return -1; }
void Group::debug() { qDebug(QString("Count: %1 - Liberties: %2").arg(count()).arg(liberties)); const_iterator i; for (i = constBegin(); i != constEnd(); i++) { Stone *s = *i; qDebug(" (%d, %d) %s", s->posX(), s->posY(), s->getColor() == stoneBlack ? "B" : "W"); } }
void GameScene::unfakeMove(Step* step){ int moveID = step->moveID; int killID = step->killID; int moveFromX = step->moveFromX; int moveFromY = step->moveFromY; Stone* moveStone = sts[moveID]; moveStone->setX(moveFromX); moveStone->setY(moveFromY); if (killID != -1){ Stone* killStone = sts[killID]; killStone->setisDead(false); } this->isRedTurn = !this->isRedTurn; }
void Ground::arrange(Stone &stone_to_arrange, int bx, int by) { if (stone_to_arrange.isPassed()) return; // speed-up: int gx = bx / BOARD_WIDTH, gy = by / BOARD_HEIGHT; int gx = bx >> 3, gy = by >> 3; // speed-up: int remx = bx % BOARD_WIDTH, remy = by % BOARD_HEIGHT; int remx = bx & 7ull, remy = by & 7ull; BitBoard arrange = stone_to_arrange.getBitBoard(); BitBoard current = shiftDown(shiftRight(arrange, remx), remy); BitBoard right = shiftDown(shiftLeft(arrange, BOARD_WIDTH - remx), remy); BitBoard bottom = shiftUp(shiftRight(arrange, remx), BOARD_HEIGHT - remy); BitBoard right_bottom = shiftUp(shiftLeft(arrange, BOARD_WIDTH - remx), BOARD_HEIGHT - remy); _obstacle[gy * GROUND_BITBOARD_WIDTH + gx] |= current; _obstacle[gy * GROUND_BITBOARD_WIDTH + gx + 1] |= right; _obstacle[(gy + 1) * GROUND_BITBOARD_WIDTH + gx] |= bottom; _obstacle[(gy + 1) * GROUND_BITBOARD_WIDTH + gx + 1] |= right_bottom; arrangeContact(_contact, stone_to_arrange.getBitBoard(), bx - 1, by); arrangeContact(_contact, stone_to_arrange.getBitBoard(), bx, by - 1); arrangeContact(_contact, stone_to_arrange.getBitBoard(), bx + 1, by); arrangeContact(_contact, stone_to_arrange.getBitBoard(), bx, by + 1); arrangeContact(_right_contact, stone_to_arrange.getBitBoard(), bx - 1, by); arrangeContact(_bottom_contact, stone_to_arrange.getBitBoard(), bx, by - 1); arrangeContact(_left_contact, stone_to_arrange.getBitBoard(), bx + 1, by); arrangeContact(_top_contact, stone_to_arrange.getBitBoard(), bx, by + 1); updateContactAndClosedArray(); }
void GameScene::fakeMove(Step* step){ int moveID = step->moveID; int killID = step->killID; int moveToX = step->moveToX; int moveToY = step->moveToY; if (isCanMove(moveID, killID, moveToX, moveToY)){ Stone* moveStone = sts[moveID]; moveStone->setX(moveToX); moveStone->setY(moveToY); if (killID != -1){ Stone* killStone = sts[killID]; killStone->setisDead(true); } this->isRedTurn = !this->isRedTurn; } }
int Ground::calculateNumBlockInNeumannNeighborhood(Stone &stone_to_arrange, int bx, int by) { // speed-up: int gx = bx / BOARD_WIDTH, gy = by / BOARD_HEIGHT; int gx = bx >> 3, gy = by >> 3; // speed-up: int remx = bx % BOARD_WIDTH, remy = by % BOARD_HEIGHT; int remx = bx & 7ull, remy = by & 7ull; BitBoard arrange = stone_to_arrange.getBitBoard(); BitBoard current = shiftDown(shiftRight(arrange, remx), remy); BitBoard right = shiftDown(shiftLeft(arrange, BOARD_WIDTH - remx), remy); BitBoard bottom = shiftUp(shiftRight(arrange, remx), BOARD_HEIGHT - remy); BitBoard right_bottom = shiftUp(shiftLeft(arrange, BOARD_WIDTH - remx), BOARD_HEIGHT - remy); return countBits(_left_contact[gy * GROUND_BITBOARD_WIDTH + gx] & current) + countBits(_left_contact[gy * GROUND_BITBOARD_WIDTH + gx + 1] & right) + countBits(_left_contact[(gy + 1) * GROUND_BITBOARD_WIDTH + gx] & bottom) + countBits(_left_contact[(gy + 1) * GROUND_BITBOARD_WIDTH + gx + 1] & right_bottom) + countBits(_right_contact[gy * GROUND_BITBOARD_WIDTH + gx] & current) + countBits(_right_contact[gy * GROUND_BITBOARD_WIDTH + gx + 1] & right) + countBits(_right_contact[(gy + 1) * GROUND_BITBOARD_WIDTH + gx] & bottom) + countBits(_right_contact[(gy + 1) * GROUND_BITBOARD_WIDTH + gx + 1] & right_bottom) + countBits(_top_contact[gy * GROUND_BITBOARD_WIDTH + gx] & current) + countBits(_top_contact[gy * GROUND_BITBOARD_WIDTH + gx + 1] & right) + countBits(_top_contact[(gy + 1) * GROUND_BITBOARD_WIDTH + gx] & bottom) + countBits(_top_contact[(gy + 1) * GROUND_BITBOARD_WIDTH + gx + 1] & right_bottom) + countBits(_bottom_contact[gy * GROUND_BITBOARD_WIDTH + gx] & current) + countBits(_bottom_contact[gy * GROUND_BITBOARD_WIDTH + gx + 1] & right) + countBits(_bottom_contact[(gy + 1) * GROUND_BITBOARD_WIDTH + gx] & bottom) + countBits(_bottom_contact[(gy + 1) * GROUND_BITBOARD_WIDTH + gx + 1] & right_bottom); }
bool Ground::checkNotCollideAndContact(Stone &stone_to_arrange, int bx, int by) { // speed-up: int gx = bx / BOARD_WIDTH, gy = by / BOARD_HEIGHT; int gx = bx >> 3, gy = by >> 3; // speed-up: int remx = bx % BOARD_WIDTH, remy = by % BOARD_HEIGHT; int remx = bx & 7, remy = by & 7; BitBoard arrange = stone_to_arrange.getBitBoard(); BitBoard current = shiftDown(shiftRight(arrange, remx), remy); BitBoard right = shiftDown(shiftLeft(arrange, BOARD_WIDTH - remx), remy); BitBoard bottom = shiftUp(shiftRight(arrange, remx), BOARD_HEIGHT - remy); BitBoard right_bottom = shiftUp(shiftLeft(arrange, BOARD_WIDTH - remx), BOARD_HEIGHT - remy); int c_idx = gy * GROUND_BITBOARD_WIDTH + gx; int r_idx = gy * GROUND_BITBOARD_WIDTH + gx + 1; int b_idx = (gy + 1) * GROUND_BITBOARD_WIDTH + gx; int rb_idx = (gy + 1) * GROUND_BITBOARD_WIDTH + gx + 1; bool collide = (_obstacle[c_idx] & current) || (_obstacle[r_idx] & right) || (_obstacle[b_idx] & bottom) || (_obstacle[rb_idx] & right_bottom); bool contact = (_contact[c_idx] & current) || (_contact[r_idx] & right) || (_contact[b_idx] & bottom) || (_contact[rb_idx] & right_bottom); return !collide && contact; }
bool GameScene::canMoveMA(int moveID, int killID, int tox, int toy){ Stone* moveStone = sts[moveID]; int m_x = moveStone->getX(); int m_y = moveStone->getY(); int xoff = abs(m_x - tox); int yoff = abs(m_y - toy); int checkXY = xoff * 10 + yoff; if (checkXY != 12 && checkXY != 21){ return false; } if (xoff == 2 && (getStoneIDByXY((m_x + tox) / 2, m_y) != -1)){ return false; } else if (yoff == 2 && (getStoneIDByXY(m_x, (m_y + toy) / 2) != -1)){ return false; } else{} return true; }
void StoneHandler::updateDeadMarks(int &black, int &white) { Q3IntDictIterator<Stone> it(*stones); Stone *s; while (it.current()) { s = it.current(); CHECK_PTR(s); if (s->isDead()) { if (s->getColor() == stoneBlack) white ++; else black ++; } ++it; } }
bool GameScene::rabbitHitByStone() { int rabbitX = rabbit->getX(); int rabbitY = rabbit->getY(); for (StoneAnimation *s: stones) { Stone *stone = s->getStone(); int stoneX = stone->getX(); int stoneY = stone->getY(); float stoneScale = stone->getScale(); if (pow((stoneX-rabbitX), 2.) + pow((stoneY-rabbitY), 2.) < pow(STONE_HIT_DISTANCE, 2.) && stoneScale > .5) { stone->setHidden(true); return true; } } return false; }
bool GameScene::isCanMove(int moveID, int killID, int tox, int toy){ /*根据要移动的棋子的类型来分别判断*/ Stone* moveStone = sts[moveID]; switch (moveStone->getType()){ case Stone::JIANG: return canMoveJIANG(moveID, killID, tox, toy); case Stone::SHI: return canMoveSHI(moveID, tox, toy); case Stone::XIANG: return canMoveXIANG(moveID, killID, tox, toy); case Stone::JU: return canMoveJU(moveID, killID, tox, toy); case Stone::MA: return canMoveMA(moveID, killID, tox, toy); case Stone::PAO: return canMovePAO(moveID, killID, tox, toy); case Stone::BING: return canMoveBING(moveID, killID, tox, toy); default:return false; } }
void GameStartLayer::regret(CCObject *) { if (_steps.size() == 0) { return; } Step *step = *_steps.rbegin(); _steps.pop_back(); //! 具体恢复工作 Stone *s = _s[step->moveid]; s->_proper._row = step->rowFrom; s->_proper._col = step->colFrom; s->setPosition(s->fromPlate()); Stone *killed; if (step->killid != -1) { killed = _s[step->killid]; killed->_dead = false; killed->setVisible(true); } delete step; //! 隐藏选中框 _selectid = -1; //_selectedSprite->setVisible(false); _selectedSprite->setPosition(s->getPosition()); }
void StoneHandler::debug() { qDebug("StoneHandler::debug()"); #if 0 Q3IntDictIterator<Stone> its(*stones); Stone *s; while (its.current()) { s = its.current(); qDebug("%d -> %s", its.currentKey(), s->getColor() == stoneBlack ? "Black" : "White"); ++its; } #endif Q3PtrListIterator<Group> it(*groups); for (; it.current(); ++it) { Group *g = it.current(); g->debug(); } }
bool Ground::contactWithStones(Stone &stone_to_arrange, int bx, int by) { // speed-up: int gx = bx / BOARD_WIDTH, gy = by / BOARD_HEIGHT; int gx = bx >> 3, gy = by >> 3; // speed-up: int remx = bx % BOARD_WIDTH, remy = by % BOARD_HEIGHT; int remx = bx & 7, remy = by & 7; BitBoard arrange = stone_to_arrange.getBitBoard(); BitBoard current = shiftDown(shiftRight(arrange, remx), remy); BitBoard right = shiftDown(shiftLeft(arrange, BOARD_WIDTH - remx), remy); BitBoard bottom = shiftUp(shiftRight(arrange, remx), BOARD_HEIGHT - remy); BitBoard right_bottom = shiftUp(shiftLeft(arrange, BOARD_WIDTH - remx), BOARD_HEIGHT - remy); return (_contact[gy * GROUND_BITBOARD_WIDTH + gx] & current) || (_contact[gy * GROUND_BITBOARD_WIDTH + gx + 1] & right) || (_contact[(gy + 1) * GROUND_BITBOARD_WIDTH + gx] & bottom) || (_contact[(gy + 1) * GROUND_BITBOARD_WIDTH + gx + 1] & right_bottom); }
void StoneHandler::checkNeighbourLiberty(int x, int y, Q3ValueList<int> &libCounted, int &liberties, Matrix *m) //SL added eb 8 { if (!x || !y) return; Stone *s; // CHECK_PTR(m); // SL added eb 8 if (m==NULL) //added eb 8 -> we don't have a matrix passed here, so we check on the board { if (x <= boardHandler->board->getBoardSize() && y <= boardHandler->board->getBoardSize() && x >= 0 && y >= 0 && !libCounted.contains(100*x + y) && ((s = stones->find(Matrix::coordsToKey(x, y))) == NULL || !s->isVisible())) { libCounted.append(100*x + y); liberties ++; } } else { if (x <= boardHandler->board->getBoardSize() && y <= boardHandler->board->getBoardSize() && x >= 0 && y >= 0 && !libCounted.contains(100*x + y) && (m->at(x - 1, y - 1) == stoneNone )) // ?? check stoneErase ? { libCounted.append(100*x + y); liberties ++; } // end add eb 8 } }