static void downOneLine (void) { if (canMoveDown()) { ses->winy++; } else { alert(ALERT_BOUNCE); } }
void TableViewWidget::notifySelectionChanged() { if (m_model) { emit canMoveUpChanged(canMoveUp()); emit canMoveDownChanged(canMoveDown()); emit needsActionsUpdate(); } }
void ItemTortoise::move(float dt) { if (isFarAwayFromMario()) { removeFromParent(); return; } if (_status == SLEEP || _status ==DEAD || !isLeftInWindow()) { return ; } // 根据方向,再具体确定 if (_dir == Common::LEFT) { if (canMoveLeft(dt)) { moveLeft(dt); } else { _dir = Common::RIGHT; if (_status == NORMAL) { stopAllActions(); runAnimation("TortoiseMoveLeft"); } } } else { if (canMoveRight(dt)) { moveRight(dt); } else { _dir = Common::LEFT; if (_status == NORMAL) { stopAllActions(); runAnimation("TortoiseMoveRight"); } } } if (canMoveDown(dt)) { moveDown(dt); } else { _speedDown = 10; } }
void ItemViewWidget::notifySelectionChanged() { if (m_model) { m_previousIndex = m_currentIndex; m_currentIndex = getIndex(getCurrentRow()); emit canMoveUpChanged(canMoveUp()); emit canMoveDownChanged(canMoveDown()); emit needsActionsUpdate(); } }
int main(int argc, char* args[]) { srand(time(NULL)); PLAYER* player = createPlayer(); BACKGROUND* background = createBackground(); LTexture lt; BANANA* bananaArray[MAX_NUM_OF_BANANA]; BARRIER* barrierArray[MAX_NUM_OF_BARRIER]; int i; for(i = 0; i < MAX_NUM_OF_BANANA; i++) { bananaArray[i] = createBanana(); } for(i = 0; i < MAX_NUM_OF_BARRIER; i++) { barrierArray[i] = createBarrier(); } if( !init() ) { printf( "Failed to initialize!\n" ); } else { if( !loadBackground("./media/background.png", &background->background_tex, gRenderer) || !loadPlayer("./media/minion.png", &player->player_tex, gRenderer, gSpriteClips)) { printf( "Failed to load media!\n" ); } else { for(i = 0; i < MAX_NUM_OF_BANANA; i++) { loadBanana("./media/banana.png", &bananaArray[i]->banana_tex, gRenderer); setPosRectBanana(bananaArray[i]); } for(i = 0; i < MAX_NUM_OF_BARRIER; i++) { loadBarrier("./media/barrier.png", &barrierArray[i]->barrier_tex, gRenderer); setPosRectBarrier(barrierArray[i]); } bool quit = false; SDL_Event e; player->frame = 0; background->scrollingOffset = 0; while( !quit ) { while( SDL_PollEvent( &e ) != 0 ) { if( e.type == SDL_QUIT ) { quit = true; } if(e.key.type == SDL_KEYDOWN) { switch( e.key.keysym.sym ) { case SDLK_UP: if(canMoveUp(player)) { moveUp(player); } break; case SDLK_DOWN: if(canMoveDown(player)) { moveDown(player); } break; } } } --(background->scrollingOffset); if( background->scrollingOffset < -background->background_tex.mWidth ) { background->scrollingOffset = 0; } SDL_Rect* currentClip; SDL_SetRenderDrawColor( gRenderer, 0xFF, 0xFF, 0xFF, 0xFF ); SDL_RenderClear( gRenderer ); renderBackground(background, background->scrollingOffset, gRenderer); currentClip = &gSpriteClips[ player->frame / 16 ]; renderPlayer(player, currentClip, gRenderer); setPosRectPlayer(player); for (i = 0; i < MAX_NUM_OF_BANANA; i++) { if( checkCollision(player->mPlayer, bananaArray[i]->mBanana, background->scrollingOffset)) { increaseTotalScore(); eraseBanana(bananaArray[i]); } renderBanana(bananaArray[i], background->scrollingOffset + bananaArray[i]->posX, gRenderer); } for (i = 0; i < MAX_NUM_OF_BARRIER; i++) { if( checkCollisionEnd(player->mPlayer, barrierArray[i]->mBarrier, background->scrollingOffset)) { closeWin(player, background, bananaArray, barrierArray); return 0; } renderBarrier(barrierArray[i], background->scrollingOffset + barrierArray[i]->posX, gRenderer); } ++player->frame; if( player->frame / 4 >= WALKING_ANIMATION_FRAMES ) { player->frame = 0; } SDL_RenderPresent(gRenderer); } closeWin(player, background, bananaArray, barrierArray); } } return 0; }
/** Searches for solution */ int solveFifteen() { struct GameState *queue; int i; while (notEmptyPQ()) { queue = getQueueTop(); if (queue->manhattanDistance == 0) { printSolution(queue); for (i = 0; i < rows; i++) { free(queue->tilesPosition[i]); } free(queue->tilesPosition); free(queue->prev); queue->prev = NULL; /* deallocate memory */ int pocet = 0; while (notEmptyPQ()) { pocet++; free(queue); queue = NULL; queue = getQueueTop(); for (i = 0; i < rows; i++) { free(queue->tilesPosition[i]); } free(queue->tilesPosition); free(queue->prev); queue->prev = NULL; } printf("Ve fronte bylo %d\n", pocet); system("PAUSE"); return 0; } else { int lastMove = getLastMove(queue); if (canMoveLeft(queue) && lastMove != MOVE_RIGHT) { struct GameState *s = createNewState(queue); if (s == NULL) { return OUT_OF_MEMORY; } moveLeft(s); s->manhattanDistance = getManhattanDistance(*s); insertPQ(s); } if (canMoveRight(queue) && lastMove != MOVE_LEFT) { struct GameState *s = createNewState(queue); if (s == NULL) { return OUT_OF_MEMORY; } moveRight(s); s->manhattanDistance = getManhattanDistance(*s); insertPQ(s); } if (canMoveUp(queue) && lastMove != MOVE_DOWN) { struct GameState *s = createNewState(queue); if (s == NULL) { return OUT_OF_MEMORY; } moveUp(s); s->manhattanDistance = getManhattanDistance(*s); insertPQ(s); } if (canMoveDown(queue) && lastMove != MOVE_UP) { struct GameState *s = createNewState(queue); if (s == NULL) { return OUT_OF_MEMORY; } moveDown(s); s->manhattanDistance = getManhattanDistance(*s); insertPQ(s); } } } return 1; }
void ItemTortoiseFly::move(float dt) { if (_status == NORMAL) { if (_dir == Common::LEFT) { moveLeft(dt); if (getPositionX() <= _left) { _dir = Common::RIGHT; updateStatus(); } } else { moveRight(dt); if (getPositionX() >= _right) { _dir = Common::LEFT; updateStatus(); } } } else if (_status == DROPPING) { if (canMoveDown(dt)) { moveDown(dt); } else { _speedDown = _speedAcc; _status = ONLAND; updateStatus(); } } else if (_status == ONLAND || _status == CRAZY) { if (canMoveDown(dt)) { moveDown(dt); } else { _speedDown = _speedAcc; } if (_dir == Common::LEFT) { if (canMoveLeft(dt)) { moveLeft(dt); } else { _dir = Common::RIGHT; } } else { if (canMoveRight(dt)) { moveRight(dt); } else { _dir = Common::LEFT; } } } }
void Player::update(float frameTime, LevelController* lc) { // 1-Press NoClip if (noClipButtonReleased && input->isKeyDown(VK_F2)) { noClip = !noClip; noClipButtonReleased = false; } else { noClipButtonReleased = true; } velocityX = getVelocity().x; velocityY = getVelocity().y; // Handle NoClip if (noClip) { if (input->isKeyDown(PLAYER_RIGHT)) { velocityX = playerNS::NOCLIP_SPEED * frameTime; orientation = Right; } else if (input->isKeyDown(PLAYER_LEFT)) { velocityX = -playerNS::NOCLIP_SPEED * frameTime; orientation = Left; } else { velocityX = 0; } if (input->isKeyDown(PLAYER_UP)) { velocityY = -playerNS::NOCLIP_SPEED * frameTime; orientation = Up; } else if (input->isKeyDown(PLAYER_DOWN)) { velocityY = playerNS::NOCLIP_SPEED * frameTime; orientation = Down; } else { velocityY = 0; } velocity = VECTOR2(velocityX, velocityY); frameDelay = 1000000; Item* activeItem = inventory->getActiveItem()->getItem(); if (inventory->getActiveItem()->getItem()->getItemType() == Item::Equipable) { Gun* gun = dynamic_cast<Gun*>(activeItem); if (gun != 0) { gun->update(frameTime, orientation, getX(), getY(), input, lc); } } Entity::update(frameTime); return; } // Set Obj Vars levelController = lc; // Debug Messages OSD::instance()->addLine("Jump Distance: " + std::to_string(jumpdistance) + " / " + std::to_string(playerNS::JUMP_HEIGHT)); OSD::instance()->addLine("Can | Left: " + std::to_string(canMoveLeft(true)) + " | Right: " + std::to_string(canMoveRight(true)) + " | Up: " + std::to_string(canMoveUp(true)) + " | Down: " + std::to_string(canMoveDown(true))); // Stuck Hotfix if (!canMoveLeft() && !canMoveRight() && !canMoveUp() && !canMoveDown()) { setX(spawnPos.x); setY(spawnPos.y); } // Update Guns inventory->update(frameTime, input); // Boss Audio if (lc->getMapX() * -1.0 > 1900) { audio->stopCue(BK_MUSIC); audio->playCue(BOSS_MUSIC); } // Start of Player Movement if (healthStatus != Dead) { if (!canMoveDown()) { if (!input->isKeyDown(PLAYER_UP) && !input->isKeyDown(PLAYER_JUMP)) canJump = true; canFall = false; falling = false; } else { canFall = true; falling = true; } // Move Left and Right if (input->isKeyDown(PLAYER_RIGHT) && canMoveRight()) { velocityX = playerNS::SPEED * frameTime; while (!canMoveRight()) { spriteData.x -= 0.1; velocityX = 0; } orientation = Right; } else if (input->isKeyDown(PLAYER_LEFT) && canMoveLeft()) { velocityX = -playerNS::SPEED * frameTime; while (!canMoveLeft()) { spriteData.x += 0.1; velocityX = 0; } orientation = Left; } else { velocityX = 0; if (input->isKeyDown(PLAYER_UP)) { orientation = Up; } if (input->isKeyDown(PLAYER_DOWN)) { orientation = Down; } } // Handle Jumping if (jumping || (((input->isKeyDown(PLAYER_JUMP) || input->isKeyDown(PLAYER_UP)) && canMoveUp() && canJump))) { jumpdistance = jumpOriginY - getY(); if (canJump && !jumping) jumpOriginY = getY(); if (jumpdistance > playerNS::JUMP_HEIGHT || !canMoveUp()) { jumping = false; canJump = false; falling = true; } else { if (!jumping) velocityY = -playerNS::JUMP_SPEED * frameTime; else velocityY += 0.5 * frameTime; jumping = true; canJump = false; } } if (!jumping) jumpOriginY = getY(); if (falling && !jumping) { if (canMoveDown()) { velocityY = playerNS::FALLING_SPEED * frameTime; } else { velocityY = 0; } } // Handle Stuck while (canMoveUp() && !canMoveDown() && !canMoveLeft() && !canMoveRight()) { spriteData.y -= 0.1; } while (!canMoveUp() && !canMoveDown() && !canMoveLeft() && canMoveRight()) { spriteData.x += 0.1; } while (!canMoveUp() && !canMoveDown() && canMoveLeft() && !canMoveRight()) { spriteData.x -= 0.1; } // Final Sanity Check if (!canMoveLeft() && velocityX < 0 || !canMoveRight() && velocityX > 0) velocityX = 0; if (!canMoveUp() && velocityY < 0 || !canMoveDown() && velocityY > 0) velocityY = 0; setVelocity(VECTOR2(velocityX, velocityY)); // Handle Orientations if (input->isKeyDown(PLAYER_UP)) orientation = Up; else if (input->isKeyDown(PLAYER_DOWN)) orientation = Down; switch (orientation) { case Right: currentFrame = 953; spriteData.flipHorizontal = true; break; case Down: currentFrame = 954; break; case Left: currentFrame = 953; spriteData.flipHorizontal = false; break; case Up: currentFrame = 952; break; } // Draw Items Item* activeItem = inventory->getActiveItem()->getItem(); if (inventory->getActiveItem()->getItem()->getItemType() == Item::Equipable) { Gun* gun = dynamic_cast<Gun*>(activeItem); if (gun != 0) { gun->update(frameTime, orientation, getX(), getY(), input, lc); } } // Crate Collision if (lc->collidedWithCrate() == 1 && lc->getCrateItem() != -1) { audio->playCue(RELOAD); if (lc->collidedWithCrate() == 1 && lc->getCrateItem() != -1) { int itemid = lc->getCrateItem(); InventoryItem *invItem; std::vector<InventoryItem*>* itemList = inventory->getItems(); switch (itemid) { case playerNS::ItemType::shotGun: shotgun = new Shotgun(); shotgun->initialize(gameptr, 136, 41, 2, gunTexture); shotgun->setCurrentFrame(6); invItem = new InventoryItem(shotgun); break; case playerNS::ItemType::machineGun: machineGun = new MachineGun(); machineGun->initialize(gameptr, 136, 41, 2, gunTexture); machineGun->setCurrentFrame(0); invItem = new InventoryItem(machineGun); break; case 3: break; } for (int i = 0; i < itemList->size(); i++) { InventoryItem *iItem = itemList->at(i); Item* item = iItem->getItem(); Item* newItem = invItem->getItem(); if (item->getItemType() == Item::Equipable && newItem->getItemType() == Item::Equipable) { Gun* gunInvItem = dynamic_cast<Gun*>(item); Gun* gunNewItem = dynamic_cast<Gun*>(newItem); if (gunInvItem->getGunId() == gunNewItem->getGunId()) { gunInvItem->addAmmo(); lc->setCrateCollided(0); return; // Should this be return or break? } } else if (item->getItemType() == Item::Usable && newItem->getItemType() == Item::Usable) { lc->setCrateCollided(0); return; } // Should this be return or break? } inventory->addItem(invItem); lc->setCrateCollided(0); lc->setCrateItem(-1); } } Entity::update(frameTime); } }
void Jack::ai(float frameTime, Entity & ent, float mapX, LevelController* lc) { OSD::instance()->addLine("AI Can | Left: " + std::to_string(canMoveLeft()) + " | Right: " + std::to_string(canMoveRight()) + " | Up: " + std::to_string(canMoveUp()) + " | Down: " + std::to_string(canMoveDown())); switch (aiState) { case Patrol: if (currDest != VECTOR2(-1, -1)) { derivedDest = VECTOR2(currDest.x + offsetOld.x, currDest.y + offsetOld.y); } if (!canMoveLeft() && !canMoveRight() && !canMoveUp() && !canMoveDown()) { setX(derivedDest.x); setY(derivedDest.y); } if (pathList.size() == 0) return; if (currDest == VECTOR2(-1, -1) || spriteData.x == derivedDest.x) { pathCount++; if (pathCount >= pathList.size()) pathCount = 0; currDest = pathList.at(pathCount); } if (spriteData.x > derivedDest.x) { if (velocity.x > 0 && spriteData.x - derivedDest.x < 1 && canMoveLeft()) { velocity.x = 0; setX(derivedDest.x); } else { orientation = Left; if (!moveLeft(frameTime)) { currDest = VECTOR2(-1, -1); } } } else if (spriteData.x < derivedDest.x) { if (velocity.x < 0 && derivedDest.x - spriteData.x < 1 && canMoveRight()) { velocity.x = 0; setX(derivedDest.x); } else { orientation = Right; if (!moveRight(frameTime)) { currDest = VECTOR2(-1, -1); } } } else { velocity.x = 0; } chatString = "SAVE ME PLEASE!"; break; case Chase: if (currDest != VECTOR2(-1, -1)) { derivedDest = VECTOR2(gameptr->getPlayer()->getX(), gameptr->getPlayer()->getY()); } if (pathList.size() == 0) return; if (currDest == VECTOR2(-1, -1) || spriteData.x == derivedDest.x) { pathCount++; if (pathCount >= pathList.size()) pathCount = 0; currDest = pathList.at(pathCount); } if (spriteData.x > derivedDest.x) { if (velocity.x > 0 && spriteData.x - derivedDest.x < 1) { velocity.x = 0; setX(derivedDest.x); } else { orientation = Left; if (!moveLeft(frameTime)) { currDest = VECTOR2(-1, -1); } } } else if (spriteData.x < derivedDest.x) { if (velocity.x < 0 && derivedDest.x - spriteData.x < 1) { velocity.x = 0; setX(derivedDest.x); } else { orientation = Right; if (!moveRight(frameTime)) { currDest = VECTOR2(-1, -1); } } } else { velocity.x = 0; } chatString = "THANK YOU AGENT FOR SAVING ME! <3"; break; case Attack: velocity = VECTOR2(0, 0); if (currDest != VECTOR2(-1, -1)) { derivedDest = VECTOR2(currDest.x, currDest.y); } //OSD::instance()->addLine("NPC Shoot Orientation: " + std::to_string(derivedDest.x - getX()) + " (" + std::to_string((int)(derivedDest.x)) + " - " + std::to_string((int)getX()) + ")"); VECTOR2 delta = VECTOR2(derivedDest.x - getX(), 0); if (delta.x < 0) orientation = Left; else if (delta.x > 0) orientation = Right; else orientation = Up; break; } //OSD::instance()->addLine("MapX: " + std::to_string(mapX)); //OSD::instance()->addLine("NPC AI (" + std::to_string(aiState) + ") at (" + std::to_string(spriteData.x) + ", " + std::to_string(spriteData.y) + ") going to (" + std::to_string((derivedDest.x)) + ", " + std::to_string(derivedDest.y) + ") Moving at: (" + std::to_string((velocity.x)) + ", " + std::to_string(velocity.y) + ") "); }
int uniqueMoves(char moves[][256]) { /* * complex throw away a lot of equal moves * and symmetries (hopefully) */ int movesIndex = 0; int i, j, k; char dl, dr, ur, rr, ul; /* which neighbors - default all values 0 */ int neighbors[BOARD_SIZE + 2][BOARD_SIZE + 2]; int directionList[BOARD_SIZE + 2][BOARD_SIZE + 2][3]; /* * which directions for move * 0 -> / * 1 -> \ * 2 -> + * true means already used * default all values false */ int ohs_up, ohs_down, ohs_right, ohs_left, eks_up, eks_down, eks_right, eks_left; int up, down, left, right; int iBegin, jBegin, iEnd, jEnd; int rsym; if (current.gameOver != NOPLAYER) return 0; /* empty board only two moves */ if (current.boardEmpty) { strcpy(moves[movesIndex], "@0/"); movesIndex++; strcpy(moves[movesIndex], "@0+"); movesIndex++; return movesIndex; } if (getRowSize() * getColSize() == 1) { switch (getAt(1, 1)) { case NW: strcpy(moves[movesIndex], "@1+"); movesIndex++; strcpy(moves[movesIndex], "@1/"); movesIndex++; strcpy(moves[movesIndex], "@1\\"); movesIndex++; strcpy(moves[movesIndex], "B1+"); movesIndex++; strcpy(moves[movesIndex], "B1/"); movesIndex++; strcpy(moves[movesIndex], "B1\\"); movesIndex++; strcpy(moves[movesIndex], "A0\\"); movesIndex++; strcpy(moves[movesIndex], "A0/"); movesIndex++; strcpy(moves[movesIndex], "A0+"); movesIndex++; strcpy(moves[movesIndex], "A2/"); movesIndex++; strcpy(moves[movesIndex], "A2\\"); movesIndex++; strcpy(moves[movesIndex], "A2+"); movesIndex++; break; case NS: strcpy(moves[movesIndex], "@1+"); movesIndex++; strcpy(moves[movesIndex], "@1/"); movesIndex++; strcpy(moves[movesIndex], "@1\\"); movesIndex++; strcpy(moves[movesIndex], "A0/"); movesIndex++; strcpy(moves[movesIndex], "A0+"); movesIndex++; strcpy(moves[movesIndex], "A0\\"); movesIndex++; strcpy(moves[movesIndex], "B1/"); movesIndex++; strcpy(moves[movesIndex], "B1\\"); movesIndex++; strcpy(moves[movesIndex], "A2/"); movesIndex++; strcpy(moves[movesIndex], "A2\\"); movesIndex++; break; default: /* This should never happen */ break; } return movesIndex; } for (i = 0; i < BOARD_SIZE + 2; i++) for (j = 0; j < BOARD_SIZE + 2; j++) for (k = 0; k < 3; k++) directionList[i][j][k] = false; rsym = isRotateMirror(); iBegin = (canMoveDown()) ? 0 : 1; jBegin = (canMoveRight()) ? 0 : 1; iEnd = (getRowSize() < BOARD_SIZE) ? getRowSize() : BOARD_SIZE; jEnd = (getColSize() < BOARD_SIZE) ? getColSize() : BOARD_SIZE; for (i = iBegin; i <= iEnd; i++) { for (j = jBegin; j <= jEnd; j++) { if (!(isBlank(i, j))) { neighbors[i][j] = 0; } else { ohs_up = 0; ohs_down = 0; ohs_right = 0; ohs_left = 0; eks_up = 0; eks_down = 0; eks_right = 0; eks_left = 0; up = getAt(i - 1, j); down = getAt(i + 1, j); left = getAt(i, j - 1); right = getAt(i, j + 1); if (up == SN || up == SW || up == SE) { ohs_up = 1; } else if (up != EMPTY) { eks_up = 1; } if (down == NS || down == NW || down == NE) { ohs_down = 1; } else if (down != EMPTY) { eks_down = 1; } if (left == EN || left == ES || left == WE) ohs_left = 1; else if (left != EMPTY) eks_left = 1; if (right == WE || right == WS || right == WN) ohs_right = 1; else if (right != EMPTY) eks_right = 1; neighbors[i][j] = ohs_up + 2 * ohs_down + 4 * ohs_left + 8 * ohs_right + 16 * eks_up + 32 * eks_down + 64 * eks_left + 128 * eks_right; } } } for (i = iBegin; i <= iEnd; i++) { for (j = jBegin; j <= jEnd; j++) { if (neighbors[i][j] != 0) { dl = getAt(i + 1, j - 1); dr = getAt(i + 1, j + 1); ur = getAt(i - 1, j + 1); ul = getAt(i - 1, j - 1); rr = getAt(i, j + 2); switch (neighbors[i][j]) { case 1: if (dr == NS || dr == NW || dr == NE) directionList[i][j + 1][1] = true; if (dr == WN || dr == WS || dr == WE) directionList[i + 1][j][1] = true; if (dl == EW || dl == ES || dl == ES) directionList[i + 1][j][0] = true; if (ur == SW || ur == SE || ur == SN) directionList[i][j + 1][0] = true; break; case 2: { if (dr == NS || dr == NW || dr == NE) directionList[i][j + 1][1] = true; if (ur == SW || ur == SE || ur == SN) directionList[i][j + 1][0] = true; break; } case 4: { if (dl == ES || dl == EN || dl == EW) directionList[i + 1][j][0] = true; if (dr == WN || dr == WS || dr == WE) directionList[i + 1][j][1] = true; if (ur == SW || ur == SN || ur == SE) directionList[i][j + 1][0] = true; if (dr == NS || dr == NE || dr == NW) directionList[i][j + 1][1] = true; break; } case 8: { if (dl == ES || dl == EN || dl == EW) directionList[i + 1][j][0] = true; if (dr == WN || dr == WE || dr == WS) directionList[i + 1][j][1] = true; break; } case 16: { if (dr == SW || dr == SE || dr == WE) directionList[i][j + 1][1] = true; if (dr == SE || dr == SN || dr == EN) directionList[i + 1][j][1] = true; if (dl == NW || dl == NS || dl == WS) directionList[i + 1][j][0] = true; if (ur == NW || ur == NE || ur == WE) directionList[i][j + 1][0] = true; break; } case 18: case 33: { directionList[i][j + 1][1] = true; directionList[i][j + 1][0] = true; directionList[i][j][2] = true; break; } case 20: case 65: { if (rr != EMPTY) directionList[i][j + 1][2] = true; directionList[i + 1][j][0] = true; directionList[i + 1][j][1] = true; directionList[i][j + 1][0] = true; directionList[i][j][0] = true; break; } case 24: case 129: { directionList[i + 1][j][1] = true; directionList[i][j][1] = true; break; } case 32: { if (dr == SE || dr == SW || dr == EW) directionList[i][j + 1][1] = true; if (ur == NW || ur == NE || ur == WE) directionList[i][j + 1][0] = true; break; } case 36: { if (ul == NW || ul == SW || ul == NS) directionList[i - 1][j][1] = true; directionList[i][j + 1][1] = true; directionList[i][j + 1][0] = true; directionList[i][j][1] = true; break; } case 40: case 130: { directionList[i][j][0] = true; break; } case 64: { if (dl == WN || dl == WS || dl == NS) directionList[i + 1][j][0] = true; if (dr == EN || dr == ES || dr == NS) directionList[i + 1][j][1] = true; if (ur == NW || ur == NE || ur == WE) directionList[i][j + 1][0] = true; if (dr == SE || dr == SW || dr == EW) directionList[i][j + 1][1] = true; break; } case 66: { if (ul == EW || ul == ES || ul == EN) directionList[i - 1][j][1] = true; directionList[i][j + 1][1] = true; directionList[i][j + 1][0] = true; directionList[i][j][1] = true; break; } case 72: case 132: { directionList[i + 1][j][0] = true; directionList[i + 1][j][1] = true; directionList[i][j][2] = true; break; } case 128: { if (dl == WS || dl == WN || dl == SN) directionList[i + 1][j][0] = true; if (dr == EN || dr == ES || dr == NS) directionList[i + 1][j][1] = true; break; } default: break; } } } } /* collects the moves */ for (i = iBegin; i <= iEnd; i++) { for (j = jBegin; j <= jEnd; j++) { /* remove rotation symmetry moves */ if (rsym && getRowSize() % 2 == 1) { int jMiddle = (getColSize() + 1) / 2; if (j > jMiddle && i == iEnd) { continue; } } if (neighbors[i][j] != 0) { ohs_up = 0; ohs_down = 0; ohs_right = 0; ohs_left = 0; eks_up = 0; eks_down = 0; eks_right = 0; eks_left = 0; up = getAt(i - 1, j); down = getAt(i + 1, j); left = getAt(i, j - 1); right = getAt(i, j + 1); if (up == SN || up == SW || up == SE) ohs_up = 1; else if (up != EMPTY) eks_up = 1; if (down == NS || down == NW || down == NE) ohs_down = 1; else if (down != EMPTY) eks_down = 1; if (left == EN || left == ES || left == WE) ohs_left = 1; else if (left != EMPTY) eks_left = 1; if (right == WE || right == WS || right == WN) ohs_right = 1; else if (right != EMPTY) eks_right = 1; if (!directionList[i][j][0]) { saveState(); if ((ohs_up + ohs_left > 0) || (eks_right + eks_down > 0)) putAt(i, j, NW); if ((eks_up + eks_left > 0) || (ohs_right + ohs_down > 0)) putAt(i, j, SE); if (forcedMove(i - 1, j) && forcedMove(i + 1, j) && forcedMove(i, j - 1) && forcedMove(i, j + 1)) { getTraxMoveString(i, j, moves[movesIndex], '/'); movesIndex++; } restoreState(); } if (!directionList[i][j][1]) { saveState(); if ((ohs_up + ohs_right > 0) || (eks_left + eks_down > 0)) putAt(i, j, NE); if ((eks_up + eks_right > 0) || (ohs_left + ohs_down > 0)) putAt(i, j, SW); if (forcedMove(i - 1, j) && forcedMove(i + 1, j) && forcedMove(i, j - 1) && forcedMove(i, j + 1)) { getTraxMoveString(i, j, moves[movesIndex], '\\'); movesIndex++; } restoreState(); } if (!directionList[i][j][2]) { saveState(); if ((ohs_up + ohs_down > 0) || (eks_left + eks_right > 0)) putAt(i, j, NS); if ((eks_up + eks_down > 0) || (ohs_left + ohs_right > 0)) putAt(i, j, WE); if (forcedMove(i - 1, j) && forcedMove(i + 1, j) && forcedMove(i, j - 1) && forcedMove(i, j + 1)) { getTraxMoveString(i, j, moves[movesIndex], '+'); movesIndex++; } restoreState(); } } } } return movesIndex; }
int makeMove(const char *move) { int col, row, neighbor; char direction; int ohs_up = 0, ohs_down = 0, ohs_right = 0, ohs_left = 0, eks_up = 0, eks_down = 0, eks_right = 0, eks_left = 0; if (current.gameOver != NOPLAYER); /* Game is over */ if (current.boardEmpty) { if (!strcmp(move, "@0/")) { putAt(1, 1, NW); switchPlayer(); return 0; } if (!strcmp(move, "@0+")) { putAt(1, 1, NS); switchPlayer(); return 0; } } /* parse move string */ getTraxMoveDefinition(&row, &col, move, &direction); if (col == 0 && row == 0) return -1; /* No neighbours */ if ((row == 0) && (!canMoveDown())) return -1; /* illegal row */ if ((col == 0) && (!canMoveRight())) return -1; /* illegal column */ if (!isBlank(row, col)) return -1; /* occupy */ char up = getAt(row - 1, col); char down = getAt(row + 1, col); char left = getAt(row, col - 1); char right = getAt(row, col + 1); if (up == SN || up == SE || up == SW) ohs_up = 1; if (up == EW || up == NW || up == NE) eks_up = 1; if (down == NS || down == NE || down == NW) ohs_down = 1; if (down == EW || down == SW || down == SE) eks_down = 1; if (left == EN || left == ES || left == EW) ohs_left = 1; if (left == WS || left == WN || left == NS) eks_left = 1; if (right == WN || right == WE || right == WS) ohs_right = 1; if (right == ES || right == NS || right == EN) eks_right = 1; neighbor = ohs_up + (2 * ohs_down) + (4 * ohs_left) + (8 * ohs_right) + (16 * eks_up) + (32 * eks_down) + (64 * eks_left) + (128 * eks_right); switch (neighbor) { case 0: /* no neighbor error */ return -1; case 1: switch (direction) { case '/': putAt(row, col, NW); break; case '\\': putAt(row, col, NE); break; case '+': putAt(row, col, NS); break; default: /* This should never happen */ break; } break; case 2: switch (direction) { case '/': putAt(row, col, SE); break; case '\\': putAt(row, col, SW); break; case '+': putAt(row, col, NS); break; default: /* This should never happen */ break; } break; case 4: switch (direction) { case '/': putAt(row, col, WN); break; case '\\': putAt(row, col, WS); break; case '+': putAt(row, col, WE); break; default: /* This should never happen */ break; } break; case 8: switch (direction) { case '/': putAt(row, col, ES); break; case '\\': putAt(row, col, EN); break; case '+': putAt(row, col, EW); break; default: /* This should never happen */ break; } break; case 16: switch (direction) { case '/': putAt(row, col, SE); break; case '\\': putAt(row, col, SW); break; case '+': putAt(row, col, WE); break; default: /* This should never happen */ break; } break; case 18: switch (direction) { case '/': putAt(row, col, SE); break; case '\\': putAt(row, col, SW); break; case '+': return -1; default: /* This should never happen */ break; } break; case 20: switch (direction) { case '/': return -1; case '\\': putAt(row, col, WS); break; case '+': putAt(row, col, WE); break; default: /* This should never happen */ break; } break; case 24: switch (direction) { case '/': putAt(row, col, SE); break; case '\\': return -1; case '+': putAt(row, col, WE); break; default: /* This should never happen */ break; } break; case 32: switch (direction) { case '/': putAt(row, col, NW); break; case '\\': putAt(row, col, NE); break; case '+': putAt(row, col, WE); break; default: /* This should never happen */ break; } break; case 33: switch (direction) { case '/': putAt(row, col, NW); break; case '\\': putAt(row, col, NE); break; case '+': return -1; default: /* This should never happen */ break; } break; case 36: switch (direction) { case '/': putAt(row, col, NW); break; case '+': putAt(row, col, WE); break; case '\\': return -1; default: /* This should never happen */ break; } break; case 40: switch (direction) { case '\\': putAt(row, col, EN); break; case '+': putAt(row, col, EW); break; case '/': return -1; default: /* This should never happen */ break; } break; case 64: switch (direction) { case '/': putAt(row, col, ES); break; case '\\': putAt(row, col, EN); break; case '+': putAt(row, col, NS); break; default: /* This should never happen */ break; } break; case 65: switch (direction) { case '\\': putAt(row, col, NE); break; case '+': putAt(row, col, NS); break; case '/': return -1; default: /* This should never happen */ break; } break; case 66: switch (direction) { case '/': putAt(row, col, SE); break; case '+': putAt(row, col, SN); break; case '\\': return -1; default: /* This should never happen */ break; } break; case 72: switch (direction) { case '/': putAt(row, col, ES); break; case '\\': putAt(row, col, EN); break; case '+': return -1; default: /* This should never happen */ break; } break; case 128: switch (direction) { case '/': putAt(row, col, WN); break; case '\\': putAt(row, col, WS); break; case '+': putAt(row, col, NS); break; default: /* This should never happen */ break; } break; case 129: switch (direction) { case '/': putAt(row, col, NW); break; case '+': putAt(row, col, NS); break; case '\\': return -1; default: /* This should never happen */ break; } break; case 130: switch (direction) { case '\\': putAt(row, col, SW); break; case '+': putAt(row, col, SN); break; case '/': return -1; default: /* This should never happen */ break; } break; case 132: switch (direction) { case '/': putAt(row, col, WN); break; case '\\': putAt(row, col, WS); break; case '+': return -1; default: /* This should never happen */ break; } break; default: /* This should never happen */ break; } if (row == 0) row++; if (col == 0) col++; if (!forcedMove(row - 1, col)) { return -1; } if (!forcedMove(row + 1, col)) { return -1; } if (!forcedMove(row, col - 1)) { return -1; } if (!forcedMove(row, col + 1)) { return -1; } /* note that switchPlayer() _must_ come before isGameOver() */ switchPlayer(); /* updates the gameOver attribute */ isGameOver(); return 0; }