From d02f9641b4f7c0b29a9989a140799ce512fa8d87 Mon Sep 17 00:00:00 2001 From: Nate Butler Date: Sun, 7 Jan 2024 01:49:52 -0500 Subject: [PATCH] Render grid --- crates/workspace/src/tetris.rs | 355 +----------------------------- crates/workspace/src/workspace.rs | 2 +- 2 files changed, 10 insertions(+), 347 deletions(-) diff --git a/crates/workspace/src/tetris.rs b/crates/workspace/src/tetris.rs index 1bf8af2127..1b59b6f8b5 100644 --- a/crates/workspace/src/tetris.rs +++ b/crates/workspace/src/tetris.rs @@ -100,19 +100,19 @@ pub struct Grid { } impl RenderOnce for Grid { - fn render(self, cx: &mut WindowContext) -> impl IntoElement { + fn render(self, _cx: &mut WindowContext) -> impl IntoElement { div() .border() .border_color(gpui::white()) - .p_px() + .p_2() .flex() .flex_col() .gap_1() .children(self.grid_blocks.iter().map(|row| { - div() - .flex() - .gap_1() - .children(row.iter().map(|block| div().child(block.to_owned()))) + div().flex_none().flex().gap_1().children( + row.iter() + .map(|block| div().flex_none().gap_1().child(block.to_owned())), + ) })) } } @@ -254,6 +254,8 @@ impl RenderOnce for Game { let score: SharedString = format!("Score: {}", self.score).to_string().into(); div() + .w_96() + .h_96() .bg(gpui::black()) .p_1() .flex() @@ -261,7 +263,7 @@ impl RenderOnce for Game { .gap_1() .child("GPUI Tetris") .child(score) - .child(self.grid.render(cx)); + .child(self.grid); } } @@ -345,342 +347,3 @@ fn get_player_input() -> PlayerAction { // Example hardcoded player action: PlayerAction::MoveDown } - -// impl Grid { -// pub fn new() -> Self { -// // Initialize the grid -// } - -// pub fn place_tetromino(&mut self, tetromino: &Tetromino, position: (usize, usize)) { -// // Place a tetromino in the grid -// } - -// pub fn check_rows(&mut self) -> Vec { -// // Check if full rows need to be removed and return their indices -// } - -// pub fn remove_row(&mut self, row: usize) { -// // Remove a row from the grid and shift everything down -// } -// } - -// pub struct Player { -// // Information about the player, e.g., current score -// } - -// pub struct Score { -// points: usize, -// } - -// impl Score { -// pub fn new() -> Self { -// // Initialize the score -// } - -// pub fn increase_score(&mut self, points: usize) { -// // Increase the score -// } -// } - -// pub struct Game { -// grid: Grid, -// player: Player, -// score: Score, -// current_tetromino: Tetromino, -// } - -// impl Game { -// pub fn new() -> Self { -// // Init the game -// } - -// pub fn update(&mut self) { -// // Run one iteration of the game logic -// } -// } - -// pub struct Utils; - -// impl Utils { -// pub fn get_random_tetromino() -> Tetromino { -// // Return a random tetromino -// } -// } - -// ----------------------------------------------------------------------------- - -// use gpui::{div, IntoElement, ParentElement, RenderOnce, Styled, WindowContext}; - -// const GRID_WIDTH: usize = 10; -// const GRID_HEIGHT: usize = 20; - -// #[derive(Debug, Clone, Copy)] -// enum Cell { -// Empty, -// Occupied, -// } - -// type Rotation = [(isize, isize); 4]; - -// #[derive(Debug, Clone, Copy)] -// pub struct Tetromino { -// shape: Shape, -// rotations: [Rotation; 4], -// current_rotation: usize, -// } - -// #[derive(Debug, Clone, Copy)] -// pub enum Shape { -// I, -// O, -// T, -// S, -// Z, -// J, -// L, -// } - -// impl Tetromino { -// pub fn new(shape: Shape) -> Self { -// let rotations = Self::default_rotation(&shape); -// Self { -// shape, -// rotations, -// current_rotation: 0, -// } -// } - -// pub fn random() -> Self { -// use rand::Rng; -// let shape = match rand::thread_rng().gen_range(0..=6) { -// 0 => Shape::I, -// 1 => Shape::O, -// 2 => Shape::T, -// 3 => Shape::S, -// 4 => Shape::Z, -// 5 => Shape::J, -// 6 => Shape::L, -// _ => unreachable!(), -// }; -// Self::new(shape) -// } - -// fn default_rotation(shape: &Shape) -> [Rotation; 4] { -// match shape { -// Shape::I => [ -// [(0, 0), (1, 0), (2, 0), (3, 0)], -// [(0, 0), (0, 1), (0, 2), (0, 3)], -// [(0, 0), (1, 0), (2, 0), (3, 0)], -// [(0, 0), (0, 1), (0, 2), (0, 3)], -// ], -// // Remaining shapes... -// _ => unimplemented!(), -// } -// } - -// pub fn rotate(&mut self) { -// self.current_rotation = (self.current_rotation + 1) % 4; -// } - -// pub fn current_rotation(&self) -> &Rotation { -// &self.rotations[self.current_rotation] -// } -// } - -// #[derive(IntoElement)] -// pub struct Tetris { -// score: usize, -// grid: [[Cell; GRID_WIDTH]; GRID_HEIGHT], -// next_tetromino: Option, -// current_tetromino: Option, -// current_position: (isize, isize), -// history: Vec, -// } - -// impl Tetris { -// pub fn new() -> Self { -// Self { -// score: 0, -// grid: [[Cell::Empty; GRID_WIDTH]; GRID_HEIGHT], -// next_tetromino: None, -// current_tetromino: None, -// current_position: (0, 0), -// history: Vec::new(), -// } -// } - -// pub fn reset(&mut self) { -// *self = Self::new(); -// } - -// pub fn update(&mut self) { -// if self.current_tetromino.is_none() { -// self.spawn_piece(GRID_WIDTH / 2); -// self.next_tetromino = Some(Tetromino::random()); -// } else { -// if !self.move_piece_down() { -// self.fix_piece(); -// let complete_rows = &self.check_rows(); -// // Clear rows and calculate score -// for row in complete_rows { -// self.clear_and_shift_row(*row); -// self.score += Self::points_for_rows(complete_rows.len()); -// } -// } - -// if self.is_game_over() { -// println!("Game over, final score: {}", self.score); -// self.reset(); -// } -// } -// } - -// pub fn spawn_piece(&mut self, column: usize) { -// let tetromino = self -// .next_tetromino -// .take() -// .unwrap_or_else(|| Tetromino::random()); -// // Positions the Tetrimino horizontally based on the given column, -// // and vertically just off the top of the grid -// self.current_position = (column as isize, -1); -// self.current_tetromino = Some(tetromino); -// } - -// pub fn fix_piece(&mut self) { -// if let Some(tetromino) = self.current_tetromino { -// for &(x, y) in tetromino.current_rotation() { -// let cell_x = self.current_position.0 + x; -// let cell_y = self.current_position.1 + y; - -// if cell_y >= 0 { -// self.grid[cell_y as usize][cell_x as usize] = Cell::Occupied; -// } -// } - -// self.current_tetromino = None; -// } -// } - -// pub fn move_piece_down(&mut self) -> bool { -// if let Some(tetromino) = self.current_tetromino { -// let new_position = (self.current_position.0, self.current_position.1 + 1); -// if self.validate_position(tetromino, new_position) { -// self.current_position = new_position; -// true -// } else { -// false -// } -// } else { -// false -// } -// } - -// fn validate_position(&self, tetromino: Tetromino, position: (isize, isize)) -> bool { -// for &(x, y) in tetromino.current_rotation() { -// let cell_x = position.0 + x; -// let cell_y = position.1 + y; - -// // If cell is off the grid, or if it's occupied, the position is invalid -// if cell_y >= GRID_HEIGHT as isize -// || cell_x < 0 -// || cell_x >= GRID_WIDTH as isize -// || (cell_y >= 0 -// && matches!(self.grid[cell_y as usize][cell_x as usize], Cell::Occupied)) -// { -// return false; -// } -// } -// true -// } - -// pub fn check_rows(&mut self) -> Vec { -// let mut rows_to_clear = Vec::new(); -// for (row_index, row) in self.grid.iter().enumerate() { -// let mut row_is_full = true; -// for cell in row.iter() { -// if let Cell::Empty = cell { -// row_is_full = false; -// break; -// } -// } -// if row_is_full { -// rows_to_clear.push(row_index); -// } -// } -// rows_to_clear -// } - -// pub fn points_for_rows(rows: usize) -> usize { -// match rows { -// 1 => 100, // Single -// 2 => 300, // Double -// 3 => 500, // Triple -// 4 => 800, // Tetris -// _ => 0, -// } -// } - -// pub fn next_frame(&mut self) { -// let complete_rows = self.check_rows(); -// if !complete_rows.is_empty() { -// self.score += Self::points_for_rows(complete_rows.len()); -// for row in complete_rows { -// self.clear_and_shift_row(row); -// } -// } -// } - -// pub fn update_row(&mut self, row: usize, new_row: [Cell; GRID_WIDTH]) { -// self.grid[row] = new_row; -// } - -// pub fn shift_row_down(&mut self, row: usize) { -// if row > 0 { -// self.grid[row] = self.grid[row - 1]; -// } -// } - -// pub fn clear_row(&mut self, row: usize) { -// self.update_row(row, [Cell::Empty; GRID_WIDTH]); -// } - -// pub fn clear_and_shift_row(&mut self, row: usize) { -// self.clear_row(row); -// for index in (1..=row).rev() { -// self.shift_row_down(index); -// } -// } - -// pub fn is_game_over(&self) -> bool { -// // If there is an occupied cell on the top row of the grid, the game is over -// self.grid[0] -// .iter() -// .any(|&cell| matches!(cell, Cell::Occupied)) -// } -// } - -// impl RenderOnce for Tetris { -// fn render(self, _cx: &mut WindowContext) -> impl IntoElement { -// div() -// .size_full() -// .items_center() -// .flex() -// .flex_col() -// .gap_px() -// .children( -// self.grid -// .iter() -// .map(|row| { -// div().flex().gap_px().children( -// row.iter() -// .map(|cell| match cell { -// Cell::Empty => div().w_8().h_8().bg(gpui::red()), -// Cell::Occupied => div().w_8().h_8().bg(gpui::blue()), -// }) -// .collect::>(), -// ) -// }) -// .collect::>(), -// ) -// } -// } diff --git a/crates/workspace/src/workspace.rs b/crates/workspace/src/workspace.rs index 1e92c7306a..e47619d8ed 100644 --- a/crates/workspace/src/workspace.rs +++ b/crates/workspace/src/workspace.rs @@ -3515,7 +3515,7 @@ impl Render for Workspace { let colors = theme.colors(); cx.set_rem_size(ui_font_size); - let game = tetris::Game::new(); + let game = tetris::Grid::new(); self.actions(div(), cx) .key_context(context)