2024电赛E题三子棋游戏第1、2、4、5题

四天三夜做出来的,主要修改的openmv开源的代码。自制的机械臂装置,老师来评测的时候因为机械臂不稳固,导致机械臂没办法到写死的坐标,就只算了前两问。但是经过测试证明4、5问的逻辑是正确的。只用到openmv,三个舵机直接通过openmv驱动。

openmv摄像头在最顶上,机械臂摆放位置如图。末端改成了电磁铁,还是继电器加电磁铁好用点,比一开始的用软磁铁直接吸的方案好多了。

第一题代码

from pyb import Pin, Timer, Servo
import time
import math

# 控制继电器,继电器控制电磁铁
pin4 = Pin('P4', Pin.OUT_PP, Pin.PULL_NONE)
pin4.value(0)

# 定义舵机连接的引脚
servo_pins = ['P7', 'P8', 'P9']

# 创建 Timer 对象
tim = Timer(4, freq=50)

# 创建 PWM 通道并添加到列表 servos
servos = []
for pin in servo_pins:
    s = Pin(pin)
    channel_number = servo_pins.index(pin) + 1  # 通道编号从 1 开始
    channel = tim.channel(channel_number, Timer.PWM, pin=s)
    servos.append(channel)


# 设置舵机的最小和最大脉宽
min_us = 500
max_us = 2500

# 三个舵机的初始位置
servo_positions = [260, 155, 180]

# 控制一个舵机移动
def move(index, angle):
    pulse_width = int(min_us + (max_us - min_us) * angle / 180)
    servos[index].pulse_width(pulse_width)
    servo_positions[index] = angle

# 控制三个舵机移动
def move_list(angle_list):
    for index, angle in enumerate(angle_list):
        move(index, angle)

# 控制三个舵机慢速移动
def slow_move_to(angle_list):

    init_positions = servo_positions.copy()

    d0 = angle_list[0] - init_positions[0]
    d1 = angle_list[1] - init_positions[1]
    d2 = angle_list[2] - init_positions[2]

    dm = int(max(abs(d0), abs(d1), abs(d2)))
    if dm == 0:
        return

    for i in range(dm+1):
        move_list([
            init_positions[0]+i*d0/dm,
            init_positions[1]+i*d1/dm,
            init_positions[2]+i*d2/dm
        ])
        time.sleep_ms(40)

# 设置棋子拾取区的位置
PICK_WHITE = [[188,230,88],[186,200,137],[185,182,168],[182,173,194],[175,167,222]]
PICK_BLACK = [[250,230,80], [252,200,130], [257,185,160], [262,180,190], [265,165,217]]

# 拾取区机械臂提起来的位置
HIGH_PICK = [240, 120, 200]

# 棋盘的放置位置
BOARD = [
    [[238,194,154], [219,193,155], [202,192,154]],
    [[238,163,195], [220,168,200], [196,180,196]],
    [[243,150,240], [220,153,231], [202,158,232]]
]

# 棋盘落子上方的位置
HIGH_BOARD = [230,160,130]


# 拾取棋子,并放置到 x,y
def pick_and_place(x,y):

    slow_move_to(HIGH_PICK)
    time.sleep_ms(500)

    slow_move_to(PICK_BLACK[4])
    time.sleep_ms(500)
    pin4.value(1) # 继电器打开
    time.sleep_ms(500)

    slow_move_to(HIGH_PICK)
    time.sleep_ms(500)

#    slow_move_to(HIGH_BOARD)
#    time.sleep_ms(500)

    slow_move_to(BOARD[x][y])
    time.sleep_ms(500)
    pin4.value(0) # 继电器关闭
    time.sleep_ms(500)

    slow_move_to(HIGH_PICK)


    slow_move_to([270,150,150])


if __name__ == "__main__":
    # 校准测试用
    time.sleep_ms(1)

