Exemplo n.º 1
0
void handle_keyboard_event(nstate *state)
{
	GR_EVENT_KEYSTROKE *event = &state->event.keystroke;

	switch(event->ch) {
		case 'q':
		case 'Q':
		case MWKEY_CANCEL:
			state->state = STATE_EXIT;
			return;
		case 'n':
		case 'N':
		case MWKEY_APP1:
			state->state = STATE_NEWGAME;
			return;
	}

	if(state->state == STATE_STOPPED) return;

	state->state = STATE_RUNNING;

	switch(event->ch) {
		case 'p':
		case 'P':
			state->state = STATE_PAUSED;
			break;
		case 'j':
		case 'J':
        	case MWKEY_LEFT:
			move_block(state, 0);
			break;
		case 'k':
		case 'K':
        	case MWKEY_RIGHT:
			move_block(state, 1);
			break;
		case 'd':
		case 'D':
        	case MWKEY_UP:
			rotate_block(state, 0);
			break;
		case 'f':
		case 'F':
        	case MWKEY_DOWN:
			rotate_block(state, 1);
			break;
		case ' ':
        	case MWKEY_MENU:
			drop_block(state);
			break;
	}
}
Exemplo n.º 2
0
// This should probably go in the helper file with the save logic.
// But it's late and I want to get saving/loading working.
static void load_game() {
  // We already know that we have valid data (can_load).
  lines_cleared = persist_read_int(SCORE_KEY);
  level = (lines_cleared / 10) + 1;
  if (level > 10) { level = 10; }
  update_num_layer(lines_cleared, scoreStr, score_layer);
  update_num_layer(level, levelStr, level_layer);
  tick_time = max_tick - (tick_interval * level);
  persist_read_data(GRID_KEY, grid, sizeof(grid));
  persist_read_data(GRID_COL_KEY, grid_col, sizeof(grid_col));
  blockType = persist_read_int(BLOCK_TYPE_KEY);
  nextBlockType = persist_read_int(NEXT_BLOCK_TYPE_KEY);
  blockX = persist_read_int(BLOCK_X_KEY);
  blockY = persist_read_int(BLOCK_Y_KEY);
  make_block(block, blockType, blockX, blockY);
  make_block(nextBlock, nextBlockType, nextBlockX, nextBlockY);
  rotation = persist_read_int(ROTATION_KEY);
  if (rotation != 0) {
    for (int i=0; i<rotation; i++) {
      GPoint rPoints[4];
      rotate_block(rPoints, block, blockType, i);
      for (int j=0; j<4; j++) {
        block[j] = rPoints[j];
      }
    }
  }
}
Exemplo n.º 3
0
static void select_click_handler(ClickRecognizerRef recognizer, void *context) {
  if (!playing && lost) {
    restart_after_loss();
    return;
  }

  if (!playing && !lost && (load_choice < 2)) {
    setup_game();
    if (can_load && (load_choice == 1)) {
      load_game();
    }
    if (!s_timer) {
      drop_block();
      s_timer = app_timer_register(tick_time, game_tick, NULL);
    }
    return;
  }

  if (!playing && (load_choice == 2)) { // kamotswolf - had to modify several things in here to add new option
    option_shadows_buffer = !option_shadows_buffer;
    persist_write_bool(OPTION_SHADOWS_KEY, option_shadows_buffer);
    if(option_shadows_buffer) {
      text_layer_set_text(option_shadows_layer, "Drop Shadows ON");
    }
    else {
      text_layer_set_text(option_shadows_layer, "Drop Shadows OFF");
    }
    //layer_mark_dirty(s_title_pane_layer);
    return;
  }
  
  if (paused) {
    paused = false;
    s_timer = app_timer_register(tick_time, game_tick, NULL);
    layer_remove_from_parent(text_layer_get_layer(paused_label_layer));
    return;
  }

  if (blockType == -1) { return; }
  GPoint newPos[4];
  rotate_block(newPos, block, blockType, rotation);

  bool should_rotate = true;
  for (int i=0; i<4; i++) {
    if (newPos[i].x < 0 || newPos[i].x > 9) { should_rotate = false; }
    if (newPos[i].y < 0 || newPos[i].y > 19) { should_rotate = false; }
    if (grid[newPos[i].x][newPos[i].y]) { should_rotate = false; }
  }
  if (!should_rotate) { return; }

  for (int i=0; i<4; i++) {
    block[i] = newPos[i];
  }
  rotation = (rotation + 1) % 4;
  layer_mark_dirty(s_left_pane_layer);
}
Exemplo n.º 4
0
/*
 * Tetris Guidlines say wallkicks first try to move left, attempt rotation
 * again. Then if that fails, we try again but by moving to the right.
 */
