用鸿蒙HarmonyOS5实现中国象棋小游戏的过程
下面是一个基于鸿蒙OS (HarmonyOS) 的中国象棋小游戏的实现代码。这个实现使用Java语言和鸿蒙的Ability框架。
1. 项目结构
/src/main/java/com/example/chinesechess/├── MainAbilitySlice.java // 主界面逻辑├── ChessView.java // 游戏视图和逻辑├── ChessPiece.java // 棋子类└── resources/├── base/│ ├── layout/│ │ └── ability_main.xml // 布局文件│ └── graphic/│ └── board_bg.xml // 棋盘背景
2. 实现代码
ChessPiece.java (棋子类)
package com.example.chinesechess;public class ChessPiece {public static final int RED = 0;public static final int BLACK = 1;private int type; // 棋子类型private int color; // 棋子颜色private int row; // 行private int col; // 列public ChessPiece(int type, int color, int row, int col) {this.type = type;this.color = color;this.row = row;this.col = col;}// 棋子类型常量public static final int GENERAL = 0; // 将/帅public static final int ADVISOR = 1; // 士public static final int ELEPHANT = 2; // 象public static final int HORSE = 3; // 马public static final int CHARIOT = 4; // 车public static final int CANNON = 5; // 炮public static final int SOLDIER = 6; // 兵/卒// getter和setter方法public int getType() {return type;}public int getColor() {return color;}public int getRow() {return row;}public void setRow(int row) {this.row = row;}public int getCol() {return col;}public void setCol(int col) {this.col = col;}// 获取棋子名称public String getName() {String[] redNames = {"帅", "仕", "相", "马", "车", "炮", "兵"};String[] blackNames = {"将", "士", "象", "马", "车", "炮", "卒"};return color == RED ? redNames[type] : blackNames[type];}
}
ChessView.java (游戏视图和逻辑)
package com.example.chinesechess;import ohos.agp.components.Component;
import ohos.agp.render.Canvas;
import ohos.agp.render.Paint;
import ohos.agp.utils.Color;
import ohos.agp.utils.RectFloat;
import ohos.app.Context;
import ohos.agp.components.AttrSet;
import ohos.multimodalinput.event.TouchEvent;import java.util.ArrayList;
import java.util.List;public class ChessView extends Component implements Component.DrawTask {private static final int ROWS = 10; // 棋盘行数private static final int COLS = 9; // 棋盘列数private Paint linePaint; // 棋盘线画笔private Paint redPaint; // 红方棋子画笔private Paint blackPaint; // 黑方棋子画笔private Paint textPaint; // 文字画笔private Paint selectedPaint; // 选中状态画笔private List<ChessPiece> pieces; // 棋子列表private ChessPiece selectedPiece; // 当前选中的棋子private int currentPlayer = ChessPiece.RED; // 当前玩家public ChessView(Context context) {super(context);init();}public ChessView(Context context, AttrSet attrSet) {super(context, attrSet);init();}private void init() {linePaint = new Paint();linePaint.setColor(new Color(0xFF000000));linePaint.setStrokeWidth(2);redPaint = new Paint();redPaint.setColor(new Color(0xFFFF0000));redPaint.setStyle(Paint.Style.FILL_STYLE);blackPaint = new Paint();blackPaint.setColor(new Color(0xFF000000));blackPaint.setStyle(Paint.Style.FILL_STYLE);textPaint = new Paint();textPaint.setColor(new Color(0xFFFFFFFF));textPaint.setTextSize(40);textPaint.setTextAlign(Paint.Align.CENTER);selectedPaint = new Paint();selectedPaint.setColor(new Color(0x6600FF00));selectedPaint.setStyle(Paint.Style.FILL_STYLE);initPieces();addDrawTask(this);setTouchEventListener(this::onTouchEvent);}private void initPieces() {pieces = new ArrayList<>();// 初始化红方棋子pieces.add(new ChessPiece(ChessPiece.CHARIOT, ChessPiece.RED, 9, 0));pieces.add(new ChessPiece(ChessPiece.HORSE, ChessPiece.RED, 9, 1));pieces.add(new ChessPiece(ChessPiece.ELEPHANT, ChessPiece.RED, 9, 2));pieces.add(new ChessPiece(ChessPiece.ADVISOR, ChessPiece.RED, 9, 3));pieces.add(new ChessPiece(ChessPiece.GENERAL, ChessPiece.RED, 9, 4));pieces.add(new ChessPiece(ChessPiece.ADVISOR, ChessPiece.RED, 9, 5));pieces.add(new ChessPiece(ChessPiece.ELEPHANT, ChessPiece.RED, 9, 6));pieces.add(new ChessPiece(ChessPiece.HORSE, ChessPiece.RED, 9, 7));pieces.add(new ChessPiece(ChessPiece.CHARIOT, ChessPiece.RED, 9, 8));pieces.add(new ChessPiece(ChessPiece.CANNON, ChessPiece.RED, 7, 1));pieces.add(new ChessPiece(ChessPiece.CANNON, ChessPiece.RED, 7, 7));pieces.add(new ChessPiece(ChessPiece.SOLDIER, ChessPiece.RED, 6, 0));pieces.add(new ChessPiece(ChessPiece.SOLDIER, ChessPiece.RED, 6, 2));pieces.add(new ChessPiece(ChessPiece.SOLDIER, ChessPiece.RED, 6, 4));pieces.add(new ChessPiece(ChessPiece.SOLDIER, ChessPiece.RED, 6, 6));pieces.add(new ChessPiece(ChessPiece.SOLDIER, ChessPiece.RED, 6, 8));// 初始化黑方棋子pieces.add(new ChessPiece(ChessPiece.CHARIOT, ChessPiece.BLACK, 0, 0));pieces.add(new ChessPiece(ChessPiece.HORSE, ChessPiece.BLACK, 0, 1));pieces.add(new ChessPiece(ChessPiece.ELEPHANT, ChessPiece.BLACK, 0, 2));pieces.add(new ChessPiece(ChessPiece.ADVISOR, ChessPiece.BLACK, 0, 3));pieces.add(new ChessPiece(ChessPiece.GENERAL, ChessPiece.BLACK, 0, 4));pieces.add(new ChessPiece(ChessPiece.ADVISOR, ChessPiece.BLACK, 0, 5));pieces.add(new ChessPiece(ChessPiece.ELEPHANT, ChessPiece.BLACK, 0, 6));pieces.add(new ChessPiece(ChessPiece.HORSE, ChessPiece.BLACK, 0, 7));pieces.add(new ChessPiece(ChessPiece.CHARIOT, ChessPiece.BLACK, 0, 8));pieces.add(new ChessPiece(ChessPiece.CANNON, ChessPiece.BLACK, 2, 1));pieces.add(new ChessPiece(ChessPiece.CANNON, ChessPiece.BLACK, 2, 7));pieces.add(new ChessPiece(ChessPiece.SOLDIER, ChessPiece.BLACK, 3, 0));pieces.add(new ChessPiece(ChessPiece.SOLDIER, ChessPiece.BLACK, 3, 2));pieces.add(new ChessPiece(ChessPiece.SOLDIER, ChessPiece.BLACK, 3, 4));pieces.add(new ChessPiece(ChessPiece.SOLDIER, ChessPiece.BLACK, 3, 6));pieces.add(new ChessPiece(ChessPiece.SOLDIER, ChessPiece.BLACK, 3, 8));}@Overridepublic void onDraw(Component component, Canvas canvas) {int width = getWidth();int height = getHeight();float cellWidth = width / (float) COLS;float cellHeight = height / (float) ROWS;// 绘制棋盘drawBoard(canvas, width, height, cellWidth, cellHeight);// 绘制棋子drawPieces(canvas, cellWidth, cellHeight);}private void drawBoard(Canvas canvas, int width, int height, float cellWidth, float cellHeight) {// 绘制横线for (int i = 0; i < ROWS; i++) {float y = i * cellHeight;canvas.drawLine(0, y, width, y, linePaint);}// 绘制竖线for (int j = 0; j < COLS; j++) {float x = j * cellWidth;canvas.drawLine(x, 0, x, height, linePaint);}// 绘制楚河汉界float centerY = (ROWS / 2 - 0.5f) * cellHeight;canvas.drawText("楚河", width * 0.3f, centerY - 20, textPaint);canvas.drawText("汉界", width * 0.7f, centerY - 20, textPaint);// 绘制九宫格drawNinePalaces(canvas, cellWidth, cellHeight, 0); // 上方九宫格drawNinePalaces(canvas, cellWidth, cellHeight, 7); // 下方九宫格}private void drawNinePalaces(Canvas canvas, float cellWidth, float cellHeight, int startRow) {float left = 3 * cellWidth;float top = startRow * cellHeight;float right = 5 * cellWidth;float bottom = (startRow + 2) * cellHeight;// 绘制斜线canvas.drawLine(left, top, right, bottom, linePaint);canvas.drawLine(right, top, left, bottom, linePaint);}private void drawPieces(Canvas canvas, float cellWidth, float cellHeight) {for (ChessPiece piece : pieces) {float centerX = (piece.getCol() + 0.5f) * cellWidth;float centerY = (piece.getRow() + 0.5f) * cellHeight;float radius = Math.min(cellWidth, cellHeight) * 0.4f;// 绘制棋子背景Paint bgPaint = piece.getColor() == ChessPiece.RED ? redPaint : blackPaint;canvas.drawCircle(centerX, centerY, radius, bgPaint);// 绘制棋子文字textPaint.setColor(piece.getColor() == ChessPiece.RED ? Color.WHITE : Color.WHITE);canvas.drawText(piece.getName(), centerX, centerY + 15, textPaint);// 绘制选中状态if (piece == selectedPiece) {canvas.drawCircle(centerX, centerY, radius + 5, selectedPaint);}}}private boolean onTouchEvent(Component component, TouchEvent event) {if (event.getAction() == TouchEvent.PRIMARY_POINT_DOWN) {int width = getWidth();int height = getHeight();float cellWidth = width / (float) COLS;float cellHeight = height / (float) ROWS;int col = (int) (event.getPointerPosition(0).getX() / cellWidth);int row = (int) (event.getPointerPosition(0).getY() / cellHeight);if (row >= 0 && row < ROWS && col >= 0 && col < COLS) {handleClick(row, col);}}return true;}private void handleClick(int row, int col) {ChessPiece clickedPiece = getPieceAt(row, col);if (selectedPiece == null) {// 没有选中棋子时,尝试选中一个棋子if (clickedPiece != null && clickedPiece.getColor() == currentPlayer) {selectedPiece = clickedPiece;invalidate();}} else {// 已经选中了一个棋子if (clickedPiece != null && clickedPiece.getColor() == currentPlayer) {// 点击的是己方棋子,切换选中selectedPiece = clickedPiece;invalidate();} else {// 尝试移动棋子if (isValidMove(selectedPiece, row, col)) {// 如果目标位置有对方棋子,则吃掉if (clickedPiece != null) {pieces.remove(clickedPiece);// 检查是否将/帅被吃if (clickedPiece.getType() == ChessPiece.GENERAL) {gameOver(currentPlayer);return;}}// 移动棋子selectedPiece.setRow(row);selectedPiece.setCol(col);// 切换玩家currentPlayer = (currentPlayer == ChessPiece.RED) ? ChessPiece.BLACK : ChessPiece.RED;selectedPiece = null;invalidate();}}}}private ChessPiece getPieceAt(int row, int col) {for (ChessPiece piece : pieces) {if (piece.getRow() == row && piece.getCol() == col) {return piece;}}return null;}private boolean isValidMove(ChessPiece piece, int toRow, int toCol) {int fromRow = piece.getRow();int fromCol = piece.getCol();// 目标位置不能是己方棋子ChessPiece targetPiece = getPieceAt(toRow, toCol);if (targetPiece != null && targetPiece.getColor() == piece.getColor()) {return false;}// 根据棋子类型判断移动是否合法switch (piece.getType()) {case ChessPiece.GENERAL: // 将/帅return isValidGeneralMove(piece, fromRow, fromCol, toRow, toCol);case ChessPiece.ADVISOR: // 士return isValidAdvisorMove(piece, fromRow, fromCol, toRow, toCol);case ChessPiece.ELEPHANT: // 象return isValidElephantMove(piece, fromRow, fromCol, toRow, toCol);case ChessPiece.HORSE: // 马return isValidHorseMove(fromRow, fromCol, toRow, toCol);case ChessPiece.CHARIOT: // 车return isValidChariotMove(fromRow, fromCol, toRow, toCol);case ChessPiece.CANNON: // 炮return isValidCannonMove(fromRow, fromCol, toRow, toCol);case ChessPiece.SOLDIER: // 兵/卒return isValidSoldierMove(piece, fromRow, fromCol, toRow, toCol);default:return false;}}private boolean isValidGeneralMove(ChessPiece piece, int fromRow, int fromCol, int toRow, int toCol) {// 将/帅只能在九宫格内移动if (piece.getColor() == ChessPiece.RED) {if (toRow < 7 || toRow > 9 || toCol < 3 || toCol > 5) {return false;}} else {if (toRow < 0 || toRow > 2 || toCol < 3 || toCol > 5) {return false;}}// 将/帅每次只能走一格直线int rowDiff = Math.abs(toRow - fromRow);int colDiff = Math.abs(toCol - fromCol);if ((rowDiff == 1 && colDiff == 0) || (rowDiff == 0 && colDiff == 1)) {return true;}// 将帅对面特殊情况if (fromCol == toCol && colDiff == 0) {ChessPiece target = getPieceAt(toRow, toCol);if (target != null && target.getType() == ChessPiece.GENERAL && target.getColor() != piece.getColor()) {// 检查中间是否有其他棋子int minRow = Math.min(fromRow, toRow);int maxRow = Math.max(fromRow, toRow);for (int r = minRow + 1; r < maxRow; r++) {if (getPieceAt(r, fromCol) != null) {return false;}}return true;}}return false;}private boolean isValidAdvisorMove(ChessPiece piece, int fromRow, int fromCol, int toRow, int toCol) {// 士只能在九宫格内移动if (piece.getColor() == ChessPiece.RED) {if (toRow < 7 || toRow > 9 || toCol < 3 || toCol > 5) {return false;}} else {if (toRow < 0 || toRow > 2 || toCol < 3 || toCol > 5) {return false;}}// 士每次只能走一格斜线int rowDiff = Math.abs(toRow - fromRow);int colDiff = Math.abs(toCol - fromCol);return rowDiff == 1 && colDiff == 1;}private boolean isValidElephantMove(ChessPiece piece, int fromRow, int fromCol, int toRow, int toCol) {// 象不能过河if (piece.getColor() == ChessPiece.RED && toRow < 5) {return false;}if (piece.getColor() == ChessPiece.BLACK && toRow > 4) {return false;}// 象走田字int rowDiff = Math.abs(toRow - fromRow);int colDiff = Math.abs(toCol - fromCol);if (rowDiff == 2 && colDiff == 2) {// 检查象眼是否被堵int eyeRow = (fromRow + toRow) / 2;int eyeCol = (fromCol + toCol) / 2;return getPieceAt(eyeRow, eyeCol) == null;}return false;}private boolean isValidHorseMove(int fromRow, int fromCol, int toRow, int toCol) {int rowDiff = Math.abs(toRow - fromRow);int colDiff = Math.abs(toCol - fromCol);// 马走日if ((rowDiff == 2 && colDiff == 1) || (rowDiff == 1 && colDiff == 2)) {// 检查马腿是否被堵if (rowDiff == 2) {int middleRow = (fromRow + toRow) / 2;return getPieceAt(middleRow, fromCol) == null;} else {int middleCol = (fromCol + toCol) / 2;return getPieceAt(fromRow, middleCol) == null;}}return false;}private boolean isValidChariotMove(int fromRow, int fromCol, int toRow, int toCol) {// 车走直线if (fromRow != toRow && fromCol != toCol) {return false;}// 检查路径上是否有其他棋子if (fromRow == toRow) {int minCol = Math.min(fromCol, toCol);int maxCol = Math.max(fromCol, toCol);for (int c = minCol + 1; c < maxCol; c++) {if (getPieceAt(fromRow, c) != null) {return false;}}} else {int minRow = Math.min(fromRow, toRow);int maxRow = Math.max(fromRow, toRow);for (int r = minRow + 1; r < maxRow; r++) {if (getPieceAt(r, fromCol) != null) {return false;}}}return true;}private boolean isValidCannonMove(int fromRow, int fromCol, int toRow, int toCol) {// 炮走直线if (fromRow != toRow && fromCol != toCol) {return false;}ChessPiece targetPiece = getPieceAt(toRow, toCol);int pieceCount = 0;// 计算路径上的棋子数量if (fromRow == toRow) {int minCol = Math.min(fromCol, toCol);int maxCol = Math.max(fromCol, toCol);for (int c = minCol + 1; c < maxCol; c++) {if (getPieceAt(fromRow, c) != null) {pieceCount++;}}} else {int minRow = Math.min(fromRow, toRow);int maxRow = Math.max(fromRow, toRow);for (int r = minRow + 1; r < maxRow; r++) {if (getPieceAt(r, fromCol) != null) {pieceCount++;}}}// 炮移动时不能有棋子阻挡if (targetPiece == null) {return pieceCount == 0;}// 炮吃子时必须有一个棋子作为炮架else {return pieceCount == 1;}}private boolean isValidSoldierMove(ChessPiece piece, int fromRow, int fromCol, int toRow, int toCol) {int rowDiff = toRow - fromRow;int colDiff = Math.abs(toCol - fromCol);if (piece.getColor() == ChessPiece.RED) {// 红方兵向上走if (rowDiff != -1) {return false;}} else {// 黑方卒向下走if (rowDiff != 1) {return false;}}// 未过河只能向前if ((piece.getColor() == ChessPiece.RED && fromRow > 4) || (piece.getColor() == ChessPiece.BLACK && fromRow < 5)) {return colDiff == 0;}// 过河后可以左右移动else {return colDiff == 0 || colDiff == 1;}}private void gameOver(int winner) {String message = (winner == ChessPiece.RED) ? "红方胜利!" : "黑方胜利!";if (getContext() instanceof MainAbilitySlice) {((MainAbilitySlice) getContext()).showGameOverDialog(message);}// 重置游戏initPieces();currentPlayer = ChessPiece.RED;selectedPiece = null;invalidate();}public void resetGame() {initPieces();currentPlayer = ChessPiece.RED;selectedPiece = null;invalidate();}
}
MainAbilitySlice.java (主界面)
package com.example.chinesechess;import ohos.aafwk.ability.AbilitySlice;
import ohos.aafwk.content.Intent;
import ohos.agp.components.*;
import ohos.agp.window.dialog.ToastDialog;
import ohos.agp.components.DirectionalLayout;
import ohos.agp.components.Text;
import ohos.agp.components.Button;public class MainAbilitySlice extends AbilitySlice {private ChessView chessView;private Text statusText;@Overridepublic void onStart(Intent intent) {super.onStart(intent);DirectionalLayout layout = new DirectionalLayout(this);layout.setOrientation(DirectionalLayout.VERTICAL);// 状态文本statusText = new Text(this);statusText.setText("当前回合: 红方");statusText.setTextSize(50);statusText.setPadding(10, 10, 10, 10);// 象棋视图chessView = new ChessView(this);// 按钮布局DirectionalLayout buttonLayout = new DirectionalLayout(this);buttonLayout.setOrientation(DirectionalLayout.HORIZONTAL);buttonLayout.setPadding(10, 10, 10, 10);// 重新开始按钮Button resetButton = new Button(this);resetButton.setText("重新开始");resetButton.setClickedListener(component -> {chessView.resetGame();statusText.setText("当前回合: 红方");});// 悔棋按钮Button undoButton = new Button(this);undoButton.setText("悔棋");undoButton.setClickedListener(component -> {// 悔棋功能待实现new ToastDialog(this).setText("悔棋功能待实现").show();});buttonLayout.addComponent(resetButton);buttonLayout.addComponent(undoButton);layout.addComponent(statusText);layout.addComponent(chessView);layout.addComponent(buttonLayout);super.setUIContent(layout);}public void showGameOverDialog(String message) {new ToastDialog(this).setText(message).show();statusText.setText("游戏结束 - " + message);}
}
ability_main.xml (布局文件)
<?xml version="1.0" encoding="utf-8"?>
<DirectionalLayoutxmlns:ohos="http://schemas.huawei.com/res/ohos"ohos:width="match_parent"ohos:height="match_parent"ohos:orientation="vertical"><Textohos:id="$+id:status_text"ohos:width="match_parent"ohos:height="50vp"ohos:text="当前回合: 红方"ohos:text_size="20fp"ohos:padding="10vp"/><com.example.chinesechess.ChessViewohos:id="$+id:chess_view"ohos:width="match_parent"ohos:height="0vp"ohos:weight="1"/><DirectionalLayoutohos:id="$+id:button_layout"ohos:width="match_parent"ohos:height="wrap_content"ohos:orientation="horizontal"ohos:padding="10vp"><Buttonohos:id="$+id:reset_button"ohos:width="0vp"ohos:height="50vp"ohos:weight="1"ohos:text="重新开始"ohos:margin="5vp"/><Buttonohos:id="$+id:undo_button"ohos:width="0vp"ohos:height="50vp"ohos:weight="1"ohos:text="悔棋"ohos:margin="5vp"/></DirectionalLayout>
</DirectionalLayout>
3. 功能说明
- 游戏规则:标准中国象棋规则
- 棋子类型:
- 将/帅、士、象、马、车、炮、兵/卒
- 界面元素:
- 棋盘:9×10网格,包含楚河汉界和九宫格
- 棋子:红黑两色,带有汉字标识
- 状态显示:当前回合信息
- 操作按钮:重新开始、悔棋(待实现)
- 交互:
- 点击选中棋子
- 再次点击目标位置移动棋子
- 自动判断移动是否合法
- 自动判断胜负
相关文章:
用鸿蒙HarmonyOS5实现中国象棋小游戏的过程
下面是一个基于鸿蒙OS (HarmonyOS) 的中国象棋小游戏的实现代码。这个实现使用Java语言和鸿蒙的Ability框架。 1. 项目结构 /src/main/java/com/example/chinesechess/├── MainAbilitySlice.java // 主界面逻辑├── ChessView.java // 游戏视图和逻辑├──…...
MFE(微前端) Module Federation:Webpack.config.js文件中每个属性的含义解释
以Module Federation 插件详为例,Webpack.config.js它可能的配置和含义如下: 前言 Module Federation 的Webpack.config.js核心配置包括: name filename(定义应用标识) remotes(引用远程模块࿰…...

stm32wle5 lpuart DMA数据不接收
配置波特率9600时,需要使用外部低速晶振...

Unity中的transform.up
2025年6月8日,周日下午 在Unity中,transform.up是Transform组件的一个属性,表示游戏对象在世界空间中的“上”方向(Y轴正方向),且会随对象旋转动态变化。以下是关键点解析: 基本定义 transfor…...
Java求职者面试指南:Spring、Spring Boot、Spring MVC与MyBatis技术解析
Java求职者面试指南:Spring、Spring Boot、Spring MVC与MyBatis技术解析 一、第一轮基础概念问题 1. Spring框架的核心容器是什么?它的作用是什么? Spring框架的核心容器是IoC(控制反转)容器。它的主要作用是管理对…...
SpringAI实战:ChatModel智能对话全解
一、引言:Spring AI 与 Chat Model 的核心价值 🚀 在 Java 生态中集成大模型能力,Spring AI 提供了高效的解决方案 🤖。其中 Chat Model 作为核心交互组件,通过标准化接口简化了与大语言模型(LLM࿰…...
Python 高效图像帧提取与视频编码:实战指南
Python 高效图像帧提取与视频编码:实战指南 在音视频处理领域,图像帧提取与视频编码是基础但极具挑战性的任务。Python 结合强大的第三方库(如 OpenCV、FFmpeg、PyAV),可以高效处理视频流,实现快速帧提取、压缩编码等关键功能。本文将深入介绍如何优化这些流程,提高处理…...

Elastic 获得 AWS 教育 ISV 合作伙伴资质,进一步增强教育解决方案产品组合
作者:来自 Elastic Udayasimha Theepireddy (Uday), Brian Bergholm, Marianna Jonsdottir 通过搜索 AI 和云创新推动教育领域的数字化转型。 我们非常高兴地宣布,Elastic 已获得 AWS 教育 ISV 合作伙伴资质。这一重要认证表明,Elastic 作为 …...
Python竞赛环境搭建全攻略
Python环境搭建竞赛技术文章大纲 竞赛背景与意义 竞赛的目的与价值Python在竞赛中的应用场景环境搭建对竞赛效率的影响 竞赛环境需求分析 常见竞赛类型(算法、数据分析、机器学习等)不同竞赛对Python版本及库的要求硬件与操作系统的兼容性问题 Pyth…...
华为OD最新机试真题-数组组成的最小数字-OD统一考试(B卷)
题目描述 给定一个整型数组,请从该数组中选择3个元素 组成最小数字并输出 (如果数组长度小于3,则选择数组中所有元素来组成最小数字)。 输入描述 行用半角逗号分割的字符串记录的整型数组,0<数组长度<= 100,0<整数的取值范围<= 10000。 输出描述 由3个元素组成…...

MySQL的pymysql操作
本章是MySQL的最后一章,MySQL到此完结,下一站Hadoop!!! 这章很简单,完整代码在最后,详细讲解之前python课程里面也有,感兴趣的可以往前找一下 一、查询操作 我们需要打开pycharm …...

渗透实战PortSwigger靶场:lab13存储型DOM XSS详解
进来是需要留言的,先用做简单的 html 标签测试 发现面的</h1>不见了 数据包中找到了一个loadCommentsWithVulnerableEscapeHtml.js 他是把用户输入的<>进行 html 编码,输入的<>当成字符串处理回显到页面中,看来只是把用户输…...
API网关Kong的鉴权与限流:高并发场景下的核心实践
🔥「炎码工坊」技术弹药已装填! 点击关注 → 解锁工业级干货【工具实测|项目避坑|源码燃烧指南】 引言 在微服务架构中,API网关承担着流量调度、安全防护和协议转换的核心职责。作为云原生时代的代表性网关,Kong凭借其插件化架构…...

[论文阅读]TrustRAG: Enhancing Robustness and Trustworthiness in RAG
TrustRAG: Enhancing Robustness and Trustworthiness in RAG [2501.00879] TrustRAG: Enhancing Robustness and Trustworthiness in Retrieval-Augmented Generation 代码:HuichiZhou/TrustRAG: Code for "TrustRAG: Enhancing Robustness and Trustworthin…...

水泥厂自动化升级利器:Devicenet转Modbus rtu协议转换网关
在水泥厂的生产流程中,工业自动化网关起着至关重要的作用,尤其是JH-DVN-RTU疆鸿智能Devicenet转Modbus rtu协议转换网关,为水泥厂实现高效生产与精准控制提供了有力支持。 水泥厂设备众多,其中不少设备采用Devicenet协议。Devicen…...

Linux中《基础IO》详细介绍
目录 理解"文件"狭义理解广义理解文件操作的归类认知系统角度文件类别 回顾C文件接口打开文件写文件读文件稍作修改,实现简单cat命令 输出信息到显示器,你有哪些方法stdin & stdout & stderr打开文件的方式 系统⽂件I/O⼀种传递标志位…...

【Veristand】Veristand环境安装教程-Linux RT / Windows
首先声明,此教程是针对Simulink编译模型并导入Veristand中编写的,同时需要注意的是老用户编译可能用的是Veristand Model Framework,那个是历史版本,且NI不会再维护,新版本编译支持为VeriStand Model Generation Suppo…...

Ubuntu系统多网卡多相机IP设置方法
目录 1、硬件情况 2、如何设置网卡和相机IP 2.1 万兆网卡连接交换机,交换机再连相机 2.1.1 网卡设置 2.1.2 相机设置 2.3 万兆网卡直连相机 1、硬件情况 2个网卡n个相机 电脑系统信息,系统版本:Ubuntu22.04.5 LTS;内核版本…...

《Docker》架构
文章目录 架构模式单机架构应用数据分离架构应用服务器集群架构读写分离/主从分离架构冷热分离架构垂直分库架构微服务架构容器编排架构什么是容器,docker,镜像,k8s 架构模式 单机架构 单机架构其实就是应用服务器和单机服务器都部署在同一…...
上位机开发过程中的设计模式体会(1):工厂方法模式、单例模式和生成器模式
简介 在我的 QT/C 开发工作中,合理运用设计模式极大地提高了代码的可维护性和可扩展性。本文将分享我在实际项目中应用的三种创造型模式:工厂方法模式、单例模式和生成器模式。 1. 工厂模式 (Factory Pattern) 应用场景 在我的 QT 项目中曾经有一个需…...

ubuntu22.04有线网络无法连接,图标也没了
今天突然无法有线网络无法连接任何设备,并且图标都没了 错误案例 往上一顿搜索,试了很多博客都不行,比如 Ubuntu22.04右上角网络图标消失 最后解决的办法 下载网卡驱动,重新安装 操作步骤 查看自己网卡的型号 lspci | gre…...

【堆垛策略】设计方法
堆垛策略的设计是积木堆叠系统的核心,直接影响堆叠的稳定性、效率和容错能力。以下是分层次的堆垛策略设计方法,涵盖基础规则、优化算法和容错机制: 1. 基础堆垛规则 (1) 物理稳定性优先 重心原则: 大尺寸/重量积木在下…...
小木的算法日记-多叉树的递归/层序遍历
🌲 从二叉树到森林:一文彻底搞懂多叉树遍历的艺术 🚀 引言 你好,未来的算法大神! 在数据结构的世界里,“树”无疑是最核心、最迷人的概念之一。我们中的大多数人都是从 二叉树 开始入门的,它…...

消息队列系统设计与实践全解析
文章目录 🚀 消息队列系统设计与实践全解析🔍 一、消息队列选型1.1 业务场景匹配矩阵1.2 吞吐量/延迟/可靠性权衡💡 权衡决策框架 1.3 运维复杂度评估🔧 运维成本降低策略 🏗️ 二、典型架构设计2.1 分布式事务最终一致…...

ubuntu系统文件误删(/lib/x86_64-linux-gnu/libc.so.6)修复方案 [成功解决]
报错信息:libc.so.6: cannot open shared object file: No such file or directory: #ls, ln, sudo...命令都不能用 error while loading shared libraries: libc.so.6: cannot open shared object file: No such file or directory重启后报错信息&…...
Modbus RTU与Modbus TCP详解指南
目录 1. Modbus协议基础 1.1 什么是Modbus? 1.2 Modbus协议历史 1.3 Modbus协议族 1.4 Modbus通信模型 🎭 主从架构 🔄 请求响应模式 2. Modbus RTU详解 2.1 RTU是什么? 2.2 RTU物理层 🔌 连接方式 ⚡ 通信参数 2.3 RTU数据帧格式 📦 帧结构详解 🔍…...
云原生周刊:k0s 成为 CNCF 沙箱项目
开源项目推荐 HAMi HAMi(原名 k8s‑vGPU‑scheduler)是一款 CNCF Sandbox 级别的开源 K8s 中间件,通过虚拟化 GPU/NPU 等异构设备并支持内存、计算核心时间片隔离及共享调度,为容器提供统一接口,实现细粒度资源配额…...
0x-3-Oracle 23 ai-sqlcl 25.1 集成安装-配置和优化
是不是受够了安装了oracle database之后sqlplus的简陋,无法删除无法上下翻页的苦恼。 可以安装readline和rlwrap插件的话,配置.bahs_profile后也能解决上下翻页这些,但是很多生产环境无法安装rpm包。 oracle提供了sqlcl免费许可,…...
6个月Python学习计划 Day 16 - 面向对象编程(OOP)基础
第三周 Day 3 🎯 今日目标 理解类(class)和对象(object)的关系学会定义类的属性、方法和构造函数(init)掌握对象的创建与使用初识封装、继承和多态的基本概念(预告) &a…...
k8s从入门到放弃之HPA控制器
k8s从入门到放弃之HPA控制器 Kubernetes中的Horizontal Pod Autoscaler (HPA)控制器是一种用于自动扩展部署、副本集或复制控制器中Pod数量的机制。它可以根据观察到的CPU利用率(或其他自定义指标)来调整这些对象的规模,从而帮助应用程序在负…...