#    for order in [
#        BOARD[1][1], BOARD[0][0], BOARD[1][0],
#        BOARD[2][0], BOARD[2][1], BOARD[2][2],
#        BOARD[1][2], BOARD[0][2], BOARD[0][1],
#    ]:
#        slow_move_to(HIGH_BOARD)
#        time.sleep_ms(500)
#        slow_move_to(order)
#        time.sleep_ms(500)
    pick_and_place(1,1)
#    slow_move_to(BOARD[1][1])
#    time.sleep_ms(5000)

#    slow_move_to(servo_positions)
#    time.sleep_ms(4000)
#    slow_move_to([240, 150, 150])
#    time.sleep_ms(500)
#    slow_move_to([247,205,229])
#    time.sleep_ms(500)
#    slow_move_to([90,90,90])

第二题代码

from pyb import Pin, Timer, Servo,LED
import time
import math

# 控制继电器,继电器控制电磁铁
pin4 = Pin('P4', Pin.OUT_PP, Pin.PULL_NONE)
pin4.value(0)
# 定义按键连接的引脚
button1_pin = 'P0'
button2_pin = 'P1'
button3_pin = 'P2'

# 定义舵机连接的引脚
servo_pins = ['P7', 'P8', 'P9']

# 创建 Pin 对象
button1 = Pin(button1_pin, Pin.IN, Pin.PULL_UP)
button2 = Pin(button2_pin, Pin.IN, Pin.PULL_UP)


# 创建 Timer 对象
tim = Timer(4, freq=50)

# 创建 PWM 通道并添加到列表 servos
servos = []
for pin in servo_pins:
    s = Pin(pin)
    channel_number = servo_pins.index(pin) + 1  # 通道编号从 1 开始
    channel = tim.channel(channel_number, Timer.PWM, pin=s)
    servos.append(channel)
# 设置舵机的最小和最大脉宽
min_us = 500
max_us = 2500

# 三个舵机的初始位置
servo_positions = [260, 155, 180]

# 控制一个舵机移动
def move(index, angle):
    pulse_width = int(min_us + (max_us - min_us) * angle / 180)
    servos[index].pulse_width(pulse_width)
    servo_positions[index] = angle

# 控制三个舵机移动
def move_list(angle_list):
    for index, angle in enumerate(angle_list):
        move(index, angle)

# 控制三个舵机慢速移动
def slow_move_to(angle_list):

    init_positions = servo_positions.copy()

    d0 = angle_list[0] - init_positions[0]
    d1 = angle_list[1] - init_positions[1]
    d2 = angle_list[2] - init_positions[2]

    dm = int(max(abs(d0), abs(d1), abs(d2)))
    if dm == 0:
        return

    for i in range(dm+1):
        move_list([
            init_positions[0]+i*d0/dm,
            init_positions[1]+i*d1/dm,
            init_positions[2]+i*d2/dm
        ])
        time.sleep_ms(40)

# 设置棋子拾取区的位置
PICK_WHITE = [[188,230,88],[186,200,137],[185,182,168],[182,173,194],[175,167,222]]
PICK_BLACK = [[250,230,80], [252,200,130], [257,185,160], [262,180,190], [265,165,217]]

# 拾取区机械臂提起来的位置
HIGH_PICK = [250, 120, 200]

# 棋盘的放置位置
BOARD = [
    [[238,194,154], [219,193,155], [202,192,154]],
    [[238,163,195], [220,168,200], [196,180,196]],
    [[243,150,240], [220,153,231], [202,158,232]]
]

# 棋盘落子上方的位置
HIGH_BOARD = [230,160,130]


# 拾取棋子,并放置到 x,y
def pick_and_place(pick, x, y):
    slow_move_to(HIGH_PICK)
    time.sleep_ms(500)

    # 从pick列表中提取坐标值
    a, b, c = pick

    slow_move_to([a, b, c])
    time.sleep_ms(500)
    pin4.value(1)  # 继电器打开
    time.sleep_ms(500)

    slow_move_to(HIGH_PICK)
    time.sleep_ms(500)

    slow_move_to(HIGH_BOARD)
    time.sleep_ms(500)

    slow_move_to(BOARD[x][y])
    time.sleep_ms(500)
    pin4.value(0)  # 继电器关闭
    time.sleep_ms(500)

    slow_move_to(HIGH_PICK)

