zoukankan      html  css  js  c++  java
  • 结对编程作业

    一、链接
    github博客链接:https://github.com/031804120/huarongdao
    队友博客链接:https://www.cnblogs.com/sunqingqing/p/13799014.html
    队友孙晴晴的github链接:https://github.com/031804126/pairWork
    游戏部分为Java语言,AI大比拼代码重点内容为python。
    具体分工:

    • 二、原型设计
      (1)设计说明:
      1、HTML界面主要分为两部分,游戏菜单部分和游戏活动区域。
      2、整个html文件采用flex布局,所以css文件里需要使用flex布局实现html文件的界面需求;总体布局采用列方向排列子元素;然后每一列中采用行方向排列子元素。

    3、进行游戏的区域中内容通过JS动态生成
    所以生成的界面是这样的。

    在这个界面内,实现的功能有:
    关于更换游戏图片的实现
    因为要动态更换图片,所以我们需要一个全局变量来记录我们当前用到的图片,在js中我们用到了image对象以及imagePath这两个变量。image对象在动态计算小方格的宽度和高度时需要用到;而imagePath则是为了在更换图片事件发生时,重新修改image对象的属性;具体功能由onChooseImage()函数实现;
    关于难度选择的实现
    通过image的宽度和高度除以难度值来计算每一个小方格的宽度和高度,并计算填充小方块时图片的偏移量;具体功能由onChooseDifficulty()来实现;
    关于记录操作次数的实现
    我们都需要交换两个小方块的数据(即背景图像的位置信息),所以只需要在这个函数里更新一个score全局变量即可;这个函数是doExchange(item);即将item的相关内容同emptyBlock(空方块)交换;
    关于提示功能:
    在getOpeningPosition()函数里模拟用户操作交换小方块时,如果空块向左移动,那么我们就将一个使空块向右移动的函数emptyMoveRIght对象压入操作栈,即把用户操作的反动作压入操作栈;当用户产生操作时,我们就接着把对应的反动作压入操作栈。当用户点击提示时,我们从操作栈弹出一个函数对象并执行,当栈空时,自然游戏场景被还原,即游戏结束。
    数据存储
    每一个position对象有x属性和y属性;然后将该对象转换为字符串后存到div的dataset中。当触发事件是就可以获得div的imagePosition和physicalPosition。

    (2)原型设计工具:
    JavaScript。Prototype。

    (3)讨论照片

    (4)遇到的困难与解决方法
    1、困难描述:HTML浏览器打开的时候,碰到了不稳定的情况,如以下。

    2、解决尝试:
    查询了B站,百度,知乎等相关APP极其网站上的相关知识文章。
    3、是否解决:不是非常的确定。
    4、有何收获:
    通过这一次的学习和查询资料,我更加的理解了js的使用,以及在网页脚本之类的内容有了亲身实践过后的理解。

    • 三、AI与原型设计实现
      (1)、代码实现思路:
      1、网络接口的使用:
      一开始的接口用的是:
    url = "http://47.102.118.1:8089/api/problem?stuid=031804120"
    # 发送get请求
    r=requests.get(url)
    user_dic = json.loads(r.text)
    # swap=user_dic['step']
    # uuid=user_dic['uuid']
    data = user_dic['img']
    image_data = base64.b64decode(data)
    np_img=imageio.imread(image_data)
    plt.imshow(np_img)
    plt.show()
    

    后面发现还不如用postman。

    2、代码组织与内部实现设计(类图):

    3、说明算法的关键与关键实现部分流程图:
    AI大比拼的算法:主要还是广度优先搜索,A*那里只是大约是排序,把那些最有可能得到解的结果先搜索。

    游戏设计的时候:我觉得在进行图片排列的这一步挺重要的。

    4、贴出你认为重要的/有价值的代码片段,并解释:
    AI中:

      def cal_distance(idxs):
                distance = 0
                for i in range(len(idxs)):
                    if idxs[i] == 0:
                        continue
                    distance += abs(i // width - (idxs[i] - 1) // width) + 
                                abs(i % width - (idxs[i] - 1) % width)
                return distance
    
            # 优先队列,值越小,优先级越高
            pq = PriorityQueue()
            # [优先级, 中间List(3*3=9), 初始值的0索引, 步数, 按键顺序输出序列, 拼图中间转换过程]
            pq.put([0 + cal_distance(board_start), board_start, board_start.index(0), 0, "", []])
            # 已遍历过的序列
            visited = set(board_start)
            # BFS搜索
            while not pq.empty():
                # 获取中间值
                _, board, position, step, move_str, board_roads = pq.get()
                # 最终结果返回, 循环停止条件
                if board == board_end:
                    return step, move_str, board_roads
                # BFS遍历上下左右的相邻结点
                for idx in (-width, width, -1, 1):
                    # wsad字母 对应 上下左右 的按钮
                    id2button = {-1: "a", 1: "d", - "w",  "s"}
                    # 下一个需要遍历的点
                    neighbor = position + idx
                    # 不是相邻点的跳过
                    if abs(neighbor // width - position // width) + abs(neighbor % width - position % width) != 1:
                        continue
                    # 遍历上下左右符合边界条件的相邻数字(图片)
                    if 0 <= neighbor < width * hight:
                        board_mid = list(board)
                        # 交换, 即移动0(即空图片)
                        board_mid[position], board_mid[neighbor] = board_mid[neighbor], board_mid[position]
                        board_new = tuple(board_mid)
                        if board_new not in visited:
                            visited.add(board_new)
                            pq.put([cal_distance(board_new) + step + 1, board_new, neighbor, step + 1,
                                    move_str + id2button[idx], board_roads + [board_mid]])
    

    这个地方主要就是为了找出好的路劲来。
    游戏:

    class ImgButtonAction implements ActionListener {
            public void actionPerformed(ActionEvent e) {
    //			System.out.println(444);
                nums++;
    //			System.out.println(nums);
                if (nums > 20) {
                    JButton clickButton = (JButton) e.getSource();
                    JPanel panel = (JPanel) clickButton.getParent();
                    JButton one;
                    while ((one = (JButton) panel.getComponent((int) (Math.random() * panel.getComponentCount()))) == emptyButton) {
                    }
                    JButton two;
                    while ((two = (JButton) panel.getComponent((int) (Math.random() * panel.getComponentCount()))) == emptyButton || two == one) {
                    }
                    Icon icon=one.getIcon();
                    one.setIcon(two.getIcon());
                    two.setIcon(icon);
                    nums=0;
                } else {
                    String emptyName = emptyButton.getName();
                    char emptyRow = emptyName.charAt(0);
    //			System.out.println(emptyRow);
                    if (emptyRow == '1') {
                        System.out.println("s");
                    } else {
                        System.out.println("w");
                    }
    
                    char emptyCol = emptyName.charAt(1);
    //			System.out.println(emptyCol);
                    JButton clickButton = (JButton) e.getSource();
                    String clickName = clickButton.getName();
                    char clickRow = clickName.charAt(0);
                    if (emptyRow == '1') {
                        System.out.println("a");
                    } else {
                        System.out.println("d");
                    }
    //			System.out.println(clickRow);
                    char clickCol = clickName.charAt(1);
    //			System.out.println(clickCol);
                    if (Math.abs(clickRow - emptyRow) + Math.abs(clickCol - emptyCol) == 1) {
                        emptyButton.setIcon(clickButton.getIcon());
                        clickButton.setIcon(new ImageIcon("image/" + num + "00.jpg"));
                        emptyButton = clickButton;
                    }
                }
            }
        }
    

    游戏过程中的移动以及强制调换图片。

    5、性能分析与改进:
    刚开始的时候还是存在着一些局限性,专一的用着一种方法,存在着一些比较浪费时间的没必要步骤。
    6、描述你改进的思路:
    改进的时候,就是将A*和广度以及深度优先搜索之类的,都尝试一下,然后再试着能不能结合改进。
    7、展示性能分析图和程序中消耗最大的函数:
    AI算法:


    游戏程序:

    8、展示出项目部分单元测试代码,并说明测试的函数,构造测试数据的思路 :
    部分代码:

    单元测试coverage:

    测试的函数的思路:就是在单元测试建立新的测试数据,然后通过调用同文件夹下的相关函数。
    构造测试数据的思路:为了尽量保证有解,参考了逆序数的思想打乱。

    (2)贴出Github的代码签入记录,合理记录commit信息:

    (3)遇到的代码模块异常或结对困难及解决方法:
    1、问题描述:
    分着写部分代码的时候,一开始没有统一商量好,导致再整合代码后,出现了一些函数调用问题。还有一些思路上的小分歧。
    2、解决尝试:
    再次商量确定了负责部分的内容的代码写的规范。
    3、是否解决:
    解决了。
    4、有何收获:
    交谈非常重要,尤其是开始一项合作项目之前的商量!而且交流思路的时候要越详细越好,因为很容易出岔子,或者理解错误,毕竟每个人的思路都不一样的。

    (4)评价你的队友:
    1、值得学习的地方:
    比我有耐心,有时候敲代码敲到烦的时候,感谢她的鼓励。
    2、需要改进的地方:
    没有,因为一样的缺点,菜是原罪。

    PSP:

    学习进度条:

  • 相关阅读:
    BZOJ.4842.[NEERC2016]Delight for a Cat(费用流)
    LOJ.6060.[2017山东一轮集训Day1/SDWC2018Day1]Set(线性基)
    BZOJ.5319.[JSOI2018]军训列队(主席树)
    BZOJ.4212.神牛的养成计划(Trie 可持久化Trie)
    HDU.5385.The path(构造)
    HDU.4903.The only survival(组合 计数)
    Codeforces.1043F.Make It One(DP 容斥)
    BZOJ.5110.[CodePlus2017]Yazid 的新生舞会(线段树/树状数组/分治)
    洛谷.3676.小清新数据结构题(树链剖分 树状数组)
    BZOJ.4598.[SDOI2016]模式字符串(点分治 Hash)
  • 原文地址:https://www.cnblogs.com/Jelor/p/13836371.html
Copyright © 2011-2022 走看看