forms实现连连看

news2025/7/12 23:30:47

说明:
forms实现连连看
效果图:
在这里插入图片描述

step1:C:\Users\wangrusheng\RiderProjects\WinFormsApp2\WinFormsApp2\Form1.cs

  using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Windows.Forms;

namespace WinFormsApp2
{
    public partial class Form1 : Form
    {
        private const int ROWS = 12;
        private const int COLS = 12;
        private const int CELL_SIZE = 40;
        private const int BORDER = 1;
        
        private readonly string[] EMOJI_LIST = {
            "🐶", "🐱", "🐭", "🐹", "🐰", "🦊", "🐻", "🐼",
            "🐨", "🐯", "🦁", "🐮", "🐷", "🐸", "🐵", "🐧"
        };

        private Button[,] grid = new Button[ROWS, COLS];
        private int[,] board = new int[ROWS, COLS];
        private Point? firstSelection = null;
        private List<Point> currentPath = null;
        private System.Windows.Forms.Timer pathTimer = new System.Windows.Forms.Timer();
        private int score = 0;
        private List<Point> hintPair = new List<Point>();
        private System.Windows.Forms.Timer hintTimer = new System.Windows.Forms.Timer();

        public Form1()
        {
            InitializeComponent();
            InitializeGameBoard();
            SetupControls();
            
            pathTimer.Interval = 500;
            pathTimer.Tick += (s, e) => ClearPath();
            hintTimer.Interval = 2000;
            hintTimer.Tick += (s, e) => ClearHint();
            
            this.DoubleBuffered = true;
            this.ClientSize = new Size(COLS * CELL_SIZE, ROWS * CELL_SIZE + 60);
        }

        private void SetupControls()
        {
            // Score Label
            var lblScore = new Label
            {
                Name = "lblScore",
                Location = new Point(10, ROWS * CELL_SIZE + 10),
                AutoSize = true,
                Text = "得分: 0"
            };

            // Restart Button
            var btnRestart = new Button
            {
                Text = "重新开始",
                Location = new Point(100, ROWS * CELL_SIZE + 10),
                Size = new Size(80, 30)
            };
            btnRestart.Click += (s, e) => RestartGame();

            // Hint Button
            var btnHint = new Button
            {
                Text = "提示",
                Location = new Point(200, ROWS * CELL_SIZE + 10),
                Size = new Size(80, 30)
            };
            btnHint.Click += (s, e) => ShowHint();

            Controls.AddRange(new Control[] { lblScore, btnRestart, btnHint });
        }

        private void InitializeGameBoard()
        {
            int innerRows = ROWS - 2 * BORDER;
            int innerCols = COLS - 2 * BORDER;
            int totalInner = innerRows * innerCols;

            List<int> tileList = new List<int>();
            for (int i = 0; i < totalInner / 2; i++)
            {
                int index = i % EMOJI_LIST.Length;
                tileList.Add(index);
                tileList.Add(index);
            }

            var rand = new Random();
            tileList = tileList.OrderBy(x => rand.Next()).ToList();

            int tileIndex = 0;
            for (int i = 0; i < ROWS; i++)
            {
                for (int j = 0; j < COLS; j++)
                {
                    var btn = new Button
                    {
                        Size = new Size(CELL_SIZE, CELL_SIZE),
                        Location = new Point(j * CELL_SIZE, i * CELL_SIZE),
                        Tag = new Point(i, j),
                        Font = new Font("Segoe UI Emoji", 12),
                        FlatStyle = FlatStyle.Flat
                    };
                    btn.Click += Button_Click;

                    if (IsBorder(i, j))
                    {
                        board[i, j] = -1;
                        btn.Enabled = false;
                        btn.BackColor = Color.Gray;
                    }
                    else
                    {
                        board[i, j] = tileList[tileIndex++];
                        btn.Text = EMOJI_LIST[board[i, j]];
                    }

                    grid[i, j] = btn;
                    Controls.Add(btn);
                }
            }
        }