#定义按键相关变量
position_index = [0,0]
button_press_count = 0
program_running = False
last_button1_state = button1.value()
last_button2_state = button2.value()
debounce_delay = 20  # 消抖延迟时间(毫秒)


if __name__ == "__main__":
    # 校准测试用
    time.sleep_ms(1)

    # 确保在程序开始时将舵机移动到一个安全位置
    slow_move_to(servo_positions)
    time.sleep_ms(500)

    while True:
        current_button1_state = button1.value()
        current_button2_state = button2.value()

        # 检测按键 1 的状态
        if last_button1_state != current_button1_state:
            time.sleep_ms(debounce_delay)
            current_button1_state = button1.value()
            if last_button1_state != current_button1_state:
                if not current_button1_state:
                    position_index[1] += 1
                    if position_index[1] >= len(BOARD[position_index[0]]):
                        position_index[1] = 0
                        position_index[0] += 1
                        if position_index[0] >= len(BOARD):
                            position_index[0] = 0
                    print(f"Position: {position_index[0]}, {position_index[1]}")
                last_button1_state = current_button1_state

        # 检测按键 2 的状态
        if last_button2_state != current_button2_state:
           time.sleep_ms(debounce_delay)
           current_button2_state = button2.value()
           if last_button2_state != current_button2_state:
               if not current_button2_state and not program_running:
                   print("Button2 pressed.")
                   button_press_count += 1
                   program_running = True

                   # 根据按钮按下的次数执行不同的动作
                   if button_press_count == 1:
                       print("First press.")
                       pick_and_place(PICK_BLACK[4], position_index[0], position_index[1])
                   elif button_press_count == 2:
                       print("Second press.")
                       pick_and_place(PICK_BLACK[3], position_index[0], position_index[1])
                   elif button_press_count == 3:
                       print("Third press.")
                       pick_and_place(PICK_WHITE[4], position_index[0], position_index[1])
                   elif button_press_count == 4:
                       print("Fourth press.")
                       pick_and_place(PICK_WHITE[3], position_index[0], position_index[1])
                       button_press_count = 0  # 重置计数器

                   # 程序执行完成后,重置程序运行标志
                   program_running = False
                   print("Program finished.")

               last_button2_state = current_button2_state

        time.sleep_ms(50)  # 等待以减少 CPU 负载

第四题代码

from pyb import Pin, Timer, Servo,LED
import sensor, image, time
import time
import math

sensor.reset()
sensor.set_pixformat(sensor.GRAYSCALE)
sensor.set_framesize(sensor.QVGA)
sensor.skip_frames(time = 2000)

clock = time.clock()


# 轻触开关
pin0 = Pin('P2', Pin.IN, Pin.PULL_UP)
red_led   = LED(1)

distance = 39
block = 25

# 控制继电器,继电器控制电磁铁
pin4 = Pin('P4', Pin.OUT_PP, Pin.PULL_NONE)
pin4.value(0)

# 定义舵机连接的引脚
servo_pins = ['P7', 'P8', 'P9']

# 创建 Timer 对象
tim = Timer(4, freq=50)

# 创建 PWM 通道并添加到列表 servos
servos = []
for pin in servo_pins:
    s = Pin(pin)
    channel_number = servo_pins.index(pin) + 1  # 通道编号从 1 开始
    channel = tim.channel(channel_number, Timer.PWM, pin=s)
    servos.append(channel)

SIZE = 3
def check_win(board, player):
    for i in range(SIZE):
        if all(board[i][j] == player for j in range(SIZE)) or \
           all(board[j][i] == player for j in range(SIZE)):
            return True
    if all(board[i][i] == player for i in range(SIZE)) or \
       all(board[i][SIZE - 1 - i] == player for i in range(SIZE)):
        return True
    return False
def check_draw(board):
    return all(board[i][j] != ' ' for i in range(SIZE) for j in range(SIZE))
