当前位置: 首页 > news >正文

Tauri(2.5.1)+Leptos(0.8.2)开发自用桌面小程序--DeepSeek辅助编程(俄罗斯方块)

 在之前工作基础上(Tauri(2.5.1)+Leptos(0.8.2)开发自用桌面小程序-CSDN博客),继续进行自用桌面小程序的开发,这次完全使用DeepSeek辅助编程做一个俄罗斯方块游戏,大部分代码由DeepSeek自主完成,Bug扔给DeepSeek自行处理,期间人为简单干预即可。具体游戏界面如下:

 1. DeepSeek辅助编程界面

Win10的操作系统,使用VS Code及Rust analyzer插件搭建的Rust开发环境,使用Roo Code绑定DeepSeek API ,配置比较简单,网上教程很多。

 2. 页面设置

还是使用leptos-router新建一个页面(类似浏览器的标签页),用于俄罗斯方块游戏界面。主要在src/app/app.rs文件中设置,具体代码如下:

#[warn(unused_imports)]
use leptos::prelude::*;
use leptos_router::components::{Route, Router, Routes};
use leptos_router::path;
mod acidinput;
mod schedule;
mod game2048;
mod game5;
mod match_game;use acidinput::*;
use schedule::*;
use game2048::*;
use game5::*;
use match_game::*;#[component]
pub fn App() -> impl IntoView {view! {<Router><nav><a class="nav" href="/">"工作进度表"</a><a class="nav" href="/acidinput">"产品录入"</a><a class="nav" href="/game2048">"2048数字游戏"</a><a class="nav" href="/game5">"五子棋游戏"</a><a class="nav" href="/matchgame">"俄罗斯方块"</a></nav><main><Routes fallback=|| "Not found.">// / just has an un-nested "Home"<Route path=path!("/") view= || view! {<WorkSchedule />} /><Route path=path!("/acidinput") view=|| view! {<AcidInput />} /><Route path=path!("/game2048") view=|| view! {<GameBoard />} /><Route path=path!("/game5") view=|| view! {<GomokuGame />} /><Route path=path!("/matchgame") view=|| view! {<TetrisGameBoard />} /></Routes>                </main></Router>}
}

3. 游戏主程序

 俄罗斯方块游戏的代码被放在了文件src/app/match_game.rs中,绝大部分代码和注释都是DeepSeek完成的,具体代码如下:

use leptos::*;
use leptos::prelude::*;
use leptos::component;
use leptos::view;
use wasm_bindgen::prelude::*;
use web_sys;
use leptos::task::spawn_local;
use std::rc::Rc;
use std::cell::RefCell;
use wasm_bindgen::prelude::Closure;
use leptos::logging::log;/// 方块形状枚举
#[derive(Clone, Copy, PartialEq, Debug)]
pub enum Tetromino {I, // I形J, // J形L, // L形O, // O形S, // S形T, // T形Z, // Z形
}/// 游戏方向枚举
#[derive(Clone, Copy, PartialEq)]
pub enum Direction {Left,Right,Down,
}/// 游戏状态结构体
#[derive(Clone)]
pub struct Game {pub grid: [[Option<Tetromino>; 10]; 20], // 10x20游戏网格pub current_piece: (Tetromino, [[i32; 2]; 4]), // 当前方块及其位置pub next_piece: (Tetromino, u8), // 下一个方块及其旋转状态pub score: u32, // 当前得分pub level: u32, // 当前等级pub game_over: bool, // 游戏是否结束pub paused: bool, // 游戏是否暂停pub is_locked: bool, // 方块是否已锁定pub current_rotation: u8, // 当前旋转状态(0-3)
}impl Game {/// 创建新游戏实例pub fn new() -> Self {let mut game = Game {grid: [[None; 10]; 20],current_piece: (Tetromino::I, [[0; 2]; 4]),next_piece: (Self::random_tetromino(), (rand::random::<f32>() * 4.0).floor() as u8),score: 0,level: 1,game_over: false,paused: false,is_locked: false,current_rotation: 0,};game.spawn_piece();game}/// 随机生成方块fn random_tetromino() -> Tetromino {use rand::random;let piece = match (random::<f64>() * 7.0).floor() as u8 {0 => Tetromino::I,1 => Tetromino::J,2 => Tetromino::L,3 => Tetromino::O,4 => Tetromino::S,5 => Tetromino::T,_ => Tetromino::Z,};log!("Generated new piece: {:?}", piece);piece}/// 生成新方块fn spawn_piece(&mut self) {//log!("[SPAWN] Current state - next_piece: {:?}, current_piece: {:?}",//    self.next_piece, self.current_piece.0);// 保存当前预览方块及其旋转状态let (current_falling, preview_rotation) = self.next_piece;let actual_rotation = preview_rotation % 4;//log!("[SPAWN] Will spawn: {:?} with preview_rotation {:?} (actual: {:?})",//    current_falling, preview_rotation, actual_rotation);// 验证旋转状态一致性//log!("[ROTATION VERIFY] Preview rotation: {}, Actual rotation: {}",//    preview_rotation, actual_rotation);// 确保预览和实际方块类型一致//log!("[SPAWN] Verifying piece types - preview: {:?}, actual: {:?}",//    current_falling, self.next_piece.0);// 设置当前方块状态self.current_piece.0 = current_falling;self.is_locked = false;self.current_rotation = actual_rotation; // 确保旋转状态同步// 使用与预览完全相同的旋转状态计算方式let positions = match (current_falling, actual_rotation) {// 调整初始位置,确保最下端在第0行,其他部分可以在第0行以上(Tetromino::I, 0) => [[-2, 3], [-2, 4], [-2, 5], [-2, 6]],  // I型水平(Tetromino::I, 1) => [[-3, 4], [-2, 4], [-1, 4], [0, 4]],    // I型垂直(Tetromino::I, 2) => [[-2, 3], [-2, 4], [-2, 5], [-2, 6]],   // I型水平(反向)(Tetromino::I, 3) => [[-3, 4], [-2, 4], [-1, 4], [0, 4]],    // I型垂直(反向)(Tetromino::O, _) => [[-1, 4], [-1, 5], [0, 4], [0, 5]],     // O型(Tetromino::J, 0) => [[-1, 4], [0, 4], [0, 5], [0, 6]],      // J型初始(Tetromino::J, 1) => [[-2, 5], [-2, 6], [-1, 5], [0, 5]],    // J型90度(Tetromino::J, 2) => [[-1, 4], [-1, 5], [-1, 6], [0, 6]],    // J型180度(Tetromino::J, 3) => [[-2, 5], [-1, 5], [0, 5], [0, 4]],     // J型270度(Tetromino::L, 0) => [[-1, 6], [0, 4], [0, 5], [0, 6]],      // L型初始(Tetromino::L, 1) => [[-2, 4], [-1, 4], [0, 4], [0, 5]],     // L型90度(Tetromino::L, 2) => [[-1, 4], [-1, 5], [-1, 6], [0, 4]],    // L型180度(Tetromino::L, 3) => [[-2, 4], [-2, 5], [-1, 5], [0, 5]],     // L型270度(Tetromino::S, 0) => [[-1, 5], [-1, 6], [0, 4], [0, 5]],     // S型初始(右凸)(Tetromino::S, 1) => [[-2, 5], [-1, 5], [-1, 6], [0, 6]],    // S型90度(左凸)(Tetromino::S, 2) => [[-1, 5], [-1, 6], [0, 4], [0, 5]],    // S型180度(右凸)(Tetromino::S, 3) => [[-2, 4], [-1, 4], [-1, 5], [0, 5]],    // S型270度(左凸)(Tetromino::T, 0) => [[-1, 5], [0, 4], [0, 5], [0, 6]],      // T型初始(Tetromino::T, 1) => [[-2, 5], [-1, 5], [-1, 6], [0, 5]],    // T型90度(Tetromino::T, 2) => [[-1, 4], [-1, 5], [-1, 6], [0, 5]],    // T型180度(Tetromino::T, 3) => [[-2, 5], [-1, 4], [-1, 5], [0, 5]],    // T型270度(Tetromino::Z, 0) => [[-1, 4], [-1, 5], [0, 5], [0, 6]],     // Z型初始(Tetromino::Z, 1) => [[-2, 6], [-1, 5], [-1, 6], [0, 5]],    // Z型90度(Tetromino::Z, 2) => [[-1, 4], [-1, 5], [0, 5], [0, 6]],     // Z型180度(Tetromino::Z, 3) => [[-2, 5], [-1, 4], [-1, 5], [0, 4]],    // Z型270度_ => unreachable!("Invalid rotation state"),};//log!("[POSITION] Final positions for {:?} with rotation {}: {:?}",//    current_falling, actual_rotation, positions);//log!("[POSITION] Calculated positions for {:?} with rotation {}: {:?}",//    current_falling, actual_rotation, positions);self.current_piece.1 = positions;// 生成新预览方块及随机旋转状态(0-3)let new_piece = Self::random_tetromino();let new_rotation = (rand::random::<f32>() * 4.0).floor() as u8;let new_preview = (new_piece, new_rotation);//log!("[SPAWN] Generated new preview: {:?} with rotation {} (will be next piece)",//    new_preview.0, new_preview.1);// 双重验证预览方块类型if new_preview.0 != current_falling {log!("[SPAWN] Preview and current piece match verified");}// 更新预览方块self.next_piece = new_preview;//log!("[SPAWN] Updated next_piece to: {:?}", self.next_piece);//log!("[SPAWN] After update - next_piece: {:?}, current_piece: {:?}",//    self.next_piece, self.current_piece.0);// 检查新方块位置是否有效(允许部分超出顶部)let dropped_pos = self.get_dropped_position();if !self.is_valid_position(&dropped_pos) || dropped_pos == self.current_piece.1 {self.lock_piece();} else {// 检查新方块位置是否有效(允许部分超出顶部)let mut valid_spawn = true;for &[i, j] in &self.current_piece.1 {if j < 0 || j >= 10 || i >= 20 || (i >= 0 && self.grid[i as usize][j as usize].is_some()) {valid_spawn = false;break;}}self.game_over = !valid_spawn;}}/// 检查方块是否完全无法移动fn is_piece_stuck(&self) -> bool {// 检查方块是否无法继续下落for &[i, j] in &self.current_piece.1 {// 如果方块在网格内(i >= 0)if i >= 0 {// 检查是否到达底部或下方有方块if i >= 19 || self.grid[(i + 1) as usize][j as usize].is_some() {return true;}}}false}/// 移动方块pub fn move_piece(&mut self, direction: Direction) {if self.game_over || self.paused || self.is_locked {return;}let mut new_positions = self.current_piece.1;// 计算新位置for pos in &mut new_positions {match direction {Direction::Left => pos[1] -= 1,Direction::Right => pos[1] += 1,Direction::Down => pos[0] += 1,}}// 检查新位置是否有效if self.is_valid_position(&new_positions) {self.current_piece.1 = new_positions;// 如果是向下移动if direction == Direction::Down {// 检查是否已经到底部if self.is_piece_stuck() {self.lock_piece();return; // 锁定后立即返回,防止后续移动}} else if self.is_piece_stuck() {// 其他方向移动时检查是否卡住self.lock_piece();return; // 锁定后立即返回,防止后续移动}} else if direction == Direction::Down && self.is_piece_stuck() {// 如果向下移动无效且方块卡住,也锁定self.lock_piece();}}/// 旋转方块pub fn rotate_piece(&mut self) {if self.game_over || self.paused || self.current_piece.0 == Tetromino::O {return; // O方块不需要旋转}// 获取当前旋转状态(0-3)let current_rot = self.current_rotation;//log!("[ROTATE] Rotating {:?} from state {}", self.current_piece.0, current_rot);// 根据方块类型定义精确旋转中心(取第二和第三个方块中间)let (center_x, center_y) = match self.current_piece.0 {Tetromino::I => ((self.current_piece.1[1][0] + self.current_piece.1[2][0]) / 2,(self.current_piece.1[1][1] + self.current_piece.1[2][1]) / 2),Tetromino::O => (self.current_piece.1[0][0] + 1, self.current_piece.1[0][1] + 1), // O型中心在四个方块中间Tetromino::J => ((self.current_piece.1[1][0] + self.current_piece.1[2][0]) / 2,(self.current_piece.1[1][1] + self.current_piece.1[2][1]) / 2),Tetromino::L => ((self.current_piece.1[1][0] + self.current_piece.1[2][0]) / 2,(self.current_piece.1[1][1] + self.current_piece.1[2][1]) / 2),Tetromino::S => ((self.current_piece.1[1][0] + self.current_piece.1[2][0]) / 2,(self.current_piece.1[1][1] + self.current_piece.1[2][1]) / 2),Tetromino::Z => ((self.current_piece.1[1][0] + self.current_piece.1[2][0]) / 2,(self.current_piece.1[1][1] + self.current_piece.1[2][1]) / 2),Tetromino::T => (self.current_piece.1[1][0], self.current_piece.1[1][1]), // T型中心取第二个方块};//log!("[ROTATE] Fixed center for {:?}: ({}, {})", self.current_piece.0, center_x, center_y);let mut new_positions = self.current_piece.1.clone();// 应用旋转for pos in &mut new_positions {// 计算相对于中心的坐标let x = pos[1] - center_y;let y = pos[0] - center_x;// 应用标准90度顺时针旋转矩阵let new_x = -y;let new_y = x;// 计算新位置pos[1] = center_y + new_x;pos[0] = center_x + new_y;}// 尝试原始位置if self.is_valid_position(&new_positions) {self.apply_rotation(new_positions, current_rot);return;}// 墙踢: 尝试左右移动1-2格for offset in [1, -1, 2, -2].iter() {let mut kicked_positions = new_positions.clone();for pos in &mut kicked_positions {pos[1] += offset;}if self.is_valid_position(&kicked_positions) {self.apply_rotation(kicked_positions, current_rot);//log!("[ROTATE] Applied wall kick with offset {}", offset);return;}}//log!("[ROTATE] Rotation failed - all positions invalid");}/// 检查位置是否有效fn is_valid_position(&self, positions: &[[i32; 2]; 4]) -> bool {for &[i, j] in positions {// 允许i<0(顶部以上),只要j在有效范围内// 仅检查网格内(i>=0)的方块重叠if j < 0 || j >= 10 || i >= 20 || (i >= 0 && self.grid[i as usize][j as usize].is_some()) {return false;}}true}/// 获取下落到底部的位置fn get_dropped_position(&self) -> [[i32; 2]; 4] {let mut dropped = self.current_piece.1;loop {for pos in &mut dropped {pos[0] += 1;}if !self.is_valid_position(&dropped) {for pos in &mut dropped {pos[0] -= 1;}break;}}dropped}/// 硬降(直接下落到底部)pub fn hard_drop(&mut self) {if self.game_over || self.paused {return;}self.current_piece.1 = self.get_dropped_position();self.lock_piece();}/// 固定当前方块到网格fn lock_piece(&mut self) {if self.is_locked || self.game_over {return;}let piece_type = self.current_piece.0;for &[i, j] in &self.current_piece.1 {if i >= 0 {self.grid[i as usize][j as usize] = Some(piece_type);// 如果方块被锁定在第0行,游戏结束if i == 0 {self.game_over = true;}}}self.is_locked = true;self.clear_lines();if !self.game_over {self.spawn_piece();}}/// 应用旋转并更新状态(内部方法)pub(crate) fn apply_rotation(&mut self, positions: [[i32; 2]; 4], current_rot: u8) {self.current_piece.1 = positions;self.current_rotation = (current_rot + 1) % 4;//log!("[ROTATE] Success! New state: {}", self.current_rotation);//log!("[ROTATE] New positions: {:?}", self.current_piece.1);// 旋转后检查是否卡住if self.is_piece_stuck() {self.lock_piece();}}/// 清除完整的行fn clear_lines(&mut self) {let mut lines_cleared = 0;// 从下往上扫描let mut row = 19;while row > 0 {if self.grid[row].iter().all(|cell| cell.is_some()) {lines_cleared += 1;// 将上方行下移for move_row in (1..=row).rev() {self.grid[move_row] = self.grid[move_row - 1];}// 清空最顶行self.grid[0] = [None; 10];// 继续检查当前行(因为上方行已经下移)continue;}row -= 1;}// 更新分数match lines_cleared {1 => self.score += 100 * self.level,2 => self.score += 300 * self.level,3 => self.score += 500 * self.level,4 => self.score += 800 * self.level,_ => (),}// 更新等级if lines_cleared > 0 {self.level = (self.score / 2000) + 1;}}/// 暂停/继续游戏pub fn toggle_pause(&mut self) {if !self.game_over {self.paused = !self.paused;}}
}/// 游戏界面组件
#[component]
pub fn TetrisGameBoard() -> impl IntoView {// 创建游戏状态信号let (game, set_game) = signal(Game::new());// 设置游戏循环(自动下落)let tick = move || {set_game.update(|g| {if !g.game_over && !g.paused {g.move_piece(Direction::Down);}});};// 每500ms触发一次下落(速度随等级提高)let tick_interval = move || {500.0 / (game.get_untracked().level as f64).max(1.0)};// 使用Leptos的spawn_local和web_sys的set_timeout实现游戏循环spawn_local(async move {let window = web_sys::window().expect("no global window exists");let closure: Rc<RefCell<Option<Closure<dyn FnMut()>>>> = Rc::new(RefCell::new(None));let closure_clone = Rc::clone(&closure);*closure_clone.borrow_mut() = Some(Closure::<dyn FnMut()>::new({let closure_clone = Rc::clone(&closure_clone);let window = window.clone();move || {if !game.get_untracked().game_over && !game.get_untracked().paused {tick();}let interval = tick_interval();window.set_timeout_with_callback_and_timeout_and_arguments_0(closure_clone.borrow().as_ref().unwrap().as_ref().unchecked_ref(),interval as i32).expect("failed to set timeout");}}));// 初始调用window.set_timeout_with_callback_and_timeout_and_arguments_0(closure.borrow().as_ref().unwrap().as_ref().unchecked_ref(),tick_interval() as i32).expect("failed to set timeout");});// 监听键盘事件let key_listener = window_event_listener(ev::keydown, move |ev| {if game.get().game_over {return;}ev.prevent_default();match &ev.key()[..] {"ArrowLeft" => set_game.update(|g| g.move_piece(Direction::Left)),"ArrowRight" => set_game.update(|g| g.move_piece(Direction::Right)),"ArrowDown" => set_game.update(|g| g.move_piece(Direction::Down)),"ArrowUp" => set_game.update(|g| g.rotate_piece())," " => {if !game.get().paused {set_game.update(|g| g.hard_drop());}},"p" | "P" => set_game.update(|g| g.toggle_pause()),_ => (),}});// 组件卸载时清理事件监听器和闭包on_cleanup(move || {key_listener.remove();// 闭包会在离开作用域时自动释放});// 根据方块类型返回对应的CSS颜色类fn tile_color(tile: Option<Tetromino>) -> &'static str {if let Some(t) = tile {match t {Tetromino::I => "tetromino-i",Tetromino::J => "tetromino-j",Tetromino::L => "tetromino-l",Tetromino::O => "tetromino-o",Tetromino::S => "tetromino-s",Tetromino::T => "tetromino-t",Tetromino::Z => "tetromino-z",}} else {"tetromino-empty"}}// 渲染预览方块fn render_preview((tetromino, rotation): (Tetromino, u8)) -> impl IntoView {// 使用与实际方块相同的旋转状态let rotation_mod = rotation % 4;//log!("[PREVIEW] Rendering {:?} with rotation {}", tetromino, rotation_mod);// 使用与实际方块相同的精确旋转中心(取第二和第三方块中间)let (center_x, center_y) = match tetromino {Tetromino::I => (1, 2),  // I型中心(第二和第三方块中间)Tetromino::O => (1, 1),  // O型中心(四个方块中间)Tetromino::J => (1, 1),  // J型中心(第二和第三方块中间)Tetromino::L => (1, 1),  // L型中心(第二和第三方块中间)Tetromino::S => (1, 1),  // S型中心(第二和第三方块中间)Tetromino::Z => (1, 1),  // Z型中心(第二和第三方块中间)Tetromino::T => (1, 1),  // T型中心(第二个方块)};// 根据旋转状态计算相对位置let positions = match (tetromino, rotation_mod) {(Tetromino::I, 0) => vec![(center_x, center_y-2), (center_x, center_y-1), (center_x, center_y), (center_x, center_y+1)],(Tetromino::I, 1) => vec![(center_x-1, center_y), (center_x, center_y), (center_x+1, center_y), (center_x+2, center_y)],(Tetromino::I, 2) => vec![(center_x, center_y-2), (center_x, center_y-1), (center_x, center_y), (center_x, center_y+1)],(Tetromino::I, 3) => vec![(center_x-1, center_y), (center_x, center_y), (center_x+1, center_y), (center_x+2, center_y)],(Tetromino::O, _) => vec![(center_x, center_y), (center_x, center_y+1), (center_x+1, center_y), (center_x+1, center_y+1)],// J型方块定义(Tetromino::J, 0) => vec![(center_x, center_y), (center_x+1, center_y), (center_x+1, center_y+1), (center_x+1, center_y+2)],(Tetromino::J, 1) => vec![(center_x, center_y+1), (center_x, center_y+2), (center_x+1, center_y+1), (center_x+2, center_y+1)],(Tetromino::J, 2) => vec![(center_x+1, center_y), (center_x+1, center_y+1), (center_x+1, center_y+2), (center_x+2, center_y+2)],(Tetromino::J, 3) => vec![(center_x, center_y+1), (center_x+1, center_y+1), (center_x+2, center_y), (center_x+2, center_y+1)],// L型方块定义(Tetromino::L, 0) => vec![(center_x, center_y+2), (center_x+1, center_y), (center_x+1, center_y+1), (center_x+1, center_y+2)],(Tetromino::L, 1) => vec![(center_x, center_y+1), (center_x+1, center_y+1), (center_x+2, center_y+1), (center_x+2, center_y+2)],(Tetromino::L, 2) => vec![(center_x+1, center_y), (center_x+1, center_y+1), (center_x+1, center_y+2), (center_x+2, center_y)],(Tetromino::L, 3) => vec![(center_x, center_y), (center_x, center_y+1), (center_x+1, center_y+1), (center_x+2, center_y+1)],(Tetromino::S, 0) => vec![(center_x, center_y), (center_x, center_y+1), (center_x+1, center_y-1), (center_x+1, center_y)],(Tetromino::S, 1) => vec![(center_x-1, center_y), (center_x, center_y), (center_x, center_y+1), (center_x+1, center_y+1)],(Tetromino::S, 2) => vec![(center_x-1, center_y), (center_x-1, center_y+1), (center_x, center_y-1), (center_x, center_y)],(Tetromino::S, 3) => vec![(center_x-1, center_y-1), (center_x, center_y-1), (center_x, center_y), (center_x+1, center_y)],(Tetromino::T, 0) => vec![(center_x, center_y), (center_x+1, center_y-1), (center_x+1, center_y), (center_x+1, center_y+1)],(Tetromino::T, 1) => vec![(center_x-1, center_y), (center_x, center_y), (center_x, center_y+1), (center_x+1, center_y)],(Tetromino::T, 2) => vec![(center_x, center_y-1), (center_x, center_y), (center_x, center_y+1), (center_x-1, center_y)],(Tetromino::T, 3) => vec![(center_x-1, center_y), (center_x, center_y-1), (center_x, center_y), (center_x+1, center_y)],// Z型方块定义(Tetromino::Z, 0) => vec![(center_x, center_y), (center_x, center_y+1), (center_x+1, center_y+1), (center_x+1, center_y+2)],(Tetromino::Z, 1) => vec![(center_x, center_y+1), (center_x+1, center_y), (center_x+1, center_y+1), (center_x+2, center_y)],(Tetromino::Z, 2) => vec![(center_x, center_y), (center_x, center_y+1), (center_x+1, center_y+1), (center_x+1, center_y+2)],(Tetromino::Z, 3) => vec![(center_x, center_y+1), (center_x+1, center_y), (center_x+1, center_y+1), (center_x+2, center_y)],_ => unreachable!("Invalid rotation state"),};//log!("[PREVIEW] Calculated relative positions: {:?}", positions);view! {<div style="display: grid; grid-template-columns: repeat(4, 20px); grid-template-rows: repeat(4, 20px); width: 80px; height: 80px; gap: 1px;">{positions.into_iter().map(|(i, j)| {view! {<divstyle=format!("grid-row: {}; grid-column: {};", i + 1, j + 1)class=format!("{} tetromino-border", tile_color(Some(tetromino)))></div>}}).collect::<Vec<_>>()}</div>}}// 重置游戏函数let reset = move |_| {set_game.update(|g| *g = Game::new());};// 暂停/继续游戏函数let toggle_pause = move |_| {set_game.update(|g| g.toggle_pause());};// 游戏界面视图view! {<div class="game-container"><div class="game-header">//<h1 class="game-title" style="display: block; text-align: center; width: 100%; margin-bottom: 1rem;">"俄罗斯方块"</h1><div class="game-controls-container"><div class="game-scores-container"><div class="game-score-box"><div class="game-score-label">"得分:"{move || game.get().score}</div></div><div class="game-score-box"><div class="game-score-label">"等级:"{move || game.get().level}</div></div></div><div class="game-buttons-container"><buttonon:click=toggle_pauseclass="game-button">{move || if game.get().paused { "继续" } else { "暂停" }}</button><buttonon:click=resetclass="game-button">"新游戏"</button></div></div></div><div style="display: flex; justify-content: space-between; align-items: flex-start; width: 100%; margin-top: 1rem;"><div class="game-main-area"><div class="game-board"><div style="display: grid; grid-template-columns: repeat(10, 24px); grid-template-rows: repeat(20, 24px); gap: 1px;">{move || {// 创建网格副本用于渲染let mut render_grid = game.get().grid.clone();// 添加当前方块到渲染网格if !game.get().game_over {for &[i, j] in &game.get().current_piece.1 {if i >= 0 {render_grid[i as usize][j as usize] = Some(game.get().current_piece.0);}}}// 渲染网格render_grid.iter().flat_map(|row| {row.iter().map(|&tile| {view! {<div class=format!("{} tetromino-border", tile_color(tile))></div>}})}).collect::<Vec<_>>()}}</div></div></div><div class="game-side-panel"><div class="game-preview"><h2 class="game-preview-title">"下一个"</h2>{move || {let (tetromino, rotation) = game.get().next_piece;render_preview((tetromino, rotation))}}</div><div class="game-instructions"><h2 class="game-instructions-title">"操作说明"</h2><ul class="game-instructions-list"><li>"← → : 左右移动"</li><li>"↓ : 加速下落"</li><li>"↑ : 旋转方块"</li><li>"空格 : 硬降到底部"</li><li>"P : 暂停/继续"</li></ul></div></div></div>{/* 游戏结束提示 */}<Show when=move || game.get().game_over><div class="game-over-message">"游戏结束! 最终得分: " {move || game.get().score}</div></Show>{/* 暂停提示 */}<Show when=move || game.get().paused><div class="game-paused-message">"游戏暂停"</div></Show></div>}
}

DeepSeek刚写出来的程序bug比较多,要一步一步引导其修改完善。游戏界面的css设置文件内容如下:

/* 俄罗斯方块颜色 */
.tetromino-i {background-color: #06b6d4; /* I方块 - 青色 */
}.tetromino-l {background-color: #f97316; /* L方块 - 橙色 */
}.tetromino-z {background-color: #ef4444; /* Z方块 - 红色 */
}.tetromino-j {background-color: #2563eb; /* J方块 - 深蓝色 */
}.tetromino-s {background-color: #10b981; /* S方块 - 绿色 */
}.tetromino-o {background-color: #facc15; /* O方块 - 黄色 */
}.tetromino-t {background-color: #a855f7; /* T方块 - 紫色 */
}.tetromino-empty {background-color: #1f2937; /* 空单元格 - 深灰色 */
}/* 边框样式 */
.tetromino-border {border: 1px solid #374151;
}/* 按钮样式 */
.game-button {background-color: #3b82f6;color: #000;padding: 0.5rem 1rem;border-radius: 0.25rem;margin: 10px 5px;
}.game-button:hover {background-color: #2563eb;
}/* 容器样式 */
.game-container {width: 550px;margin-left: auto;margin-right: auto;padding: 1rem;
}.game-header {display: block;margin-bottom: 1rem;
}.game-title {font-size: 1.875rem;font-weight: bold;text-align: center;margin-bottom: 1rem;display: block;
}.game-score-container {display: flex;justify-content: center;gap: 1rem;margin-bottom: 1rem;
}.game-title {font-size: 1.875rem;font-weight: bold;
}.game-controls-container {display: flex;justify-content: center;align-items: center;gap: 2rem;width: 100%;
}.game-scores-container {display: flex;gap: 1rem;align-items: center;justify-content: center;
}.game-buttons-container {display: flex;gap: 1rem;align-items: center;justify-content: center;
}.game-score-box {display: flex;flex-direction: column;align-items: center;justify-content: center;text-align: center;
}.game-score-container {display: flex;gap: 1rem;
}.game-score-box {background-color: #e5e7eb;padding: 0.5rem;border-radius: 0.25rem;
}.game-score-label {font-size: 1rem;font-weight: bold;
}.game-score-value {font-size: 1.25rem;font-weight: bold;
}.game-content-wrapper {display: flex;gap: 1rem;
}.game-main-area {width:250px;margin:0px 0px 0px 10px;
}.game-board {width:100%;background-color: #1f2937;padding: 0.5rem;border-radius: 0.5rem;
}.game-side-panel {width:250px;
}.game-preview {width:100%;background-color: #e5e7eb;padding: 1rem;border-radius: 0.25rem;
}.game-instructions {width:100%;background-color: #e5e7eb;padding: 1rem;border-radius: 0.25rem;
}.game-over-message {margin-top: 1rem;padding: 1rem;background-color: #ef4444;color: #000;border-radius: 0.25rem;text-align: center;
}.game-paused-message {margin-top: 1rem;padding: 1rem;background-color: #facc15;color: #000;border-radius: 0.25rem;text-align: center;
}

总体而言,DeekSeek辅助编程效率还是很高的,对于编程初学者尤其方便。

相关文章:

Tauri(2.5.1)+Leptos(0.8.2)开发自用桌面小程序--DeepSeek辅助编程(俄罗斯方块)

在之前工作基础上&#xff08;Tauri(2.5.1)Leptos(0.8.2)开发自用桌面小程序-CSDN博客&#xff09;&#xff0c;继续进行自用桌面小程序的开发&#xff0c;这次完全使用DeepSeek辅助编程做一个俄罗斯方块游戏&#xff0c;大部分代码由DeepSeek自主完成&#xff0c;Bug扔给DeepS…...

flex布局实例:把色子放进盒子里

目录 一、flex布局实例&#xff1a;把色子放进盒子里 1、基础样式 二、justify-content 属性 三、flex-direction 属性 四、align-items 属性 五、flex-wrap 属性 二、flex布局应用到常见场景 非常详细的讲解flex布局&#xff0c;看一看&#xff0c;练一练&#xff01; …...

【启发式算法】RRT*算法详细介绍(Python)

&#x1f4e2;本篇文章是博主人工智能&#xff08;AI&#xff09;领域学习时&#xff0c;用于个人学习、研究或者欣赏使用&#xff0c;并基于博主对相关等领域的一些理解而记录的学习摘录和笔记&#xff0c;若有不当和侵权之处&#xff0c;指出后将会立即改正&#xff0c;还望谅…...

基于R语言的亚组分析与森林图绘制1

亚组分析是临床研究中的重要分析方法,其核心是通过将研究对象按基线特征(如年龄、性别或吸烟状况等)划分为不同亚组,进而评估干预措施或暴露因素在各亚组中对结局影响的差异性。 在亚组分析中,交互作用(P for interaction)是关键指标,用于判断干预措施或暴露因素与亚组…...

idea, CreateProcess error=206, 文件名或扩展名太长

idea, CreateProcess error206, 文件名或扩展名太长 解决 “CreateProcess error206, 文件名或扩展名太长” 错误 CreateProcess error206 是 Windows 系统特有的错误&#xff0c;表示命令行参数超出了 Windows 的 32767 字符限制。这个问题在 Java 开发中尤其常见&#xff0c…...

aspose.word在IIS后端DLL中高并发运行,线程安全隔离

aspose.word在IIS后端DLL中运行,加载很慢,如何为全部用户加载,再每个用户访问时在各自线程中直接可以打开WORD文件处理 Aspose.Words 在 IIS 中优化加载性能方案 针对 Aspose.Words 在 IIS 后端 DLL 中加载缓慢的问题&#xff0c;我们可以通过单例模式预加载组件并结合线程安…...

day042-负载均衡与web集群搭建

文章目录 0. 老男孩思想-面试官问&#xff1a;你对加班的看法?1. 负载均衡2. 搭建负载均衡的WordPress集群2.1 负载均衡服务器2.2 配置web服务器2.3 测试 踩坑记录1. /var/cache/nginx权限问题 0. 老男孩思想-面试官问&#xff1a;你对加班的看法? 互联网公司没有不加班的&a…...

DuDuTalk | 武汉赛思云科技有限公司通过武汉市人工智能企业认定!

近日&#xff0c;2025年武汉市人工智能企业名单正式公布&#xff01;武汉赛思云科技有限公司&#xff08;以下简称赛思云科技&#xff09;凭借卓越的技术实力与创新成果&#xff0c;成功入选武汉市人工智能企业。这是对公司长期深耕AI语音智能领域、推动数字化转型的高度认可&a…...

Tita CRM飞书协同版:解锁企业销售与交付管理新效能

数字化转型的破局之道 在数字经济加速发展的今天&#xff0c;传统管理模式正面临前所未有的挑战&#xff1a; • 销售过程缺乏可视化管控手段 • 项目执行存在严重的信息孤岛 • 跨部门协作效率持续低下 • 绩效考核缺乏客观数据支撑 Tita CRM作为专业的智能化管理平台&#x…...

web安全之h2注入系统学习

起初是在N1 Junior 2025 上面碰到一题&#xff0c;考点是h2的sql注入。由于之前没有见过&#xff0c;趁此机会系统学习一番 实验代码 public class H2Inject {public static void main(String[] args) throws Exception{JdbcDataSource dataSource new JdbcDataSource();dataS…...

LVS-DR负载均衡群集深度实践:高性能架构设计与排障指南

目录 一、核心原理与理论 二、背景与架构设计 三、全流程部署步骤 1. NFS共享存储配置&#xff08;192.168.7.100&#xff09; 2. Real Server节点配置&#xff08;四台服务器&#xff09; 3. Director服务器配置 四、常见问题解决方案 五、生产环境总结 拓扑示意图&am…...

Java如何导出word(根据模板生成),通过word转成pdf,放压缩包

<!-- 导出word文档所需依赖--><dependency><groupId>com.deepoove</groupId><artifactId>poi-tl</artifactId><version>1.10.0-beta</version></dependency><dependency><groupId>org.apache.poi</gr…...

.NET 7.0 EF Core:一、创建Web API 项目基础框架和用户表的增删改查

demo 地址: https://github.com/iotjin/Jh.Admin.NETCore 代码不定时更新&#xff0c;请前往github查看最新代码 .NET 7.0 EF Core&#xff1a;一、创建Web API项目 官方教程序一、项目目录结构各层职责说明1️⃣ Admin.NETCore.API&#xff08;接口层&#xff09;2️⃣ Admin.…...

一篇文章了解XML

一、什么是 XML&#xff1f; XML 是一种结构化数据的标记语言&#xff0c;用来存储、传输和描述数据。 它和 HTML 很像&#xff0c;但它的标签是自定义的&#xff0c;不限定格式和外观&#xff0c;而是强调数据的结构和含义。 XML不是用来展示数据的&#xff0c;HTML是用来展…...

Windows下安装zookeeper

有关Linux安装zk的文章可以参考下我之前写的&#xff1a; Zookeeper 3.8.4 安装和参数解析 Windows下的下载和Linux是一样的&#xff0c;都是同一个包&#xff0c;目前zk稳定版是 3.8.4 下载解压后 在根目录下创建 data 文件夹用来存放数据文件 在 conf 文件夹中&#xff0c;…...

计算机网络 网络层:控制平面

在本章中&#xff0c;包含网络层的控制平面组件。控制平面作为一种网络范围的逻辑&#xff0c;不仅控制沿着从源主机到目的主机的端到端路径间的路由器如何转发数据报&#xff0c;而且控制网络层组件和服务如何配置和管理。5.2节&#xff0c;传统的计算图中最低开销路径的路由选…...

探索阿里云智能媒体管理IMM:解锁媒体处理新境界

一、引言&#xff1a;开启智能媒体管理新时代 在数字化浪潮的席卷下&#xff0c;媒体行业正经历着前所未有的变革。从传统媒体到新媒体的转型&#xff0c;从内容生产到传播分发&#xff0c;每一个环节都在寻求更高效、更智能的解决方案。而云计算&#xff0c;作为推动这一变革…...

微信点餐小程序—美食物

本项目是基于WAMP Server 和PHP 动态网页技术构建的微信小程序点餐系统&#xff0c;该系统主要分为前端&#xff08;微信小程序&#xff09;和后端&#xff08;基于PHPMySQL服务器端&#xff09; 整体架构流程 1、前端部分 用户界面&#xff1a;展示菜品、处理用户点餐操作、…...

Python零基础入门到高手8.5节: 实现选择排序算法

目录 8.5.1 排序算法简介 8.5.2 选择排序算法 8.5.3 好好学习&#xff0c;天天向上 8.5.1 排序算法简介 所谓排序&#xff0c;是指将数据集合中的元素按从小到大的顺序进行排列&#xff0c;或按从大到小的顺序进行排列。前者称为升序排序&#xff0c;后者称为降序排序。在数…...

JavaEE初阶第四期:解锁多线程,从 “单车道” 到 “高速公路” 的编程升级(二)

专栏&#xff1a;JavaEE初阶起飞计划 个人主页&#xff1a;手握风云 目录 一、Thread类及常用方法 2.1. Thread的常见构造方法 2.2. Thread的常见属性 2.3. 启动一个线程 2.4. 中断一个线程 2.5. 等待一个线程 2.6. 休眠当前线程 一、Thread类及常用方法 2.1. Thread的…...

Metasploit常用命令详解

一、Metasploit 概述 Metasploit是一款开源的渗透测试框架&#xff0c;由 H.D. Moore 于 2003 年首次发布&#xff0c;目前由 rapid7 公司维护。它整合了大量漏洞利用模块、后渗透工具和漏洞扫描功能&#xff0c;已成为网络安全工程师、红队 / 蓝队成员及安全研究人员的核心工…...

2025.6.24总结

今天发生了两件事&#xff0c;这每件事情都足以影响我的工作状态。 1.团队中有人要转岗 这算是最让我有些小震惊的事件了。我不明白&#xff0c;那个同事干得好好的&#xff0c;为啥会转岗&#xff0c;为啥会被调到其他团队。虽然团队有正编&#xff0c;有od,但我自始自终觉得…...

2023年全国青少年信息素养大赛Python 复赛真题——玩石头游戏

今日python每日练习题为——玩石头游戏&#xff0c;大家记得坚持刷题哦&#xff0c;闯入国赛~ 每轮可拿 1-3 块石头&#xff0c;双方均采取最优策略。若石头数 n 为 4 的倍数&#xff0c;无论先手取 k 块&#xff08;1≤k≤3&#xff09;&#xff0c;后手总能取 4-k 块&#xf…...

MySQL之SQL性能优化策略

MySQL之SQL性能优化策略 一、主键优化策略1.1 主键的核心作用1.2 主键设计原则1.3 主键优化实践 二、ORDER BY优化策略2.1 ORDER BY执行原理2.2 ORDER BY优化技巧2.3 处理大结果集排序 三、GROUP BY优化策略3.1 GROUP BY执行原理3.2 GROUP BY优化方法 四、LIMIT优化策略4.1 LIM…...

AI时代工具:AIGC导航——AI工具集合

大家好!AIGC导航是一个汇集多种AIGC工具的平台&#xff0c;提供了丰富的工具和资源。 工具功能​: 该平台整合了多样的AIGC工具&#xff0c;涵盖了绘画创作、写作辅助以及视频制作等多个领域。绘画工具能够生成高质量的图像作品&#xff1b;写作工具支持从构思到润色的全流程写…...

性能测试-jmeter实战4

课程&#xff1a;B站大学 记录软件测试-性能测试学习历程、掌握前端性能测试、后端性能测试、服务端性能测试的你才是一个专业的软件测试工程师 性能测试-jmeter实战4 jmeter环境搭建1. 安装Java环境&#xff08;必需&#xff09; JMeter环境搭建完整指南1. 安装Java&#xff0…...

C++字符串的行输入

1、字符串的输入 下面用一个真实的示例来进行演示&#xff1a; #include<iostream> #include<string>int main() {using namespace std;const int ArSize 20;char name[ArSize];char dessert[ArSize];cout << "Enter your name:\n";cin >>…...

【Linux网络与网络编程】15.DNS与ICMP协议

1. DNS 1.1 DNS介绍 TCP/IP 中使用 IP 地址和端口号来确定网络上的一台主机的一个程序&#xff0c;但是 IP 地址不方便记忆&#xff0c;于是人们发明了一种叫主机名的字符串&#xff0c;并使用 hosts 文件来描述主机名和 IP 地址的关系。最初, 通过互连网信息中心(SRI-NIC)来…...

Python训练营-Day40-训练和测试的规范写法

1.单通道图片训练 # import torch # import torch.nn as nn # import torch.optim as optim # from torchvision import datasets, transforms # from torch.utils.data import DataLoader # import matplotlib.pyplot as plt # import numpy as np# # 设置中文字体支持 # plt…...

【Python-Day 29】万物皆对象:详解 Python 类的定义、实例化与 `__init__` 方法

Langchain系列文章目录 01-玩转LangChain&#xff1a;从模型调用到Prompt模板与输出解析的完整指南 02-玩转 LangChain Memory 模块&#xff1a;四种记忆类型详解及应用场景全覆盖 03-全面掌握 LangChain&#xff1a;从核心链条构建到动态任务分配的实战指南 04-玩转 LangChai…...

内存泄漏和内存溢出的区别

内存泄漏&#xff08;Memory Leak&#xff09;和内存溢出&#xff08;Memory Overflow / Out Of Memory, OOM&#xff09;是软件开发中两个密切相关但又本质不同的内存问题&#xff1a; 核心区别一句话概括&#xff1a; 内存泄漏&#xff1a; 有垃圾对象占用内存却无法被回收&…...

Linux系统---Nginx配置nginx状态统计

配置Nignx状态统计 1、下载vts模块 https://github.com/vozlt/nginx-module-vts [rootclient ~]# nginx -s stop [rootclient ~]# ls anaconda-ks.cfg nginx-1.27.3 ceph-release-1-1.el7.noarch.rpm nginx-1.27.3.tar.gz info.sh …...

linux操作系统的软件架构分析

一、linux操作系统的层次结构 1.内核的主要功能 1&#xff09;进程管理 2&#xff09;内存管理 3&#xff09;文件系统 4&#xff09;进程间通信、I/O系统、网络通信协议等 2.系统程序 1&#xff09;系统接口函数库&#xff0c;比如libc 2)shell程序 3&#xff09;编译器、编辑…...

快速手搓一个MCP服务指南(三):FastMCP的核心组件-构建MCP服务的关键技术实现

FastMCP 是一套面向 LLM 应用开发的工具框架&#xff0c;通过标准化协议衔接大语言模型与外部功能组件&#xff0c;构建「LLM工具」的闭环交互体系。其核心技术体系包含四大模块&#xff1a;工具系统将 Python 函数转化为 LLM 可调用的能力单元&#xff0c;通过类型注解实现参数…...

创建首个 Spring Boot 登录项目

&#x1f4cc; 摘要 在 Java Web 开发中&#xff0c;登录功能是最基础也是最重要的模块之一。本文将手把手带你使用 IntelliJ IDEA 和 Maven 构建一个基于 Spring Boot 的简单登录系统&#xff0c;涵盖&#xff1a; 使用 IDEA 创建 Spring Boot 项目配置 Maven 依赖&#xff…...

order、sort、distribute和cluster by(Spark/Hive)

1. abstract ORDER BY&#xff1a;完整查询结果的全局行排序。与SORT BY、CLUSTER BY、DISTRIBUTE BY互斥&#xff0c;不能同时使用。 示例SELECT * FROM table_name ORDER BY column_name;SORT BY&#xff1a;只在每个分区内排序&#xff0c;局部排序结果不是全局有序。与ORD…...

# Python中等于号的使用

# Python中等于号的使用 ## 1. 问题的分析与思考 在Python中&#xff0c;等于号&#xff08;&#xff09;是一个赋值运算符&#xff0c;用于将右侧的值或表达式的结果赋给左侧的变量。这是Python&#xff08;以及许多其他编程语言&#xff09;中非常基础且核心的一个概念。理…...

无人机神经网络模块运行与技术难点

一、神经网络模块的运行方式 1. 分层处理架构 感知层 多模态数据融合&#xff1a;通过八元数卷积网络&#xff08;OCNN&#xff09;统一处理LiDAR、摄像头、IMU等异构传感器数据&#xff0c;将点云坐标&#xff08;x/y/z&#xff09;、图像RGB与光流信息编码至8维虚部&#…...

宝塔服务器调优工具 1.1(Opcache优化)

第一步&#xff1a;宝塔服务器调优工具 1.1&#xff08;按照下面的参数填写&#xff09; 第二步&#xff1a;路径/www/server/php/80/etc/php.ini 搜索jit jit1235 其中1235根据服务器情况修改 第三步&#xff1a;路径/www/server/php/80/etc/php-cli.ini 搜索 jit1235 其中…...

day041-web集群架构搭建

文章目录 0. 老男孩思想-高薪四板斧1. web集群架构图2. 搭建异地备份服务2.1 服务端-阿里云服务器2.1.1 查看rsync软件包2.1.2 添加rsync配置文件2.1.3 添加虚拟用户2.1.4 创建校验用户密码文件2.1.5 创建备份目录2.1.6 启动服务2.1.7 开放安全组端口2.1.8 发送检查邮件 2.2 客…...

国产化条码类库Spire.Barcode教程:如何使用 C# 读取 PDF 中的条码(两种方法轻松实现)

在 PDF 文档的 .NET 平台处理流程中&#xff0c;使用 C# 读取 PDF 条码 是一项常见需求&#xff0c;特别适用于处理扫描件或电子表单。无论是物流、金融、医疗还是制造行业&#xff0c;PDF 文档中经常包含用于追踪或识别的条码。这些条码可能是嵌入图像&#xff0c;也可能是矢量…...

vue 3 计算器

效果&#xff1a; <template><div class"calculator-container"><div class"calculator"><!-- 显示区域 --><div class"display">{{ formattedDisplay }}</div><!-- 按钮区域 --><div class"…...

CRMEB PHP多门店版v3.2.1系统全开源+Uniapp前端+搭建教程

一.介绍 CRMEB多店版是一款为品牌连锁门店打造的私域电商解决方案&#xff0c;以三大运营模式为核心&#xff0c;助力品牌连锁门店轻松构建全渠道、一体化的私域电商生态&#xff0c;促进“线上电商”与“线下门店”销售运营融合&#xff0c;加速品牌数字化转型&#xff0c;为…...

主机复制文字和文件到 Ubuntu 虚拟机

在 VMware Workstation Pro 16 中复制文字和文件到 Ubuntu 虚拟机&#xff0c;方法如下&#xff1a; Open-VM-Tools 禁用 Wayland 解决 。 1.安装 VMware Tools&#xff08;推荐&#xff09;或 open-vm-tools&#xff1a; sudo apt update sudo apt install open-vm-tools…...

性能测试 —— 数据库的连接池和主从同步和分表分区

一、数据库的调优&#xff08;库层面&#xff09; 1、数据库连接池 1、介绍&#xff1a;数据库连接池(Database Connection Pool)是一种用于管理数据库连接的技术&#xff0c;它通过预先创建并维护一组数据库连接来提高应用程序的性能和可扩展性。 2、创建、管理、关闭 数据…...

猿人学js逆向比赛第一届第十二题

一、分析请求 看到这里只有一个m的密文参数&#xff0c;没有cookie&#xff0c;请求头等其他的参数&#xff0c;那么这里跟一堆栈信息。 很顺利地锁定了m的加密位置。看到是字符串拼接然后使用btoa函数进行编码&#xff0c;那么这里尝试使用Python复现一下。顺利拿到结果。 复现…...

第十节 新特性与趋势-CSS层叠规则升级

以下是关于 ​​CSS层叠规则升级​​ 的全面解析&#xff0c;结合最新规范&#xff08;如级联层layer&#xff09;和传统层叠机制的演进&#xff0c;从核心原理、应用场景到实践策略的系统性总结&#xff1a; 一、传统层叠规则的三大支柱 CSS层叠规则的传统机制基于以下三个维…...

关键领域软件工厂的安全中枢如何全面升级供应链检测能力

随着软件供应链安全体系在互联网、金融等领域逐步成熟&#xff0c;关键领域正加速迈向以 MLOps、软件工厂为核心的新型研发生态。在这一过程中&#xff0c;面对代码安全、依赖合规、系统可信等多重挑战&#xff0c;传统人工审查模式已难以满足国家级高安全性要求。 Gitee Scan…...

西门子G120XA变频器:数据中心能效革命的核心引擎

在数字经济爆发式增长的今天&#xff0c;数据中心已成为支撑社会运转的"数字心脏"。然而&#xff0c;其庞大的能耗需求与绿色低碳目标之间的矛盾日益凸显——尤其是冷却系统作为数据中心第二大能耗单元&#xff08;占比约35%&#xff09;&#xff0c;正成为能效提升的…...

从零开始学习Spring Cloud Alibaba (一)

人狠话不多,直接开始少点屁话本着共同学习进步的目的和大家交流如有不对的地方望铁子们多多谅解 准备工具 开发工具 idea Java环境 jdk17 容器: docker Maven 3.8.6 仓库镜像阿里云 <mirror><id>alimaven</id><name>aliyun maven</name><…...