        private void Button_Click(object sender, EventArgs e)
        {
            var btn = (Button)sender;
            var pos = (Point)btn.Tag;
            
            if (board[pos.X, pos.Y] == -1) return;

            if (firstSelection == null)
            {
                firstSelection = pos;
                btn.BackColor = Color.LightBlue;
            }
            else
            {
                var second = pos;
                if (firstSelection == second)
                {
                    ClearSelection();
                    return;
                }

                var p1 = firstSelection.Value;
                var p2 = second;

                if (board[p1.X, p1.Y] == board[p2.X, p2.Y] && CheckConnection(p1, p2))
                {
                    currentPath = GetConnectionPath(p1, p2);
                    pathTimer.Start();
                    Invalidate();

                    board[p1.X, p1.Y] = -1;
                    board[p2.X, p2.Y] = -1;
                    grid[p1.X, p1.Y].Text = "";
                    grid[p2.X, p2.Y].Text = "";
                    score += 10;
                    UpdateScore();
                }

                ClearSelection();
            }
        }

        private bool CheckConnection(Point p1, Point p2)
        {
            if (DirectConnection(p1, p2)) return true;
            if (OneTurnConnection(p1, p2)) return true;
            return TwoTurnConnection(p1, p2);
        }

        private bool DirectConnection(Point a, Point b)
        {
            if (a.X == b.X)
            {
                int minY = Math.Min(a.Y, b.Y);
                int maxY = Math.Max(a.Y, b.Y);
                for (int y = minY + 1; y < maxY; y++)
                {
                    if (board[a.X, y] != -1) return false;
                }
                return true;
            }

            if (a.Y == b.Y)
            {
                int minX = Math.Min(a.X, b.X);
                int maxX = Math.Max(a.X, b.X);
                for (int x = minX + 1; x < maxX; x++)
                {
                    if (board[x, a.Y] != -1) return false;
                }
                return true;
            }

            return false;
        }

        private bool OneTurnConnection(Point a, Point b)
        {
            var corner1 = new Point(a.X, b.Y);
            if (board[corner1.X, corner1.Y] == -1)
            {
                if (DirectConnection(a, corner1) && DirectConnection(corner1, b)) return true;
            }

            var corner2 = new Point(b.X, a.Y);
            if (board[corner2.X, corner2.Y] == -1)
            {
                if (DirectConnection(a, corner2) && DirectConnection(corner2, b)) return true;
            }

            return false;
        }

        private bool TwoTurnConnection(Point a, Point b)
        {
            // Horizontal scan
            for (int x = 0; x < ROWS; x++)
            {
                var p1 = new Point(x, a.Y);
                var p2 = new Point(x, b.Y);
                if (board[p1.X, p1.Y] == -1 && board[p2.X, p2.Y] == -1)
                {
                    if (DirectConnection(a, p1) && DirectConnection(p1, p2) && DirectConnection(p2, b))
                        return true;
                }
            }

            // Vertical scan
            for (int y = 0; y < COLS; y++)
            {
                var p1 = new Point(a.X, y);
                var p2 = new Point(b.X, y);
                if (board[p1.X, p1.Y] == -1 && board[p2.X, p2.Y] == -1)
                {
                    if (DirectConnection(a, p1) && DirectConnection(p1, p2) && DirectConnection(p2, b))
                        return true;
                }
            }

            return false;
        }

        private List<Point> GetConnectionPath(Point a, Point b)
        {
            var path = new List<Point> { a };

            if (DirectConnection(a, b))
            {
                path.Add(b);
                return path;
            }

            if (OneTurnConnection(a, b))
            {
                if (board[a.X, b.Y] == -1)
                {
                    path.Add(new Point(a.X, b.Y));
                }
                else
                {
                    path.Add(new Point(b.X, a.Y));
                }
                path.Add(b);
                return path;
            }

            // For two-turn connection (simplified path)
            path.Add(a);
            path.Add(b);
            return path;
        }

        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);
            if (currentPath != null && currentPath.Count >= 2)
            {
                using (var pen = new Pen(Color.Blue, 4))
                {
                    var points = currentPath.Select(p => 
                        new Point(p.Y * CELL_SIZE + CELL_SIZE/2, p.X * CELL_SIZE + CELL_SIZE/2)).ToArray();
                    e.Graphics.DrawLines(pen, points);
                }
            }

