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

井字棋--课后程序(Python程序开发案例教程-黑马程序员编著-第7章-课后作业)

实例2:井字棋

井字棋是一种在3 * 3格子上进行的连珠游戏,又称井字游戏。井字棋的游戏有两名玩家,其中一个玩家画圈,另一个玩家画叉,轮流在3 * 3格子上画上自己的符号,最先在横向、纵向、或斜线方向连成一条线的人为胜利方。如图1所示为画圈的一方为胜利者。

 

图1 井字棋

本实例要求编写程序,实现具有人机交互功能的井字棋。

实例目标

  1. 理解面向对象的思想
  2. 能独立设计类
  3. 掌握类的继承和父类方法的重写

实例分析

根据实例描述的井字棋游戏的规则,下面模拟一次游戏的流程如图2所示。

 

图2 井字棋游戏流程

图2中的描述的游戏流程如下:

  1. 重置棋盘数据,清理之前一轮的对局数据,为本轮对局做好准备。
  2. 显示棋盘上每个格子的编号,让玩家熟悉落子位置。
  3. 根据系统随机产生的结果确定先手玩家(先手使用X)。
  4. 当前落子一方落子。
  5. 显示落子后的棋盘。
  6. 判断落子一方是否胜利?若落子一方取得胜利,修改玩家得分,本轮对局结束,跳转至第(9)步。
  7. 判断是否和棋?若出现和棋,本轮对局结束,跳转至第(9)步。
  8. 交换落子方,跳转至第(4)步,继续本轮游戏。
  9. 显示玩家当前对局比分。

以上流程中,落子是游戏中的核心功能,如何落子则是体现电脑智能的关键步骤,实现智能落子有策略可循的。按照井字棋的游戏规则:当玩家每次落子后,玩家的棋子在棋盘的水平、垂直或者对角线任一方向连成一条直线,则表示玩家获胜。因此,我们可以将电脑的落子位置按照优先级分成以下三种:

(1)必胜落子位置

我方在该位置落子会获胜。一旦出现这种情况,显然应该毫不犹豫在这个位置落子。

(2)必救落子位置

对方在该位置落子会获胜。如果我方暂时没有必胜落子位置,那么应该在必救落子位置落子,以阻止对方获胜。

(3)评估子力价值

评估子力价值,就是如果在该位置落子获胜的几率越高,子力价值就越大;获胜的几率越低,子力价值就越小。

如果当前的棋盘上,既没有必胜落子位置,也没有必救落子位置,那么就应该针对棋盘上的每一个空白位置寻找子力价值最高的位置落子。

要编写一个评估子力价值的程序,需要考虑诸多因素,这里我们选择了一种简单评估子力价值的方式——只考虑某个位置在空棋盘上的价值,而不考虑已有棋子以及落子之后的盘面变化。下面来看一下在空棋盘上不同位置落子的示意图,如图3所示。

 

图3 棋盘落子示意图

观察图3不难发现,玩家在空棋盘上落子的位置可分为以下3种情况:

  1. 中心点,这个位置共有4个方向可能和其它棋子连接成直线,获胜的几率最高。
  2. 4个角位,这4个位置各自有3个方向可能和其它棋子连接成直线,获胜几率中等。
  3. 4个边位,这4个位置各自有2个方向可能和其它棋子连接成直线,获胜几率最低。

综上所述,如果电脑在落子时,既没有必胜落子位置,也没有必救落子位置时,我们就可以让电脑按照胜率的高低来选择落子位置,也就是说,若棋盘的中心点没有棋子,则选择中心点作为落子位置;若中心点已有棋子,而角位没有棋子,则随机选择一个没有棋子的角位作为落子位置;若中心点和四个角位都有棋子,而边位没有棋子,则随机选择一个没有棋子的边位作为落子位置。

井字棋游戏一共需要设计4个类,不同的类创建的对象承担不同的职责,分别是:

(1)游戏类(Game):负责整个游戏流程的控制,是该游戏的入口。

(2)棋盘类(Board):负责显示棋盘、记录本轮对局数据、以及判断胜利等和对弈相关的处理工作。

(3)玩家类(Player):负责记录玩家姓名、棋子类型和得分、以及实现玩家在棋盘上落子。

(4)电脑玩家类(AIPlayer):是玩家类的子类。在电脑玩家类类中重写玩家类的落子方法,在重写的方法中实现电脑智能选择落子位置的功能。

设计后的类图如图4所示。

 

图4 类结构图

本实例中涉及到多个类,为保证程序具有清晰的结构,可以将每个类的相关代码分别放置到与其同名的py文件中。另外,由于Player和AIPlayer类具有继承关系,可以将这两个类的代码放置到player.py文件中。

代码实现

