SYSTEM:
You are a helpful assistant. You can help me by answering my questions. You can also ask me questions.
USER:
我需要一段简单的Python写的的用户表增删改查 RESTAPI的例子,数据库是MySQL,我需要起码的授权验证,使用中文说明,日语代码注释
ASSISTANT:
好的,下面是一个简单的Python REST API 示例,使用 Flask 框架和 SQLAlchemy ORM 来与 MySQL 数据库进行交互。这个示例包括用户表的增删改查操作以及基本的授权验证。
首先,确保你已经安装了必要的依赖:
<BASH>pip install Flask SQLAlchemy Flask-JWT-Extended
然后,创建一个名为 app.py
的文件,并添加以下代码:
<PYTHON>from flask import Flask, request, jsonify from flask_sqlalchemy import SQLAlchemy from flask_jwt_extended import JWTManager, create_access_token, jwt_required, get_jwt_identity app = Flask(__name__) app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql+pymysql://username:password@localhost/dbname' app.config['JWT_SECRET_KEY'] = 'your-secret-key' # 替换为你自己的密钥 db = SQLAlchemy(app) jwt = JWTManager(app) # 用户模型 class User(db.Model): id = db.Column(db.Integer, primary_key=True) username = db.Column(db.String(80), unique=True, nullable=False) password = db.Column(db.String(120), nullable=False) # 初始化数据库 @app.before_first_request def create_tables(): db.create_all() # 用户注册 @app.route('/register', methods=['POST']) def register(): data = request.get_json() new_user = User(username=data['username'], password=data['password']) db.session.add(new_user) db.session.commit() return jsonify({'message': 'User registered successfully'}), 201 # 用户登录 @app.route('/login', methods=['POST']) def login(): data = request.get_json() user = User.query.filter_by(username=data['username']).first() if user and user.password == data['password']: access_token = create_access_token(identity={'username': user.username}) return jsonify({'access_token': access_token}), 200 else: return jsonify({'message': 'Invalid credentials'}), 401 # 获取用户列表(需要授权) @app.route('/users', methods=['GET']) @jwt_required() def get_users(): current_user = get_jwt_identity() users = User.query.all() return jsonify([{'username': user.username} for user in users]), 200 # 创建用户(需要授权) @app.route('/users', methods=['POST']) @jwt_required() def create_user(): data = request.get_json() new_user = User(username=data['username'], password=data['password']) db.session.add(new_user) db.session.commit() return jsonify({'message': 'User created successfully'}), 201 # 更新用户(需要授权) @app.route('/users/<int:id>', methods=['PUT']) @jwt_required() def update_user(id): data = request.get_json() user = User.query.get(id) if user: user.username = data['username'] user.password = data['password'] db.session.commit() return jsonify({'message': 'User updated successfully'}), 200 else: return jsonify({'message': 'User not found'}), 404 # 删除用户(需要授权) @app.route('/users/<int:id>', methods=['DELETE']) @jwt_required() def delete_user(id): user = User.query.get(id) if user: db.session.delete(user) db.session.commit() return jsonify({'message': 'User deleted successfully'}), 200 else: return jsonify({'message': 'User not found'}), 404 if __name__ == '__main__': app.run(debug=True)
/register
和 /login
端点进行注册和登录。登录成功后,会返回一个 JWT 令牌。SQLALCHEMY_DATABASE_URI
替换为你的 MySQL 数据库连接字符串,并确保数据库已经创建并且包含一个名为 users
的表。<PYTHON># 用户模型 class User(db.Model): id = db.Column(db.Integer, primary_key=True) # 主键 username = db.Column(db.String(80), unique=True, nullable=False) # 唯一的用户名 password = db.Column(db.String(120), nullable=False) # 密码
希望这个示例对你有帮助!如果你有任何问题,请随时提问。
USER:
我需要一段简单的Java写的Springboot例子,实现用户表增删改查 RESTAPI,数据库是MySQL,我需要起码的授权验证,使用中文说明,日语代码注释
ASSISTANT:
好的,下面是一个简单的 Spring Boot 示例,实现用户表的增删改查操作以及基本的授权验证。这个示例使用 Spring Data JPA 与 MySQL 数据库进行交互,并使用 Spring Security 进行授权验证。
首先,创建一个新的 Maven 项目,并在 pom.xml
文件中添加以下依赖:
<XML><dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies>
在 src/main/resources/application.properties
文件中添加以下内容:
<PROPERTIES>spring.datasource.url=jdbc:mysql://localhost:3306/your_database?useSSL=false&serverTimezone=UTC spring.datasource.username=your_username spring.datasource.password=your_password spring.jpa.hibernate.ddl-auto=update
在 src/main/java/com/example/demo/model
包下创建一个名为 User.java
的文件:
<JAVA>package com.example.demo.model; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; @Entity public class User { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String username; private String password; // Getters and Setters }
在 src/main/java/com/example/demo/repository
包下创建一个名为 UserRepository.java
的文件:
<JAVA>package com.example.demo.repository; import com.example.demo.model.User; import org.springframework.data.jpa.repository.JpaRepository; public interface UserRepository extends JpaRepository<User, Long> { }
在 src/main/java/com/example/demo/service
包下创建一个名为 UserService.java
的文件:
<JAVA>package com.example.demo.service; import com.example.demo.model.User; import com.example.demo.repository.UserRepository; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.List; @Service public class UserService { @Autowired private UserRepository userRepository; public List<User> getAllUsers() { return userRepository.findAll(); } public User getUserById(Long id) { return userRepository.findById(id).orElse(null); } public User createUser(User user) { return userRepository.save(user); } public User updateUser(Long id, User userDetails) { User user = userRepository.findById(id).orElse(null); if (user != null) { user.setUsername(userDetails.getUsername()); user.setPassword(userDetails.getPassword()); return userRepository.save(user); } else { return null; } } public void deleteUser(Long id) { userRepository.deleteById(id); } }
在 src/main/java/com/example/demo/controller
包下创建一个名为 UserController.java
的文件:
<JAVA>package com.example.demo.controller; import com.example.demo.model.User; import com.example.demo.service.UserService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; import java.util.List; @RestController @RequestMapping("/api/users") public class UserController { @Autowired private UserService userService; @GetMapping public List<User> getAllUsers() { return userService.getAllUsers(); } @GetMapping("/{id}") public ResponseEntity<User> getUserById(@PathVariable Long id) { User user = userService.getUserById(id); if (user != null) { return ResponseEntity.ok(user); } else { return ResponseEntity.notFound().build(); } } @PostMapping public User createUser(@RequestBody User user) { return userService.createUser(user); } @PutMapping("/{id}") public ResponseEntity<User> updateUser(@PathVariable Long id, @RequestBody User userDetails) { User updatedUser = userService.updateUser(id, userDetails); if (updatedUser != null) { return ResponseEntity.ok(updatedUser); } else { return ResponseEntity.notFound().build(); } } @DeleteMapping("/{id}") public void deleteUser(@PathVariable Long id) { userService.deleteUser(id); } }
在 src/main/java/com/example/demo/config
包下创建一个名为 SecurityConfig.java
的文件:
<JAVA>package com.example.demo.config; import org.springframework.context.annotation.Bean; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder; @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests() .antMatchers("/api/users/**").hasRole("ADMIN") .anyRequest().authenticated() .and() .httpBasic(); } @Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); } }
在 src/main/java/com/example/demo
包下创建一个名为 DemoApplication.java
的文件:
<JAVA>package com.example.demo; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class DemoApplication { public static void main(String[] args) { SpringApplication.run(DemoApplication.class, args); } }
现在你可以运行 DemoApplication
类来启动Spring Boot应用程序。所有的REST API端点都需要管理员权限才能访问。
USER:
数据层我想使用mybatis
ASSISTANT:
使用MyBatis作为数据访问层(DAL)是一个不错的选择,因为它提供了一种简单而强大的方式来与数据库进行交互。以下是一些基本步骤和建议,帮助你在项目中集成MyBatis:
首先,你需要在你的项目中添加MyBatis的依赖。如果你使用的是Maven,可以在pom.xml
文件中添加以下依赖:
<XML><dependencies> <!-- MyBatis --> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.5.6</version> </dependency> <!-- MySQL Connector/J --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.26</version> </dependency> </dependencies>
创建一个MyBatis的配置文件,通常命名为mybatis-config.xml
。这个文件用于配置数据源、事务管理器等。
<XML><!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration> <environments default="development"> <environment id="development"> <transactionManager type="JDBC"/> <dataSource type="POOLED"> <property name="driver" value="com.mysql.cj.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/your_database"/> <property name="username" value="your_username"/> <property name="password" value="your_password"/> </dataSource> </environment> </environments> </configuration>
定义一个Mapper接口,用于定义SQL查询。例如:
<JAVA>public interface UserMapper { @Select("SELECT * FROM users WHERE id = #{id}") User getUserById(int id); }
为每个Mapper接口创建一个XML映射文件。例如,对于上面的UserMapper
:
<XML><!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.example.UserMapper"> <select id="getUserById" parameterType="int" resultType="com.example.User"> SELECT * FROM users WHERE id = #{id} </select> </mapper>
在你的应用程序中,创建一个SqlSessionFactory
实例。通常在启动时进行一次性初始化:
<JAVA>import org.apache.ibatis.io.Resources; import org.apache.ibatis.session.SqlSessionFactory; import org.apache.ibatis.session.SqlSessionFactoryBuilder; import java.io.Reader; public class MyBatisUtil { private static SqlSessionFactory sqlSessionFactory; static { try (Reader reader = Resources.getResourceAsReader("mybatis-config.xml")) { sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader); } catch (Exception e) { e.printStackTrace(); } } public static SqlSessionFactory getSqlSessionFactory() { return sqlSessionFactory; } }
在你的业务逻辑中,使用SqlSession
来执行SQL查询:
<JAVA>import org.apache.ibatis.session.SqlSession; import org.apache.ibatis.session.SqlSessionFactory; public class UserService { private SqlSessionFactory sqlSessionFactory = MyBatisUtil.getSqlSessionFactory(); public User getUserById(int id) { try (SqlSession session = sqlSessionFactory.openSession()) { UserMapper mapper = session.getMapper(UserMapper.class); return mapper.getUserById(id); } } }
确保你的实体类与数据库表结构一致,并且包含相应的getter和setter方法。例如:
<JAVA>public class User { private int id; private String name; private String email; // getters and setters }
编写一些单元测试来验证你的配置和查询是否正常工作。
通过这些步骤,你应该能够在项目中成功集成MyBatis作为数据访问层。如果你有任何具体问题或需要进一步的帮助,请告诉我!
USER:
我需要一段简单的TypeScript写的Express的例子,实现用户表增删改查 RESTAPI,数据库是MySQL,我需要起码的授权验证,使用中文说明,日语代码注释
ASSISTANT:
好的,下面是一个简单的TypeScript写的Express示例,实现用户表的增删改查REST API。这个示例使用MySQL作为数据库,并包含基本的授权验证。
首先,你需要安装一些必要的依赖:
<BASH>npm install express mysql2 body-parser jsonwebtoken bcryptjs
创建一个简单的项目结构:
<TEXT>my-express-app/ ├── src/ │ ├── controllers/ │ │ └── userController.ts │ ├── middlewares/ │ │ └── authMiddleware.ts │ ├── models/ │ │ └── userModel.ts │ ├── routes/ │ │ └── userRoutes.ts │ ├── utils/ │ │ └── db.ts │ └── index.ts ├── tsconfig.json └── package.json
创建一个tsconfig.json
文件:
<JSON>{ "compilerOptions": { "target": "ES6", "module": "commonjs", "outDir": "./dist", "strict": true, "esModuleInterop": true }, "include": ["src/**/*.ts"], "exclude": ["node_modules"] }
在src/utils/db.ts
中创建一个数据库连接:
<TYPESCRIPT>import mysql from 'mysql2/promise'; const pool = mysql.createPool({ host: 'localhost', user: 'your_username', password: 'your_password', database: 'your_database', waitForConnections: true, connectionLimit: 10, queueLimit: 0 }); export default pool;
在src/models/userModel.ts
中定义用户模型:
<TYPESCRIPT>// 用户表结构 const userTable = `CREATE TABLE IF NOT EXISTS users ( id INT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(255) NOT NULL, email VARCHAR(255) UNIQUE NOT NULL, password VARCHAR(255) NOT NULL );`; // 创建用户表 export const createUserTable = async () => { const connection = await pool.getConnection(); try { await connection.query(userTable); } finally { connection.release(); } };
在src/controllers/userController.ts
中定义用户控制器:
<TYPESCRIPT>import pool from '../utils/db'; import bcrypt from 'bcryptjs'; import jwt from 'jsonwebtoken'; // 创建用户 export const createUser = async (req, res) => { const { name, email, password } = req.body; const hashedPassword = await bcrypt.hash(password, 10); const connection = await pool.getConnection(); try { await connection.query('INSERT INTO users (name, email, password) VALUES (?, ?, ?)', [name, email, hashedPassword]); res.status(201).json({ message: '用户创建成功' }); } finally { connection.release(); } }; // 获取所有用户 export const getUsers = async (req, res) => { const connection = await pool.getConnection(); try { const [rows] = await connection.query('SELECT * FROM users'); res.status(200).json(rows); } finally { connection.release(); } }; // 获取单个用户 export const getUser = async (req, res) => { const { id } = req.params; const connection = await pool.getConnection(); try { const [rows] = await connection.query('SELECT * FROM users WHERE id = ?', [id]); if (rows.length === 0) { return res.status(404).json({ message: '用户不存在' }); } res.status(200).json(rows[0]); } finally { connection.release(); } }; // 更新用户 export const updateUser = async (req, res) => { const { id } = req.params; const { name, email, password } = req.body; const connection = await pool.getConnection(); try { await connection.query('UPDATE users SET name = ?, email = ?, password = ? WHERE id = ?', [name, email, password, id]); res.status(200).json({ message: '用户更新成功' }); } finally { connection.release(); } }; // 删除用户 export const deleteUser = async (req, res) => { const { id } = req.params; const connection = await pool.getConnection(); try { await connection.query('DELETE FROM users WHERE id = ?', [id]); res.status(200).json({ message: '用户删除成功' }); } finally { connection.release(); } };
在src/middlewares/authMiddleware.ts
中定义授权中间件:
<TYPESCRIPT>import jwt from 'jsonwebtoken'; // 验证JWT export const verifyToken = (req, res, next) => { const token = req.headers['authorization']; if (!token) return res.status(401).json({ message: '未授权' }); jwt.verify(token, 'your_secret_key', (err, user) => { if (err) return res.status(403).json({ message: '无效的令牌' }); req.user = user; next(); }); };
在src/routes/userRoutes.ts
中定义用户路由:
<TYPESCRIPT>import express from 'express'; import { createUser, getUsers, getUser, updateUser, deleteUser } from '../controllers/userController'; import { verifyToken } from '../middlewares/authMiddleware'; const router = express.Router(); router.post('/users', createUser); router.get('/users', verifyToken, getUsers); router.get('/users/:id', verifyToken, getUser); router.put('/users/:id', verifyToken, updateUser); router.delete('/users/:id', verifyToken, deleteUser); export default router;
在src/index.js
中定义主应用:
<TYPESCRIPT>import express from 'express'; import userRoutes from './routes/userRoutes'; const app = express(); app.use(express.json()); // 创建用户表 createUserTable().then(() => { console.log('用户表创建成功'); }); // 使用路由 app.use('/api', userRoutes); const PORT = process.env.PORT || 3000; app.listen(PORT, () => { console.log(`服务器运行在端口 ${PORT}`); });
确保你已经安装了所有依赖项,然后运行以下命令:
<BASH>node src/index.js
这样,你就创建了一个简单的RESTful API,支持用户的创建、读取、更新和删除操作,并且包含了基本的授权机制。
USER:
我需要一段简单的Golang写的Express的例子,实现用户表增删改查 RESTAPI,数据库是MySQL,我需要起码的授权验证,使用中文说明,日语代码注释
ASSISTANT:
好的,下面是一个简单的Golang写的Express示例,实现用户表增删改查REST API,数据库是MySQL,并且包含基本的授权验证。
首先,你需要安装一些必要的依赖:
<SH>go get -u github.com/gin-gonic/gin go get -u gorm.io/gorm go get -u gorm.io/driver/mysql go get -u github.com/dgrijalva/jwt-go
创建一个新的Golang项目文件夹,并在其中创建以下文件:
main.go
models/user.go
handlers/user.go
middlewares/auth.go
<GO>package main import ( "github.com/gin-gonic/gin" "your_project_path/models" "your_project_path/handlers" "your_project_path/middlewares" ) func main() { // 初始化数据库 models.InitDB() r := gin.Default() // 中间件:授权验证 r.Use(middlewares.AuthRequired()) // 用户路由 api := r.Group("/api") { api.POST("/users", handlers.CreateUser) api.GET("/users", handlers.GetUsers) api.PUT("/users/:id", handlers.UpdateUser) api.DELETE("/users/:id", handlers.DeleteUser) } r.Run(":8080") }
<GO>package models import ( "gorm.io/driver/mysql" "gorm.io/gorm" ) type User struct { ID uint `json:"id"` Username string `json:"username"` Password string `json:"password"` } var DB *gorm.DB func InitDB() { dsn := "user:pass@tcp(127.0.0.1:3306)/dbname?charset=utf8mb4&parseTime=True&loc=Local" database, err := gorm.Open(mysql.Open(dsn), &gorm.Config{}) if err != nil { panic("failed to connect database") } DB = database DB.AutoMigrate(&User{}) }
<GO>package handlers import ( "github.com/gin-gonic/gin" "your_project_path/models" ) // CreateUser 创建用户 func CreateUser(c *gin.Context) { var user models.User if err := c.ShouldBindJSON(&user); err != nil { c.JSON(400, gin.H{"error": err.Error()}) return } models.DB.Create(&user) c.JSON(201, user) } // GetUsers 获取所有用户 func GetUsers(c *gin.Context) { var users []models.User models.DB.Find(&users) c.JSON(200, users) } // UpdateUser 更新用户 func UpdateUser(c *gin.Context) { id := c.Param("id") var user models.User if err := models.DB.Where("id = ?", id).First(&user).Error; err != nil { c.AbortWithStatus(404) return } c.BindJSON(&user) models.DB.Save(&user) c.JSON(200, user) } // DeleteUser 删除用户 func DeleteUser(c *gin.Context) { id := c.Param("id") var user models.User if err := models.DB.Where("id = ?", id).Delete(&user).Error; err != nil { c.AbortWithStatus(404) return } c.JSON(204, gin.H{"id #" + id: "deleted"}) }
<GO>package middlewares import ( "github.com/gin-gonic/gin" "github.com/dgrijalva/jwt-go" ) var jwtKey = []byte("your_secret_key") // AuthRequired 授权验证中间件 func AuthRequired() gin.HandlerFunc { return func(c *gin.Context) { tokenString := c.GetHeader("Authorization") if tokenString == "" { c.JSON(401, gin.H{"error": "Authorization header required"}) c.Abort() return } token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) { if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok { return nil, fmt.Errorf("unexpected signing method: %v", token.Header["alg"]) } return jwtKey, nil }) if err != nil { c.JSON(401, gin.H{"error": "token is invalid"}) c.Abort() return } if claims, ok := token.Claims.(jwt.MapClaims); ok && token.Valid { c.Set("userId", claims["sub"]) } else { c.JSON(401, gin.H{"error": "token is not valid"}) c.Abort() return } } }
确保你已经安装了MySQL并且数据库配置正确,然后运行:
<SH>go run main.go
这个示例展示了如何使用Gin和GORM来创建一个简单的REST API,并包含基本的授权验证。你可以根据需要进一步扩展和优化代码。
USER:
我需要一段简单的Python的pygame写一个简单俄罗斯方块游戏
ASSISTANT:
好的,下面是一个简单的Python使用pygame库实现的俄罗斯方块游戏示例。这个示例包括基本的游戏逻辑和图形显示。
首先,你需要安装pygame库:
<SH>pip install pygame
创建一个新的Python文件,例如 tetris.py
,并在其中添加以下代码:
<PYTHON>import pygame import random # 初始化pygame pygame.init() # 屏幕大小 screen_width = 300 screen_height = 600 play_width = 300 play_height = 700 block_size = 30 top_left_x = (screen_width - play_width) // 2 top_left_y = (screen_height - play_height) // 2 # 屏幕颜色 black = (0, 0, 0) white = (255, 255, 255) red = (211, 211, 211) cyan = (0, 255, 255) blue = (0, 0, 255) orange = (255, 165, 0) yellow = (255, 255, 0) green = (0, 255, 0) purple = (128, 0, 128) # 方块形状 shapes = [ [[1, 1, 1], [0, 1, 0]], [[1, 1, 0], [0, 1, 1]], [[0, 1, 1], [1, 1, 0]], [[1, 1, 1, 1]] ] # 方块颜色 colors = [cyan, blue, orange, yellow, green, purple, red] class Piece(object): def __init__(self, x, y, shape): self.x = x self.y = y self.shape = shape self.color = colors[len(shapes) - len(self.shape)] self.rotation = 0 def create_grid(locked_positions={}): grid = [[black for _ in range(10)] for _ in range(20)] for y in range(20): for x in range(10): if (x, y) in locked_positions: c = locked_positions[(x, y)] grid[y][x] = c return grid def convert_shape_format(piece): positions = [] format = piece.shape[piece.rotation % len(piece.shape)] for i, line in enumerate(format): row = list(line) for j, column in enumerate(row): if column == 1: positions.append((piece.x + j, piece.y + i)) for i, pos in enumerate(positions): positions[i] = (pos[0] - 2, pos[1] - 4) return positions def valid_space(piece, grid): accepted_positions = [[(x, y) for x in range(10) if grid[y][x] == black] for y in range(20)] accepted_positions = [x for item in accepted_positions for x in item] formatted = convert_shape_format(piece) for pos in formatted: if pos not in accepted_positions: if pos[1] > -1: return False return True def check_lost(positions): for pos in positions: x, y = pos if y < 1: return True return False def get_shape(): return Piece(5, 0, random.choice(shapes)) def draw_text_middle(text, size, color, surface): font = pygame.font.Font(pygame.font.get_default_font(), size) label = font.render(text, True, color) surface.blit(label, (top_left_x + play_width // 2 - (label.get_width() // 2), top_left_y + play_height // 2 - label.get_height() // 2)) def draw_grid(surface, grid): for y in range(len(grid)): for x in range(len(grid[y])): pygame.draw.rect(surface, grid[y][x], (top_left_x + x * block_size, top_left_y + y * block_size), (block_size, block_size)) for y in range(len(grid)): pygame.draw.line(surface, white, (top_left_x, top_left_y + y * block_size), (top_left_x + play_width, top_left_y + y * block_size)) for x in range(len(grid[0])): pygame.draw.line(surface, white, (top_left_x + x * block_size, top_left_y), (top_left_x + x * block_size, top_left_y + play_height)) def clear_rows(grid, locked): increment = 0 for y in range(len(grid) - 1, -1, -1): row = grid[y] if black not in row: increment += 1 ind = y for x in range(len(row)): try: del locked[(x, y)] except: continue if increment > 0: for key in sorted(list(locked), key=lambda x: -x[1]): x, y = key if y < ind: newKey = (x, y + increment) locked[newKey] = locked.pop(key) return increment def draw_next_shape(piece, surface): font = pygame.font.Font(pygame.font.get_default_font(), 30) label = font.render('Next Shape', True, white) sx = top_left_x + play_width + 50 sy = top_left_y + (play_height // 2 - 10) format = piece.shape[piece.rotation % len(piece.shape)] for i, line in enumerate(format): row = list(line) for j, column in enumerate(row): if column == 1: pygame.draw.rect(surface, piece.color, (sx + j * block_size, sy + i * block_size), (block_size, block_size)) surface.blit(label, (sx + 10, sy - 30)) def draw_window(surface, grid, score=0): surface.fill(black) pygame.draw.rect(surface, white, (top_left_x, top_left_y), (play_width, play_height)) pygame.draw.rect(surface, white, (top_left_x + play_width + 10, top_left_y + 20), (200, 300)) draw_grid(surface, grid) draw_next_shape(next_piece, surface) pygame.draw.rect(surface, white, (top_left_x + play_width + 10, top_left_y + 270), (150, 50)) font = pygame.font.Font(pygame.font.get_default_font(), 60) label = font.render('Score', True, white) surface.blit(label, (top_left_x + play_width + 25, top_left_y + 290)) font = pygame.font.Font(pygame.font.get_default_font(), 80) label = font.render(str(score), True, white) surface.blit(label, (top_left_x + play_width + 35, top_left_y + 320)) def main(): locked_positions = {} grid = create_grid(locked_positions) change_piece = False run = True current_piece = get_shape() next_piece = get_shape() clock = pygame.time.Clock() fall_time = 0 while run: grid = create_grid(locked_positions) fall_speed = 0.27 fall_time += clock.get_rawtime() clock.tick() if fall_time / 1000 >= fall_speed: fall_time = 0 current_piece.y += 1 if not (valid_space(current_piece, grid)) and current_piece.y > 0: current_piece.y -= 1 change_piece = True for event in pygame.event.get(): if event.type == pygame.QUIT: run = False pygame.display.quit() if event.type == pygame.KEYDOWN: if event.key == pygame.K_LEFT: current_piece.x -= 1 if not valid_space(current_piece, grid): current_piece.x += 1 if event.key == pygame.K_RIGHT: current_piece.x += 1 if not valid_space(current_piece, grid): current_piece.x -= 1 if event.key == pygame.K_DOWN: current_piece.y += 1 if not valid_space(current_piece, grid): current_piece.y -= 1 if event.key == pygame.K_UP: current_piece.rotation = current_piece.rotation + 1 % len(current_piece.shape) if not valid_space(current_piece, grid): current_piece.rotation = current_piece.rotation - 1 % len(current_piece.shape) shape_format = [line for line in current_piece.shape[current_piece.rotation % len(current_piece.shape)]] for i, line in enumerate(shape_format): row = list(line) for j, column in enumerate(row): if column == 1: p = (current_piece.x + j, current_piece.y + i) if p in locked_positions: run = False if change_piece: for pos in [[0, 0], [0, 1], [1, 0], [1, 1]]: p = (current_piece.x + pos[0], current_piece.y + pos[1]) locked_positions[p] = current_piece.color change_piece = False score += clear_rows(grid, locked_positions) * 10 current_piece = next_piece next_piece = get_shape() if valid_space(current_piece, grid) == False: run = False draw_window(win, grid, score) pygame.display.update() if __name__ == "__main__": pygame.init() win = pygame.display.set_mode((720, 576)) pygame.display.set_caption('Tetris') main()
This code is a simple implementation of the Tetris game using Python and Pygame library. The game window displays the current state of the grid and the next shape to fall, as well as the score. The player can control the falling shapes with the arrow keys.
To run this code, you need to have Python and the Pygame library installed on your system. You can install Pygame using pip:
<TEXT>pip install pygame
After installing Pygame, save the code in a file named tetris.py
. Then, open a terminal or command prompt, navigate to the directory where you saved the file, and run the following command:
<TEXT>python tetris.py
This will start the Tetris game, and you can use the arrow keys to control the falling shapes. The game will end when a shape reaches the top of the grid or overlaps with another shape.