            // Draw hint
            if (hintPair.Count == 2)
            {
                using (var pen = new Pen(Color.Gold, 4))
                {
                    var points = hintPair.Select(p => 
                        new Point(p.Y * CELL_SIZE + CELL_SIZE/2, p.X * CELL_SIZE + CELL_SIZE/2)).ToArray();
                    e.Graphics.DrawLines(pen, points);
                }
            }
        }

        private void ShowHint()
        {
            for (int i = BORDER; i < ROWS - BORDER; i++)
            {
                for (int j = BORDER; j < COLS - BORDER; j++)
                {
                    if (board[i, j] == -1) continue;

                    for (int x = i; x < ROWS - BORDER; x++)
                    {
                        for (int y = (x == i ? j + 1 : BORDER); y < COLS - BORDER; y++)
                        {
                            if (board[x, y] == board[i, j] && CheckConnection(new Point(i, j), new Point(x, y)))
                            {
                                hintPair = new List<Point> { new Point(i, j), new Point(x, y) };
                                hintTimer.Start();
                                Invalidate();
                                return;
                            }
                        }
                    }
                }
            }
        }

        private void ClearPath() => currentPath = null;
        private void ClearHint() => hintPair.Clear();
        private void UpdateScore() => Controls["lblScore"].Text = $"得分: {score}";
        private bool IsBorder(int x, int y) => x < BORDER || y < BORDER || x >= ROWS - BORDER || y >= COLS - BORDER;
        private void ClearSelection()
        {
            if (firstSelection != null)
                grid[firstSelection.Value.X, firstSelection.Value.Y].BackColor = DefaultBackColor;
            firstSelection = null;
        }

        private void RestartGame()
        {
            Controls.OfType<Button>().Where(b => b.Tag != null).ToList().ForEach(b => Controls.Remove(b));
            board = new int[ROWS, COLS];
            grid = new Button[ROWS, COLS];
            score = 0;
            UpdateScore();
            InitializeGameBoard();
            ClearPath();
            ClearHint();
        }
    }
}

备选方案: 纯数字版

 namespace WinFormsApp2
{
public partial class Form1 : Form
{
// Board dimensions (include a border to simplify connection checking)
private int rows = 12; // for example, 12 rows (including border)
private int cols = 12; // 12 columns (including border)
private int cellSize = 40; // pixel size for each button

// Game grid of buttons and underlying board values.
    private Button[,] grid;
    private int[,] board;

    // To store the first and second selected positions
    private Point? firstSelection = null;

    public Form1()
    {
        InitializeComponent();
        InitializeGameBoard();
    }

    // Initializes the game board with a border and fills the inner cells with matching pairs.
    private void InitializeGameBoard()
    {
        grid = new Button[rows, cols];
        board = new int[rows, cols];

        // Calculate total inner cells (excluding borders) and make sure they form pairs.
        int innerRows = rows - 2;
        int innerCols = cols - 2;
        int totalInner = innerRows * innerCols;
        if(totalInner % 2 != 0)
        {
            MessageBox.Show("Total number of inner cells must be even.");
            return;
        }

        // Prepare list of pairs (here we simply use numbers to represent different tiles)
        List<int> tileList = new List<int>();
        for (int i = 0; i < totalInner / 2; i++)
        {
            tileList.Add(i);
            tileList.Add(i);
        }

        // Shuffle the tile list randomly
        Random rand = new Random();
        tileList = tileList.OrderBy(x => rand.Next()).ToList();

        // Create buttons and assign values
        int index = 0;
        for (int i = 0; i < rows; i++)
        {
            for (int j = 0; j < cols; j++)
            {
                Button btn = new Button();
                btn.Width = cellSize;
                btn.Height = cellSize;
                btn.Location = new Point(j * cellSize, i * cellSize);
                btn.Tag = new Point(i, j);
                btn.Click += Button_Click;
                grid[i, j] = btn;
                this.Controls.Add(btn);

                // Create a border: outside the inner grid, set value to -1 (indicating an always-empty cell)
                if (i == 0 || j == 0 || i == rows - 1 || j == cols - 1)
                {
                    board[i, j] = -1;
                    btn.Enabled = false; // disable border buttons
                    btn.BackColor = Color.Gray;
                }
                else
                {
                    board[i, j] = tileList[index];
                    index++;
                    // Display the tile value (in a final game you would show an image/icon)
                    btn.Text = board[i, j].ToString();
                }
            }
        }
    }

