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

牛角棋项目实践1:牛角棋的定义和用python实现简单功能

牛角棋的定义:

有这样一种棋,叫牛角棋,也叫十三太保棋,整个棋盘是三角形,中间有横线和斜线,总共13个交叉点,也就是落子点。两个人比赛,一方拿两颗白棋,一方拿一颗黑棋。拿白棋的一方目标是将黑棋堵住不能行走。

下图就是牛角棋的图示,当然这里只画了11个落子点。

具体规则

黑白双方轮流移动棋子,每次只能移动一枚棋子,且只能沿着棋盘上的线条移动到相邻的棋位。比如1可以走到2和3, 而4可以走到2、3、5和6 ,最下面的11可以走到9和10.

牛角棋的规则是由白棋先走。

主要的获胜条件是:白棋一方将另一方也就是黑方棋子围住,导致黑棋无法移动,这时黑棋输。严格的规则是黑棋在1,白棋在2和3,且这时候轮到黑棋走,黑棋被围住,无法行动,这时候白棋就赢了。还有一种较宽松的规则,就是只要黑棋无法行动就输,也就是如果黑棋在11,白棋在9和10,这时候如果轮到黑棋走,黑棋无法行动,黑棋输。一般用严格的规则来判定。

如果双方共计走了80步,白棋还没有赢,则黑棋胜利。也就是超过一定的步数(比如2*交叉点数+3),白棋都没有围住黑棋,那么白棋被判超时(超过步数)输。这个步数可以根据双方的棋力等级调整,还有一种规则,就是白棋走最佳步骤,一步都不错,判白棋赢。如果白棋走错一步,判黑棋赢。

棋盘可以表示为qi=[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] ,共计13个落子点。如果落白子,则用1表示,落黑子,用2表示,0则表示此位置没有任何棋子。比如0号位黑子,表示为qi[0]=2 

11和12位为白子,表示为qi[11]=1 qi[12]=1 ,整个棋盘表示为qi=[2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1]

根据规则,每个子的临近可移动位置是-2 -1 +1 +2 ,但不能超出qi的下标区间,比如qi[0]=2,是黑子, 0-2=-2 0-1=-1 ,这两个为负数,超出0-12的下标,因此要舍弃,不可移动到-1和-2 位置。如果要移动的目标位置有其他其它子(不管是黑子还是白子),也不可以走到该位置。比如qi[0]=2,是黑子,可以移动到0+1 =1 和0+2 =2 这两个坐标,如果移动到下标1,则qi[0]=0 , qi[1]=3 ,棋盘表示为qi=[0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1] 。如果移动到下标2,则qi[0]=0 , qi[2]=3 ,棋盘表示为qi=[0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1] 。同理对qi[12]的白子,可以移动到10, 11  。当然因为11有子,那么就只能移动到10,也就是qi[12]=0 qi[10]=1, 棋盘数据变成qi=[0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0]

棋盘python实现

棋盘初始化

初始棋盘表示为:

board=[2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1]

后来为了可以灵活的设置棋盘大小,设置落子点数为boardsize,这样初始化棋盘的代码为:

boardsize = 13

board = [0] * boardsize

board[0] = 2

board[-1] = 1

board[-2] = 1

最终初始化代码为:

def __init__(self, num=7):
        # 初始化棋盘,13个位置,0表示空,1表示白棋,2表示黑棋
        # self.qi = [2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1]
        # 牛角棋也叫13太保棋,默认是13个位置。测试中设置默认为7个位置
        # 因为所以从0开始,位置的最大索引值为num-1
        self.num = num
        self.maxindex = self.num -1
        self.qi = [0] * self.num
        self.qi[0] = 2
        self.qi[-1] = 1
        self.qi[-2] = 1
        self.total_moves = 0
        self.max_moves = 13*self.num+6
        self.current_player = 'white'  # 白棋先走

将牛角棋的定义传给AI大模型,让它们帮着写代码。

使用海螺AI的实现

根据您提供的牛角棋(十三太保棋)的详细定义和规则,以下是一个完整的Python实现。该实现包括棋盘的表示、棋子的移动、吃子规则以及胜利条件的判断。为了确保与您提供的规则一致,我们将棋盘表示为一个包含13个元素的列表 qi,其中:

  • 0:表示该位置没有棋子。
  • 1:表示白棋(农夫)。
  • 2:表示黑棋(牛)。

