让AI玩一千万次贪吃蛇

如果让人工智能来玩贪吃蛇游戏,会发生什么?

 图源:DALL·E   

目录

贪吃蛇实现

游戏规则

游戏实现

Q学习算法实现

Q学习简介

Q表和Q值

Q学习更新规则

Q学习在贪吃蛇游戏中的应用

整体项目完整代码

运行过程截图

代码分析

环境设置

蛇的行为定义

Q学习代理实现

Q学习代理实现

小结


贪吃蛇实现

        在深入探讨人工智能如何掌握贪吃蛇游戏之前,让我们先回顾一下贪吃蛇游戏的基本设计和规则。贪吃蛇是一款经典的电子游戏,其简单的规则和直观的游戏玩法使其成为了历史上最受欢迎的游戏之一。

游戏规则

        在贪吃蛇游戏中,玩家控制一条不断移动的蛇,游戏目标是吃掉出现在屏幕上的食物,每吃掉一个食物,蛇的长度就会增加。游戏的挑战在于蛇不能触碰到屏幕边缘或自己的身体,否则游戏结束。随着蛇的不断增长,避免撞到自己变得越来越难,这就需要玩家有较高的策略和反应能力。

游戏实现

        在我们的Python实现中,游戏界面使用Pygame库创建,设置了固定的宽度和高度,以及基本的颜色定义,如黑色背景、绿色蛇身和红色食物。游戏中的蛇和食物都以方块的形式表示,每个方块的大小由block_size变量定义。游戏的主体是SnakeGame类,它封装了游戏的所有基本逻辑,包括蛇的初始化、移动、食物的生成以及碰撞检测等。

width, height = 640, 480  # 游戏窗口的宽度和高度
block_size = 20  # 每个方块的大小,包括蛇的每一部分和食物
class SnakeGame:def __init__(self, width, height, block_size):self.width = widthself.height = heightself.block_size = block_sizeself.reset()

        在reset方法中,游戏被重置到初始状态,蛇回到屏幕中心,长度为3个方块,方向向上。同时,食物被随机放置在屏幕上的某个位置。

