예제 #1
0
int MancalaBoard::util_value(int player_turn, int root_player){
    if(moves_available(player_turn) == 0){
        //If this is the case then the game is over and you need to add all stones from the opposing side to their mancala
        if(player_turn == 1){
            for(int i=p2_cell_start; i <= p2_cell_end; i++){
                p2_mancala += cells[i];
                cells[i] = 0;
            }
        }
        else if(player_turn == 2){
            for(int i=0; i <= p1_cell_end; i++){
                p1_mancala += cells[i];
                cells[i] = 0;
            }
        }
    }
    
    if(root_player == 1){
        return p1_mancala - p2_mancala;
    }
    else{
        return p2_mancala - p1_mancala;
    }
    
}
예제 #2
0
bool MancalaBoard::checkMoveValid(int move, int player_num){
    int count = moves_available(player_num);
    int *options = next_moves(player_num);
    
    for (int i=0; i<count; ++i) {
        if(options[i] == move){
            delete options;
            return true;
        }
    }
    delete options;
    return false;
}
예제 #3
0
bool MancalaBoard::checkGameOver(int player_turn){
    if(moves_available(player_turn) == 0){
        //If this is the case then the game is over and you need to add all stones from the opposing side to their mancala
        if(player_turn == 1){
            for(int i=p2_cell_start; i <= p2_cell_end; i++){
                p2_mancala += cells[i];
                cells[i] = 0;
                return true;
            }
        }
        else if(player_turn == 2){
            for(int i=0; i <= p1_cell_end; i++){
                p1_mancala += cells[i];
                cells[i] = 0;
                return true;
            }
        }
    }
    return false;
}
예제 #4
0
int* MancalaBoard::next_moves(int player_num){
    int count = moves_available(player_num);
    int *result = new int[count];
    if(player_num == 1){
        int j = 0;
        for(int i=0; i <= p1_cell_end; i++){
            if(cells[i] != 0){
                result[j] = i;
                j++;
            }
        }
    }
    else if(player_num == 2){
        int j = 0;
        for(int i=p2_cell_start; i <= p2_cell_end; i++){
            if(cells[i] != 0){
                result[j] = i - num_cells;
                j++;
            }
        }
    }
    return result;
}
예제 #5
0
/* parses options and stores the main game loop */
int main(int argc, char **argv)
{
    /* init ncurses environment */
    initscr();
    cbreak();
    noecho();
    curs_set(FALSE);

    /* init variables */
    file = ".hs2048g";
    hs = 0;
    s  = 0;
    sl = 0;
    SZ = 4;
    MAXVAL = 4;
    CALLOC2D(g, SZ);

    load_score();
    int n_blocks = 1;
    
    /* parse options */
    int c;
    while ((c = getopt(argc, argv, "rchs:b:")) != -1) {
        switch (c) {
            // color support - assumes your terminal can display colours
            // should still work regardless
            case 'c':
                start_color();
                init_pair(1, 1, 0);
                init_pair(2, 2, 0);
                init_pair(3, 3, 0);
                init_pair(4, 4, 0);
                init_pair(5, 5, 0);
                init_pair(6, 6, 0);
                init_pair(7, 7, 0);
                break;
            // different board sizes
            case 's':
                FREE2D(g, SZ);
                int optint = atoi(optarg);
                SZ = optint > 4 ? optint : 4;
                CALLOC2D(g, SZ);
                break;
            // different block spawn rate
            case 'b':
                n_blocks = atoi(optarg);
                break;
            // reset hiscores
            case 'r':
                endwin();
                printf("Are you sure you want to reset your highscores? (Y)es or (N)o\n");
                int response;
                if ((response = getchar()) == 'y' || response == 'Y') {
                    FILE *fd = fopen(file, "w+");
                    fclose(fd);
                }
                exit(EXIT_SUCCESS);
            // help menu
            case 'h':
                endwin();
                printf("Controls:\n"
                       "    hjkl, wasd      Movement\n"
                       "    q               Quit\n"
                       "\n"
                       "Usage:\n"
                       "    2048 [options]\n"
                       "\n"
                       "Options:\n"
                       "    -s <size>       Set the grid border length\n"
                       "    -b <rate>       Set the block spawn rate\n"
                       "    -c              Enables color support\n");
                exit(EXIT_SUCCESS);
        }
    }
    
    int width  = SZ * (MAXVAL + 2) + 1;
    int height = SZ * (MAXVAL + 2) + 3;

    // might center in middle of screen
    WINDOW *gamewin = newwin(height, width, 1, 1);
    keypad(gamewin, TRUE);

    /* random seed */
    srand((unsigned int)time(NULL));
    ITER(2, rand_block());
    draw_grid(gamewin);

    int key, moved;
    while (1) {
        /* will goto this if we didn't get a valid keypress */
        retry:;
        moved = 0;
        key = wgetch(gamewin);
        sl = 0;

        /* should check if anything changed during merge and if not retry */
        switch (key) {
            case 'h':
            case 'a':
            case KEY_LEFT:
                moved = TURN(DL);
                break;
            case 'l':
            case 'd':
            case KEY_RIGHT:
                moved = TURN(DR);
                break;
            case 'j':
            case 's':
            case KEY_DOWN:
                moved = TURN(DD);
                break;
            case 'k':
            case 'w':
            case KEY_UP:
                moved = TURN(DU);
                break;
            case 'q':
                FREE2D(g, SZ);
                erase();
                refresh();
                endwin();
                save_score();
                exit(EXIT_SUCCESS);
            default:
                goto retry;
        }
        
        if (!moves_available()) {
            endwin();
            printf("\n"
                   "YOU LOSE! - Your score was %d\n", s);
            save_score();
            exit(EXIT_SUCCESS);
        }

        if (moved) {
            ITER(n_blocks, rand_block());
            draw_grid(gamewin);
        }
    }
}
예제 #6
0
//Enocdes rules of the game, pretty crazy function
//excepts a 0-indexed move relative to the player's cells from left to right
bool MancalaBoard::make_move(int player, int cell){
    checkGameOver(player);
    if(player == 1){
        if(cell > p1_cell_end || cell < 0){
            std::cout << "Invalid move for p1" << std::endl;
            return false;
        }
        
        int num_moves = cells[cell];
        cells[cell] = 0;
        int pos = cell; //current position during loop
        while(num_moves > 0){
            if(pos < p1_cell_end){//iterating through own player's cells just move to next cell
                pos++;
                if(num_moves == 1){//ending on own side (check if cell is empty)
                    if(cells[pos] == 0){
                        p1_mancala += cells[pos + num_cells];
                        cells[pos + num_cells] = 0;
                        cells[pos] = 0;
                        p1_mancala ++;
                    }
                    else{
                        cells[pos]++;
                    }
                }
                else{
                    cells[pos]++;
                }
            }
            else if(pos == p1_cell_end){//at the end of player's row, add to mancala and begin iterating backwards
                p1_mancala++;
                pos = p2_cell_end + 1;
            }
            else{//at other player's side add to their cell and iterate
                if(pos == p2_cell_start){//reset to bottom cell
                    pos = p1_cell_start;
                    if(num_moves == 1){//ending on own side (check if cell is empty)
                        if(cells[pos] == 0){
                            p1_mancala += cells[pos + num_cells];
                            cells[pos + num_cells] = 0;
                            cells[pos] = 0;
                            p1_mancala ++;
                        }
                        else{
                            cells[pos]++;
                        }
                        
                    }
                    else{
                        cells[pos]++;
                    }
                }
                else{
                    pos--;
                    cells[pos]++;
                }
            }
            num_moves--;
        }
        if(pos == p2_cell_end + 1)//bonus move!
        {
            if(moves_available(player) > 0){
                return true;
            }
            else{
                checkGameOver(player);
            }
        }
    }
    else if(player == 2){
        if(cell >= num_cells || cell < 0){
            std::cout << "Invalid move for p2" << std::endl;
            return false;
        }
        
        cell = cell + num_cells;//convert to upper cell location in internal state representation
        int num_moves = cells[cell];
        cells[cell] = 0;
        int pos = cell;//current position during iteration
        //A move involves placing a stone into the next cell and updating position accordingly
        while(num_moves > 0){
            if(pos > p2_cell_start){//iterating through player's own cells (CCW => negative)
                pos--;
                if(num_moves == 1){
                    if(cells[pos] == 0){//ending in void cell on own side
                        p2_mancala += cells[pos - num_cells];
                        cells[pos - num_cells] = 0;
                        cells[pos] = 0;
                        p2_mancala++;
                    }
                    else{
                        cells[pos]++;
                    }
                }
                else{
                    cells[pos]++;
                }
            }
            else if(pos == p2_cell_start){//at the end of the player's row, add to mancala and begin iterating forwards
                p2_mancala++;
                pos = p1_cell_start - 1;
            }
            else{//on p1's side increment forwards
                if(pos == p1_cell_end){//reset to top cell
                    pos = p2_cell_end;
                    if(num_moves == 1){
                        if(cells[pos] == 0){
                            p2_mancala += cells[pos - num_cells];
                            cells[pos - num_cells] = 0;
                            cells[pos] = 0;
                            p2_mancala++;
                        }
                        else{
                            cells[pos]++;
                        }
                    }
                    else{
                        cells[pos]++;
                    }
                }
                else{
                    pos++;
                    cells[pos]++;
                }
            }
            num_moves--;
        }
        if(pos == p1_cell_start - 1){//bonus move!
            if(moves_available(player) > 0){
                return true;
            }
            else{
                checkGameOver(player);
            }
        }
    }
    return false;//performed action with no bonus move
}