static int try_wall_kick(struct blocks *block, enum blocks_input_cmd cmd)
{
	/* Try to move left and rotate again. */
	if (translate_block(block, MOVE_LEFT) == 1) {
		if (rotate_block(block, cmd) == 1)
			return 1;
	}

	/* undo previous translation */
	translate_block(block, MOVE_RIGHT);

	/* Try to move right and rotate again. */
	if (translate_block(block, MOVE_RIGHT) == 1) {
		if (rotate_block(block, cmd) == 1)
			return 1;
	}

	return 0;
}
Exemplo n.º 5
0
block create_block(uint8_t max_block_id)
{
	uint8_t block_id = rand() % (max_block_id + 1);
	block ret;
	memcpy_P(&ret, &blocks[block_id], sizeof(ret));
	for(uint8_t i = 0, rotations = rand() % 4; i != rotations; ++i)
		ret = rotate_block(ret);
	
	return ret;
}
Exemplo n.º 6
0
void handle_mouse_event(nstate *state)
{
	GR_EVENT_MOUSE *event = &state->event.mouse;

	if(event->wid == state->new_game_button) {
		state->state = STATE_NEWGAME;
		return;
	}
	if(event->wid == state->pause_continue_button) {
		if(state->state == STATE_PAUSED) state->state = STATE_RUNNING;
		else state->state = STATE_PAUSED;
		return;
	}
	if(event->wid == state->anticlockwise_button) {
		if(state->state == STATE_PAUSED) state->state = STATE_RUNNING;
		rotate_block(state, 0);
		return;
	}
	if(event->wid == state->clockwise_button) {
		if(state->state == STATE_PAUSED) state->state = STATE_RUNNING;
		rotate_block(state, 1);
		return;
	}
	if(event->wid == state->left_button) {
		if(state->state == STATE_PAUSED) state->state = STATE_RUNNING;
		move_block(state, 0);
		return;
	}
	if(event->wid == state->right_button) {
		if(state->state == STATE_PAUSED) state->state = STATE_RUNNING;
		move_block(state, 1);
		return;
	}
	if(event->wid == state->drop_button) {
		if(state->state == STATE_PAUSED) state->state = STATE_RUNNING;
		drop_block(state);
		return;
	}
}
Exemplo n.º 7
0
Move Game::find_move()
{
  for (int x = 0; x < dimension; x++) {
    for (int y = 0; y < dimension; y++) {
      for (int rot = 0; rot < 4; rot++) {
        for (int i = 0; i < blocks.size(); i++) {
          block b = blocks[my_number][i];
          block bb = rotate_block(b, rot);
          if (can_place(bb, Point(x, y))) {
            Move move = {i, rot, x, y};
            return move;
          }
        }
      }
    }
  }

  Move move = {0, 0, 0, 0};
  return move;
}
Exemplo n.º 8
0
void GameArea::key_press(QKeyEvent* event)
{
  switch (event->key()) {

  case Qt::Key_Left: {
    _start_x -= _step;

    if (is_left_most()) {
      _start_x += _step;
    } else {
      cur_block_2_map();
      drawArea();
    }

    break;
  }

  case Qt::Key_Right: {
    _start_x += _step;

    if (is_right_most()) {
      _start_x -= _step;
    } else {
      cur_block_2_map();
      drawArea();
    }

    break;
  }

  case Qt::Key_Up: {
    rotate_block();
    cur_block_2_map();
    drawArea();

    break;
  }

  case Qt::Key_Down: {
    if (_is_straight_down) {
      _start_y += _step;

      if (isMoveFini()) {
        _start_y -= _step;
      } else {
        cur_block_2_map();
        drawArea();
      }
    } else {
      int i = 0;
      while (!this->isMoveFini()) {
        _start_y += _step;
        ++i;
      }
      _start_y -= _step;

      if (i > 0) {
        cur_block_2_map();
        drawArea();
      }
    }

    break;
  }

  default:
    QFrame::keyPressEvent(event);
  }
}
Exemplo n.º 9
0
/*
 * User input. Hopefully self explanatory.
 *
 * Input keys are currently:
 * 	F1 pause
 * 	F3 quit
 *
 * 	wasdqe
 * 	- w hard drops a piece to the bottom.
 * 	- a/d move left/right respectively.
 * 	- s soft drops one row.
 * 	- qe rotate counter clockwise/clockwise repectively.
 *
 * 	- space is used to hold the currently falling block.
 */