实现细节

1.

棋盘表示

  • 使用一个长度为13的列表 qi 来表示棋盘,每个索引对应一个落子点。
  • 初始棋盘设置为 qi = [2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1],其中索引0为黑棋,索引11和12为白棋。

2.

移动规则

  • 白棋和黑棋:每次只能移动一枚棋子,且只能沿着棋盘上的线条移动到相邻的节点。
  • 相邻位置:每个位置的相邻位置为其索引加减1和加减2,但需确保不超出 qi 的索引范围(0到12)。
  • 移动限制:白棋(1)只能向棋盘顶部移动,即只能向索引减小的方向移动;黑棋(2)可以向任意方向移动。

3.

胜利条件

  • 白棋胜利:将黑棋围住,使其无法移动。
  • 黑棋胜利:如果双方共计走了80步,白棋还没有赢,则黑棋胜利。

4.

用户交互

  • 游戏通过命令行进行,玩家交替输入移动指令。
  • 白棋由玩家控制,黑棋由程序自动移动(简单策略:随机移动)。

    Python 实现

    import sys
    import random
    
    class NiuJiaoQi:
        def __init__(self):
            # 初始化棋盘,13个位置,0表示空,1表示白棋,2表示黑棋
            self.qi = [2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1]
            self.total_moves = 0
            self.max_moves = 80
            self.current_player = 'white'  # 白棋先走
    
        def display_board(self):
            """
            显示当前棋盘状态。
            """
            print("\n当前棋盘状态:")
            for idx, piece in enumerate(self.qi):
                if piece == 1:
                    marker = 'W'
                elif piece == 2:
                    marker = 'B'
                else:
                    marker = '.'
                print(f"位置{idx}: {marker}")
            print()
    
        def get_valid_moves(self, position):
            """
            获取指定位置的所有有效移动。
            :param position: 当前棋子的位置(索引)。
            :return: 一个列表,包含可以移动到的位置索引。
            """
            # 相邻位置为-2, -1, +1, +2
            adjacent = [-2, -1, 1, 2]
            valid = []
            for move in adjacent:
                target = position + move
                if 0 <= target <= 12:
                    if self.qi[target] == 0:
                        valid.append(target)
            return valid
    
        def make_move(self, from_pos, to_pos):
            """
            执行移动。
            :param from_pos: 起始位置(索引)。
            :param to_pos: 目标位置(索引)。
            :return: 如果移动合法,返回True;否则返回False。
            """
            if 0 <= from_pos <= 12 and 0 <= to_pos <= 12:
                if self.qi[from_pos] != 0:
                    if self.qi[to_pos] == 0:
                        self.qi[to_pos] = self.qi[from_pos]
                        self.qi[from_pos] = 0
                        return True
            return False
    
        def is_black_trapped(self):
            """
            判断黑棋是否被围住。
            :return: 如果黑棋无法移动,返回True;否则返回False。
            """
            black_pos = self.qi.index(2)
            return len(self.get_valid_moves(black_pos)) == 0
    
        def is_game_over(self):
            """
            判断游戏是否结束。
            :return: 如果游戏结束,返回获胜方('white'或'black');否则返回None。
            """
            if self.is_black_trapped():
                return 'white'
            if self.total_moves >= self.max_moves:
                return 'black'
            return None
    
        def switch_player(self):
            """
            切换当前玩家。
            """
            self.current_player = 'black' if self.current_player == 'white' else 'white'
    
        def play(self):
            """
            开始游戏循环。
            """
            while True:
                self.display_board()
                print(f"当前玩家: {self.current_player}")
                if self.current_player == 'white':
                    from_pos = self.get_player_move('white')
                    to_pos = self.get_player_move('white', from_pos)
                    if self.make_move(from_pos, to_pos):
                        self.total_moves += 1
                        self.switch_player()
                    else:
                        print("无效的移动,请重新选择。")
                else:
                    # 黑棋自动移动(简单策略:随机移动)
                    black_pos = self.qi.index(2)
                    moves = self.get_valid_moves(black_pos)
                    if moves:
                        to_pos = random.choice(moves)
                        self.make_move(black_pos, to_pos)
                        self.total_moves += 1
                        self.switch_player()
                    else:
                        print("黑棋无法移动,白棋胜利!")
                        return
                winner = self.is_game_over()
                if winner:
                    self.display_board()
                    if winner == 'white':
                        print("白棋胜利!黑棋被围住。")
                    else:
                        print("黑棋胜利!达到最大步数。")
                    break
    
        def get_player_move(self, player, from_pos=None):
            """
            获取玩家移动的棋子位置和目标位置。
            :param player: 'white'或'black'
            :param from_pos: 如果提供,则只获取目标位置。
            :return: (from_pos, to_pos)
            """
            if player == 'white':
                if from_pos is None:
                    while True:
                        try:
                            from_pos = int(input("选择要移动的白棋位置(位置索引0-12):"))
                            if 0 <= from_pos <= 12 and self.qi[from_pos] == 1:
                                break
                            else:
                                print("无效的选择。请选择白棋的位置。")
                        except ValueError:
                            print("请输入一个有效的整数。")
                while True:
                    try:
                        to_pos = int(input(f"选择要移动到的位置(位置索引0-12):"))
                        if to_pos in self.get_valid_moves(from_pos):
                            return from_pos, to_pos
                        else:
                            print("无效的移动。请重新选择。")
                    except ValueError:
                        print("请输入一个有效的整数。")
            else:
                # 黑棋自动移动策略(简单策略:随机移动)
                black_pos = self.qi.index(2)
                moves = self.get_valid_moves(black_pos)
                if moves:
                    to_pos = random.choice(moves)
                    return black_pos, to_pos
                else:
                    return None, None
    
    if __name__ == "__main__":
        game = NiuJiaoQi()
        game.play()
    

    代码说明

    1.

    棋盘表示

    • self.qi:长度为13的列表,表示棋盘上的每个位置的状态。
    • 初始棋盘设置为 qi = [2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1],其中索引0为黑棋,索引11和12为白棋。

    2.

    移动逻辑

    • get_valid_moves(position):获取指定位置的所有有效移动,确保不超出棋盘范围且目标位置为空。
    • make_move(from_pos, to_pos):执行移动,更新棋盘状态。
    • is_black_trapped():判断黑棋是否被围住,即黑棋没有有效的移动位置。
    • is_game_over():判断游戏是否结束,包括黑棋被围住或达到最大步数。

    3.

    玩家交互

    • play():游戏主循环,交替进行白棋和黑棋的移动。
    • get_player_move(player, from_pos=None):获取玩家移动的棋子位置和目标位置。白棋由玩家输入,黑棋采用简单策略(随机移动)。
    • get_black_move():黑棋的移动策略,这里采用随机选择相邻节点。

    4.

    胜利判断

    • 如果黑棋被围住,白棋胜利。
    • 如果总步数达到80步,白棋未获胜,则黑棋胜利。

      示例运行

       
      

      取消自动换行

      复制

      当前棋盘状态:
      位置0: B
      位置1: .
      位置2: .
      位置3: .
      位置4: .
      位置5: .
      位置6: .
      位置7: .
      位置8: .
      位置9: .
      位置10: .
      位置11: W
      位置12: W
      
      当前玩家: white
      选择要移动的白棋位置(位置索引0-12):11
      选择要移动到的位置(位置索引0-12):10
      
      当前棋盘状态:
      位置0: B
      位置1: .
      位置2: .
      位置3: .
      位置4: .
      位置5: .
      位置6: .
      位置7: .
      位置8: .
      位置9: .
      位置10: W
      位置11: .
      位置12: W
      
      当前玩家: black
      ...
      

      注意事项

      • 移动策略:当前黑棋的移动策略为随机移动。您可以根据需要实现更复杂的策略,例如避开被围的风险或主动攻击白棋。
      • 棋盘显示:为了简化,棋盘的显示仅为位置索引和棋子位置。您可以扩展 display_board() 方法,使用图形库(如 pygame)来绘制更直观的棋盘。
      • 输入验证:当前实现对玩家输入进行了基本验证,但在实际应用中可能需要更严格的验证和错误处理。

      这个实现提供了一个基础框架,您可以根据具体需求进行扩展和优化,例如添加图形界面、实现更复杂的AI策略或调整游戏规则。

      总结

      这段代码并不能直接运行,主要问题有两点:

      1 会一直询问白棋的索引和移动位置,第二次重复后白棋执行报错can only concatenate tuple (not "int") to tuple,好像是逻辑有点问题。解决问题见调试部分。

      2 白棋之后黑棋报错。是因为刚开始修改白棋报错,是在公共处理部分修改的,导致黑棋的传参有问题。在白棋部分修改,这样黑棋传参就没问题了。

      后来又加上了设置棋盘大小的功能。最终代码最后面。

      文心代码实现

      文心也给了代码,但是初始化里第一句:self.board =  * 13 就把我拦下了,不明白这里为什么这样写,所以这段代码算费了。

      class HornChess:
          def __init__(self):
              # 初始化棋盘,13个位置都为0
              self.board =  * 13
              # 黑棋初始位置在0号位
              self.board = 2
              # 白棋初始位置在11和12号位
              self.board = 1
              self.board = 1
              # 当前步数
              self.steps = 0
              # 当前轮到谁走,1表示白棋,2表示黑棋
              self.current_player = 1
      
          def is_valid_move(self, position, target):
              # 检查目标位置是否在棋盘范围内
              if target < 0 or target >= 13:
                  return False
              # 检查目标位置是否为空
              if self.board[target] != 0:
                  return False
              # 检查移动是否合法(只能移动到相邻位置)
              valid_moves = [position - 2, position - 1, position + 1, position + 2]
              return target in valid_moves
      
          def move_piece(self, position, target):
              # 移动棋子并更新棋盘状态
              self.board[position] = 0
              self.board[target] = self.current_player
              self.steps += 1
              # 切换玩家
              self.current_player = 3 - self.current_player
      
          def check_win(self):
              # 检查白棋是否获胜(黑棋无法移动)
              for i in range(13):
                  if self.board[i] == 2:
                      valid_moves = [i - 2, i - 1, i + 1, i + 2]
                      for move in valid_moves:
                          if 0 <= move < 13 and self.board[move] == 0:
                              return False
              return True
      
          def play(self):
              # 游戏主循环
              while self.steps < 80:
                  self.print_board()
                  # 获取玩家输入(这里简化为自动选择合法移动)
                  moved = False
                  for i in range(13):
                      if self.board[i] == self.current_player:
                          for target in [i - 2, i - 1, i + 1, i + 2]:
                              if self.is_valid_move(i, target):
                                  self.move_piece(i, target)
                                  moved = True
                                  break
                          if moved:
                              break
                  # 检查是否获胜
                  if self.check_win():
                      self.print_board()
                      print(f"Player {self.current_player} wins!")
                      return
                  # 如果80步内没有获胜,则黑棋获胜
              self.print_board()
              print("Player 2 (black) wins by reaching 80 steps!")
      
          def print_board(self):
              # 打印棋盘状态
              board_str = " ".join(str(self.board[i]) for i in range(13))
              print(board_str)
      
      # 创建游戏实例并开始游戏
      game = HornChess()
      game.play()
      

      最终:修改之后的可运行版本

      import sys
      import random
       
      class NiuJiaoQi():
          def __init__(self, num=7):
              # 初始化棋盘,13个位置,0表示空,1表示白棋,2表示黑棋
              # self.qi = [2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1]
              # 牛角棋也叫13太保棋,默认是13个位置。测试中设置默认为7个位置
              # 因为所以从0开始,位置的最大索引值为num-1
              self.num = num
              self.maxindex = self.num -1
              self.qi = [0] * self.num
              self.qi[0] = 2
              self.qi[-1] = 1
              self.qi[-2] = 1
              self.total_moves = 0
              self.max_moves = 13*self.num+6
              self.current_player = 'white'  # 白棋先走
       
          def display_board(self):
              """
              显示当前棋盘状态。
              """
              print("\n当前棋盘状态:")
              for idx, piece in enumerate(self.qi):
                  if piece == 1:
                      marker = 'W'
                  elif piece == 2:
                      marker = 'B'
                  else:
                      marker = '.'
                  print(f"位置{idx}: {marker}")
              print()
       
          def get_valid_moves(self, position):
              """
              获取指定位置的所有有效移动。
              :param position: 当前棋子的位置(索引)。
              :return: 一个列表,包含可以移动到的位置索引。
              """
              # 相邻位置为-2, -1, +1, +2
              adjacent = [-2, -1, 1, 2]
              valid = []
              for move in adjacent:
                  target = position + move
                  if 0 <= target <= self.maxindex:
                      if self.qi[target] == 0:
                          valid.append(target)
              # print(f"当前棋子位置:{position}可移动位置:{valid}")
              return valid
       
          def make_move(self, from_pos, to_pos):
              """
              执行移动。
              :param from_pos: 起始位置(索引)。
              :param to_pos: 目标位置(索引)。
              :return: 如果移动合法,返回True;否则返回False。
              """
              print(f"准备移动,源:{from_pos} 移动到:{to_pos}")
              # to_pos=from_pos[1]
              # from_pos=from_pos[0]
              # print(f"修改后准备移动,源:{from_pos} 移动到:{to_pos}")
              if 0 <= from_pos <= self.maxindex and 0 <= to_pos <= self.maxindex:
                  if self.qi[from_pos] != 0:
                      if self.qi[to_pos] == 0:
                          self.qi[to_pos] = self.qi[from_pos]
                          self.qi[from_pos] = 0
                          # self.display_board()
                          return True
              return False
       
          def is_black_trapped(self):
              """
              判断黑棋是否被围住。
              :return: 如果黑棋无法移动,返回True;否则返回False。
              """
              black_pos = self.qi.index(2)
              return len(self.get_valid_moves(black_pos)) == 0
       
          def is_game_over(self):
              """
              判断游戏是否结束。
              :return: 如果游戏结束,返回获胜方('white'或'black');否则返回None。
              """
              if self.is_black_trapped():
                  return 'white'
              if self.total_moves >= self.max_moves:
                  return 'black'
              return None
       
          def switch_player(self):
              """
              切换当前玩家。
              """
              self.current_player = 'black' if self.current_player == 'white' else 'white'
       
          def play(self):
              """
              开始游戏循环。
              """
              while True:
                  self.display_board()
                  print(f"当前玩家: {self.current_player}")
                  if self.current_player == 'white':
                      from_pos = self.get_player_move('white')
                      # print(f"in play white from_pos:{from_pos}")
                      to_pos = self.get_player_move('white', from_pos)
                      # print(f"in play white to_pos:{to_pos}")
                      to_pos=from_pos[1]
                      from_pos=from_pos[0]
                      # print(f"in play white after change from_pos:{from_pos} to_pos:{to_pos}")
                      if self.make_move(from_pos, to_pos):
                          self.total_moves += 1
                          self.switch_player()
                      else:
                          print("无效的移动,请重新选择。")
                  else:
                      # 黑棋自动移动(简单策略:随机移动)
                      black_pos = self.qi.index(2)
                      moves = self.get_valid_moves(black_pos)
                      if moves:
                          to_pos = random.choice(moves)
                          self.make_move(black_pos, to_pos)
                          self.total_moves += 1
                          self.switch_player()
                      else:
                          print("黑棋无法移动,白棋胜利!")
                          return
                  winner = self.is_game_over()
                  if winner:
                      self.display_board()
                      if winner == 'white':
                          print("白棋胜利!黑棋被围住。")
                      else:
                          print("黑棋胜利!达到最大步数。")
                      break
       
          def get_player_move(self, player, from_pos=None):
              """
              获取玩家移动的棋子位置和目标位置。
              :param player: 'white'或'black'
              :param from_pos: 如果提供,则只获取目标位置。
              :return: (from_pos, to_pos)
              """
              if player == 'white':
                  if from_pos is None:
                      while True:
                          try:
                              # from_pos = int(input(f"选择要移动的白棋位置(位置索引0-{self.maxindex}):"))
                              from_pos = int(input(f"选择要移动的白棋位置(位置索引\
                              {[index for index, value in enumerate(self.qi) if value == 1]}:"))
                              self.get_valid_moves(from_pos)
                              # print(from_pos)
                              if 0 <= from_pos <= self.maxindex and self.qi[from_pos] == 1:
                                  break
                              else:
                                  print("无效的选择。请选择白棋的位置。")
                          except ValueError:
                              print("请输入一个有效的整数。")
                      while True:
                          try:
                              # to_pos = int(input(f"选择要移动到的位置(位置索引0-{self.maxindex}):"))
                              to_pos = int(input(f"选择要移动到的位置(可选位置索引:{self.get_valid_moves(from_pos)}):"))
                              
                              # print(f"目标移动位置:{to_pos}")
                              if to_pos in self.get_valid_moves(from_pos):
                                  # print(f"get_player_move:白棋move ok from {from_pos}to {to_pos}")
                                  return from_pos, to_pos
                                  
                              else:
                                  print("无效的移动。请重新选择。")
                          except ValueError:
                              print("请输入一个有效的整数。")
              else:
                  # 黑棋自动移动策略(简单策略:随机移动)
                  black_pos = self.qi.index(2)
                  print(f"黑棋black_pos:(black_pos)")
                  moves = self.get_valid_moves(black_pos)
                  print(f"黑棋moves:{moves}")
                  if moves:
                      to_pos = random.choice(moves)
                      print(f"black moves:{moves} to_pos:{to_pos}")
                      print(f"get_player_move:黑棋 move ok from {from_pos}to {to_pos}")
                      return black_pos, to_pos
                  else:
                      return None, None
                  
      if __name__ == "__main__":
          game = NiuJiaoQi()
          game.play()

      调试

      白棋执行报错can only concatenate tuple (not "int") to tuple

      ~\AppData\Local\Temp\ipykernel_18688\4084430725.py in get_player_move(self, player, from_pos)
          141                 try:
          142                     to_pos = int(input(f"选择要移动到的位置(位置索引0-12):"))
      --> 143                     if to_pos in self.get_valid_moves(from_pos):
          144                         return from_pos, to_pos
          145                         print(f"move ok from {from_pos}to {to_pos}")
      
      ~\AppData\Local\Temp\ipykernel_18688\4084430725.py in get_valid_moves(self, position)
           35         valid = []
           36         for move in adjacent:
      ---> 37             target = position + move
           38             if 0 <= target <= 12:
           39                 if self.qi[target] == 0:
      
      TypeError: can only concatenate tuple (not "int") to tuple
      
      原来是这段代码
      
                  if self.current_player == 'white':
                      from_pos = self.get_player_move('white')
                      to_pos = self.get_player_move('white', from_pos)
       发现这里from_pos返回的是一个tuple,包含位置和目标,修改代码,让其返回一个值位置,目标值传入to_pos变量:
                  if self.current_player == 'white':
                      from_pos = self.get_player_move('white')
                      # print(f"in play white from_pos:{from_pos}")
                      to_pos = self.get_player_move('white', from_pos)
                      # print(f"in play white to_pos:{to_pos}")
                      to_pos=from_pos[1]
                      from_pos=from_pos[0]


      http://www.kler.cn/a/519591.html

      相关文章:

    1. 2024年度总结:技术探索与个人成长的交织
    2. java后端之事务管理
    3. 破解浏览器渲染“死锁”:CSS与JS如何影响页面加载速度?
    4. Docker快速部署高效照片管理系统LibrePhotos搭建私有云相册
    5. C++的类Class
    6. 为什么IDEA提示不推荐@Autowired❓️如果使用@Resource呢❓️
    7. 大模型开发 | RAG在实际开发中可能遇到的坑
    8. rewrite规则
    9. STL中的list容器
    10. 汇编的使用总结
    11. CSS:跑马灯
    12. 使用MQTT.fx向阿里云物理网平台上报物理模型数据
    13. mysql安装记录
    14. 十、VUE中的CSS
    15. 边缘存储如何高效存储和调用数据?
    16. “AI教学实训系统:打造未来教育的超级引擎
    17. C# OpenCV机器视觉:利用CNN实现快速模板匹配
    18. 【JS|第29期】JavaScript中的事件类型
    19. 【PySide6 快速入门】第一个QtWidget程序
    20. 1_相向双指针_leetcode_16_4
    21. AWS Outposts
    22. 低代码系统-钉、微表单控件对比
    23. VMware 的 AWS
    24. 【C++高并发服务器WebServer】-5:内存映射与进程通信
    25. 【中间件快速入门】什么是Redis
    26. Java使用FFM API调用SDL