本实例的实现过程如下所示。

  1. 创建项目

使用PyCharm创建一个名为“井字棋V1.0”的文件夹,在该文件夹下分别创建3个py文件,分别为board.py、game.py与player.py,此时程序的目录结构如图5所示。

 

图5 井字棋文件目录

由于棋盘类是井字棋游戏的重点,因此我们先开发Board类。

  1. 设计Board

(1)属性

井字棋的棋盘上共有9个格子落子,落子也是有位置可循的,因此这里使用列表作为棋盘的数据结构,列表中的元素则是棋盘上的棋子,它有以下三种取值:

  1. " " 表示没有落子,是初始值;
  2. "X" 表示玩家在该位置下了一个X的棋子;
  3. "O" 表示玩家在该位置下了一个O的棋子。

其中列表中的元素为" "的位置才允许玩家落子。为了让玩家明确可落子的位置,需要增加可落子列表。根据图4中设计的类图,在board.py文件中定义Board类,并在该类的构造方法中添加属性board_data和movable_list,具体代码如下。

class Board(object):

    """棋盘类"""

    def __init__(self):

        self.board_data = [" "] * 9          # 棋盘数据

        self.movable_list = list(range(9))  # 可移动列表

(2)show_board()方法

show_board()方法实现创建一个九宫格棋盘的功能。游戏过程中显示的棋盘分为两种情况,一种是新一轮游戏开始前显示的有索引的棋盘,让玩家明确棋盘格子与序号的对应关系;另一种是游戏中显示当前落子情况的棋盘,会在玩家每次落子后展示。在Board类中添加show_board()方法,并在该方法中传递一个参数show_index,用于设置是否在棋盘中显示索引(默认为False,表示不显示索引),具体代码如下。

def show_board(self, show_index=False):

    """显示棋盘

    :param show_index: True 表示显示索引 / False 表示显示数据

    """

    for i in (0, 3, 6):

        print("       |       |")

        if show_index:

            print("   %d   |   %d   |   %d" % (i, i + 1, i + 2))

        else:

            print("   %s   |   %s   |   %s" % (self.board_data[i],

                                             self.board_data[i + 1],

                                             self.board_data[i + 2]))

        print("       |       |")

        if i != 6:

            print("-" * 23)

(3)move_down ()方法

move_down ()方法实现在指定的位置落子的功能,该方法接收两个参数,分别是表示落子位置的index和表示落子类型(X或者O)的chess,接收的这些参数都是落子前需要考虑的必要要素,具体代码如下。

def move_down(self, index, chess):

    """在指定位置落子

    :param index: 列表索引

    :param chess: 棋子类型 X O

    """

    # 1. 判断 index 是否在可移动列表中

    if index not in self.movable_list:

        print("%d 位置不允许落子" % index)

        return

    # 2. 修改棋盘数据

    self.board_data[index] = chess

    # 3. 修改可移动列表

    self.movable_list.remove(index)

以上代码首先判断落子位置是否可以落子,如果可以就将棋子添加到board_data列表的对应位置,并从movable_list列表中删除。

(4)is_draw ()方法

is_draw ()方法实现判断游戏是否平局的功能,该方法会查看可落子索引列表中是否有值,若没有值表示棋盘中的棋子已经落满了,说明游戏平局,具体代码如下。

def is_draw(self):

    """是否平局"""

    return not self.movable_list

(5)is_win ()方法

is_draw ()方法实现判断游戏是否胜利的功能,该方法会先定义方向列表,再遍历方向列表判断游戏是否胜利,胜利则返回True,否则返回False,具体代码如下。

def is_win(self, chess, ai_index=-1):

    """是否胜利

    :param chess: 玩家的棋子

    :param ai_index: 预判索引,-1 直接判断当前棋盘数据

    """

    # 1. 定义检查方向列表

    check_dirs = [[0, 1, 2], [3, 4, 5], [6, 7, 8],

                     [0, 3, 6], [1, 4, 7], [2, 5, 8],

                     [0, 4, 8], [2, 4, 6]]

    # 2. 定义局部变量记录棋盘数据副本

    data = self.board_data.copy()

    # 判断是否预判胜利

    if ai_index > 0:

        data[ai_index] = chess

    # 3. 遍历检查方向列表判断是否胜利

    for item in check_dirs:

        if (data[item[0]] == chess and

            data[item[1]] == chess

                and data[item[2]] == chess):

            return True

    return False

注意,is_win()方法的ai_index参数的默认值为-1,表示无需进行预判,即提示玩家最有利的落子位置;若该参数不为-1时,表示需要进行预判。

(6)reset_board ()方法

reset_board ()方法实现清空棋盘的功能,该方法中会先清空movable_list,再将棋盘上的数据全部置为初始值,最后往movable_list中添加0~8的数字,具体代码如下。