void *blocks_input(void *vp)
{
	(void) vp; /* unused */
	
	int ch;

	if (!CURRENT_BLOCK())
		return NULL;

	while ((ch = getch())) {
		/* prevent modification of the game from blocks_loop in the
		 * other thread */
		pthread_mutex_lock(&pgame->lock);

		switch (ch) {
		case KEY_F(1):
			pgame->pause = !pgame->pause;
			goto draw_game;
		case KEY_F(3):
			pgame->pause = false;
			pgame->quit = true;
			goto draw_game;
		}

		/* remove the current piece from the board */
		unwrite_cur_block();

		/* modify it */
		switch (toupper(ch)) {
		case 'A':
			translate_block(CURRENT_BLOCK(), MOVE_LEFT);
			break;
		case 'D':
			translate_block(CURRENT_BLOCK(), MOVE_RIGHT);
			break;
		case 'S':
			if (drop_block(CURRENT_BLOCK()))
				CURRENT_BLOCK()->soft_drop++;
			else
				CURRENT_BLOCK()->lock_delay = 1E9 -1;
			break;
		case 'W':
			/* drop the block to the bottom of the game */
			while (drop_block(CURRENT_BLOCK()))
				CURRENT_BLOCK()->hard_drop++;

			/* XXX */
			CURRENT_BLOCK()->lock_delay = 1E9 -1;
			break;
		case 'Q':
			if (!rotate_block(CURRENT_BLOCK(), ROT_LEFT))
			{
				try_wall_kick(CURRENT_BLOCK(), ROT_LEFT);
			}
			break;
		case 'E':
			if (!rotate_block(CURRENT_BLOCK(), ROT_RIGHT))
			{
				try_wall_kick(CURRENT_BLOCK(), ROT_RIGHT);
			}
			break;
		case ' ': {
			struct blocks *tmp;

			/* We can hold each block exactly once */
			if (CURRENT_BLOCK()->hold == true)
				break;

			tmp = CURRENT_BLOCK();

			/* Effectively swap the first and second elements in
			 * the linked list. The "Current Block" is element 2.
			 * And the "Hold Block" is element 1. So we remove the
			 * current block and reinstall it at the head, pushing
			 * the hold block to the current position.
			 */
			LIST_REMOVE(tmp, entries);
			LIST_INSERT_HEAD(&pgame->blocks_head, tmp, entries);

			reset_block(HOLD_BLOCK());
			HOLD_BLOCK()->hold = true;

			break;
			}
		}

		/* then rewrite it */
		write_cur_block();

		draw_game:

		screen_draw_game();
		pthread_mutex_unlock(&pgame->lock);
	}

	return NULL;
}
Exemplo n.º 10
0
bool loop(uint32_t& score)
{
	score = 0;
	const uint8_t max_brightness = options::get_max_brightness();
	const bool accelerometer_enabled = options::is_accelerometer_enabled();
	
	block fig;
	uint8_t block_x = invalid_block_pos, block_y = invalid_block_pos;
	color::rgb block_color;
	uint8_t new_x;
	bool need_redraw = false;
	
	uint8_t game_counter = 0;
	uint8_t game_difficulty;
	uint8_t multiplier;
	uint8_t max_block_id;
	accelerometer::speed_state speed_state(5);
	accelerometer::direction last_direction = accelerometer::direction_none;
	
	init_difficulty(score, multiplier, game_difficulty, max_block_id);
	
	while(true)
	{
		timer::wait_for_interrupt();
		
		if(block_x == invalid_block_pos)
		{
			fig = create_block(max_block_id);
			game::get_random_color(block_color, max_brightness);
			
			block_y = ws2812_matrix::height - 1;
			bool have_space = get_new_block_pos(fig, block_x);
			show_block(block_x, block_y, fig, block_color);
			ws2812_matrix::show();
			if(!have_space)
				break; //No more space
		}
		
		if(++game_counter == game_difficulty)
		{
			game_counter = 0;
			hide_block(block_x, block_y, fig);
			if(block_y == fig.height - 1 || intersects(fig, block_x, block_y - 1))
			{
				show_block(block_x, block_y, fig, block_color);
				block_y = invalid_block_pos;
				block_x = invalid_block_pos; //Force new block creation
				//Re-initializes difficulty in case of fast drop
				check_filled_rows(score, multiplier, game_difficulty, max_block_id,
					max_brightness);
				continue;
			}
			
			--block_y;
			need_redraw = true;
		}
		
		auto button_up_status = buttons::get_button_status(buttons::button_up);
		auto button_down_status = buttons::get_button_status(buttons::button_down);
		if(button_up_status != buttons::button_status_not_pressed
			&& button_down_status != buttons::button_status_not_pressed)
		{
			button_up_status = buttons::button_status_not_pressed;
			button_down_status = buttons::button_status_not_pressed;
			
			hide_block(block_x, block_y, fig);
			if(!game::pause_with_screen_backup())
			{
				number_display::output_number(score);
				return true;
			}
			
			show_block(block_x, block_y, fig, block_color);
			number_display::output_number(score);
			need_redraw = true;
		}
		
		new_x = block_x;
		
		if(button_up_status == buttons::button_status_pressed)
		{
			hide_block(block_x, block_y, fig);
			const block new_fig = rotate_block(fig);
			uint8_t move_left = 0;
			
			bool rotated = true;
			if(block_y < new_fig.height - 1)
			{
				rotated = false;
			}
			else
			{
				if(new_fig.width + block_x > ws2812_matrix::width)
					move_left = block_x + new_fig.width - ws2812_matrix::width;
				
				while(intersects(new_fig, block_x - move_left, block_y))
				{
					++move_left;
					if(move_left == new_fig.width || block_x < move_left)
					{
						rotated = false;
						break;
					}
				}
			}
			
			if(rotated)
			{
				block_x -= move_left;
				new_x = block_x;
				fig = new_fig;
				need_redraw = true;
			}
			else
			{
				show_block(block_x, block_y, fig, block_color);
			}
		}
		
		switch(move_helper::process_speed(&speed_state, nullptr, accelerometer_enabled))
		{
			case move_direction_left:
				if(new_x < ws2812_matrix::width - fig.width)
					++new_x;
				break;
				
			case move_direction_right:
				if(new_x)
					--new_x;
				break;
				
			default:
				break;
		}
		
		if(accelerometer_enabled)
		{
			if(game_difficulty != fast_fall_game_difficulty)
			{
				auto accel_direction = accelerometer::get_exclusive_direction();
				
				if(accel_direction == accelerometer::direction_down
					&& last_direction == accelerometer::direction_none)
				{
					game_difficulty = fast_fall_game_difficulty;
					game_counter = game_difficulty - 1;
				}
				
				last_direction = accel_direction;
			}
		}
		else
		{
			if(button_down_status == buttons::button_status_pressed
				&& game_difficulty != fast_fall_game_difficulty)
			{
				game_difficulty = fast_fall_game_difficulty;
				game_counter = game_difficulty - 1;
			}
		}
		
		if(new_x != block_x)
		{
			hide_block(block_x, block_y, fig);
			if(!intersects(fig, new_x, block_y))
			{
				block_x = new_x;
				need_redraw = true;
			}
			else
			{
				show_block(block_x, block_y, fig, block_color);
			}
		}
		
		if(need_redraw)
		{
			show_block(block_x, block_y, fig, block_color);
			ws2812_matrix::show();
			need_redraw = false;
		}
	}
	
	return false;
}
Exemplo n.º 11
0
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
    
    int block_idx = (int) (mxGetScalar(prhs[1]));
    int translation = (int) (mxGetScalar(prhs[2]));
    int rotation = (int) (mxGetScalar(prhs[3]));
    double* map0 = mxGetPr(prhs[0]);
    int block[4][2];
    int block_pos[2];
    int new_block_pos[2];
    int map_2D[19][12];
    
    double* game_over;
    double* map1;
    
    int i;
    
    plhs[0] =mxCreateDoubleMatrix(19,12, mxREAL); /*resulting board*/
    plhs[1] =mxCreateDoubleMatrix(1,1, mxREAL); /*game over or not*/
    
    map1 = mxGetPr(plhs[0]);
    game_over = mxGetPr(plhs[1]);
    
    /* // default outcomes: */
    game_over[0] = 1;
    copy_map(map1, map0);
    
        
    if(block_idx <1 || block_idx > 7){
        printf("illegal block_idx: %d\n", block_idx);
        return;
    }
    
    if(translation > 10 || translation < 1){
        if(translation>10)
            translation = 10;
        if(translation < 1)
            translation = 1;
    }
    
    if(rotation < 0 || rotation > 3){
        while(rotation < 0)
            rotation+=4;
        while(rotation > 3)
            rotation -= 4;
    }
    
    build_2D_map(map0, map_2D);

