Example #1
0
 /*  
     This method handles the move of fire type.
     depending on the direction of the beam, either 
     a piece is captured or the beam is reflected untill
     it moves off the board
 */ 
 void Board::handleFireMove(uint32_t orig_r, uint32_t orig_c,
         Piece::Orientation beam_ori, uint32_t depth)
 {
     if (depth > 20)
         return;
     Piece* first_hit = findFirstPieceHit(orig_r, orig_c, beam_ori);
     // check if laser hits a piece
     if (first_hit) {
         if (first_hit->ptype == Piece::HYPER_HOLE)
             return;
         else if (!first_hit->can_reflect(beam_ori))
             deletePiece(first_hit);
         else {
             // generate reflected beam
             std::list<Piece::Orientation> ori_list;
             first_hit->getReflectedOrientations(beam_ori, ori_list);
             std::list<Piece::Orientation>::iterator or_it;
             for (or_it=ori_list.begin(); or_it != ori_list.end();
                     or_it++) {
                 handleFireMove(first_hit->pos.row, first_hit->pos.col,
                         *or_it, depth+1);
             }
         }
     }
 }
Example #2
0
/*
 * Moves the piece to rigth with collision detection
 * moving a piece is just a shift of the 4 chars of the piece
 */
void goRigth() {
    /* 
     * try to move piece only if it still fits in the field after rotation
     * the trick is check if one of the less significant bits of each char is equal to 1 
     */
    if (((actualPiece[0] | actualPiece[1] | actualPiece[2] | actualPiece[3]) & 0x01) == 0x00) {
        /*
         * first deletes the actual piece from the field and then
         * checks is there is no collision with the new position. if the
         * piece fits beetween the other pieces adds it to fild. else retores the original
         * piece if collides with other pieces 
         */
        deletePiece();                  // deletes the actual piece from field
        updateTempPiece();              // updates temp piece
        shiftRigth(tempPiece);          // shifts the temp piece
        if (isCollision() == 0x00) {    // no collision? shifts the actual piece
            shiftRigth(actualPiece);    //  and adds it to the field
            addPiece();
            updateTempPiece();
            pieceShift++;
        }
        addPiece();                     // no collision? replace the actual piece on field
        updateDisplayField();           // updates the display field
    }
}
Example #3
0
/*
 * Rotates the actual piece CCW with collision detection
 * the rotation is just a piece layout change with the actual piecePos,
 * rotates only if is possible.
 */
void rotate() {

    char i = 0;
    // try to rotate piece only if it still fits in the field after rotation
    if (pieceNum != 0x00 && getMaxLeftShift() <= pieceShift && pieceShift <= getMaxRigthShift()) {

        /*
         * first deletes the actual piece from the field and then
         * checks is there is no collision with the new position. if the
         * piece fits beetween the other pieces adds it to fild. else retores the original
         * piece if collides with other pieces 
         */
        deletePiece();              // deletes the actual piece from field
        piecePos++;                 // increments the piece y position
        if (piecePos == 0x04) {     // controls the rotation position range
            piecePos = 0x00;
        }
        tempPiece[0] = pieces[pieceNum][piecePos][0]; // updates the temp piece
        tempPiece[1] = pieces[pieceNum][piecePos][1];
        tempPiece[2] = pieces[pieceNum][piecePos][2];
        tempPiece[3] = pieces[pieceNum][piecePos][3];

        if (pieceShift < 0x00) { // shifts the temp piece to actal x position
            for (i = (-1) * pieceShift; i > 0; i--) {
                shiftLeft(tempPiece);
            }
        } else {
            for (i = pieceShift; i > 0; i--) {
                shiftRigth(tempPiece);
            }
        }

        if (isCollision() == 0x00) { // no collision? aplies the new rotation position
            actualPiece[0] = pieces[pieceNum][piecePos][0];
            actualPiece[1] = pieces[pieceNum][piecePos][1];
            actualPiece[2] = pieces[pieceNum][piecePos][2];
            actualPiece[3] = pieces[pieceNum][piecePos][3];
            
            // shifts the new piece to the last X position
            if (pieceShift < 0x00) {
                for (i = (-1) * pieceShift; i > 0; i--) {
                    shiftLeft(actualPiece);
                }
            } else {
                for (i = pieceShift; i > 0; i--) {
                    shiftRigth(actualPiece);
                }
            }
        } else { // collision? just go back and aplies the last piece
            if (piecePos == 0x00) {
                piecePos = 0x03;
            } else {
                piecePos--;
            }
        }

        addPiece();
        updateDisplayField(); // updates the display field
    }
}
Example #4
0
    void Board::applyMove(Move* m)
    {
        if (m->isMove()) { /* Move moves */
            int32_t dst_r, dst_c;
	    // get the destination row and column value for given move 
            m->getPieceDestination(dst_r, dst_c);
            // get the current piece at the move source point 
            Piece* p = piece_array[m->piece_r][m->piece_c];

            // dst is occupied by another piece of either colour
            if (piece_array[dst_r][dst_c] != NULL) {
                Piece* dst_p = piece_array[dst_r][dst_c];
                // dst is hyperhole
                if (dst_p->ptype == Piece::HYPER_HOLE) {
                    if (!m->tport_info) {
                        do { // find a random unoccupied position
                            p->teleportRandom();
                        } while (piece_array[p->pos.row][p->pos.col] != NULL);
                        // store teleport info
                        m->tport_info = new Move::TeleportInfo(p->pos.row,
                                p->pos.col, p->ori);
                    } else {
                        Move::TeleportInfo* t = m->tport_info;
                        p->pos.row = t->row;
                        p->pos.col = t->col;
                        p->ori = t->ori;
                    }
                    // update p info
                    piece_array[p->pos.row][p->pos.col] = p;
                    piece_array[m->piece_r][m->piece_c] = NULL;
                    return; 
                } else if (p->ptype == Piece::HYPERCUBE) { // piece is hypercube
                    if (!m->tport_info) {
                        do { // find a random unoccupied position
                            dst_p->teleportRandom();
                        } while (piece_array[dst_p->pos.row][dst_p->pos.col]
                                != NULL);
                        m->tport_info = new Move::TeleportInfo(dst_p->pos.row,
                                dst_p->pos.col, dst_p->ori);
//                        fprintf(stderr, "Stored for %p\n", m);
//                        m->printMove();
                    } else {
//                        fprintf(stderr, "getting %p\n", m);
//                        m->printMove();
                        Move::TeleportInfo* t = m->tport_info;
                        dst_p->pos.row = t->row;
                        dst_p->pos.col = t->col;
                        dst_p->ori = t->ori;
                    }
                    // update dst_p info
                    piece_array[dst_p->pos.row][dst_p->pos.col] = dst_p;
                } else { // we capture piece
                    deletePiece(dst_p);
                }
            }
            // move piece into position and set original to NULL
            piece_array[dst_r][dst_c] = p;
            piece_array[m->piece_r][m->piece_c] = NULL;

            // update piece_position
            p->pos.row = dst_r;
            p->pos.col = dst_c;
        } else if (m->isFire()) { /* Fire moves */
            Piece* p = piece_array[m->piece_r][m->piece_c];
            handleFireMove(m->piece_r, m->piece_c, p->ori);
        } else if (m->isRotate()) { /* Rotate moves */
            Piece* p = piece_array[m->piece_r][m->piece_c];
            switch (m->m_typ) {
                case ROTATE_C:
                    p->rotate_c(); break;
                case ROTATE_AC:
                    p->rotate_ac(); break;
                default:
                    assert(false && "Shouldn't be here");
            }
        }
    }