def reset_board(self):

    """重置棋盘"""

    # 1. 清空可移动列表数据

    self.movable_list.clear()

    # 2. 重置数据

    for i in range(9):

        self.board_data[i] = " "

        self.movable_list.append(i)

  1. 设计Player

根据图4中设计的类图,在player.py文件中定义Player类,分别在该类中添加属性和方法,具体内容如下。

(1)属性

在Player类中添加name、score、chess属性,具体代码如下。

import board

import random

class Player(object):

    """玩家类"""

    def __init__(self, name):

        self.name = name     # 姓名

        self.score = 0       # 成绩

        self.chess = None   # 棋子

(2)move()方法

move()方法实现玩家在指定位置落子的功能,该方法中会先提示用户棋盘上可落子的位置,之后使棋盘根据用户选择的位置重置棋盘数据后进行显示,具体代码如下。

def move(self, chess_board):

    """在棋盘上落子

    :param chess_board:

    """

    # 1. 由用户输入要落子索引

    index = -1

    while index not in chess_board.movable_list:

        try:

            index = int(input(" %s 输入落子位置 %s" %

                (self.name, chess_board.movable_list)))

        except ValueError:

            pass

    # 2. 在指定位置落子

    chess_board.move_down(index, self.chess)

  1. 设计AIPlayer

根据图4中设计的类图,在player.py文件中定义继承自Player类的子类AIPlayer。AIPlayer类中重写了父类的move()方法,在该方法中需要增加分析中的策略,使得计算机玩家变得更加聪明,具体代码如下。

class AIPlayer(Player):

    """智能玩家"""

    def move(self, chess_board):

        """在棋盘上落子

        :param chess_board:

        """

        print("%s 正在思考落子位置..." % self.name)

        # 1. 查找我方必胜落子位置

        for index in chess_board.movable_list:

            if chess_board.is_win(self.chess, index):

                print("走在 %d 位置必胜!!!" % index)

                chess_board.move_down(index, self.chess)

                return

        # 2. 查找地方必胜落子位置-我方必救位置

        other_chess = "O" if self.chess == "X" else "X"

        for index in chess_board.movable_list:

            if chess_board.is_win(other_chess, index):

                print("敌人走在 %d 位置必输,火速堵上!" % index)

                chess_board.move_down(index, self.chess)

                return

        # 3. 根据子力价值选择落子位置

        index = -1

        # 没有落子的角位置列表

        corners = list(set([0, 2, 6, 8]).intersection(

chess_board.movable_list))

        # 没有落子的边位置列表

        edges = list(set([1, 3, 5, 7]).intersection(

chess_board.movable_list))

        if 4 in chess_board.movable_list:

            index = 4

        elif corners:

            index = random.choice(corners)

        elif edges:

            index = random.choice(edges)

        # 在指定位置落子

        chess_board.move_down(index, self.chess)

  1. 设计Game

根据图4中设计的类图,在game.py文件中定义Game类,分别在该类中添加属性和方法,具体内容如下。

(1)属性

在Game类中添加chess_board、human、computer属性,具体代码如下。

import random

import board

import player

class Game(object):

    """游戏类"""

    def __init__(self):

        self.chess_board = board.Board()          # 棋盘对象

        self.human = player.Player("玩家")        # 人类玩家对象

        self.computer = player.AIPlayer("电脑")  # 电脑玩家对象

(2)random_player()方法

random_player()方法实现随机生成先手玩家的功能,该方法中会先随机生成0和1两个数,选到数字1的玩家为先手玩家,然后再为两个玩家设置棋子类型,即先手玩家为“X”,对手玩家为“O”,具体代码如下。

def random_player(self):

    """随机先手玩家

    :return: 落子先后顺序的玩家元组

    """

    # 随机到 1 表示玩家先手

    if random.randint(0, 1) == 1:

        players = (self.human, self.computer)

    else:

        players = (self.computer, self.human)

    # 设置玩家棋子

    players[0].chess = "X"

    players[1].chess = "O"

    print("根据随机抽取结果 %s 先行" % players[0].name)

    return players

(3)play_round ()方法

play_round ()方法实现一轮完整对局的功能,该方法的逻辑可按照实例分析的一次流程完成,具体代码如下。