/* //    printf("printing before block placement\n"); */
/* //    print_2D_map(map_2D); */

    copy_block(blocks[block_idx-1], block);
        
    game_over[0] = 0;
    
    block_pos[1] = BoxY-3;
    block_pos[0] = (int) (floor(BoxX/2));
    
    /*% rotate action*/
    for (i=1; i<=rotation; ++i){
        rotate_block(block);
    }
    
    
    /* check if game over*/
    if(collision(map_2D, block_pos, block)){
        copy_map(map1, map0);
        game_over[0] = 1;
        return;
    }

    

    
    /*% translate action*/
    while( translation < block_pos[0]){
        new_block_pos[0] = block_pos[0]-1;
        new_block_pos[1] = block_pos[1];
        
        if (!collision(map_2D, new_block_pos, block)){
            block_pos[0] = new_block_pos[0];
        } else {
            break;
        }
    }
    
    while( translation > block_pos[0]){
        new_block_pos[0] = block_pos[0]+1;
        new_block_pos[1] = block_pos[1];
        
        if (!collision(map_2D, new_block_pos, block)){
            block_pos[0] = new_block_pos[0];
        } else {
            break;
        }
    }
    
    /*%drop shape:*/
    new_block_pos[0] = block_pos[0];
    new_block_pos[1] = block_pos[1];
    while(!collision(map_2D, new_block_pos, block)){
        new_block_pos[1] = new_block_pos[1] - 1;
    }
    block_pos[1] = new_block_pos[1]+1;
    
    
    
    place_block_in_map(map_2D, block_pos, block);
/* //    printf("printing after block placement\n"); */
/* //    print_2D_map(map_2D); */
        
    /* % check for filled rows */
    check_map_for_filled_rows(map_2D);
    
/* //    printf("printing after row clearing\n"); */
/* //    print_2D_map(map_2D); */
    
    write_2D_map_to_1D(map_2D, map1);

    game_over[0] = 0;
}