    // Handles button click events for selecting tiles.
    private void Button_Click(object sender, EventArgs e)
    {
        Button btn = sender as Button;
        Point pos = (Point)btn.Tag;
        int x = pos.X;
        int y = pos.Y;

        // Ignore clicks on empty cells (or border cells)
        if (board[x, y] == -1 || string.IsNullOrEmpty(btn.Text))
            return;

        if (firstSelection == null)
        {
            // First tile selected
            firstSelection = pos;
            btn.BackColor = Color.Yellow;
        }
        else
        {
            // Second tile selected
            Point secondSelection = pos;

            // If user clicked the same tile, just ignore
            if (firstSelection.Value == secondSelection)
                return;

            // Check if the two tiles have the same value.
            Point p1 = firstSelection.Value;
            Point p2 = secondSelection;
            if (board[p1.X, p1.Y] != board[p2.X, p2.Y])
            {
                // Not a matching pair. Reset first tile's highlight and choose the new one.
                grid[p1.X, p1.Y].BackColor = default(Color);
                firstSelection = secondSelection;
                btn.BackColor = Color.Yellow;
            }
            else
            {
                // Same value: check if they can be connected
                if (CheckConnectivity(p1, p2))
                {
                    // Connection is valid: remove the tiles.
                    board[p1.X, p1.Y] = -1;
                    board[p2.X, p2.Y] = -1;
                    grid[p1.X, p1.Y].Text = "";
                    grid[p2.X, p2.Y].Text = "";
                    grid[p1.X, p1.Y].BackColor = default(Color);
                    grid[p2.X, p2.Y].BackColor = default(Color);
                }
                else
                {
                    // Cannot connect: reset the highlight.
                    grid[p1.X, p1.Y].BackColor = default(Color);
                }
                // Reset selection for next pair.
                firstSelection = null;
            }
        }
    }

    // Checks whether two positions can be connected using at most two turns.
    private bool CheckConnectivity(Point p1, Point p2)
    {
        // 1. Direct connection check: same row or same column.
        if (DirectConnection(p1, p2))
            return true;
        // 2. Check connection with one turn.
        if (OneTurnConnection(p1, p2))
            return true;
        // 3. Check connection with two turns.
        if (TwoTurnConnection(p1, p2))
            return true;
        return false;
    }

    // Direct connection: both positions on the same row or column and the cells between them are empty.
    private bool DirectConnection(Point p1, Point p2)
    {
        if (p1.X == p2.X)
        {
            int minY = Math.Min(p1.Y, p2.Y);
            int maxY = Math.Max(p1.Y, p2.Y);
            for (int j = minY + 1; j < maxY; j++)
            {
                if (board[p1.X, j] != -1)
                    return false;
            }
            return true;
        }
        if (p1.Y == p2.Y)
        {
            int minX = Math.Min(p1.X, p2.X);
            int maxX = Math.Max(p1.X, p2.X);
            for (int i = minX + 1; i < maxX; i++)
            {
                if (board[i, p1.Y] != -1)
                    return false;
            }
            return true;
        }
        return false;
    }

    // One-turn connection: Try turning at (p1.X, p2.Y) and (p2.X, p1.Y)
    private bool OneTurnConnection(Point p1, Point p2)
    {
        // First turning point: (p1.X, p2.Y)
        Point p3 = new Point(p1.X, p2.Y);
        if (board[p3.X, p3.Y] == -1)
        {
            if (DirectConnection(p1, p3) && DirectConnection(p3, p2))
                return true;
        }
        // Second turning point: (p2.X, p1.Y)
        Point p4 = new Point(p2.X, p1.Y);
        if (board[p4.X, p4.Y] == -1)
        {
            if (DirectConnection(p1, p4) && DirectConnection(p4, p2))
                return true;
        }
        return false;
    }

    // Two-turn connection: try connecting by scanning through possible rows and columns.
    private bool TwoTurnConnection(Point p1, Point p2)
    {
        // Try vertical scan: for each row, check if we can connect via two turns.
        for (int i = 0; i < rows; i++)
        {
            Point p3 = new Point(i, p1.Y);
            Point p4 = new Point(i, p2.Y);
            if (board[p3.X, p3.Y] == -1 && board[p4.X, p4.Y] == -1)
            {
                if (DirectConnection(p1, p3) && OneTurnConnection(p3, p2))
                    return true;
            }
        }
        // Try horizontal scan: for each column, check similarly.
        for (int j = 0; j < cols; j++)
        {
            Point p3 = new Point(p1.X, j);
            Point p4 = new Point(p2.X, j);
            if (board[p3.X, p3.Y] == -1 && board[p4.X, p4.Y] == -1)
            {
                if (DirectConnection(p1, p3) && OneTurnConnection(p3, p2))
                    return true;
            }
        }
        return false;
    }
}

}


