0.2.1 SysV ABI fix for passing certain things by struct. Fix implicitly converting to float in the case of myfloat *= -1. Prefer inferred constant over global. Allow locals to shadow global variables.

This commit is contained in:
Christoffer Lerno
2022-04-26 14:07:37 +02:00
parent 212bc7d9af
commit 22ee082d00
13 changed files with 2234 additions and 152 deletions

View File

@@ -1,167 +1,791 @@
module foo;
extern fn void printf(char*, ...);
module tetris;
/**
* raylib - classic game: tetris
*
* Sample game developed by Marc Palau and Ramon Santamaria,
* converted to C3 by Christoffer Lerno.
*
* This game has been created using raylib v1.3 (www.raylib.com)
*
* Copyright (c) 2015 Ramon Santamaria (@raysan5)
*/
enum Foo : int (int offset, char* extra_name, double x)
//----------------------------------------------------------------------------------
// Some Defines
//----------------------------------------------------------------------------------
const SQUARE_SIZE = 20;
const GRID_HORIZONTAL_SIZE = 12;
const GRID_VERTICAL_SIZE = 20;
const LATERAL_SPEED = 10;
const TURNING_SPEED = 12;
const FAST_FALL_AWAIT_COUNTER = 30;
const FADING_TIME = 33;
//----------------------------------------------------------------------------------
// Types and Structures Definition
//----------------------------------------------------------------------------------
enum GridSquare { EMPTY, MOVING, FULL, BLOCK, FADING }
//------------------------------------------------------------------------------------
// Global Variables Declaration
//------------------------------------------------------------------------------------
const int SCREEN_WIDTH = 800;
const int SCREEN_HEIGHT = 450;
bool game_over = false;
bool pause = false;
// Matrices
GridSquare[GRID_VERTICAL_SIZE][GRID_HORIZONTAL_SIZE] grid;
GridSquare[4][4] piece;
GridSquare[4][4] incoming_piece;
struct IntVec
{
BAZ(12, "hello", 3.0),
BOO(33, "oekfe", 4.0) = 3,
int x;
int y;
}
// These variables keep track of the active piece position
int piece_position_x = 0;
int piece_position_y = 0;
// Game parameters
Color fading_color;
//int fallingSpeed; // In frames
bool begin_play = true; // This var is only true at the begining of the game, used for the first matrix creations
bool piece_active = false;
bool detection = false;
bool line_to_delete = false;
// Statistics
int level = 1;
int lines = 0;
// Counters
int gravity_movement_counter = 0;
int lateral_movement_counter = 0;
int turn_movement_counter = 0;
int fast_fall_movement_counter = 0;
int fade_line_counter = 0;
// Based on level
int gravity_speed = 30;
//------------------------------------------------------------------------------------
// Program main entry point
//------------------------------------------------------------------------------------
fn void main()
{
int screenWidth = 800;
int screenHeight = 450;
// Initialization (Note windowTitle is unused on Android)
//---------------------------------------------------------
raylib::init_window(SCREEN_WIDTH, SCREEN_HEIGHT, "classic game: tetris");
raylib::init_window(screenWidth, screenHeight, "raylib [core] example - keyboard input");
init_game();
Vector2 ballPosition = { (float)screenWidth/2, (float)screenHeight/2 };
raylib::set_target_fps(60); // Set our game to run at 60 frames-per-second
raylib::set_target_fps(60);
//--------------------------------------------------------------------------------------
foo2::tester(screenHeight);
// Main game loop
while (!raylib::window_should_close()) // Detect window close button or ESC key
{
// Update
// Update and Draw
//----------------------------------------------------------------------------------
if (raylib::is_key_down(KeyboardKey.RIGHT)) ballPosition.x += 2.0f;
if (raylib::is_key_down(KeyboardKey.LEFT)) ballPosition.x -= 2.0f;
if (raylib::is_key_down(KeyboardKey.UP)) ballPosition.y -= 2.0f;
if (raylib::is_key_down(KeyboardKey.DOWN)) ballPosition.y += 2.0f;
//----------------------------------------------------------------------------------
// Draw
//----------------------------------------------------------------------------------
raylib::begin_drawing();
raylib::clear_background(raylib::RAYWHITE);
raylib::draw_text("move the ball with arrow keys", 10, 10, 20, raylib::DARKGRAY);
raylib::draw_circle_v(ballPosition, 50, raylib::MAROON);
raylib::end_drawing();
update_draw_frame();
//----------------------------------------------------------------------------------
}
// De-Initialization
//--------------------------------------------------------------------------------------
unload_game(); // Unload loaded data (textures, sounds, models...)
raylib::close_window(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------
}
/*
struct Game
//--------------------------------------------------------------------------------------
// Game Module Functions Definition
//--------------------------------------------------------------------------------------
// Initialize game variables
fn void init_game()
{
int answer;
bool done;
int guesses;
int high;
// Initialize game statistics
level = 1;
lines = 0;
fading_color = raylib::GRAY;
piece_position_x = 0;
piece_position_y = 0;
pause = false;
begin_play = true;
piece_active = false;
detection = false;
line_to_delete = false;
// Counters
gravity_movement_counter = 0;
lateral_movement_counter = 0;
turn_movement_counter = 0;
fast_fall_movement_counter = 0;
fade_line_counter = 0;
gravity_speed = 30;
// Initialize grid matrices
for (int i = 0; i < GRID_HORIZONTAL_SIZE; i++)
{
for (int j = 0; j < GRID_VERTICAL_SIZE; j++)
{
if ((j == GRID_VERTICAL_SIZE - 1) || (i == 0) || (i == GRID_HORIZONTAL_SIZE - 1))
{
grid[i][j] = BLOCK;
}
else
{
grid[i][j] = EMPTY;
}
}
}
// Initialize incoming piece matrices
for (int i = 0; i < 4; i++)
{
for (int j = 0; j< 4; j++)
{
incoming_piece[i][j] = EMPTY;
}
}
}
int err_count = 0;
import "core:bufio"
import "core:fmt"
import "core:io"
import "core:mem"
import "core:os"
import "core:strconv"
import "core:time"
import "core:math/rand"
Game :: struct {
answer: int,
done: bool,
guesses: int,
high: int,
}
int err_count = 0;
*/
/*
fn int ask_guess(int high)
// Update game (one frame)
fn void update_game()
{
libc::printf("Guess a number between 1 and %d: ", high);
}
ask_guess :: proc(high: int) -> (result: int, ok: bool) {
fmt.printf("Guess a number between 1 and %d: ", high)
if text, ok := read_line(); ok {
defer mem.delete(text)
return strconv.parse_int(s = text, base = 10)
if (game_over)
{
if (raylib::is_key_pressed(keyboard::ENTER))
{
init_game();
game_over = false;
}
return;
}
return
}
if (raylib::is_key_pressed((KeyboardKey)'P')) pause = !pause;
ask_guess_multi :: proc(high: int) -> int {
for {
if result, ok := ask_guess(high); ok {
return result
}
fmt.println("I didn't understand")
err_count += 1
if (pause) return;
if (line_to_delete)
{
// Animation when deleting lines
fade_line_counter++;
fading_color = fade_line_counter % 8 < 4 ? raylib::MAROON : raylib::GRAY;
if (fade_line_counter >= FADING_TIME)
{
lines += delete_complete_lines();
fade_line_counter = 0;
line_to_delete = false;
}
return;
}
if (!piece_active)
{
// Get another piece
piece_active = create_piece();
// We leave a little time before starting the fast falling down
fast_fall_movement_counter = 0;
}
else // Piece falling
{
// Counters update
fast_fall_movement_counter++;
gravity_movement_counter++;
lateral_movement_counter++;
turn_movement_counter++;
// We make sure to move if we've pressed the key this frame
if (raylib::is_key_pressed(keyboard::LEFT) || raylib::is_key_pressed(keyboard::RIGHT)) lateral_movement_counter = LATERAL_SPEED;
if (raylib::is_key_pressed(keyboard::UP)) turn_movement_counter = TURNING_SPEED;
// Fall down
if (raylib::is_key_down(keyboard::DOWN) && (fast_fall_movement_counter >= FAST_FALL_AWAIT_COUNTER))
{
// We make sure the piece is going to fall this frame
gravity_movement_counter += gravity_speed;
}
if (gravity_movement_counter >= gravity_speed)
{
// Basic falling movement
check_detection(&detection);
// Check if the piece has collided with another piece or with the boundings
resolve_falling_movement(&detection, &piece_active);
// Check if we fullfilled a line and if so, erase the line and pull down the the lines above
check_completion(&line_to_delete);
gravity_movement_counter = 0;
}
// Move laterally at player's will
if (lateral_movement_counter >= LATERAL_SPEED)
{
// Update the lateral movement and if success, reset the lateral counter
if (!resolve_lateral_movement()) lateral_movement_counter = 0;
}
// Turn the piece at player's will
if (turn_movement_counter >= TURNING_SPEED)
{
// Update the turning movement and reset the turning counter
if (resolve_turn_movement()) turn_movement_counter = 0;
}
}
// Game over logic
for (int j = 0; j < 2; j++)
{
for (int i = 1; i < GRID_HORIZONTAL_SIZE - 1; i++)
{
if (grid[i][j] == GridSquare.FULL)
{
game_over = true;
}
}
}
}
pick_answer :: proc(high: int, r: ^rand.Rand) -> int {
return rand.int_max(high, r) + 1
}
play :: proc(game: ^Game) {
for !game.done {
guess := ask_guess_multi(game.high)
report(game^, guess)
game^ = update(game^, guess)
}
}
read_line :: proc() -> (result: string, ok: bool) {
// See also:
// - https://github.com/odin-lang/Odin/issues/1214
// - https://p.teknik.io/Raw/IT996
s := os.stream_from_handle(os.stdin)
r: bufio.Reader
bufio.reader_init(&r, io.Reader{s})
defer bufio.reader_destroy(&r)
if line, err := bufio.reader_read_string(&r, '\n'); err == .None {
return line[:len(line) - 1], true
}
return
}
report :: proc(game: Game, guess: int) {
// game.done = true
// fmt.println(&game)
description := (
"too low" if guess < game.answer else
"too high" if guess > game.answer else
"the answer!"
)
fmt.println(guess, "is", description)
}
update :: proc(game: Game, guess: int) -> (next: Game) {
next = game
next.done = guess == game.answer
next.guesses += 1
return
}
main :: proc() {
high :: 100
r := rand.create(transmute(u64)time.now())
// Or use nil for default random.
answer := pick_answer(high, &r)
game := Game {answer = answer, done = false, guesses = 0, high = high}
play(&game)
fmt.println("Finished in", game.guesses, "guesses");
fmt.println("Total input errors:", err_count)
}
*/
module foo2;
fn void tester(int x)
// Draw game (one frame)
fn void draw_game()
{
assert(x > 1000, "Shit!");
raylib::begin_drawing();
raylib::clear_background(raylib::RAYWHITE);
if (game_over)
{
raylib::draw_text("PRESS [ENTER] TO PLAY AGAIN", raylib::get_screen_width() / 2 - raylib::measure_text("PRESS [ENTER] TO PLAY AGAIN", 20) / 2, raylib::get_screen_height() / 2 - 50, 20, raylib::GRAY);
raylib::end_drawing();
return;
}
// Draw gameplay area
IntVec offset = {
SCREEN_WIDTH / 2 - (GRID_HORIZONTAL_SIZE * SQUARE_SIZE / 2) - 50,
SCREEN_HEIGHT / 2 - ((GRID_VERTICAL_SIZE - 1) * SQUARE_SIZE / 2) + SQUARE_SIZE * 2
};
offset.y -= 50; // NOTE: Harcoded position!
int controller = offset.x;
for (int j = 0; j < GRID_VERTICAL_SIZE; j++)
{
for (int i = 0; i < GRID_HORIZONTAL_SIZE; i++)
{
// Draw each square of the grid
switch (grid[i][j])
{
case EMPTY:
raylib::draw_line(offset.x, offset.y, offset.x + SQUARE_SIZE, offset.y, raylib::LIGHTGRAY );
raylib::draw_line(offset.x, offset.y, offset.x, offset.y + SQUARE_SIZE, raylib::LIGHTGRAY );
raylib::draw_line(offset.x + SQUARE_SIZE, offset.y, offset.x + SQUARE_SIZE, offset.y + SQUARE_SIZE, raylib::LIGHTGRAY );
raylib::draw_line(offset.x, offset.y + SQUARE_SIZE, offset.x + SQUARE_SIZE, offset.y + SQUARE_SIZE, raylib::LIGHTGRAY );
offset.x += SQUARE_SIZE;
case FULL:
raylib::draw_rectangle(offset.x, offset.y, SQUARE_SIZE, SQUARE_SIZE, raylib::GRAY);
offset.x += SQUARE_SIZE;
case MOVING:
raylib::draw_rectangle(offset.x, offset.y, SQUARE_SIZE, SQUARE_SIZE, raylib::DARKGRAY);
offset.x += SQUARE_SIZE;
case BLOCK:
raylib::draw_rectangle(offset.x, offset.y, SQUARE_SIZE, SQUARE_SIZE, raylib::LIGHTGRAY);
offset.x += SQUARE_SIZE;
case FADING:
raylib::draw_rectangle(offset.x, offset.y, SQUARE_SIZE, SQUARE_SIZE, fading_color);
offset.x += SQUARE_SIZE;
default:
}
}
offset.x = controller;
offset.y += SQUARE_SIZE;
}
// Draw incoming piece (hardcoded)
offset.x = 500;
offset.y = 45;
controller = offset.x;
for (int j = 0; j < 4; j++)
{
for (int i = 0; i < 4; i++)
{
switch (incoming_piece[i][j])
{
case EMPTY:
raylib::draw_line(offset.x, offset.y, offset.x + SQUARE_SIZE, offset.y, raylib::LIGHTGRAY);
raylib::draw_line(offset.x, offset.y, offset.x, offset.y + SQUARE_SIZE, raylib::LIGHTGRAY);
raylib::draw_line(offset.x + SQUARE_SIZE, offset.y, offset.x + SQUARE_SIZE, offset.y + SQUARE_SIZE, raylib::LIGHTGRAY);
raylib::draw_line(offset.x, offset.y + SQUARE_SIZE, offset.x + SQUARE_SIZE, offset.y + SQUARE_SIZE, raylib::LIGHTGRAY);
offset.x += SQUARE_SIZE;
case MOVING:
raylib::draw_rectangle(offset.x, offset.y, SQUARE_SIZE, SQUARE_SIZE, raylib::GRAY);
offset.x += SQUARE_SIZE;
default:
break;
}
}
offset.x = controller;
offset.y += SQUARE_SIZE;
}
raylib::draw_text("INCOMING:", offset.x, offset.y - 100, 10, raylib::GRAY);
raylib::draw_text(raylib::text_format("LINES: %04i", lines), offset.x, offset.y + 20, 10, raylib::GRAY);
if (pause)
{
raylib::draw_text("GAME PAUSED", SCREEN_WIDTH / 2 - raylib::measure_text("GAME PAUSED", 40)/2, SCREEN_HEIGHT/2 - 40, 40, raylib::GRAY);
}
raylib::end_drawing();
}
// Unload game variables
fn void unload_game()
{
// TODO: Unload all dynamic loaded data (textures, sounds, models...)
}
// Update and Draw (one frame)
fn void update_draw_frame()
{
update_game();
draw_game();
}
//--------------------------------------------------------------------------------------
// Additional module functions
//--------------------------------------------------------------------------------------
fn bool create_piece()
{
piece_position_x = (int)((GRID_HORIZONTAL_SIZE - 4)/2);
piece_position_y = 0;
// If the game is starting and you are going to create the first piece, we create an extra one
if (begin_play)
{
get_random_piece();
begin_play = false;
}
// We assign the incoming piece to the actual piece
for (int i = 0; i < 4; i++)
{
for (int j = 0; j< 4; j++)
{
piece[i][j] = incoming_piece[i][j];
}
}
// We assign a random piece to the incoming one
get_random_piece();
// Assign the piece to the grid
for (int i = piece_position_x; i < piece_position_x + 4; i++)
{
for (int j = 0; j < 4; j++)
{
if (piece[i - (int)piece_position_x][j] == GridSquare.MOVING) grid[i][j] = MOVING;
}
}
return true;
}
fn void get_random_piece()
{
int random = raylib::get_random_value(0, 6);
for (int i = 0; i < 4; i++)
{
for (int j = 0; j < 4; j++)
{
incoming_piece[i][j] = EMPTY;
}
}
switch (random)
{
case 0:
incoming_piece[1][1] = MOVING;
incoming_piece[2][1] = MOVING;
incoming_piece[1][2] = MOVING;
incoming_piece[2][2] = MOVING; //Cube
case 1:
incoming_piece[1][0] = MOVING;
incoming_piece[1][1] = MOVING;
incoming_piece[1][2] = MOVING;
incoming_piece[2][2] = MOVING; //L
case 2:
incoming_piece[1][2] = MOVING;
incoming_piece[2][0] = MOVING;
incoming_piece[2][1] = MOVING;
incoming_piece[2][2] = MOVING; //L inversa
case 3:
incoming_piece[0][1] = MOVING;
incoming_piece[1][1] = MOVING;
incoming_piece[2][1] = MOVING;
incoming_piece[3][1] = MOVING; //Recta
case 4:
incoming_piece[1][0] = MOVING;
incoming_piece[1][1] = MOVING;
incoming_piece[1][2] = MOVING;
incoming_piece[2][1] = MOVING; //Creu tallada
case 5:
incoming_piece[1][1] = MOVING;
incoming_piece[2][1] = MOVING;
incoming_piece[2][2] = MOVING;
incoming_piece[3][2] = MOVING; //S
case 6:
incoming_piece[1][2] = MOVING;
incoming_piece[2][2] = MOVING;
incoming_piece[2][1] = MOVING;
incoming_piece[3][1] = MOVING; //S inversa
default:
@unreachable();
}
}
fn void resolve_falling_movement(bool* detection_ref, bool* piece_active_ref)
{
// If we finished moving this piece, we stop it
if (*detection_ref)
{
for (int j = GRID_VERTICAL_SIZE - 2; j >= 0; j--)
{
for (int i = 1; i < GRID_HORIZONTAL_SIZE - 1; i++)
{
if (grid[i][j] == GridSquare.MOVING)
{
grid[i][j] = FULL;
*detection_ref = false;
*piece_active_ref = false;
}
}
}
}
else // We move down the piece
{
for (int j = GRID_VERTICAL_SIZE - 2; j >= 0; j--)
{
for (int i = 1; i < GRID_HORIZONTAL_SIZE - 1; i++)
{
if (grid[i][j] == GridSquare.MOVING)
{
grid[i][j+1] = MOVING;
grid[i][j] = EMPTY;
}
}
}
piece_position_y++;
}
}
fn bool resolve_lateral_movement()
{
bool collision = false;
// Piece movement
if (raylib::is_key_down(keyboard::LEFT)) // Move left
{
// Check if is possible to move to left
for (int j = GRID_VERTICAL_SIZE - 2; j >= 0; j--)
{
for (int i = 1; i < GRID_HORIZONTAL_SIZE - 1; i++)
{
if (grid[i][j] == GridSquare.MOVING)
{
// Check if we are touching the left wall or we have a full square at the left
if ((i-1 == 0) || (grid[i-1][j] == GridSquare.FULL)) collision = true;
}
}
}
// If able, move left
if (!collision)
{
for (int j = GRID_VERTICAL_SIZE - 2; j >= 0; j--)
{
for (int i = 1; i < GRID_HORIZONTAL_SIZE - 1; i++) // We check the matrix from left to right
{
// Move everything to the left
if (grid[i][j] == GridSquare.MOVING)
{
grid[i-1][j] = MOVING;
grid[i][j] = EMPTY;
}
}
}
piece_position_x--;
}
}
else if (raylib::is_key_down(keyboard::RIGHT)) // Move right
{
// Check if is possible to move to right
for (int j = GRID_VERTICAL_SIZE - 2; j >= 0; j--)
{
for (int i = 1; i < GRID_HORIZONTAL_SIZE - 1; i++)
{
if (grid[i][j] == GridSquare.MOVING)
{
// Check if we are touching the right wall or we have a full square at the right
if ((i+1 == GRID_HORIZONTAL_SIZE - 1) || (grid[i+1][j] == GridSquare.FULL))
{
collision = true;
}
}
}
}
// If able move right
if (!collision)
{
for (int j = GRID_VERTICAL_SIZE - 2; j >= 0; j--)
{
for (int i = GRID_HORIZONTAL_SIZE - 1; i >= 1; i--) // We check the matrix from right to left
{
// Move everything to the right
if (grid[i][j] == GridSquare.MOVING)
{
grid[i+1][j] = MOVING;
grid[i][j] = EMPTY;
}
}
}
piece_position_x++;
}
}
return collision;
}
fn bool resolve_turn_movement()
{
// Input for turning the piece
if (raylib::is_key_down(keyboard::UP))
{
GridSquare aux;
bool checker = false;
// Check all turning possibilities
if ((grid[piece_position_x + 3][piece_position_y] == GridSquare.MOVING) &&
(grid[piece_position_x][piece_position_y] != GridSquare.EMPTY) &&
(grid[piece_position_x][piece_position_y] != GridSquare.MOVING)) checker = true;
if ((grid[piece_position_x + 3][piece_position_y + 3] == GridSquare.MOVING) &&
(grid[piece_position_x + 3][piece_position_y] != GridSquare.EMPTY) &&
(grid[piece_position_x + 3][piece_position_y] != GridSquare.MOVING)) checker = true;
if ((grid[piece_position_x][piece_position_y + 3] == GridSquare.MOVING) &&
(grid[piece_position_x + 3][piece_position_y + 3] != GridSquare.EMPTY) &&
(grid[piece_position_x + 3][piece_position_y + 3] != GridSquare.MOVING)) checker = true;
if ((grid[piece_position_x][piece_position_y] == GridSquare.MOVING) &&
(grid[piece_position_x][piece_position_y + 3] != GridSquare.EMPTY) &&
(grid[piece_position_x][piece_position_y + 3] != GridSquare.MOVING)) checker = true;
if ((grid[piece_position_x + 1][piece_position_y] == GridSquare.MOVING) &&
(grid[piece_position_x][piece_position_y + 2] != GridSquare.EMPTY) &&
(grid[piece_position_x][piece_position_y + 2] != GridSquare.MOVING)) checker = true;
if ((grid[piece_position_x + 3][piece_position_y + 1] == GridSquare.MOVING) &&
(grid[piece_position_x + 1][piece_position_y] != GridSquare.EMPTY) &&
(grid[piece_position_x + 1][piece_position_y] != GridSquare.MOVING)) checker = true;
if ((grid[piece_position_x + 2][piece_position_y + 3] == GridSquare.MOVING) &&
(grid[piece_position_x + 3][piece_position_y + 1] != GridSquare.EMPTY) &&
(grid[piece_position_x + 3][piece_position_y + 1] != GridSquare.MOVING)) checker = true;
if ((grid[piece_position_x][piece_position_y + 2] == GridSquare.MOVING) &&
(grid[piece_position_x + 2][piece_position_y + 3] != GridSquare.EMPTY) &&
(grid[piece_position_x + 2][piece_position_y + 3] != GridSquare.MOVING)) checker = true;
if ((grid[piece_position_x + 2][piece_position_y] == GridSquare.MOVING) &&
(grid[piece_position_x][piece_position_y + 1] != GridSquare.EMPTY) &&
(grid[piece_position_x][piece_position_y + 1] != GridSquare.MOVING)) checker = true;
if ((grid[piece_position_x + 3][piece_position_y + 2] == GridSquare.MOVING) &&
(grid[piece_position_x + 2][piece_position_y] != GridSquare.EMPTY) &&
(grid[piece_position_x + 2][piece_position_y] != GridSquare.MOVING)) checker = true;
if ((grid[piece_position_x + 1][piece_position_y + 3] == GridSquare.MOVING) &&
(grid[piece_position_x + 3][piece_position_y + 2] != GridSquare.EMPTY) &&
(grid[piece_position_x + 3][piece_position_y + 2] != GridSquare.MOVING)) checker = true;
if ((grid[piece_position_x][piece_position_y + 1] == GridSquare.MOVING) &&
(grid[piece_position_x + 1][piece_position_y + 3] != GridSquare.EMPTY) &&
(grid[piece_position_x + 1][piece_position_y + 3] != GridSquare.MOVING)) checker = true;
if ((grid[piece_position_x + 1][piece_position_y + 1] == GridSquare.MOVING) &&
(grid[piece_position_x + 1][piece_position_y + 2] != GridSquare.EMPTY) &&
(grid[piece_position_x + 1][piece_position_y + 2] != GridSquare.MOVING)) checker = true;
if ((grid[piece_position_x + 2][piece_position_y + 1] == GridSquare.MOVING) &&
(grid[piece_position_x + 1][piece_position_y + 1] != GridSquare.EMPTY) &&
(grid[piece_position_x + 1][piece_position_y + 1] != GridSquare.MOVING)) checker = true;
if ((grid[piece_position_x + 2][piece_position_y + 2] == GridSquare.MOVING) &&
(grid[piece_position_x + 2][piece_position_y + 1] != GridSquare.EMPTY) &&
(grid[piece_position_x + 2][piece_position_y + 1] != GridSquare.MOVING)) checker = true;
if ((grid[piece_position_x + 1][piece_position_y + 2] == GridSquare.MOVING) &&
(grid[piece_position_x + 2][piece_position_y + 2] != GridSquare.EMPTY) &&
(grid[piece_position_x + 2][piece_position_y + 2] != GridSquare.MOVING)) checker = true;
if (!checker)
{
aux = piece[0][0];
piece[0][0] = piece[3][0];
piece[3][0] = piece[3][3];
piece[3][3] = piece[0][3];
piece[0][3] = aux;
aux = piece[1][0];
piece[1][0] = piece[3][1];
piece[3][1] = piece[2][3];
piece[2][3] = piece[0][2];
piece[0][2] = aux;
aux = piece[2][0];
piece[2][0] = piece[3][2];
piece[3][2] = piece[1][3];
piece[1][3] = piece[0][1];
piece[0][1] = aux;
aux = piece[1][1];
piece[1][1] = piece[2][1];
piece[2][1] = piece[2][2];
piece[2][2] = piece[1][2];
piece[1][2] = aux;
}
for (int j = GRID_VERTICAL_SIZE - 2; j >= 0; j--)
{
for (int i = 1; i < GRID_HORIZONTAL_SIZE - 1; i++)
{
if (grid[i][j] == GridSquare.MOVING)
{
grid[i][j] = EMPTY;
}
}
}
for (int i = piece_position_x; i < piece_position_x + 4; i++)
{
for (int j = piece_position_y; j < piece_position_y + 4; j++)
{
if (piece[i - piece_position_x][j - piece_position_y] == GridSquare.MOVING)
{
grid[i][j] = MOVING;
}
}
}
return true;
}
return false;
}
fn void check_detection(bool *detection_ref)
{
for (int j = GRID_VERTICAL_SIZE - 2; j >= 0; j--)
{
for (int i = 1; i < GRID_HORIZONTAL_SIZE - 1; i++)
{
if ((grid[i][j] == GridSquare.MOVING) && ((grid[i][j+1] == GridSquare.FULL) || (grid[i][j+1] == GridSquare.BLOCK))) *detection_ref = true;
}
}
}
fn void check_completion(bool *line_to_delete_ref)
{
int calculator = 0;
for (int j = GRID_VERTICAL_SIZE - 2; j >= 0; j--)
{
calculator = 0;
for (int i = 1; i < GRID_HORIZONTAL_SIZE - 1; i++)
{
// Count each square of the line
if (grid[i][j] == GridSquare.FULL)
{
calculator++;
}
// Check if we completed the whole line
if (calculator == GRID_HORIZONTAL_SIZE - 2)
{
*line_to_delete_ref = true;
calculator = 0;
// points++;
// Mark the completed line
for (int z = 1; z < GRID_HORIZONTAL_SIZE - 1; z++)
{
grid[z][j] = FADING;
}
}
}
}
}
fn int delete_complete_lines()
{
int lines_to_erase = 0;
// Erase the completed line
for (int j = GRID_VERTICAL_SIZE - 2; j >= 0; j--)
{
while (grid[1][j] == GridSquare.FADING)
{
lines_to_erase++;
for (int i = 1; i < GRID_HORIZONTAL_SIZE - 1; i++)
{
grid[i][j] = GridSquare.EMPTY;
}
for (int j2 = j-1; j2 >= 0; j2--)
{
for (int i2 = 1; i2 < GRID_HORIZONTAL_SIZE - 1; i2++)
{
switch (grid[i2][j2])
{
case FULL:
grid[i2][j2+1] = GridSquare.FULL;
grid[i2][j2] = GridSquare.EMPTY;
case FADING:
grid[i2][j2+1] = GridSquare.FADING;
grid[i2][j2] = GridSquare.EMPTY;
default:
}
}
}
}
}
return lines_to_erase;
}