def minimax(board, depth, is_maximizing):
    computer = 'X'
    player = 'O'
    if check_win(board, computer):
        return 10 - depth
    if check_win(board, player):
        return depth - 10
    if check_draw(board):
        return 0
    if is_maximizing:
        best_score = float('-inf')
        for i in range(SIZE):
            for j in range(SIZE):
                if board[i][j] == ' ':
                    board[i][j] = computer
                    score = minimax(board, depth + 1, False)
                    board[i][j] = ' '
                    best_score = max(score, best_score)
        return best_score
    else:
        best_score = float('inf')
        for i in range(SIZE):
            for j in range(SIZE):
                if board[i][j] == ' ':
                    board[i][j] = player
                    score = minimax(board, depth + 1, True)
                    board[i][j] = ' '
                    best_score = min(score, best_score)
        return best_score
def computer_move(board):
    if board == [
        [" "," "," "],
        [" "," "," "],
        [" "," "," "]
    ]:
        return 1,1
    best_score = float('-inf')
    move = (-1, -1)
    for i in range(SIZE):
        for j in range(SIZE):
            if board[i][j] == ' ':
                board[i][j] = 'X'
                score = minimax(board, 0, False)
                board[i][j] = ' '
                if score > best_score:
                    best_score = score
                    move = (i, j)
    if move != (-1, -1):
        print(f"Computer places X at ({move[0]}, {move[1]})")
        return move[0], move[1]
def check_turn(board):
    x_count = sum(row.count("X") for row in board)
    o_count = sum(row.count("O") for row in board)
    return "X" if x_count == o_count else "O"


# 设置舵机的最小和最大脉宽
min_us = 500
max_us = 2500

# 三个舵机的初始位置
servo_positions = [260, 155, 180]

# 控制一个舵机移动
def move(index, angle):
    pulse_width = int(min_us + (max_us - min_us) * angle / 180)
    servos[index].pulse_width(pulse_width)
    servo_positions[index] = angle

# 控制三个舵机移动
def move_list(angle_list):
    for index, angle in enumerate(angle_list):
        move(index, angle)

# 控制三个舵机慢速移动
def slow_move_to(angle_list):

    init_positions = servo_positions.copy()

    d0 = angle_list[0] - init_positions[0]
    d1 = angle_list[1] - init_positions[1]
    d2 = angle_list[2] - init_positions[2]

    dm = int(max(abs(d0), abs(d1), abs(d2)))
    if dm == 0:
        return

    for i in range(dm+1):
        move_list([
            init_positions[0]+i*d0/dm,
            init_positions[1]+i*d1/dm,
            init_positions[2]+i*d2/dm
        ])
        time.sleep_ms(40)

# 设置棋子拾取区的位置
PICK_WHITE = [[188,230,88],[186,200,137],[185,182,168],[182,173,194],[175,167,222]]
PICK_BLACK = [[250,230,80], [252,200,130], [257,185,160], [262,180,190], [265,165,217]]

# 拾取区机械臂提起来的位置
HIGH_PICK = [240, 120, 200]

# 棋盘的放置位置
BOARD = [
    [[238,194,154], [219,193,155], [202,192,154]],
    [[238,163,195], [220,168,200], [196,180,196]],
    [[243,150,240], [220,153,231], [202,158,232]]
]

# 棋盘落子上方的位置
HIGH_BOARD = [230,160,130]


# 添加全局变量 picked_count
picked_count = 4

# 修改 pick_and_place 函数
def pick_and_place(x, y):

    global picked_count

    slow_move_to(HIGH_PICK)
    time.sleep_ms(500)

    slow_move_to(PICK_BLACK[picked_count])
    time.sleep_ms(500)
    pin4.value(1) # 继电器打开
    time.sleep_ms(500)

    slow_move_to(HIGH_PICK)
    time.sleep_ms(500)

    slow_move_to(HIGH_BOARD)
    time.sleep_ms(500)

    slow_move_to(BOARD[y][x])
    time.sleep_ms(500)
    pin4.value(0) # 继电器关闭
    time.sleep_ms(500)

    slow_move_to(HIGH_PICK)
    time.sleep_ms(100)

    slow_move_to([270,150,150])
    time.sleep_ms(500)

    # 更新 picked_count
    picked_count -= 1



