2024全国大学生电子设计大赛全国初赛 E题 三子棋游戏装置 一等奖满分最简方案

感想:电赛初赛控制类题还是蛮简单的,别被五花八门的硬件搞懵了(决赛当我没说)。抓住核心,理念都是通用的。我是计科专业的,因此选择的控制类E题,相对来说背的知识要少很多,更考验智商。其实电赛结果都不重要,在电赛经历中对自己的磨练,尤其是“所想即所得”的快感弥足珍贵。要不是参加电赛,我都不敢想象自己做了一个人机对弈装置。通过电赛,见到了更宽广的世界。

声明:本文中绝大部分算法(所有核心算法)均是我个人想出来的,部分细节由队友补充,转载请私信!严禁盗代码!如果我发现谁盗我代码我直接全网曝光并且停更!

前言:我本人一向以天才自居,算法也都是最简洁干练的(那些艰深晦涩而复杂的算法往往是愚蠢的人写出),很多人劝我不要把代码开源,我偏要,我看不惯CSDN的那些VIP专栏,那是把智慧锁进了笼子里。文章格式就懒得调了。如果你们发现本文在逻辑上有缺失的部分,欢迎私信我进行补充!

三个核心算法:

1.棋子识别。

通过识别棋盘方格,计算差分列表,得出棋盘状态变化情况,根据黑棋先行的规则确定棋谱并保存。由于扰动的存在,实际每帧中方格的位置都会变化,因此通过计算汉明距离来匹配方格(待匹配方格与base(全局静态变量,初始九宫格)中九个方格进行比较)。理想情况汉明距离为一个方格,我取一半(当然也可以取1/3)。

// 计算两个点之间的距离
double distance(position p1, position p2)
{
   
    return sqrt((p1.x - p2.x) * (p1.x - p2.x) + (p1.y - p2.y) * (p1.y - p2.y));
}

// 寻找A中满足条件的点,并返回满足条件的点的个数
int find_points(position A[], int sizeA, position B[], int sizeB, position result[])
{
   
    int i, j;
    double threshold;
    int result_count = 0;
    threshold = g_min_distance;

    // 遍历A中的点,判断是否满足条件
    for (i = 0; i < sizeA; ++i)
    {
   
        int satisfies = 1;
        for (j = 0; j < sizeB; ++j)
        {
   
            if (distance(A[i], B[j]) <= threshold)
            {
   
                satisfies = 0;
            }
        }
        if (satisfies)
        {
   
            result[result_count++] = A[i];
        }
    }

    return result_count;
}

double hamming(void)
{
    // 计算汉明距离
    double min_distance = 99999;
    int i, j;
    g_min_distance = 99999;
    for (i = 0; i < 9; ++i)
    {
   
        for (j = i + 1; j < 9; ++j)
        {
   
            double d = distance(g_base[i], g_base[j]);
            if (d < min_distance)
            {
   
                min_distance = d;
            }
        }
    }
    g_min_distance = min_distance / 2;
    return min_distance;
}

position bind(u8 key)
{
   
    return g_base[key - 1];
}

u8 label_1(position pos)
{
   
    int i;
    position tem;
    for (i = 1; i < 10; i++)
    {
   
        tem = bind(i);
        if (distance(pos, tem) < g_min_distance)
        {
   
            return i;
        }
    }
    return 0;
}

position findpawns(position *fields, u8 lens)
{
   

    int result_count;

    int i;
    int j;
    int k;
    int h;
    position result[MAX_POINTS];
    position result2[MAX_POINTS];
    u8 disp[9] = {
   0};
    u8 comp[9] = {
   0};
    u8 compcnt = 0;
    static position PreResult[MAX_POINTS];
    static u8 PreResultCnt = 0;
    u8 key1;
    u8 key2;
    u8 sat;
	position a;
    if (lens == prefield_len) // 悔棋判定
    {
   
        for (j = 0; j < lens; j++)
        {
   
            disp[j] = label_1(fields[j]);
        }

        for (k = 1; k < 10; k++)
        {
   	
						sat = 1;
            for (h = 0; h < g_u8BordCnt; h++)
            {
   		
								if (k == g_u8Bord[h])
                {
   
                    sat = 0;
                }
                
            }
						if (sat==1)
                {
   
                    comp[compcnt] = k;
                    compcnt++;
                }
        }
        for (j = 0; j < lens; j++)
        {
   
            sat = 1;
            for (k = 0; k < lens; k++)
            {
   
                if (disp[j] == comp[k])
                {
   
                    sat = 0;
                }
            }
            if
### 使用 OpenCV 实现三子游戏开发教程 #### 1. 环境搭建 为了使用 OpenCV 来实现三子游戏,首先需要确保已经成功安装了 OpenCV 库。对于 Ubuntu 16.04 用户来说,可以按照特定指南来完成这一过程[^1]。 ```bash sudo apt-get update sudo apt-get install python-opencv ``` #### 2. 图像采集与预处理 通过摄像头或其他图像源获取实时视频流,并对其进行必要的灰度化、二值化等操作以便后续分析。 ```python import cv2 cap = cv2.VideoCapture(0) while True: ret, frame = cap.read() gray_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) # 显示窗口 cv2.imshow('Gray Frame', gray_frame) if cv2.waitKey(1) & 0xFF == ord('q'): break cap.release() cv2.destroyAllWindows() ``` #### 3. 盘检测 利用形态学变换以及轮廓查找技术识别出完整的九宫格区域作为盘位置。 ```python _, thresh = cv2.threshold(gray_frame, 127, 255, cv2.THRESH_BINARY_INV) kernel = np.ones((5,5),np.uint8) dilation = cv2.dilate(thresh,kernel,iterations = 1) contours, _ = cv2.findContours(dilation.copy(), cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)[-2:] largest_contour = max(contours, key=cv2.contourArea) epsilon = 0.1*cv2.arcLength(largest_contour,True) approx = cv2.approxPolyDP(largest_contour, epsilon, True) if len(approx)==4: screenCnt = approx else: pass ``` #### 4. 子件分 基于颜色特征区分黑白两方的子,在此之前可能还需要做一次更精细的颜色空间转换(如 HSV 转换),从而提高准确性。 ```python hsv_img = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV) lower_black = np.array([0,0,0]) upper_black = np.array([180,255,30]) mask_black = cv2.inRange(hsv_img, lower_black, upper_black) res_black = cv2.bitwise_and(frame,frame, mask= mask_black) ``` #### 5. 下一步预测算法设计 考虑到这是一个单的博弈论问,可以采用 MiniMax 或 Alpha-Beta 剪枝法来进行下一步的佳走位计算;当然也可以引入机器学习模型训练历史数据集以获得更好的效果。
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值