def reset(self):initial_position = [self.width // 2, self.height // 2]self.snake = [initial_position,[initial_position[0] - self.block_size, initial_position[1]],[initial_position[0] - 2 * self.block_size, initial_position[1]]]self.direction = 'UP'self.food = [random.randrange(1, self.width // self.block_size) * self.block_size,random.randrange(1, self.height // self.block_size) * self.block_size]self.score = 0self.done = Falsereturn self.get_state()

        蛇的移动是通过在蛇头前面添加一个新的方块,并在蛇尾去掉一个方块来实现的。如果蛇吃到了食物,就不去掉蛇尾的方块,从而使蛇的长度增加。

        在游戏的每一步,step方法都会被调用,它接收一个动作(上、下、左、右),然后更新游戏状态,包括蛇的位置、游戏得分和游戏是否结束。这个方法是连接游戏逻辑和AI代理的桥梁,AI代理将根据游戏的当前状态决定下一步的最佳动作。

完整的游戏类:

class SnakeGame:def __init__(self, width, height, block_size):self.width = widthself.height = heightself.block_size = block_sizeself.reset()def reset(self):initial_position = [self.width // 2, self.height // 2]self.snake = [initial_position,[initial_position[0] - self.block_size, initial_position[1]],[initial_position[0] - 2 * self.block_size, initial_position[1]]]self.direction = 'UP'self.food = [random.randrange(1, self.width // self.block_size) * self.block_size,random.randrange(1, self.height // self.block_size) * self.block_size]self.score = 0self.done = Falsereturn self.get_state()def step(self, action):directions = ['UP', 'DOWN', 'LEFT', 'RIGHT']if self.direction != 'UP' and action == 1:self.direction = 'DOWN'elif self.direction != 'DOWN' and action == 0:self.direction = 'UP'elif self.direction != 'LEFT' and action == 3:self.direction = 'RIGHT'elif self.direction != 'RIGHT' and action == 2:self.direction = 'LEFT'# 计算食物的距离以判断是否靠近食物distance_to_food_before = self.distance(self.snake[0], self.food)# 移动蛇x, y = self.snake[0]if self.direction == 'UP':y -= block_sizeelif self.direction == 'DOWN':y += block_sizeelif self.direction == 'LEFT':x -= block_sizeelif self.direction == 'RIGHT':x += block_sizenew_head = [x, y]if x < 0 or x >= width or y < 0 or y >= height:self.done = Truereward = -500  # 撞墙的惩罚return self.get_state(), reward, self.doneif new_head in self.snake:self.done = Truereward = -200  # 撞到自身的严重惩罚return self.get_state(), reward, self.doneself.snake.insert(0, new_head)if new_head == self.food:self.score += 1reward = 500  # 吃到食物的奖励self.food = [random.randrange(1, width // block_size) * block_size,random.randrange(1, height // block_size) * block_size]else:self.snake.pop()distance_to_food_after = self.distance(new_head, self.food)if distance_to_food_after < distance_to_food_before:reward = 30  # 靠近食物的奖励else:reward = -15  # 无进展的小惩罚# 检查是否长时间直线移动if len(set([part[0] for part in self.snake])) == 1 or len(set([part[1] for part in self.snake])) == 1:if len(self.snake) > 5:  # 如果蛇的长度超过一定阈值reward -= 5  # 长时间直线移动的小惩罚return self.get_state(), reward, self.donedef distance(self, point1, point2):return ((point1[0] - point2[0]) ** 2 + (point1[1] - point2[1]) ** 2) ** 0.5def get_state(self):head = self.snake[0]point_l = [head[0] - self.block_size, head[1]]point_r = [head[0] + self.block_size, head[1]]point_u = [head[0], head[1] - self.block_size]point_d = [head[0], head[1] + self.block_size]state = [head[0] / self.width, head[1] / self.height,  # 蛇头的相对位置self.food[0] / self.width, self.food[1] / self.height,  # 食物的相对位置int(self.direction == 'LEFT'), int(self.direction == 'RIGHT'),int(self.direction == 'UP'), int(self.direction == 'DOWN'),  # 蛇头的方向int(self.is_collision(point_l)), int(self.is_collision(point_r)),int(self.is_collision(point_u)), int(self.is_collision(point_d))  # 周围是否会发生碰撞]return np.array(state, dtype=float)def is_collision(self, point):return point[0] < 0 or point[0] >= self.width or point[1] < 0 or point[1] >= self.height or point in self.snakedef display(self, screen):screen.fill(black)for part in self.snake:pygame.draw.rect(screen, green, pygame.Rect(part[0], part[1], self.block_size, self.block_size))pygame.draw.rect(screen, red, pygame.Rect(self.food[0], self.food[1], self.block_size, self.block_size))pygame.display.flip()

Q学习算法实现

        Q学习是一种无模型的强化学习算法,广泛应用于各种决策过程,包括我们的贪吃蛇游戏。它使代理能够在与环境交互的过程中学习,从而确定在给定状态下采取哪种动作以最大化未来的奖励。接下来,我们将深入探讨Q学习的核心概念和工作原理,并结合前文提到的贪吃蛇游戏代码进行说明。

Q学习简介

        Q学习的目标是学习一个策略,告诉代理在特定状态下应该采取什么动作以获得最大的长期奖励。这种策略通过一个叫做Q函数的东西来表示,它为每个状态-动作对分配一个值(Q值)。这个值代表了在给定状态下采取某个动作,并遵循当前策略的情况下,预期能获得的总奖励。

Q表和Q值

        在实践中,Q函数通常通过一个表格(Q表)来实现,表中的每一行对应一个可能的状态,每一列对应一个可能的动作,表中的每个元素表示该状态-动作对的Q值。在我们的贪吃蛇游戏中,状态可以是蛇头的位置、食物的位置以及蛇头的方向等信息的组合,动作则是蛇的移动方向(上、下、左、右)。

Q学习更新规则

        Q学习的核心是其更新规则,它定义了如何根据代理的经验逐步调整Q值。更新规则如下:

Q学习在贪吃蛇游戏中的应用

        在贪吃蛇游戏的实现中,我们首先定义了一个QLearningAgent类,它包含了学习率、折扣率和探索率等参数,以及一个空的Q表来存储Q值。

class QLearningAgent:def __init__(self, learning_rate=0.5, discount_rate=0.8, exploration_rate=0.45):self.learning_rate = learning_rateself.discount_rate = discount_rateself.exploration_rate = exploration_rateself.q_table = {}

代理通过get_action方法根据当前状态选择动作,这里使用了ϵ-贪婪策略来平衡探索和利用:

def get_action(self, state):state_key = str(state)if state_key not in self.q_table:self.q_table[state_key] = np.zeros(4)if np.random.rand() < self.exploration_rate:return random.randint(0, 3)  # 探索else:return np.argmax(self.q_table[state_key])  # 利用

在每一步之后,update_q_table方法会根据Q学习的更新规则来调整Q值:

def update_q_table(self, state, action, reward, next_state, done):state_key = str(state)next_state_key = str(next_state)if next_state_key not in self.q_table:self.q_table[next_state_key] = np.zeros(4)next_max = np.max(self.q_table[next_state_key])self.q_table[state_key][action] = (1 - self.learning_rate) * self.q_table[state_key][action] + \self.learning_rate * (reward + self.discount_rate * next_max)

        通过这种方式,Q学习代理能够在与环境的交互中逐渐学习到在各种状态下应该采取的最佳动作,从而在贪吃蛇游戏中获得尽可能高的分数。随着训练的进行,代理会变得越来越熟练,最终能够展示出高水平的游戏技巧。

整体项目完整代码

 import time
import pygame
import random
import numpy as npwidth, height = 640, 480black = (0, 0, 0)
green = (0, 255, 0)
red = (255, 0, 0)block_size = 20
speed = 15class SnakeGame:def __init__(self, width, height, block_size):self.width = widthself.height = heightself.block_size = block_sizeself.reset()def reset(self):initial_position = [self.width // 2, self.height // 2]self.snake = [initial_position,[initial_position[0] - self.block_size, initial_position[1]],[initial_position[0] - 2 * self.block_size, initial_position[1]]]self.direction = 'UP'self.food = [random.randrange(1, self.width // self.block_size) * self.block_size,random.randrange(1, self.height // self.block_size) * self.block_size]self.score = 0self.done = Falsereturn self.get_state()def step(self, action):directions = ['UP', 'DOWN', 'LEFT', 'RIGHT']if self.direction != 'UP' and action == 1:self.direction = 'DOWN'elif self.direction != 'DOWN' and action == 0:self.direction = 'UP'elif self.direction != 'LEFT' and action == 3:self.direction = 'RIGHT'elif self.direction != 'RIGHT' and action == 2:self.direction = 'LEFT'# 计算食物的距离以判断是否靠近食物distance_to_food_before = self.distance(self.snake[0], self.food)# 移动蛇x, y = self.snake[0]if self.direction == 'UP':y -= block_sizeelif self.direction == 'DOWN':y += block_sizeelif self.direction == 'LEFT':x -= block_sizeelif self.direction == 'RIGHT':x += block_sizenew_head = [x, y]if x < 0 or x >= width or y < 0 or y >= height:self.done = Truereward = -500  # 撞墙的惩罚return self.get_state(), reward, self.doneif new_head in self.snake:self.done = Truereward = -200  # 撞到自身的严重惩罚return self.get_state(), reward, self.doneself.snake.insert(0, new_head)if new_head == self.food:self.score += 1reward = 500  # 吃到食物的奖励self.food = [random.randrange(1, width // block_size) * block_size,random.randrange(1, height // block_size) * block_size]else:self.snake.pop()distance_to_food_after = self.distance(new_head, self.food)if distance_to_food_after < distance_to_food_before:reward = 30  # 靠近食物的奖励else:reward = -15  # 无进展的小惩罚# 检查是否长时间直线移动if len(set([part[0] for part in self.snake])) == 1 or len(set([part[1] for part in self.snake])) == 1:if len(self.snake) > 5:  # 如果蛇的长度超过一定阈值reward -= 5  # 长时间直线移动的小惩罚return self.get_state(), reward, self.donedef distance(self, point1, point2):return ((point1[0] - point2[0]) ** 2 + (point1[1] - point2[1]) ** 2) ** 0.5def get_state(self):head = self.snake[0]point_l = [head[0] - self.block_size, head[1]]point_r = [head[0] + self.block_size, head[1]]point_u = [head[0], head[1] - self.block_size]point_d = [head[0], head[1] + self.block_size]state = [head[0] / self.width, head[1] / self.height,  # 蛇头的相对位置self.food[0] / self.width, self.food[1] / self.height,  # 食物的相对位置int(self.direction == 'LEFT'), int(self.direction == 'RIGHT'),int(self.direction == 'UP'), int(self.direction == 'DOWN'),  # 蛇头的方向int(self.is_collision(point_l)), int(self.is_collision(point_r)),int(self.is_collision(point_u)), int(self.is_collision(point_d))  # 周围是否会发生碰撞]return np.array(state, dtype=float)def is_collision(self, point):return point[0] < 0 or point[0] >= self.width or point[1] < 0 or point[1] >= self.height or point in self.snakedef display(self, screen):screen.fill(black)for part in self.snake:pygame.draw.rect(screen, green, pygame.Rect(part[0], part[1], self.block_size, self.block_size))pygame.draw.rect(screen, red, pygame.Rect(self.food[0], self.food[1], self.block_size, self.block_size))pygame.display.flip()class QLearningAgent:def __init__(self, learning_rate=0.5, discount_rate=0.8, exploration_rate=0.45):self.learning_rate = learning_rateself.discount_rate = discount_rateself.exploration_rate = exploration_rateself.q_table = {}def get_action(self, state):state_key = str(state)if state_key not in self.q_table:self.q_table[state_key] = np.zeros(4)if np.random.rand() < self.exploration_rate:return random.randint(0, 3)else:return np.argmax(self.q_table[state_key])def update_q_table(self, state, action, reward, next_state, done):state_key = str(state)next_state_key = str(next_state)if next_state_key not in self.q_table:self.q_table[next_state_key] = np.zeros(4)next_max = np.max(self.q_table[next_state_key])self.q_table[state_key][action] = (1 - self.learning_rate) * self.q_table[state_key][action] + \self.learning_rate * (reward + self.discount_rate * next_max)if done:self.exploration_rate *= 0.9999if self.exploration_rate < 0.1:self.exploration_rate = 0.3game = SnakeGame(width, height, block_size)
agent = QLearningAgent()
num_episodes = 10000000
visualization_interval = 10000
for episode in range(num_episodes):if episode % visualization_interval == 1:pygame.init()screen = pygame.display.set_mode((width, height))visualize = Trueelse:visualize = Falsestate = game.reset()done = Falsetotal_reward = 0while not done:if visualize:game.display(screen)clock = pygame.time.Clock()clock.tick(12)action = agent.get_action(state)next_state, reward, done = game.step(action)agent.update_q_table(state, action, reward, next_state, done)state = next_statetotal_reward += rewardif visualize:pygame.quit()print(f"轮次: {episode}, 奖励分数: {total_reward}, 探索率: {agent.exploration_rate}, {agent}")

运行过程截图

代码分析

环境设置

游戏环境是通过Pygame库来创建和管理的。首先,我们初始化Pygame并设置游戏窗口的尺寸。接着,定义了几种基本颜色用于绘制游戏元素,如蛇身和食物。

import pygame
import randomwidth, height = 640, 480  # 游戏窗口的宽度和高度
black = (0, 0, 0)  # 背景颜色
green = (0, 255, 0)  # 蛇的颜色
red = (255, 0, 0)  # 食物的颜色
block_size = 20  # 每个方块的大小

蛇的行为定义

SnakeGame类封装了蛇的行为和游戏逻辑。蛇的初始状态是位于屏幕中心,长度为3个方块,方向向上。蛇的每一部分都是一个方块,我们通过一个列表来维护这些方块的坐标。

Q学习代理实现

QLearningAgent类实现了Q学习算法。它使用一个Q表来存储和更新状态-动作对的Q值,并根据ϵ-贪婪策略来选择动作。

Q学习代理实现

QLearningAgent类实现了Q学习算法。它使用一个Q表来存储和更新状态-动作对的Q值,并根据ϵ-贪婪策略来选择动作。

game = SnakeGame(width, height, block_size)
agent = QLearningAgent(learning_rate=0.5, discount_rate=0.8, exploration_rate=0.45)for episode in range(num_episodes):state = game.reset()done = Falsewhile not done:action = agent.get_action(state)next_state, reward, done = game.step(action)agent.update_q_table(state, action, reward, next_state, done)state = next_state

        通过这个过程,Q学习代理逐渐学会了如何在贪吃蛇游戏中做出更好的决策,从而获得更高的分数。随着训练的进行,我们可以观察到代理的性能逐渐提高,这表明它正在学习和适应游戏环境。

小结

        本文通过结合Python和Pygame库实现了一个经典的贪吃蛇游戏,并引入了Q学习算法,使得人工智能代理能够自主学习如何玩游戏并提高其性能。通过详细解析游戏设计、Q学习的核心原理以及代码实现的每个步骤,我们展示了如何将强化学习应用于实际问题中,快把代码拿走试试看吧

-----------------

以上,欢迎点赞收藏、评论区交流

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

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

相关文章

2024.2.23 C++QT 作业

思维导图 练习题 1>简单实现闹钟播报&#xff0c;设置时间&#xff0c;当系统时间与设置时间相同时播报语音5次&#xff0c;然后停止。如果设置时间小于当前系统时间&#xff0c;则弹出消息提示框&#xff0c;并清空输入框。 #include "widget.h" #include &quo…

JSON(javaScript Object Notation,Js对象标记)—我耀学IT

Json是一种轻量级的数据交换格式&#xff0c;目前使用非常广泛&#xff0c;是一种轻量级的数据交换格式。易于人阅读和编写&#xff0c;可以在多种语言之间进行数据交换 。同时也易于机器解析和生成 1.1json的值: 值可以是对象、数组、数字、字符串或者三个字面值(false、nul…

什么是nginx 、安装nginx、nginx调优

一、 什么是nginx 1.1 nginx的概念 一款高新能、轻量级Web服务软件系统资源消耗低对HTTP并发连接的处理能力高单台物理服务器可支持30 000&#xff5e;50 000个并发请求。 1.2 nginx模块与作用 核心模块&#xff1a;是 Nginx 服务器正常运行必不可少的模块&#xff0c;提供错…

深入理解JS的执行上下文、词法作用域和闭包(下)

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 &#x1f35a; 蓝桥云课签约作者、上架课程《Vue.js 和 E…

【Java程序设计】【C00262】基于Springboot的会员制医疗预约服务管理系统(有论文)

基于Springboot的会员制医疗预约服务管理系统&#xff08;有论文&#xff09; 项目简介项目获取开发环境项目技术运行截图 项目简介 这是一个基于Springboot的会员制医疗预约服务管理信息系统&#xff0c;本系统分为三种角色&#xff1a;管理员、医生和会员&#xff1b; 在系统…

JavaSec 基础之 XXE

文章目录 XMLReaderSAXReaderSAXBuilderDocumentBuilderUnmarshaller**SAXParserFactory**XMLReaderFactoryDigester总结 XMLReader public String XMLReader(RequestBody String content) {try {XMLReader xmlReader XMLReaderFactory.createXMLReader();// 修复&#xff1a…

如何让电脑待机而wifi不关的操作方法!!

1、一台电脑如果一天不关机&#xff0c;大约消耗0.3度电。 一般一台电脑的功耗约为250-400W&#xff08;台式机&#xff09;。 一台电脑每月的耗电量&#xff1a;如果是每小时300W每天10小时每月30天90KW&#xff0c;即90千瓦时的电。 这只是保守估计。 2、使用完毕后正常关闭…

企业微信应用开发:使用Cpolar域名配置进行本地接口回调的调试指南

文章目录 1. Windows安装Cpolar2. 创建Cpolar域名3. 创建企业微信应用4. 定义回调本地接口5. 回调和可信域名接口校验6. 设置固定Cpolar域名7. 使用固定域名校验 企业微信开发者在应用的开发测试阶段&#xff0c;应用服务通常是部署在开发环境&#xff0c;在有数据回调的开发场…

【MATLAB】 RLMD信号分解+FFT傅里叶频谱变换组合算法

有意向获取代码&#xff0c;请转文末观看代码获取方式~ 展示出图效果 1 RLMD分解算法 RLMD&#xff08;Robust Local Mode Decomposition&#xff09;是一种鲁棒的局部模态分解方法。它是通过在局部区间内对信号进行多项式拟合&#xff0c;提取局部特征&#xff0c;进而分解信…

【Java程序设计】【C00294】基于Springboot的车辆充电桩管理系统(有论文)

基于Springboot的车辆充电桩管理系统&#xff08;有论文&#xff09; 项目简介项目获取开发环境项目技术运行截图 项目简介 这是一个基于Springboot的车辆充电桩管理系统 本系统前台功能模块分为&#xff1a;首页功能和用户后台管理 后台功能模块分为&#xff1a;管理员功能和…

达梦数据库搭建和连接(详解一文看懂)

达梦数据库搭建和连接 一、数据库搭建1.安装前准备2.下载 Docker3.导入安装包4.启动docker版docker-compose版 5.启动/停止数据库 二、数据库连接1、下载DBeaver2、下载驱动3、DBeaver新建驱动数据库-驱动管理器新建驱动创建新驱动设置创建驱动-库驱动类确定和关闭 4、连接 博主…

回归预测 | Matlab实现SSA-BiLSTM-Attention麻雀算法优化双向长短期记忆神经网络融合注意力机制多变量回归预测

回归预测 | Matlab实现SSA-BiLSTM-Attention麻雀算法优化双向长短期记忆神经网络融合注意力机制多变量回归预测 目录 回归预测 | Matlab实现SSA-BiLSTM-Attention麻雀算法优化双向长短期记忆神经网络融合注意力机制多变量回归预测预测效果基本描述程序设计参考资料 预测效果 基…

[VulnHub靶机渗透] FourandSix2.01

&#x1f36c; 博主介绍&#x1f468;‍&#x1f393; 博主介绍&#xff1a;大家好&#xff0c;我是 hacker-routing &#xff0c;很高兴认识大家~ ✨主攻领域&#xff1a;【渗透领域】【应急响应】 【Java】 【VulnHub靶场复现】【面试分析】 &#x1f389;点赞➕评论➕收藏 …

stm32单片机的智能手环-心率-步数-距离-体温-蓝牙监控

一.硬件方案 随着社会的发展&#xff0c;人们的物质生活水平日渐提高&#xff0c;人们也越来越关注自己的健康。智能手环作为一种测量仪器&#xff0c;可以计算行走的步数和消耗的能量&#xff0c;所以人们可以定量的制定运动方案来健身&#xff0c;并根据运行情况来分析人体的…

7.(数据结构)堆

7.1 相关概念 堆&#xff08;Heap&#xff09;在计算机科学中是一种特殊的数据结构&#xff0c;它通常被实现为一个可以看作完全二叉树的数组对象。以下是一些关于堆的基本概念&#xff1a; 数据结构&#xff1a; 堆是一个优先队列的抽象数据类型实现&#xff0c;通过完全二叉树…

AI工具新革命:从ChatGPT到Sora,生成式AI改变世界

这个春节着实精彩&#xff0c;“春山学”吃透了&#xff0c;不如把目光移向OpenAI又一重磅产品——文生视频大模型Sora。智能新纪元已然开启&#xff0c;因为正如周鸿祎所说&#xff1a;“,Sora的诞生意味着AGI&#xff08;通用人工智能&#xff09;的实现将从10年缩短到1年。”…

.netcore 6.0/7.0项目迁移至.netcore 8.0 注意事项

1、SqlSugarCore 相关 1.1 主项目添加数据&#xff0c;否则会报数据库连接错误&#xff1a; <InvariantGlobalization>false</InvariantGlobalization> <PropertyGroup><TargetFramework>net8.0</TargetFramework><Nullable>enable</…

二维码(CTF)misc

知识点&#xff1a;文件剥离zip密码爆破 用到了fcrackzip工具&#xff1a; -b :采用爆破的方式 -c :采用什么类型的密码&#xff0c;1 数字类型 a 小写字母 A 大写字母 ‘aA1’ 大小写字母数字混合等 -l :指定密码的位数 -u :过滤掉不正确的密码记录&#xff1b;只显示正…

C# winfroms使用socket客户端服务端代码详解

文章目录 1️⃣ 通信相关说明1.1服务端与客户端1.2 信息发送原理1.3 信息接收原理 2️⃣ socket代码2.1 客户端代码2.2 服务端代码 3️⃣ 定时任务处理报文3.1 Timers定时任务 优质资源分享 作者&#xff1a;xcLeigh 文章地址&#xff1a;https://blog.csdn.net/weixin_4315141…

滚雪球学Java(71):深入剖析Java中的ArrayBlockingQueue底层实现与源码分析

咦咦咦&#xff0c;各位小可爱&#xff0c;我是你们的好伙伴——bug菌&#xff0c;今天又来给大家普及Java SE相关知识点了&#xff0c;别躲起来啊&#xff0c;听我讲干货还不快点赞&#xff0c;赞多了我就有动力讲得更嗨啦&#xff01;所以呀&#xff0c;养成先点赞后阅读的好…