if __name__ == "__main__":
    # 生成九宫格的区域位置
    def generate_centered_rois(width, height, b, k):
        rois = []

        # 计算每个ROI中心的位置偏移
        offset = (b - k) // 2

        # 计算整个3x3矩阵的宽度和高度
        total_width = 3 * b
        total_height = 3 * b

        # 计算左上角的起始点,使矩阵居中
        start_x = (width - total_width) // 2
        start_y = (height - total_height) // 2

        for i in range(3):
            row = []
            for j in range(3):
                x_center = start_x + j * b + b // 2
                y_center = start_y + i * b + b // 2
                x = x_center - k // 2
                y = y_center - k // 2
                row.append((x, y, k, k))
            rois.append(row)

        return rois


    # 九宫格的区域位置
    rois = generate_centered_rois(sensor.width(), sensor.height(), distance, block)


    # 棋盘数组
    # 黑子:X
    # 白子:O
    # 没有棋子:空字符串
    board = [
         [" "," "," "],
         [" "," "," "],
         [" "," "," "],
    ]


    #等开关按下并松开
    def wait_key():
        while pin0.value():
            img = sensor.snapshot().lens_corr(1.8)
            for y in range(len(rois)):
                for x in range(len(rois[y])):
                    img.draw_rectangle(rois[y][x])
        while not pin0.value():
            time.sleep_ms(1)


    while(True):
        clock.tick()
        wait_key()
        img = sensor.snapshot().lens_corr(1.8)


        # 图像识别得到棋盘数组
        for y in range(len(rois)):
            for x in range(len(rois[y])):
                gray = img.get_statistics(roi=rois[y][x]).mean()
                if gray < 100:
                    board[y][x] = "X"
                elif gray > 200:
                    board[y][x] = "O"
                else:
                    board[y][x] = " "


        # 打印当前棋盘数组
        for line in board:
            print(line)
        print()


        # 画棋盘数组
        for y in range(len(rois)):
            for x in range(len(rois[y])):
                if board[y][x] == "X":
                    color = 255
                elif board[y][x] == "O":
                    color = 0
                elif board[y][x] == " ":
                    color = 127
                img.draw_rectangle(rois[y][x], color=color)


        # 下棋策略
        if check_win(board, 'O'):
            print("你赢啦!")

        elif check_win(board, 'X'):
            print("我赢啦!")
        elif check_draw(board):
            print("平局啦!")
        elif check_turn(board) == "X":
            # 计算下一步棋子放在哪里
            line,row = computer_move(board)
            # 目标棋盘上画十字
            img.draw_cross(int(rois[line][row][0]+block/2), int(rois[line][row][1]+block/2), size=block, color=0)
            sensor.flush()
            # 机器人拾取并放置棋子
            pick_and_place(row, line)
            sensor.flush()
            red_led.on()
            time.sleep_ms(500)
            red_led.off()
            time.sleep_ms(500)
        elif check_turn(board) == "O":
            print("该你下了!")

第五题代码

from pyb import Pin, Timer, Servo,LED
import sensor, image, time
import time
import math

sensor.reset()
sensor.set_pixformat(sensor.GRAYSCALE)
sensor.set_framesize(sensor.QVGA)
sensor.skip_frames(time = 2000)

clock = time.clock()


# 轻触开关
pin0 = Pin('P2', Pin.IN, Pin.PULL_UP)
red_led   = LED(1)

distance = 40
block = 15

# 控制继电器,继电器控制电磁铁
pin4 = Pin('P4', Pin.OUT_PP, Pin.PULL_NONE)
pin4.value(0)

# 定义舵机连接的引脚
servo_pins = ['P7', 'P8', 'P9']

# 创建 Timer 对象
tim = Timer(4, freq=50)