def play_round(self):

    """一轮完整对局"""

    # 1. 显示棋盘落子位置

    self.chess_board.show_board(True)

    # 2. 随机决定先手

    current_player, next_player = self.random_player()

    # 3. 两个玩家轮流落子

    while True:

        # 下子方落子

        current_player.move(self.chess_board)

        # 显示落子结果

        self.chess_board.show_board()

        # 是否胜利?

        if self.chess_board.is_win(current_player.chess):

            print("%s 战胜 %s" % (current_player.name, next_player.name))

            current_player.score += 1

            break

        # 是否平局

        if self.chess_board.is_draw():

            print("%s %s 战成平局" % (current_player.name,

next_player.name))

            break

        # 交换落子方

        current_player, next_player = next_player, current_player

    # 4. 显示比分

    print("[%s] 对战 [%s] 比分是 %d : %d" % (self.human.name,

                                        self.computer.name,

                                        self.human.score,

                                        self.computer.score))

从上述代码可以看出,大部分的功能都是通过游戏中各个对象访问属性或调用方法实现的,这正好体现了类的封装性的特点,即每个类分工完成各自的任务。

(4)start ()方法

start ()方法实现循环对局的功能,该方法中会在每轮对局结束之后询问玩家是否再来一局,若玩家选择是,则重置棋盘数据后开始新一轮对局;若玩家选择否,则会退出游戏,具体代码如下。

def start(self):

    """循环开始对局"""

    while True:

        # 一轮完整对局

        self.play_round()

        # 询问是否继续

        is_continue = input("是否再来一盘(Y/N)?").upper()

        # 判断玩家输入

        if is_continue != "Y":

            break

        # 重置棋盘数据

        self.chess_board.reset_board()

最后在game.py文件中通过Game类对象调用start()方法启动井字棋游戏,具体代码如下。

if __name__ == '__main__':

    Game().start()

代码测试

运行程序,对战一局游戏的结果如下所示:

       |       |

   0   |   1   |   2

       |       |

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

       |       |

   3   |   4   |   5

       |       |

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

       |       |

   6   |   7   |   8

       |       |

根据随机抽取结果 电脑 先行

电脑 正在思考落子位置...

       |       |

       |       |   

       |       |

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

       |       |

       |   X   |   

       |       |

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

       |       |

       |       |   

       |       |

玩家输入落子位置 [0, 1, 2, 3, 5, 6, 7, 8]0

       |       |

   O   |       |   

       |       |

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

       |       |

       |   X   |   

       |       |

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

       |       |

       |       |   

       |       |

电脑 正在思考落子位置...

       |       |

   O   |       |   

       |       |

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

       |       |

       |   X   |   

       |       |

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

       |       |

   X   |       |   

       |       |

玩家输入落子位置 [1, 2, 3, 5, 7, 8]2

       |       |

   O   |       |   O

       |       |

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

       |       |

       |   X   |   

       |       |

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

       |       |

   X   |       |   

       |       |

电脑 正在思考落子位置...

敌人走在 1 位置必输,火速堵上!

       |       |

   O   |   X   |   O

       |       |

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

       |       |

       |   X   |   

       |       |

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

       |       |

   X   |       |   

       |       |

玩家输入落子位置 [3, 5, 7, 8]7

       |       |

   O   |   X   |   O

       |       |

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

       |       |

       |   X   |   

       |       |

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

       |       |

   X   |   O   |   

       |       |

电脑 正在思考落子位置...

       |       |

   O   |   X   |   O

       |       |

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

       |       |

       |   X   |   

       |       |

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

       |       |

   X   |   O   |   X

       |       |

玩家输入落子位置 [3, 5]5

       |       |

   O   |   X   |   O

       |       |

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

       |       |

       |   X   |   O

       |       |

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

       |       |

   X   |   O   |   X

       |       |

电脑 正在思考落子位置...

       |       |

   O   |   X   |   O

       |       |

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

       |       |

   X   |   X   |   O

       |       |

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

       |       |

   X   |   O   |   X

       |       |

电脑 玩家 战成平局

[玩家] 对战 [电脑] 比分是 0 : 0

是否再来一盘(Y/N)?n

相关文章:

井字棋--课后程序(Python程序开发案例教程-黑马程序员编著-第7章-课后作业)

实例2:井字棋 井字棋是一种在3 * 3格子上进行的连珠游戏,又称井字游戏。井字棋的游戏有两名玩家,其中一个玩家画圈,另一个玩家画叉,轮流在3 * 3格子上画上自己的符号,最先在横向、纵向、或斜线方向连成一条…...

谷粒学院开发(三):统一日志、异常及前端准备工作