end

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2327612.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

鸿蒙开发踩坑记录 - 2024S2

wrapBuilder如果想View和ObservedV2做绑定 必须要用 ComponentV2 Param 和 区别 退出两层循环 Builder的传入的参数及时是Trace修饰的也无法刷新组件 折叠屏展开后键盘无法点击 vm是公用的&#xff0c;组件生命周期问题导致 监听键盘高度变化失效 原因&#xff1a;分享面…

0基础入门scrapy 框架,获取豆瓣top250存入mysql

一、基础教程 创建项目命令 scrapy startproject mySpider --项目名称 创建爬虫文件 scrapy genspider itcast "itcast.cn" --自动生成 itcast.py 文件 爬虫名称 爬虫网址 运行爬虫 scrapy crawl baidu(爬虫名&#xff09; 使用终端运行太麻烦了&#xff0c;而且…

鸿蒙NEXT小游戏开发:井字棋

1. 引言 井字棋是一款经典的两人对战游戏&#xff0c;简单易懂&#xff0c;适合各个年龄段的玩家。本文将介绍如何使用鸿蒙NEXT框架开发一个井字棋游戏&#xff0c;涵盖游戏逻辑、界面设计及AI对战功能。 2. 开发环境准备 电脑系统&#xff1a;windows 10 开发工具&#xff1a;…

deep-sync开源程序插件导出您的 DeepSeek 与 public 聊天

一、软件介绍 文末提供下载 deep-sync开源程序插件导出您的 DeepSeek 与 public 聊天&#xff0c;这是一个浏览器扩展&#xff0c;它允许用户公开、私下分享他们的聊天对话&#xff0c;并使用密码或过期链接来增强 Deepseek Web UI。该扩展程序在 Deepseek 界面中添加了一个 “…

4. 理解Prompt Engineering:如何让模型听懂你的需求

引言:当模型变成“实习生” 想象一下,你新招的实习生总把“帮我写份报告”理解为“做PPT”或“整理数据表”——这正是开发者与大模型对话的日常困境。某金融公司优化提示词后,合同审查准确率从72%飙升至94%。本文将用3个核心法则+5个行业案例,教你用Prompt Engineering让…

网络编程—网络概念

目录 1 网络分类 1.1 局域网 1.2 广域网 2 常见网络概念 2.1 交换机 2.2 路由器 2.3 集线器 2.4 IP地址 2.5 端口号 2.6 协议 3 网络协议模型 3.1 OSI七层模型 3.2 TCP/IP五层模型 3.3 每层中常见的协议和作用 3.3.1 应用层 3.3.2 传输层 3.3.3 网络层 3.3.4…

SELinux

一、selinux技术详解 SELinux 概述 SELinux&#xff0c;即 Security-Enhanced Linux&#xff0c;意为安全强化的 Linux&#xff0c;由美国国家安全局&#xff08;NSA&#xff09;主导开发。开发初衷是防止系统资源被误用。在 Linux 系统中&#xff0c;系统资源的访问均通过程…

ES6对函数参数的新设计

ES6 对函数参数进行了新的设计&#xff0c;主要添加了默认参数、不定参数和扩展参数&#xff1a; 不定参数和扩展参数可以认为恰好是相反的两个模式&#xff0c;不定参数是使用数组来表示多个参数&#xff0c;扩展参数则是将多个参数映射到一个数组。 需要注意&#xff1a;不定…

LLaMA Factory微调后的大模型在vLLM框架中对齐对话模版

LLaMA Factory微调后的大模型Chat对话效果&#xff0c;与该模型使用vLLM推理架构中的对话效果&#xff0c;可能会出现不一致的情况。 下图是LLaMA Factory中的Chat的对话 下图是vLLM中的对话效果。 模型回答不稳定&#xff1a;有一半是对的&#xff0c;有一半是无关的。 1、未…

群体智能优化算法-鹈鹕优化算法(Pelican Optimization Algorithm, POA,含Matlab源代码)

摘要 鹈鹕优化算法&#xff08;Pelican Optimization Algorithm, POA&#xff09;是一种灵感来自自然界鹈鹕觅食行为的元启发式优化算法。POA 模拟鹈鹕捕食的两个主要阶段&#xff1a;探索阶段和开发阶段。通过模拟鹈鹕追捕猎物的动态行为&#xff0c;该算法在全局探索和局部开…

在 Blazor 中使用 Chart.js 快速创建数据可视化图表

前言 BlazorChartjs 是一个在 Blazor 中使用 Chart.js 的库&#xff08;支持Blazor WebAssembly和Blazor Server两种模式&#xff09;&#xff0c;它提供了简单易用的组件来帮助开发者快速集成数据可视化图表到他们的 Blazor 应用程序中。本文我们将一起来学习一下在 Blazor 中…

SQL server 2022和SSMS的使用案例1

一&#xff0c;案例讲解 二&#xff0c;实战讲解 实战环境 你需要确保你已经安装完成SQL Server 2022 和SSMS 20.2 管理面板。点此跳转至安装教程 SQL Server2022Windows11 专业工作站SSMS20.2 1&#xff0c;连接数据库 打开SSMS&#xff0c;连接数据库。 正常连接示意图&…

GO语言学习(14)GO并发编程

目录 &#x1f308;前言 1.goroutine&#x1f31f; 2.GMP模型&#x1f31f; 2.1 GMP的由来☀️ 2.2 什么是GMP☀️ 3.channel &#x1f31f; 3.1 通道声明与数据传输&#x1f4a5; 3.2 通道关闭 &#x1f4a5; 3.3 通道遍历 &#x1f4a5; 3.4 Select语句 &#x1f4…

【Audio开发二】Android原生音量曲线调整说明

一&#xff0c;客制化需求 客户方对于音量加减键从静音到最大音量十五个档位区域的音量变化趋势有定制化需求。 二&#xff0c;音量曲线调试流程 Android根据不同的音频流类型定义不同的曲线&#xff0c;曲线文件存放在/vendor/etc/audio_policy_volumes.xml或者default_volu…

spring-security原理与应用系列:HttpSecurity.filters

目录 AnyRequestMatcher WebSecurityConfig HttpSecurity AbstractInterceptUrlConfigurer AbstractAuthenticationProcessingFilter 类图 在前面的文章《spring-security原理与应用系列&#xff1a;securityFilterChainBuilders》中&#xff0c;我们遗留了一个问题&…

JVM生产环境问题定位与解决实战(六):总结篇——问题定位思路与工具选择策略

本文已收录于《JVM生产环境问题定位与解决实战》专栏&#xff0c;完整系列见文末目录 引言 在前五篇文章中&#xff0c;我们深入探讨了JVM生产环境问题定位与解决的实战技巧&#xff0c;从基础的jps、jmap、jstat、jstack、jcmd等工具&#xff0c;到JConsole、VisualVM、MAT的…

并行治理机制对比:Polkadot、Ethereum 与 NEAR

治理是任何去中心化网络的基础。它塑造了社区如何发展、如何为创新提供资金、如何应对挑战以及如何随着时间的推移建立信任。随着 Web3 的不断发展&#xff0c;决定这些生态系统如何做出决策的治理模型也在不断发展。 在最近的一集的【The Decentralized Mic】中, Polkadot 汇…

TDengine tar.gz和docker两种方式安装和卸载

下载地址 3.1.1.0 Linux版本 安装包 下载地址 3.1.1.0 docker 镜像 下载地址 3.1.1.0 Window客户端 1. 将文件上传至服务器后解压 tar -zxvf TDengine-server-3.1.1.0-Linux-x64.tar.gz 2. tar.gz安装 解压文件后&#xff0c;进入相应子目录&#xff0c;执行其中的 install.…

【STM32设计】基于STM32的智能门禁管理系统(指纹+密码+刷卡+蜂鸣器报警)(代码+资料+论文)

本课题为基于单片机的智能门禁系统&#xff0c;整个系统由AS608指纹识别模块&#xff0c;矩阵键盘&#xff0c;STM32F103单片机&#xff0c;OLED液晶&#xff0c;RFID识别模块&#xff0c;继电器&#xff0c;蜂鸣器等构成&#xff0c;在使用时&#xff0c;用户可以录入新的指纹…

java知识梳理(二)

一.lambda表达式 作用&#xff1a;Lambda 表达式在 Java 8 引入&#xff0c;主要用于简化匿名内部类的写法&#xff0c;特别是在函数式编程场景中&#xff0c;比如 函数式接口、流式 API&#xff08;Streams&#xff09;、并发编程等。它让 Java 代码更简洁、可读性更强&#x…