# 创建 PWM 通道并添加到列表 servos
servos = []
for pin in servo_pins:
    s = Pin(pin)
    channel_number = servo_pins.index(pin) + 1  # 通道编号从 1 开始
    channel = tim.channel(channel_number, Timer.PWM, pin=s)
    servos.append(channel)

SIZE = 3
def check_win(board, player):
    for i in range(SIZE):
        if all(board[i][j] == player for j in range(SIZE)) or \
           all(board[j][i] == player for j in range(SIZE)):
            return True
    if all(board[i][i] == player for i in range(SIZE)) or \
       all(board[i][SIZE - 1 - i] == player for i in range(SIZE)):
        return True
    return False
def check_draw(board):
    return all(board[i][j] != ' ' for i in range(SIZE) for j in range(SIZE))
def minimax(board, depth, is_maximizing):
    computer = 'X'
    player = 'O'
    if check_win(board, computer):
        return 10 - depth
    if check_win(board, player):
        return depth - 10
    if check_draw(board):
        return 0
    if is_maximizing:
        best_score = float('-inf')
        for i in range(SIZE):
            for j in range(SIZE):
                if board[i][j] == ' ':
                    board[i][j] = computer
                    score = minimax(board, depth + 1, False)
                    board[i][j] = ' '
                    best_score = max(score, best_score)
        return best_score
    else:
        best_score = float('inf')
        for i in range(SIZE):
            for j in range(SIZE):
                if board[i][j] == ' ':
                    board[i][j] = player
                    score = minimax(board, depth + 1, True)
                    board[i][j] = ' '
                    best_score = min(score, best_score)
        return best_score
def computer_move(board):
    if board == [
        [" "," "," "],
        [" "," "," "],
        [" "," "," "]
    ]:
        return 1,1
    best_score = float('-inf')
    move = (-1, -1)
    for i in range(SIZE):
        for j in range(SIZE):
            if board[i][j] == ' ':
                board[i][j] = 'X'
                score = minimax(board, 0, False)
                board[i][j] = ' '
                if score > best_score:
                    best_score = score
                    move = (i, j)
    if move != (-1, -1):
        print(f"Computer places X at ({move[0]}, {move[1]})")
        return move[0], move[1]
def check_turn(board):
    x_count = sum(row.count("X") for row in board)
    o_count = sum(row.count("O") for row in board)
    return "X" if x_count == o_count else "O"


# 设置舵机的最小和最大脉宽
min_us = 500
max_us = 2500

# 三个舵机的初始位置
servo_positions = [260, 155, 180]

# 控制一个舵机移动
def move(index, angle):
    pulse_width = int(min_us + (max_us - min_us) * angle / 180)
    servos[index].pulse_width(pulse_width)
    servo_positions[index] = angle

# 控制三个舵机移动
def move_list(angle_list):
    for index, angle in enumerate(angle_list):
        move(index, angle)

# 控制三个舵机慢速移动
def slow_move_to(angle_list):

    init_positions = servo_positions.copy()

    d0 = angle_list[0] - init_positions[0]
    d1 = angle_list[1] - init_positions[1]
    d2 = angle_list[2] - init_positions[2]

    dm = int(max(abs(d0), abs(d1), abs(d2)))
    if dm == 0:
        return

    for i in range(dm+1):
        move_list([
            init_positions[0]+i*d0/dm,
            init_positions[1]+i*d1/dm,
            init_positions[2]+i*d2/dm
        ])
        time.sleep_ms(40)

# 设置棋子拾取区的位置
PICK_WHITE = [[188,230,88],[186,200,137],[185,182,168],[182,173,194],[175,167,222]]
PICK_BLACK = [[250,230,80], [252,200,130], [257,185,160], [262,180,190], [265,165,217]]

# 拾取区机械臂提起来的位置
HIGH_PICK = [240, 120, 200]

# 棋盘的放置位置
BOARD = [
    [[238,194,154], [219,193,155], [202,192,154]],
    [[238,163,195], [220,168,200], [196,180,196]],
    [[243,150,240], [220,153,231], [202,158,232]]
]

