public bool canShapeMove(BoardLogic board, MoveType moveType) { bool result = false; bool valid = true; int leftMostPos = board.boardWidth; int rightMostPos = 0; int bottomMostPos = board.boardHeight;; Vector2 moveVec = GetMoveVec(moveType); for (int i = 0; i < this.count; ++i) { Vector2 pos = this.blocks[i].pos; BoardState state = board.GetBoardState(pos + moveVec); if (!(state == BoardState.BOARD_NULL || state == BoardState.BOARD_SHAPE || state == BoardState.BOARD_EXPLOSIVE)) { valid = false; break; } if (this.blocks[i].pos.x < leftMostPos) { leftMostPos = (int)this.blocks[i].pos.x; } if (this.blocks[i].pos.x > rightMostPos) { rightMostPos = (int)this.blocks[i].pos.x; } if (this.blocks[i].pos.y < bottomMostPos) { bottomMostPos = (int)this.blocks[i].pos.y; } } if (this.count > 0) { //Check shape won't move off the board// if (moveType == MoveType.MOVE_LEFT) { if (leftMostPos > 0 && valid) { result = true; } } else if (moveType == MoveType.MOVE_RIGHT) { Assert.IsTrue(rightMostPos < board.boardWidth); if (rightMostPos < (board.boardWidth - 1) && valid) { result = true; } } else if (moveType == MoveType.MOVE_DOWN) { if (bottomMostPos > 0 && valid) { Assert.IsTrue(bottomMostPos < board.boardHeight); result = true; } } } return(result); }
private void addToQueryList(VisitedQueue sentinel, Vector2 pos, bool[] boardArray, BoardLogic board) { if ((int)pos.x >= 0 && (int)pos.x < board.boardWidth && (int)pos.y >= 0 && (int)pos.y < board.boardHeight) { int boardIndex = (((int)pos.y) * board.boardWidth) + (int)pos.x; bool visited = boardArray[boardIndex]; if (!visited && board.GetBoardState(pos) == BoardState.BOARD_SHAPE) { boardArray[boardIndex] = true; VisitedQueue queue = new VisitedQueue(); queue.pos = pos; //add to the search queue Assert.IsTrue(sentinel.prev.next == sentinel); queue.prev = sentinel.prev; queue.next = sentinel; sentinel.prev.next = queue; sentinel.prev = queue; } } }
public void updateWindmillSide(BoardLogic board) { bool repeat = true; bool repeatedYet = false; while (repeat) { //this is for when we get blocked repeat = false; Assert.IsTrue(this.count <= this.max); BoardState stateToSet; BoardState staticState = (this.isBomb) ? BoardState.BOARD_EXPLOSIVE : BoardState.BOARD_STATIC; int addend = 0; if (this.isOut) { addend = 1; stateToSet = staticState; } else { stateToSet = BoardState.BOARD_NULL; addend = -1; } bool wasJustFlipped = this.justFlipped; if (!this.justFlipped) { this.count += addend; } else { this.justFlipped = false; } if (this.count != 0) { BoardState toBoardState = BoardState.BOARD_INVALID; Assert.IsTrue(this.count >= 0 && this.count <= this.max); Vector2 shift = new Vector2(this.growDir.x * (this.count - 1), this.growDir.y * (this.count - 1)); Vector2 newPos = this.pos + shift; toBoardState = board.GetBoardState(newPos); bool settingBlock = (toBoardState == BoardState.BOARD_NULL && stateToSet == staticState); bool isInBounds = board.InBoardBounds(newPos); bool blocked = (toBoardState != BoardState.BOARD_NULL && stateToSet == staticState); if (blocked || !isInBounds) { Assert.IsTrue(this.isOut); if (this.count == 1) { Assert.IsTrue(stateToSet != BoardState.BOARD_NULL); this.isOut = true; if (this.tryingToBegin) { //on the second attempt after the shape has moved for (int i = 0; i < this.perpSize; ++i) { this.growDir = Vector2.Perpendicular(this.growDir); } } this.count = 0; this.tryingToBegin = true; } else { this.isOut = false; repeat = true; this.justFlipped = true; this.count--; } } else { Assert.IsTrue(this.count > 0); Assert.IsTrue(stateToSet != BoardState.BOARD_INVALID); Assert.IsTrue(isInBounds); if (settingBlock || stateToSet == BoardState.BOARD_NULL) { if (stateToSet == BoardState.BOARD_NULL) { Assert.IsTrue(toBoardState == staticState); } board.SetBoardState(newPos, stateToSet, BoardValType.BOARD_VAL_DYNAMIC); } } Assert.IsTrue(this.max > 0); if (this.count == this.max) { if (!wasJustFlipped) { this.isOut = false; this.justFlipped = true; } else { Assert.IsTrue(!this.isOut); } } } else { Assert.IsTrue(this.count == 0); Assert.IsTrue(!this.isOut); this.isOut = true; for (int i = 0; i < this.perpSize; ++i) { this.growDir = Vector2.Perpendicular(this.growDir); } this.lagTimer.period = this.lagPeriod; //we change from the begin period to the lag period if (!Equals(this.lagTimer.period, 0.0f)) { active = false; //we lag for a bit. } } if (this.count == 0 && !repeatedYet) { repeat = true; repeatedYet = true; } } }
public void UpdateAndRenderShape(BoardLogic board) { Assert.IsTrue(!this.wasHitByExplosive); Assert.IsTrue(!board.createShape); bool isHoldingShape = board.currentHotIndex >= 0; bool turnSolid = false; TimerReturnInfo timerInfo = this.moveTimer.updateTimer(this.moveTime); if (timerInfo.finished) { this.moveTimer.turnTimerOn(); this.moveTimer.value = timerInfo.residue; if (!this.MoveShape(board, MoveType.MOVE_DOWN)) { turnSolid = true; } } this.wasHitByExplosive = false; if (turnSolid) { solidfyShape(board); board.createShape = true; this.wasHitByExplosive = false; ResetMouseUI(board); } else { int hotBlockIndex = -1; for (int i = 0; i < this.count; ++i) { //NOTE: Render the hover indications & check for hot player block Vector2 pos = this.blocks[i].pos; TwoColors alienColors = GetAlienHoverColor(i); Vector4 color = Color.white; Bounds blockBounds = new Bounds(new Vector3(pos.x, pos.y, keyStates.mouseInWorldSpace.z), new Vector3(1, 1, 1)); if (blockBounds.Contains(keyStates.mouseInWorldSpace)) { hotBlockIndex = i; if (board.currentHotIndex < 0) { color = alienColors.color1; } } if (hotBlockIndex >= 0 && board.currentHotIndex < 0) { if (IsMirrorPartnerIndex(board, hotBlockIndex, i, false)) { color = alienColors.color1; } } if (board.currentHotIndex == i) { Assert.IsTrue(keyStates.isDown(ButtonType.BUTTON_LEFT_MOUSE)); color = alienColors.color2; } if (IsMirrorPartnerIndex(board, board.currentHotIndex, i, true)) { color = alienColors.color2; } BoardValue val = board.GetBoardValue(pos); Assert.IsTrue(val.valid); val.color = color; } //NOTE: Have to do this afterwards since we the block can be before for the mirrorHotIndex if (board.currentHotIndex < 0 && hotBlockIndex >= 0 && board.isMirrorLevel) { int mirrorOffsetCount = board.shapeSizes[0]; int mirrorIndexAt = hotBlockIndex < mirrorOffsetCount ? (hotBlockIndex + mirrorOffsetCount) : (hotBlockIndex - mirrorOffsetCount); if (HasMirrorPartner(board, hotBlockIndex, mirrorIndexAt)) //same size { Assert.IsTrue(mirrorIndexAt >= 0 && mirrorIndexAt < GetTotalNumberOfShapeBlocks(board)); Vector2 pos = this.blocks[mirrorIndexAt].pos; BoardValue val = board.GetBoardValue(pos); Assert.IsTrue(val.valid); val.color = GetAlienHoverColor(hotBlockIndex).color1; } else { // printf("%s\n", "no mirror partner"); Assert.IsTrue(board.shapeSizes[0] != board.shapeSizes[1]); } } if (keyStates.wasPressed(ButtonType.BUTTON_LEFT_MOUSE) && hotBlockIndex >= 0) { board.currentHotIndex = hotBlockIndex; } if (board.currentHotIndex >= 0) { //We are holding onto a block Vector2 boardPosAt = keyStates.mouseInWorldSpace; boardPosAt.x = (int)(Mathf.Clamp(boardPosAt.x, 0, board.boardWidth - 1) + 0.5f); boardPosAt.y = (int)(Mathf.Clamp(boardPosAt.y, 0, board.boardHeight - 1) + 0.5f); int hotIndex = board.currentHotIndex; bool okToMove = shapeStillConnected(hotIndex, boardPosAt, board); Vector2 boardPosAtMirror = new Vector2(0, 0); //not used unless is a mirror level int mirrorIndex = -1; bool isEvenSize = true; if (board.isMirrorLevel) { int mirrorOffsetCount = board.shapeSizes[0]; mirrorIndex = hotIndex < mirrorOffsetCount? (hotIndex + mirrorOffsetCount) : (hotIndex - mirrorOffsetCount); if (HasMirrorPartner(board, board.currentHotIndex, mirrorIndex)) // { Vector2 mirrorOffset = boardPosAt - this.blocks[hotIndex].pos; boardPosAtMirror = this.blocks[mirrorIndex].pos + mirrorOffset; okToMove &= shapeStillConnected(mirrorIndex, boardPosAtMirror, board); } else { Assert.IsTrue(board.shapeSizes[0] != board.shapeSizes[1]); isEvenSize = false; } } int mirCount = (board.isMirrorLevel && isEvenSize) ? 2 : 1; int[] hotIndexes = new int[] { hotIndex, mirrorIndex }; Vector2[] newPoses = new Vector2[] { boardPosAt, boardPosAtMirror }; if (okToMove) { //play the sound once board.playArrangeSound(); for (int m = 0; m < mirCount; ++m) { int thisHotIndex = hotIndexes[m]; Vector2 oldPos = this.blocks[thisHotIndex].pos; Vector2 newPos = newPoses[m]; Assert.IsTrue(board.GetBoardState(oldPos) == BoardState.BOARD_SHAPE); Assert.IsTrue(board.GetBoardState(newPos) == BoardState.BOARD_NULL); board.SetBoardState(oldPos, BoardState.BOARD_NULL, BoardValType.BOARD_VAL_NULL); board.SetBoardState(newPos, BoardState.BOARD_SHAPE, this.blocks[thisHotIndex].type); this.blocks[thisHotIndex].pos = newPos; Assert.IsTrue(board.GetBoardState(newPos) == BoardState.BOARD_SHAPE); } } } } }
public bool shapeStillConnected(int currentHotIndex, Vector2 boardPosAt, BoardLogic board) { bool result = true; for (int i = 0; i < this.count; ++i) { Vector2 pos = this.blocks[i].pos; if ((int)boardPosAt.x == (int)pos.x && (int)boardPosAt.y == (int)pos.y) { result = false; break; } BoardState state = board.GetBoardState(boardPosAt); if (state != BoardState.BOARD_NULL) { result = false; break; } } if (result) { Vector2 oldPos = this.blocks[currentHotIndex].pos; BoardValue oldVal = board.GetBoardValue(oldPos); Assert.IsTrue(oldVal.state == BoardState.BOARD_SHAPE); IslandInfo mainIslandInfo = this.GetShapeIslandCount(oldPos, board); Assert.IsTrue(mainIslandInfo.count >= 1); if (mainIslandInfo.count <= 1) { //There is an isolated block result = false; } else { Vector2 idPos = mainIslandInfo.poses[1]; //won't be that starting pos since the first position will dissapear if it is correct. //temporaialy set the board state to where the shape was to be null, so this can't act as a bridge in the flood fill oldVal.state = BoardState.BOARD_NULL; //set where the board will be to a valid position BoardValue newVal = board.GetBoardValue(boardPosAt); Assert.IsTrue(newVal.state == BoardState.BOARD_NULL); newVal.state = BoardState.BOARD_SHAPE; //// This code isn't needed anymore. Just used for the assert below. IslandInfo islandInfo = this.GetShapeIslandCount(boardPosAt, board); //See if the new pos is part of the same island bool found = false; for (int index = 0; index < islandInfo.count; ++index) { Vector2 srchPos = islandInfo.poses[index]; if ((int)srchPos.x == (int)idPos.x && (int)srchPos.y == (int)idPos.y) { found = true; break; } } //// IslandInfo mainIslandInfo_after = this.GetShapeIslandCount(idPos, board); if (mainIslandInfo_after.count < mainIslandInfo.count) { result = false; } else { Assert.IsTrue(found); } //set the state back to being a shape. newVal.state = BoardState.BOARD_NULL; oldVal.state = BoardState.BOARD_SHAPE; } } return(result); }
bool MoveShape(BoardLogic board, MoveType moveType) { bool result = canShapeMove(board, moveType); if (result) { Vector2 moveVec = GetMoveVec(moveType); Assert.IsTrue(!this.wasHitByExplosive); // CHECK FOR EXPLOSIVES HIT int idsHitCount = 0; int[] idsHit = new int[BoardLogic.MAX_SHAPE_COUNT]; for (int i = 0; i < this.count; ++i) { Vector2 oldPos = this.blocks[i].pos; Vector2 newPos = oldPos + moveVec; BoardValue val = board.GetBoardValue(oldPos); val.color = Color.white; BoardValue newVal = board.GetBoardValue(newPos); newVal.color = Color.white; BoardState state = board.GetBoardState(newPos); if (state == BoardState.BOARD_EXPLOSIVE) { Assert.IsTrue(board.lifePointsMax > 0); board.lifePoints -= 1; this.wasHitByExplosive = true; board.PlayExplosiveSound(); //remove from shape Assert.IsTrue(idsHitCount < idsHit.Length); idsHit[idsHitCount++] = this.blocks[i].id; board.SetBoardState(oldPos, BoardState.BOARD_NULL, BoardValType.BOARD_VAL_NULL); //this is the shape board.SetBoardState(newPos, BoardState.BOARD_NULL, BoardValType.BOARD_VAL_TRANSIENT); //this is the bomb position } } //NOTE: we have this since our findBlockById wants to search the original shape with the //full count so we can't change it in the loop int newShapeCount = this.count; for (int hitIndex = 0; hitIndex < idsHitCount; ++hitIndex) { int id = idsHit[hitIndex]; int blockIndex = this.FindBlockById(id); this.blocks[--newShapeCount].Copy(this.blocks[blockIndex]); } this.count = newShapeCount; for (int i = 0; i < this.count; ++i) { Vector2 oldPos = this.blocks[i].pos; Vector2 newPos = oldPos + moveVec; // printf("boardState: %d, index: %d\n", getBoardState(params, oldPos), i); Assert.IsTrue(board.GetBoardState(oldPos) == BoardState.BOARD_SHAPE); BoardState newPosState = board.GetBoardState(newPos); Assert.IsTrue(newPosState == BoardState.BOARD_SHAPE || newPosState == BoardState.BOARD_NULL); QueryShapeInfo info = this.IsRepeatedInShape(oldPos, i); if (!info.result) { //dind't just get set by the block in shape before. board.SetBoardState(oldPos, BoardState.BOARD_NULL, BoardValType.BOARD_VAL_NULL); } board.SetBoardState(newPos, BoardState.BOARD_SHAPE, this.blocks[i].type); this.blocks[i].pos = newPos; } board.playMoveSound(); } return(result); }