特定异常处理 ControllerAdvice public class GlobalExceptionHandler {ExceptionHandler(Exception.class) // 指定出现什么异常会被处理ResponseBody // 为了能够返回数据public R error(Exception e) {e.printStackTrace();return R.error().message("执行了全局异常…...

华为OD机试题 - 招聘(JavaScript)| 机考必刷

更多题库,搜索引擎搜 梦想橡皮擦华为OD 👑👑👑 更多华为OD题库,搜 梦想橡皮擦 华为OD 👑👑👑 更多华为机考题库,搜 梦想橡皮擦华为OD 👑👑👑 华为OD机试题 最近更新的博客使用说明本篇题解:招聘题目输入输出示例一输入输出说明示例二输入输出说明示例三输…...

关于SQL优化的几点说明

1. ORACLE DBA是如何进行SQL优化的 作为一个Oracle数据库管理员(DBA),SQL优化是他们的日常工作之一,主要目标是优化查询性能,减少查询时间,并提高数据库的整体性能。 以下是Oracle DBA如何进行SQL优化的一般流程: 监控…...

使用高精度秒表StopWatch测试DateTime.Now的精度

StopWatch使用的命名空间:using System.Diagnostics;StopWatch的使用方法:创建Stopwatch对象:stopwatch;stopwatch计时表开启:stopwatch.Start();stopwatch计时表关闭:stopwatch.Stop();计算stopwatch.Stop…...

【C++】vector的使用及其模拟实现

这里写目录标题一、vector的介绍及使用1. vector的介绍2. 构造函数3. 遍历方式4. 容量操作及空间增长问题5. 增删查改6. vector二维数组二、vector的模拟实现1. 构造函数2. 迭代器和基本接口3. reserve和resize4. push_back和pop_back5. insert和erase5. 迭代器失效问题5. 浅拷…...

[洛谷-P2585][ZJOI2006]三色二叉树(树形DP+状态机DP)

[洛谷-P2585][ZJOI2006]三色二叉树(树形DP状态机DP)一、题目题目描述输入格式输出格式样例 #1样例输入 #1样例输出 #1提示数据规模与约定二、分析1、递归建树2、树形DP 状态机DP(1)状态表示(2)状态转移三、…...

BI技巧丨计算组

PowerBI有三大工具,分别是DAX Studio,Tabular Editor和Bravo。 DAX Studio通常我们会用来进行性能分析和DAX调优使用,Bravo一般用来批量格式化DAX,而Tabular Editor主要的功能就是计算组。 计算组这个名词,相信很多小伙…...

PMP项目管理项目范围管理

目录1 项目范围管理概述2 规划范围管理3 收集需求4 定义范围5 创建 WBS6 确认范围7 控制范围1 项目范围管理概述 项目范围管理包括确保项目做且只做所需的全部工作,以成功完成项目的各 个过程。管理项目范围主要在于定义和控制哪些工作应在项目内,哪些工…...

Flink 定时加载数据源

一、简介 flink 自定义实时数据源使用流处理比较简单,比如 Kafka、MQ 等,如果使用 MySQL、redis 批处理也比较简单 如果需要定时加载数据作为 flink 数据源使用流处理,比如定时从 mysql 或者 redis 获取一批数据,传入 flink 做处…...

ChatGPT、人工智能、人类和一些酒桌闲聊

© 2023 Conmajia Initiated 10th March, 2023 昨天跟某化学家喝酒,期间提到了 ChatGPT。他的评价是:这鬼东西大量输出毫无意义、错漏百出甚至是虚假的信息,“in a confident accent”。例如某次 GPT 针对“描述某某记者”这一问题&#…...

WebRTC开源库内部调用abort函数引发程序发生闪退问题的排查

目录 1、初始问题描述 2、使用Process Explorer工具查看到处理音视频业务的rtcmpdll.dll模块没有加载起来 3、使用Dependency Walker工具查看到rtcmpdll.dll依赖的库有问题 4、更新库之后Debug程序启动时就发生异常,程序闪退 5、VS调试时看不到有效的函数调用堆…...

Golang并发编程

Golang并发编程 文章目录Golang并发编程1. 协程2. channel2.1 channel的创建2.2 使用waitGroup实现同步3. 并发编程3.1 并发编程之runtime包3.2 mutex互斥锁3.3 channel遍历3.3.1 for if遍历3.3.2 for range3.4 select switch3.5 Timer3.5.1 time.NewTimer()3.5.2 Stop、reset…...

windows+Anaconda环境下安装BERT成功安装方法及问题汇总

前言 在WindowsAnaconda环境下安装BERT,遇到各种问题,几经磨难,最终成功。接下来,先介绍成功的安装方法,再附上遇到的问题汇总 成功的安装方法 1、创建虚拟环境 注意:必须加上python3.7.12以创建环境&a…...

git - 简易指南

git - 简易指南 创建新仓库 创建新文件夹,打开,然后执行 git init 以创建新的 git 仓库。 检出仓库 执行如下命令以创建一个本地仓库的克隆版本: git clone /path/to/repository 如果是远端服务器上的仓库,你的命令会是这个样…...

[论文笔记]Transformer-XL: Attentive Language Models Beyond a Fixed-Length Context

引言 我们知道Transformer很好用,但它设定的最长长度是512。像一篇文章超过512个token是很容易的,那么我们在处理这种长文本的情况下也想利用Transformer的强大表达能力需要怎么做呢? 本文就带来一种处理长文本的Transformer变种——Transf…...

华为OD机试题 - 找目标字符串(JavaScript)| 机考必刷

更多题库,搜索引擎搜 梦想橡皮擦华为OD 👑👑👑 更多华为OD题库,搜 梦想橡皮擦 华为OD 👑👑👑 更多华为机考题库,搜 梦想橡皮擦华为OD 👑👑👑 华为OD机试题 最近更新的博客使用说明本篇题解:找目标字符串题目输入输出示例一输入输出说明Code解题思路版权说…...

C++面向对象编程之六:重载操作符(<<,>>,+,+=,==,!=,=)

重载操作符C允许我们重新定义操作符(例如:,-,*,/)等,使其对于我们自定义的类类型对象,也能像内置数据类型(例如:int,float,double&…...

JS_wangEditor富文本编辑器

官网&#xff1a;https://www.wangeditor.com/ 引入 CSS 定义样式 <link href"https://unpkg.com/wangeditor/editorlatest/dist/css/style.css" rel"stylesheet"> <style>#editor—wrapper {border: 1px solid #ccc;z-index: 100; /* 按需定…...

Django实践-06导出excel/pdf/echarts

文章目录Django实践-06导出excel/pdf/echartsDjango实践-06导出excel/pdf/echarts导出excel安装依赖库修改views.py添加excel导出函数修改urls.py添加excel/运行测试导出pdf安装依赖库修改views.py添加pdf导出函数修改urls.py添加pdf/生成前端统计图表修改views.py添加get_teac…...

java并发入门(一)共享模型—Synchronized、Wait/Notify、pack/unpack

一、共享模型—管程 1、共享存在的问题 1.1 共享变量案例 package com.yyds.juc.monitor;import lombok.extern.slf4j.Slf4j;Slf4j(topic "c.MTest1") public class MTest1 {static int counter 0;public static void main(String[] args) throws InterruptedEx…...

Ast2500增加用户自定义功能

备注&#xff1a;这里使用的AMI的开发环境MegaRAC进行AST2500软件开发&#xff0c;并非openlinux版本。1、添加上电后自动执行的任务在PDKAccess.c中列出了系统启动过程中的所有任务&#xff0c;若需要添加功能&#xff0c;在相应的任务中添加自定义线程。一般在两个任务里面添…...

用Python暴力求解德·梅齐里亚克的砝码问题

文章目录固定个数的砝码可称量重量砝码的组合方法40镑砝码的组合问 一个商人有一个40磅的砝码&#xff0c;由于跌落在地而碎成4块。后来&#xff0c;称得每块碎片的重量都是整磅数&#xff0c;而且可以用这4 块来称从1 至40 磅之间的任意整数磅的重物。问这4 块砝码片各重多少&…...

离散Hopfield神经网络的分类——高校科研能力评价

离散Hopfield网络离散Hopfield网络是一种经典的神经网络模型&#xff0c;它的基本原理是利用离散化的神经元和离散化的权值矩阵来实现模式识别和模式恢复的功能。它最初由美国物理学家John Hopfield在1982年提出&#xff0c;是一种单层的全连接神经网络&#xff0c;被广泛应用于…...

Retrofit核心源码分析(三)- Call逻辑分析和扩展机制

在前面的两篇文章中&#xff0c;我们已经对 Retrofit 的注解解析、动态代理、网络请求和响应处理机制有了一定的了解。在这篇文章中&#xff0c;我们将深入分析 Retrofit 的 Call 逻辑&#xff0c;并介绍 Retrofit 的扩展机制。 一、Call 逻辑分析 Call 是 Retrofit 中最基本…...

源码分析spring如和对@Component注解进行BeanDefinition注册的

Spring ioc主要职责为依赖进行处理&#xff08;依赖注入、依赖查找&#xff09;、容器以及托管的(java bean、资源配置、事件)资源声明周期管理&#xff1b;在ioc容器启动对元信息进行读取&#xff08;比如xml bean注解等&#xff09;、事件管理、国际化等处理&#xff1b;首先…...

C语言--字符串函数1

目录前言strlenstrlen的模拟实现strcpystrcatstrcat的模拟实现strcmpstrcmp的模拟实现strncpystrncatstrncmpstrstrstrchr和strrchrstrstr的模拟实现前言 本章我们将重点介绍处理字符和字符串的库函数的使用和注意事项。 strlen 我们先来看一个我们最熟悉的求字符串长度的库…...

Webstorm使用、nginx启动、FinalShell使用

文章目录 主题设置FinalShellFinalShell nginx 启动历史命令Nginx页面发布配置Webstorm的一些常用快捷键代码生成字体大小修改Webstorm - gitCode 代码拉取webstorm 汉化webstorm导致CPU占用率高方法一 【忽略node_modules】方法二 【设置 - 代码编辑 - 快速预览文档 - 关闭】主…...

源码分析Spring @Configuration注解如何巧夺天空,偷梁换柱。

前言 回想起五年前的一次面试&#xff0c;面试官问Configuration注解和Component注解有什么区别&#xff1f;记得当时的回答是&#xff1a; 相同点&#xff1a;Configuration注解继承于Component注解&#xff0c;都可以用来通过ClassPathBeanDefinitionScanner装载Spring bean…...

vector的使用及模拟实现

目录 一.vector的介绍及使用 1.vector的介绍 2.vector的使用 1.vector的定义 2.vector iterator的使用 3. vector 空间增长问题 4.vector 增删查改 3.vector 迭代器失效问题&#xff08;重点&#xff09; 1. 会引起其底层空间改变的操作 2.指定位置元素的删除操作--erase 3. Li…...

“华为杯”研究生数学建模竞赛2007年-【华为杯】A题:基于自助法和核密度估计的膳食暴露评估模型(附获奖论文)

赛题描述 我国是一个拥有13亿人口的发展中国家,每天都在消费大量的各种食品,这批食品是由成千上万的食品加工厂、不可计数的小作坊、几亿农民生产出来的,并且经过较多的中间环节和长途运输后才为广大群众所消费,加之近年来我国经济发展迅速而环境治理没有能够完全跟上,以…...

刷题(第三周)

目录 [CISCN2021 Quals]upload [羊城杯 2020]EasySer [网鼎杯 2020 青龙组]notes [SWPU2019]Web4 [Black Watch 入群题]Web [HFCTF2020]BabyUpload [CISCN2021 Quals]upload 打开界面以后&#xff0c;发现直接给出了源码 <?php if (!isset($_GET["ctf"]))…...

新C++(14):移动语义与右值引用

当你在学习语言的时候&#xff0c;是否经常听到过一种说法,""左边的叫做左值&#xff0c;""右边的叫做右值。这句话对吗&#xff1f;从某种意义上来说&#xff0c;这句话只是说对了一部分。---前言一、什么是左右值?通常认为:左值是一个表示数据的表达式(…...

TCP相关概念

目录 一.滑动窗口 1.1概念 1.2滑动窗口存在的意义 1.3 滑动窗口的大小变化 1.4丢包问题 二.拥塞控制 三.延迟应答 四.捎带应答 五.面向字节流 六.粘包问题 七.TIME_WAIT状态 八.listen第2个参数 九.TCP总结 一.滑动窗口 1.1概念 概念&#xff1a;双方在进行通信时&a…...

MySQL锁篇

MySQL锁篇 一、一条update语句 我们的故事继续发展&#xff0c;我们还是使用t这个表&#xff1a; CREATE TABLE t (id INT PRIMARY KEY,c VARCHAR(100) ) EngineInnoDB CHARSETutf8;现在表里的数据就是这样的&#xff1a; mysql> SELECT * FROM t; —------- | id | c | —…...

SWF (Simple Workflow Service)简介

Amazon Simple Workflow Service (Amazon SWF) 提供了给应用程序异步、分布式处理的流程工具。 SWF可以用在媒体处理、网站应用程序后端、商业流程、数据分析和一系列定义好的任务上。 举个例子&#xff0c;下图表明了一个电商网站的工作流程&#xff0c;其中涉及了程序执行的…...

java(Class 常用方法 获取Class对象六种方式 动态和静态加载 类加载流程)

ClassClass常用方法获取Class对象六种方式哪些类型有Class对象动态和静态加载类加载流程加载阶段连接阶段连接阶段-验证连接阶段-准备连接阶段-解析初始化阶段获取类结构信息Class常用方法 第一步&#xff1a;创建一个实体类 public class Car {public String brand "宝…...

【数据结构】线性表和顺序表

Yan-英杰的主页 悟已往之不谏 知来者之可追 目录 1.线性表 2.顺序表 2.1 静态顺序表 2.2 动态顺序表 2.3移除元素 1.线性表 线性表&#xff08;linear list&#xff09;是n个具有相同特性的数据元素的有限序列。 线性表是一种在实际中广泛使用的数据结构&#xff0c;常见的线…...

Ubuntu数据库安装(mysql)

##1.下载mysql-apt-config_0.8.22-1_all.deb并且安装 wget https://dev.mysql.com/get/mysql-apt-config_0.8.22-1_all.deb sudo dpkg -i mysql-apt-config_0.8.22-1_all.deb##2.更新apt-updata sudo apt update##3.如果出现如下图情况执行以下命令 [外链图片转存失败,源站可…...

MyBatis-Plus的入门学习

MyBatis-Plus入门学习简介特性快速开始MyBatis-Plus的注解详解Tableld主键生成策略1、数据库自动增长 AUTO2、UUID3、Redis生成id4、MP主键自动生成TableNameTableField自动填充测试方法&#xff1a;update乐观锁select查所有根据id查多个id批量查询简单条件查询&#xff08;通…...

华为OD机试题 - 内存池(JavaScript)

更多题库,搜索引擎搜 梦想橡皮擦华为OD 👑👑👑 更多华为OD题库,搜 梦想橡皮擦 华为OD 👑👑👑 更多华为机考题库,搜 梦想橡皮擦华为OD 👑👑👑 华为OD机试题 最近更新的博客使用说明本篇题解:内存池题目输入输出示例一输入输出说明Code解题思路版权说明华为…...

数据库索引原理

数据库索引的作用是做数据的快速检索&#xff0c;而快速检索实现的本质是数据结构。像二叉树、红黑树、AVL树、B树、B树、哈希等数据结构都可以实现索引&#xff0c;但其中B树效率最高。MySQL数据库索引使用的是B树。二叉树&#xff1a;二叉树中&#xff0c;左子树比根节点小&a…...

字符函数和字符串函数详解(1)

目录前言strlen函数strlensizeofstrcpy函数strcat函数strcmp函数总结前言 最近要调整状态&#xff0c;写的文章质量不佳让大家失望&#xff0c;我现在也在反思我在做什么&#xff0c;我会什么&#xff0c;我学了什么。等我想明白的那天&#xff0c;我一定能跟大家顶峰相见的&a…...

【数据分析:工具篇】NumPy(1)NumPy介绍

【数据分析&#xff1a;工具篇】NumPy&#xff08;1&#xff09;NumPy介绍NumPy介绍NumPy的特点数组的基本操作创建数组索引和切片数组运算NumPy介绍 NumPy&#xff08;Numerical Python&#xff09;是Python的一个开源的科学计算库&#xff0c;它主要用于处理大规模的多维数组…...

mysql时区问题

设置mysql容器时间与服务器时间一致 问题背景&#xff1a; 今天测试发现一个问题&#xff0c;时间不一致&#xff0c;当工单入库时&#xff0c;其创建时间和更新时间应该是一样的&#xff0c;即使不一样最多只会错几秒的时间&#xff1b;实际上两个时间相差的大概8小时&#…...

磨金石教育摄影技能干货分享|高邮湖上观花海

江苏高邮&#xff0c;说到这里所有人能想到的&#xff0c;就是那烟波浩渺的高邮湖。高邮在旅游方面并不出名&#xff0c;但是这里的自然人文景观绝对不输于其他地方。高邮不止有浩瀚的湖泊&#xff0c;春天的油菜花海同样壮观。春日的午后&#xff0c;与家人相约游玩&#xff0…...

mysql navicat忘记密码

mysql忘记密码是常用的事情&#xff0c;那么如何解决它呢&#xff1f;1、首先将MySQL的服务关闭&#xff0c;两种方法&#xff1a;&#xff08;1&#xff09;打开命令行cmd输入net stop mysql命令即可关闭MySQL服务。&#xff08;2&#xff09;打开任务管理器&#xff0c;找到服…...

Git的下载、安装、配置、使用、卸载

前言 我是跟着狂神老师学的。该博客仅用于笔记所用。 下面是老师的B站和笔记 B站&#xff1a;https://www.bilibili.com/video/BV1FE411P7B3?p1&vd_source9266cf72b1f398b63abe0aefe358d7d6 笔记&#xff1a;https://mp.weixin.qq.com/s/Bf7uVhGiu47uOELjmC5uXQ 一、准备工…...

【博客631】监控网卡与进程网络IO使用情况

监控进程的网络IO使用情况 1、vnstat 由于 vnstat 依赖于内核提供的信息&#xff0c;因此执行以下命令来验证内核是否提供了 vnStat 所期望的所有信息&#xff1a; # vnstat --testkernel This test will take about 60 seconds. Everything is ok.不带任何参数的 vnstat 将…...

【Leetcode】【简单】35. 搜索插入位置

给定一个排序数组和一个目标值&#xff0c;在数组中找到目标值&#xff0c;并返回其索引。如果目标值不存在于数组中&#xff0c;返回它将会被按顺序插入的位置。 请必须使用时间复杂度为 O(log n) 的算法。 示例 1: 输入: nums [1,3,5,6], target 5 输出: 2 示例 2: 输入:…...