# 棋盘落子上方的位置
HIGH_BOARD = [230,160,130]


# 添加全局变量 picked_count
picked_count = 4

# 修改 pick_and_place 函数
def pick_and_place(x, y):

    global picked_count

    slow_move_to(HIGH_PICK)
    time.sleep_ms(500)

    slow_move_to(PICK_WHITE[picked_count])
    time.sleep_ms(500)
    pin4.value(1) # 继电器打开
    time.sleep_ms(500)

    slow_move_to(HIGH_PICK)
    time.sleep_ms(500)

    slow_move_to(HIGH_BOARD)
    time.sleep_ms(500)

    slow_move_to(BOARD[y][x])
    time.sleep_ms(500)
    pin4.value(0) # 继电器关闭
    time.sleep_ms(500)

    slow_move_to(HIGH_PICK)
    time.sleep_ms(100)

    slow_move_to([270,150,150])
    time.sleep_ms(500)

    # 更新 picked_count
    picked_count -= 1



if __name__ == "__main__":
    # 生成九宫格的区域位置
    def generate_centered_rois(width, height, b, k):
        rois = []

        # 计算每个ROI中心的位置偏移
        offset = (b - k) // 2

        # 计算整个3x3矩阵的宽度和高度
        total_width = 3 * b
        total_height = 3 * b

        # 计算左上角的起始点,使矩阵居中
        start_x = (width - total_width) // 2
        start_y = (height - total_height) // 2

        for i in range(3):
            row = []
            for j in range(3):
                x_center = start_x + j * b + b // 2
                y_center = start_y + i * b + b // 2
                x = x_center - k // 2
                y = y_center - k // 2
                row.append((x, y, k, k))
            rois.append(row)

        return rois


    # 九宫格的区域位置
    rois = generate_centered_rois(sensor.width(), sensor.height(), distance, block)


    # 棋盘数组
    # 黑子:X
    # 白子:O
    # 没有棋子:空字符串
    board = [
         [" "," "," "],
         [" "," "," "],
         [" "," "," "],
    ]


    #等开关按下并松开
    def wait_key():
        while pin0.value():
            img = sensor.snapshot().lens_corr(1.8)
            for y in range(len(rois)):
                for x in range(len(rois[y])):
                    img.draw_rectangle(rois[y][x])
        while not pin0.value():
            time.sleep_ms(1)


    while(True):
        clock.tick()
        wait_key()
        img = sensor.snapshot().lens_corr(1.8)


        # 图像处理部分
        gray_threshold_black = 100  # 调整此值以适应实际情况
        gray_threshold_white = 200  # 调整此值以适应实际情况

        # 图像识别得到棋盘数组
        for y in range(len(rois)):
            for x in range(len(rois[y])):
                gray = img.get_statistics(roi=rois[y][x]).mean()
                if gray < gray_threshold_black:
                    board[y][x] = "X"
                elif gray > gray_threshold_white:
                    board[y][x] = "O"
                else:
                    board[y][x] = " "

            # 打印当前棋盘数组
            for line in board:
                print(line)
            print()


            # 画棋盘数组
            for y in range(len(rois)):
                for x in range(len(rois[y])):
                    if board[y][x] == "X":
                        color = 255
                    elif board[y][x] == "O":
                        color = 0
                    elif board[y][x] == " ":
                        color = 127
                    img.draw_rectangle(rois[y][x], color=color)


        # 下棋策略
        if check_turn(board) == "O":
            # 计算下一步棋子放在哪里
            line, row = computer_move(board)
            # 目标棋盘上画十字
            img.draw_cross(int(rois[line][row][0]+block/2), int(rois[line][row][1]+block/2), size=block, color=0)
            sensor.flush()
            # 机器人拾取并放置棋子
            pick_and_place(row, line)
            sensor.flush()
            red_led.on()
            time.sleep_ms(500)
            red_led.off()
            time.sleep_ms(500)




这些代码很多一样的地方,大家也可以直接去openmv上找三子棋的代码。然后我感觉把block改小识别的会更准确。

以下是运行的图

  • 20
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值