void moveBit(char ch) { switch (ch) { case DOWN_KEY: BIT_Y++; if (collision()) { stack(); } break; case UP_KEY: rotateBlock(); if (collision()) rotateBlock(); break; case LEFT_KEY: BIT_X--; if (collision()) BIT_X++; break; case RIGHT_KEY: BIT_X++; if (collision()) BIT_X--; break; case SPACE_KEY: while (!collision()) { BIT_Y++; } BIT_Y--; break; default: break; } }
void moveBestPos(Pos bestPosition, char *nxt){ int i; BIT_Y = 1; BIT_X = 5; for (i = 0; i<bestPosition.rotation; i++) { rotateBlock(); if (collision()) *nxt = QUIT; animationeffect(2); } while (BIT_X != bestPosition.x) { if (BIT_X>bestPosition.x) { BIT_X--; animationeffect(2); if (collision()) *nxt = QUIT; } else if (BIT_X<bestPosition.x) { BIT_X++; animationeffect(2); if (collision()) *nxt = QUIT; } } animationeffect(4); while (!collision()) { animationeffect(0.5); BIT_Y++; } stack(); return; }//findIdealPosition함수를 통해 찾은 최적의 위치와 모양을 animaioneffect함수를 이용하여 자연스럽게 이동하는것처럼 보이게 구현
Pos findIdealPosition(void)//점수요소:getIdealPoint();getClearLinePoint();getAdjacentPoint();getMinusPoint(); { int firstX = BIT_X, firstY = BIT_Y; Pos position[4] = { 0, }; int highestScore = 0, plusScore = 0, minusScore = 0, totalScore = 0; int rotation = 0, bestRotation = 0; int i = 0; for (rotation = 0; rotation<4; rotation++)//방향을 4방향으로 돌려본다 { for (BIT_X = 0, i = 0; 1; BIT_X++)//X축 왼쪽부터 오른쪽까지 다 이동시켜본다 { BIT_Y = 1; if (i == 0 && collision())//블럭에 따라 BIT_X = 0일때 테두리 프레임에 부딪히는 경우가 있어서 일부러 팅겨내기 위함 { BIT_X = 1; i++; } else if (collision()) { break; } while (!collision())//매 X축마다 블럭을 아래로 충돌할 때까지 내려본다 { BIT_Y++; } BIT_Y--; writeBlockOnBoard(); plusScore = 4 * getIdealPoint() + 4 * getClearLinePoint() + 4 * getAdjacentPoint(); minusScore = 14 * getMinusPoint(); totalScore = plusScore - minusScore; eraseBlockOffBoard(); if (highestScore <= totalScore)//최적의 장소,모양을 검사한 최종점수가 여태까지의 최고점수보다 높으면 갱신 { highestScore = totalScore; position[rotation].x = BIT_X; position[rotation].y = BIT_Y; position[rotation].rotation = rotation; position[rotation].score = totalScore; } } rotateBlock(); } for (rotation = 0; rotation<4; rotation++) { if (position[rotation].score >= highestScore) { highestScore = position[rotation].score; bestRotation = rotation; } } BIT_X = firstX; BIT_Y = firstY; return position[bestRotation]; }//최적의 회전 형태 찾기
void fetchUserInput() { Block orgBlock = currentBlock; if (gameState == 0) { switch (getch()) { case KEY_LEFT: moveLeft(); break; case KEY_RIGHT: moveRight(); break; case KEY_UP: rotateBlock(); break; case KEY_DOWN: moveDown(); break; case 'p': gameState = 1; break; } } else { switch (getch()) { case 'p': if (gameState == 1) { gameState = 0; } break; case 'r': resetGame(); break; case 'q': inGame = 0; break; } } if (isCollision()) { currentBlock = orgBlock; } }
/* * Überprüft ob das Drehen eines Block-Containers überhaupt möglich ist, dazu wird * überprüft, ob alle Zielfeldblöcke noch nicht belegt sind. * Danach wird der Container gedreht. */ bool rotateBlockContainer(int rotation) { if (hasBlockContainer == true) { // Ermittle mittleren Block als Rotationsbasis int middle[2]; middle[0] = blockContainer[(int)floor(BLOCK_CONTAINER_SIZE/2)][0]; middle[1] = blockContainer[(int)floor(BLOCK_CONTAINER_SIZE/2)][1]; // Gehe durch die Container-Elemente um deren referenzierte Zielkoordinaten zu validieren int possible = 1; possible = rotateBlock(0, rotation, middle[0], middle[1], 1, true); // rekursiv if (possible == 1) { // Geht durch die Container-Elemente um die referenzierten Blöcke zu verschieben rotateBlock(0, rotation, middle[0], middle[1], 1, false); // rekursiv playSound(1); // Sound beim Rotieren return true; } } return false; }
/* * Drehe einen einzelnen Block oder überprüfe nur, * ob das Drehen des Block-Containers überhaupt möglich ist. * Siehe auch rotateBlockContainer. */ int rotateBlock(int i, int rotation, int mX, int mY, int possible, bool checkOnly) { int newX = -1; int newY = -1; if (blockContainer[i][0] != mX || blockContainer[i][1] != mY) { if (blockContainer[i][0] == mX) { // x-Werte stimmen überein newY = blockContainer[i][1] + ((mY - blockContainer[i][1])); newX = blockContainer[i][0] + ((mY - blockContainer[i][1]) * rotation); } else if (blockContainer[i][1] == mY) { // y-Werte stimmen überein newX = blockContainer[i][0] + ((mX - blockContainer[i][0])); newY = blockContainer[i][1] + ((mX - blockContainer[i][0]) * -rotation); } // Überprüfe nur, anstatt zu drehen if (checkOnly == true) { // Überprüfe ob der Feldblock schon belegt ist, und dieser im gültigen Bereich ist if ((newX < 0 || newX >= FIELD_COLS || newY < 0 || newY >= FIELD_ROWS) || fieldBlocks[newX][newY] > 0) { possible = 0; } } else { // Drehe Block fieldBlocks[newX][newY] = fieldBlocks[blockContainer[i][0]][blockContainer[i][1]]; fieldBlocks[blockContainer[i][0]][blockContainer[i][1]] = 0; // Und referenziere die neue Position im Container blockContainer[i][0] = newX; blockContainer[i][1] = newY; } } if (i+1 < BLOCK_CONTAINER_SIZE) { // sofern noch Blöcke bestehen prüfe / verschiebe auch diese possible = rotateBlock(i+1, rotation, mX, mY, possible, checkOnly); } return possible; }
BlockPattern::BlockPattern(int _gridWidth, int _pattern) { originX = _gridWidth / 2 - 2; originY = -4; valid = new bool*[4]; for (int i = 0; i < 4; i++) { valid[i] = new bool[4]; } switch (_pattern) { case 0: for (int i = 0; i < 4; i++) { for (int j = 0; j < 4; j++) { if (i == 1 && j == 1) { valid[i][j] = TRUE; } else { valid[i][j] = FALSE; } } } break; case 1: for (int i = 0; i < 4; i++) { for (int j = 0; j < 4; j++) { if ((i == 1 && j == 1) || (i == 2 && j == 1)) { valid[i][j] = TRUE; } else { valid[i][j] = FALSE; } } } break; case 2: for (int i = 0; i < 4; i++) { for (int j = 0; j < 4; j++) { if ((i == 1 && j == 0) || (i == 1 && j == 1) || (i == 1 && j == 2)) { valid[i][j] = TRUE; } else { valid[i][j] = FALSE; } } } break; case 3: for (int i = 0; i < 4; i++) { for (int j = 0; j < 4; j++) { if ((i == 1 && j == 1) || (i == 1 && j == 2) || (i == 2 && j == 2)) { valid[i][j] = TRUE; } else { valid[i][j] = FALSE; } } } break; case 4: for (int i = 0; i < 4; i++) { for (int j = 0; j < 4; j++) { if ((i == 0 && j == 1) || (i == 1 && j == 1) || (i == 2 && j == 1) || (i == 3 && j == 1)) { valid[i][j] = TRUE; } else { valid[i][j] = FALSE; } } } break; case 5: for (int i = 0; i < 4; i++) { for (int j = 0; j < 4; j++) { if ((i == 1 && j == 1) || (i == 1 && j == 2) || (i == 2 && j == 1) || (i == 3 && j == 1)) { valid[i][j] = TRUE; } else { valid[i][j] = FALSE; } } } break; case 6: for (int i = 0; i < 4; i++) { for (int j = 0; j < 4; j++) { if ((i == 1 && j == 1) || (i == 2 && j == 1) || (i == 2 && j == 2) || (i == 3 && j == 1)) { valid[i][j] = TRUE; } else { valid[i][j] = FALSE; } } } break; case 7: for (int i = 0; i < 4; i++) { for (int j = 0; j < 4; j++) { if ((i == 1 && j == 1) || (i == 2 && j == 1) || (i == 3 && j == 1) || (i == 3 && j == 2)) { valid[i][j] = TRUE; } else { valid[i][j] = FALSE; } } } break; case 8: for (int i = 0; i < 4; i++) { for (int j = 0; j < 4; j++) { if ((i == 1 && j == 1) || (i == 2 && j == 1) || (i == 2 && j == 2) || (i == 3 && j == 2)) { valid[i][j] = TRUE; } else { valid[i][j] = FALSE; } } } break; case 9: for (int i = 0; i < 4; i++) { for (int j = 0; j < 4; j++) { if ((i == 1 && j == 2) || (i == 2 && j == 1) || (i == 2 && j == 2) || (i == 3 && j == 1)) { valid[i][j] = TRUE; } else { valid[i][j] = FALSE; } } } break; case 10: for (int i = 0; i < 4; i++) { for (int j = 0; j < 4; j++) { if ((i == 1 && j == 1) || (i == 2 && j == 1) || (i == 1 && j == 2) || (i == 2 && j == 2)) { valid[i][j] = TRUE; } else { valid[i][j] = FALSE; } } } break; default: for (int i = 0; i < 4; i++) { for (int j = 0; j < 4; j++) { *(*(valid+i)+j) = FALSE; } } break; } for (int i = 0; i < (int)ofRandom(4); i++) { rotateBlock(1); } int j = 0; for (int i = 3; i >= 0; i--) { for (j = 0; j < 4; j++) { if (valid[i][j]) { break; } } if (valid[i][j]) { break; } originY++; } }
//main int main() { REG_DISPCNT = MODE_3 | BG2_ENABLE; enum GBAState state = START; enum GBAState prevState = state; while(1) { waitForVblank(); switch(state) { case START: drawImage3(0,0,SPLASH_WIDTH,SPLASH_HEIGHT,splash); prevState = START; state = NODRAW; break; case NODRAW: if (prevState == START) { if (KEY_DOWN_NOW(BUTTON_START)) { state = GAME; } if (KEY_DOWN_NOW(BUTTON_A)) { state = HELP; } } if (prevState == HELP) { if (KEY_DOWN_NOW(BUTTON_SELECT)) { state = START; } } if (prevState == GAMEOVER) { if (KEY_DOWN_NOW(BUTTON_SELECT)) { state = START; } } break; case GAME: drawImage3(0,0,GAME2_WIDTH,GAME2_HEIGHT,game2); char stuff[4] = "000\0"; stuff[0] = 48 + (clearedRows/100)%10; stuff[1] = 48 + (clearedRows/10)%10; stuff[2] = 48 + clearedRows%10; drawImagePartial(25, 180, 20, 30, GAME2_WIDTH, game2); drawString(25,180,stuff, WHITE); block curr = randomBlock(); block next = randomBlock(); drawBlock(curr); int button = 0; while(1) { delay(20); if (KEY_DOWN_NOW(BUTTON_SELECT)) { prevState = GAME; state = START; break; } block old = curr; tick++; if (collisionDetectBottom(curr) == 1) { rowCheck(curr); curr = next; next = randomBlock(); if(collisionDetect(curr) == 1) { prevState = GAME; state = GAMEOVER; break; } } else { if(KEY_DOWN_NOW(BUTTON_LEFT) && collisionDetectLeft(curr) == 0){ curr.x--; } else if(KEY_DOWN_NOW(BUTTON_RIGHT) && collisionDetectRight(curr) == 0){ curr.x++; } else if(KEY_DOWN_NOW(BUTTON_DOWN) && collisionDetectBottom(curr) == 0){ curr.y--; } else if(button == 0 && KEY_DOWN_NOW(BUTTON_UP) && rotationDetect(curr) == 0){ button = 1; rotateBlock(&curr); } else if (tick > 20) { tick = 0; curr.y--; } else if (!KEY_DOWN_NOW(BUTTON_DOWN)){ //drawString(25,70,"stuff stuff", WHITE); button = 0; } waitForVblank(); eraseBlock(old); drawBlock(curr); } } clearBoard(); drawRect(4,4,70,10, BLACK); break; case GAMEOVER: drawImage3(0,0,END_WIDTH,END_HEIGHT,end); prevState = GAMEOVER; state = NODRAW; break; case HELP: drawImage3(0,0,HELP_WIDTH,HELP_HEIGHT,help); prevState = HELP; state = NODRAW; break; } } return 0; }
int playGame() { int tempx = current.getPosX(); //Temp variables for position int tempy = current.getPosY(); if (keyboard_counter > 0 && keypressed()) //Keyboard Delay { if (key[KEY_LEFT]) //Move to the left { if (noCollision(current, tempx - 1, tempy)) //Checks collisions with the left movement { tempx--; //If there is not collision move the piece current.setPosX(tempx); } } if (key[KEY_RIGHT]) { if (noCollision(current, tempx + 1, tempy)) { tempx++; current.setPosX(tempx); } } if (key[KEY_DOWN]) { if (noCollision(current, tempx, tempy + 1)) { tempy++; current.setPosY(tempy); } } if (key[KEY_UP]) //Rotate the piece to the right { /*Create a temp piece for the request rotation*/ cPiece temp; temp.type = current.type; temp.rotation = rotateBlock(1, current.rotation); cleanPiece(temp); changePiece(temp, temp.type, temp.rotation); temp.setPosX(current.getPosX()); temp.setPosY(current.getPosY()); if (noCollision(temp, temp.getPosX(), temp.getPosY())) //Checks collision for the temp piece { //If there is not collision, the real falling(current) piece rotates to the right current.rotation = rotateBlock(1, current.rotation); cleanPiece(current); changePiece(current, current.type, current.rotation); } } if (key[KEY_T]) //Up the volume of the music { volume[0]+= 5; if (volume[0] > 255){ volume[0] = 255;} options[4].d2 = volume[0]; adjust_sample(sound[0], volume[0], 128, 1000, TRUE); adjust_sample(sound[1], volume[0], 128, 1000, TRUE); } if (key[KEY_G]) //Down the volume of the music { volume[0]-= 5; if (volume[0] < 0){ volume[0] = 0;} options[4].d2 = volume[0]; adjust_sample(sound[0], volume[0], 128, 1000, TRUE); adjust_sample(sound[1], volume[0], 128, 1000, TRUE); } if (key[KEY_Y]) //Up the volume of the sound effects { volume[1]+= 5; if (volume[1] > 255){ volume[1] = 255;} options[6].d2 = volume[1]; adjust_sample(sound[2], volume[1], 128, 1000, TRUE); adjust_sample(sound[3], volume[1], 128, 1000, TRUE); } if (key[KEY_H]) //Down the volume of the sound effects { volume[1]-= 5; if (volume[1] < 0){ volume[1] = 0;} options[6].d2 = volume[1]; adjust_sample(sound[2], volume[1], 128, 1000, TRUE); adjust_sample(sound[3], volume[1], 128, 1000, TRUE); } keyboard_counter--; } fpscount++; if (ticks > speed) { tempx = current.getPosX(); tempy = current.getPosY(); if (noCollision(current, tempx, tempy + 1)) //Checks collision for the falling { tempy++; current.setPosY(tempy); } else { play_sample(sound[2], volume[1], 128, 1000, FALSE); putBlock(current, tempx, tempy); //Put block on the board possibleRows(); //Check if a row is fill if (gameOver()) //Checks if the game is over { quitgame = 1; } else createBlock(current, next); //If the game it's not over create new pieces } ticks = 0; } return quitgame; }