精华内容
下载资源
问答
  • 小学数学计算题随机出题软件

    千次阅读 2015-03-18 21:46:00
    做这个软件的时候 ,我应该从用户角度考虑问题,而不是简单实现了老师交代功能。 于是我把功能选择变成了年级选择 , 选择哪一个年级,然后填写出题数量,按下出题按钮,然后在下面文本框中就会出现...

            做这个软件的时候 ,我应该从用户的角度考虑问题,而不是简单实现了老师交代的功能。 于是我把功能的选择变成了年级的选择 ,

    选择哪一个年级的,然后填写出题的数量,按下出题按钮,然后在下面的文本框中就会出现对应年级的难度的题目,这样简化的用户的选择。

          开始的时候我将数字生成单独写在一个类里边的,但是后来做界面的时候,本想调用实例化对象,但是出现了线程的问题,尝试了解决方法但是没有奏效

      于是我又将生成数字的方法直接写在一个类里边直接就是利用这一个形成了出题的界面和处理。

           当然本软件是为小学生准备的 于是我去百度了小学各个年级数学题出题范围 ,于是发现自己写的方法没有调用上,是因为小学难度还没有达到那个水平 ,但是

    方法我已经写出了,如果要用的话,到时候可以调用就可以了。

         源代码如下:

     

    import java.awt.Dimension;

    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.text.DecimalFormat;
    import java.util.Random;

    import javax.swing.ButtonGroup;
    import javax.swing.JButton;
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    import javax.swing.JPanel;
    import javax.swing.JRadioButton;
    import javax.swing.JScrollPane;
    import javax.swing.JTextArea;
    import javax.swing.JTextField;

    public class Jiemian extends JFrame{
          public JPanel Panel1;
          public JLabel graselect;//年纪选择
          public JLabel questnum;//题目数量
          public ButtonGroup buttonGroup;
          public JTextField textnum;//添加题目数量
          public JButton  chuti;
          public JButton   chongzhi;
          public  JTextArea  quest;//出题的地方
          public JRadioButton gradetwo;
          public JRadioButton gradethree;
          public JRadioButton gradefour;
          public JRadioButton gradefive;

         public static void main(String[] args) {
             try{
                Jiemian jm=new Jiemian();
                  jm.setVisible(true);
                 }
            catch(Exception e){
              e.printStackTrace();
      }
     }
      public Jiemian(){
      super();
      setTitle("随机出题系统");
      setBounds(0,0,400,500);
      getContentPane().setLayout(null);
      setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

     //年级选择
      graselect=new JLabel();
      graselect.setBounds(0, 30, 50, 30);
      graselect.setText("年级:");
      getContentPane().add(graselect);
      //二年级
         buttonGroup=new ButtonGroup();
         gradetwo =new JRadioButton();
         buttonGroup.add(gradetwo);
         gradetwo.setText("二年级");
         gradetwo.setBounds(60, 30, 80, 30);
         gradetwo.setSelected(true);
         getContentPane().add(gradetwo);
         //三年级
         gradethree =new JRadioButton();
         buttonGroup.add(gradethree);
         gradethree.setText("三年级");
         gradethree.setBounds(140, 30, 80, 30);
         //gradetwo.setSelected(false);
         getContentPane().add(gradethree);
         //四年级
         gradefour =new JRadioButton();
         buttonGroup.add(gradefour);
         gradefour.setText("四年级");
         gradefour.setBounds(220, 30, 80, 30);
         //gradetwo.setSelected(false);
         getContentPane().add(gradefour);
         //五年级
         gradefive =new JRadioButton();
         buttonGroup.add(gradefive);
         gradefive.setText("五年级");
         gradefive.setBounds(300, 30, 80, 30);
         //gradetwo.setSelected(false);
         getContentPane().add(gradefive);

    questnum=new JLabel();
         questnum.setText("题目数量:");
         questnum.setBounds(0, 80, 80, 40);
         getContentPane().add(questnum);
     
         //题目数量
         textnum=new JTextField();
         textnum.setBounds(90,90, 80, 20);
         getContentPane().add(textnum);
          //出题的按钮
         chuti= new JButton();
         chuti.setText("出题");
         chuti.setBounds(60, 150, 60, 30);
       
      
      chuti.addActionListener( new chutiListener());
         getContentPane().add(chuti);
         //重置的按钮
         chongzhi =new JButton();
         chongzhi.setText("重置");
         chongzhi.setBounds(240, 150, 60, 30);
         chongzhi.addActionListener(new chongzhiListener());
         getContentPane().add(chongzhi);
        //出题的方框
          quest=new JTextArea();
          quest.setColumns(15);
          quest.setRows(3);
          quest.setLineWrap(true);
          JScrollPane scrollPane=new JScrollPane();
          scrollPane.setViewportView(quest);
          Dimension dime=quest.getPreferredSize();
          scrollPane.setBounds(0, 200, 400, 200);
          getContentPane().add(scrollPane);
         }
     //生成数的方法
     public  int shenchengnum(int a){
         Random rand=new Random();
         int k=0;
         int j=0;
         for(int i=0;i<a;i++)
         {
          j=rand.nextInt(9)+1;
          k=k*10+j;
         }
         return k;
        }
     public char shengchenchar(boolean zhfu){
         Random rand=new Random();
         char c=' ';
         if(zhfu){
          int j=rand.nextInt()%2;
           if(j==0)
           {
            c='-';
           }
          
         }
            return c;
         }
        public void fenshunum(int a,int b,int c){   
         a=shenchengnum(c);
         b=shenchengnum(c);
        }
        public String xiaoshusc(){
         Random rand=new Random();
         DecimalFormat dcmFmt = new DecimalFormat("0.00");
         float a=rand.nextFloat()*100;
            String b=dcmFmt.format(a);
            return b;    
           
        }
        public char yunsuanchar(boolean szyf){
         Random rand=new Random();
         int j=0;
         char c=' ';
         if(szyf){
          j=rand.nextInt(2);
           if(j==0){
            c='/';
           } else if(j==1){
               c='*';
              }
           }

    else{
          j=rand.nextInt()%2;
          if(j==0){
           c='+';
          }
          else {
           c='-';
          }
         }
         return c;
        }
    //生成数的方法

    public void actionPerformed(ActionEvent e) {
      // TODO Auto-generated method stub
      String num=textnum.getText();
      int qtnum=Integer.parseInt(num);
       if(gradetwo.isSelected()){
        for(int i=0;i<qtnum;i++){
         Random rand=new Random();
         int k=rand.nextInt()%2;
         if(k==0){

            String fnum=String.valueOf(shenchengnum(4));
            String snum=String.valueOf(shenchengnum(4));
            String ch=String.valueOf(yunsuanchar(false));
                  quest.append(fnum+" "+" "+ch+" "+snum+"=");
                  quest.append("\n");
                  }else{
                  String fnum=String.valueOf(shenchengnum(2));
            String snum=String.valueOf(shenchengnum(1));
            String ch=String.valueOf(yunsuanchar(true));
                  quest.append(fnum+" "+" "+ch+" "+snum+"=");
                  quest.append("\n");
              }

         }
        }
       else if(gradethree.isSelected()){
        for(int i=0;i<qtnum;i++){
         Random rand=new Random();
         int k=rand.nextInt()%2;
         if(k==0){
            String fnum=String.valueOf(shenchengnum(4));
            String snum=String.valueOf(shenchengnum(4));
            String ch=String.valueOf(yunsuanchar(false));
                  quest.append(fnum+" "+" "+ch+" "+snum+"=");
                  quest.append("\n");
                  }else{
                  String fnum=String.valueOf(shenchengnum(4));
            String snum=String.valueOf(shenchengnum(1));
            String ch=String.valueOf(yunsuanchar(true));
                  quest.append(fnum+" "+" "+ch+" "+snum+"=");
                  quest.append("\n");
              }
          }

    }else if(gradefour.isSelected()){
        for(int i=0;i<qtnum;i++){
         String fnum=String.valueOf(shenchengnum(3));
            String snum=String.valueOf(shenchengnum(2));
            String ch=String.valueOf(yunsuanchar(true));
                  quest.append(fnum+" "+" "+ch+" "+snum+"=");
                  quest.append("\n");
        }
       }
       else if (gradefive.isSelected()){
        for(int i=0;i<qtnum;i++){
         String fnum=xiaoshusc();
            String snum=xiaoshusc();
            String ch=String.valueOf(yunsuanchar(true));
                  quest.append(fnum+" "+" "+ch+" "+snum+"=");
                  quest.append("\n");
        

      }

       }

    }  

      }     public class chongzhiListener implements ActionListener{

              @Override  public void actionPerformed(ActionEvent e) {

                 // TODO Auto-generated method stub  

                  textnum.setText(null);

                    quest.setText(null);

        }    

       }

    }


        
      

    转载于:https://www.cnblogs.com/qerror404/p/4348740.html

    展开全文
  • 原型设计加用户规格说明 蔡晨旸349 蔺皓雯369 工具:墨刀 博客作业:https://edu.cnblogs.com/campus/fzzcxy/2016SE/homework/2180...一.... 核心功能:随机生成任意题数小学计算题 设计目的:使小学生数学计算能力...

    原型设计加用户规格说明

    蔡晨旸349 蔺皓雯369
    工具:墨刀
    博客作业:https://edu.cnblogs.com/campus/fzzcxy/2016SE/homework/2180
    原型链接:https://modao.cc/app/8kIgaQgq0a3U7EON3W8C2Jzti8VezYf

    一.定义相关概念

    • 核心功能:随机生成任意题数的小学计算题
    • 设计目的:使小学生的数学计算能力提升,老师和家长对小学生的作业布置和批改更轻松。

    二.定义典型用户和典型场景

    用户 身份 困难 期望
    小张 小学生(成绩一般) 无法及时知道作业答案 能及时知道自己答案对错
    小华 小学生(成绩较好) 老师的作业量太少,想更快提升自己成绩 做更多的题
    林老师 老师 作业题数量一大,难布置 更轻松地布置作业
    李先生 家长 检查作业困难 知道题目答案

    三.用户如何使用软件功能

    • 首先进入登录页面,点击注册,提交注册信息,后进入题目属性页面,选择所需作业年级和题数,进入练习题界面,抄写题目并进行作业。

    三.给出界面原型设计

    一.登录页面

    1472254-20181009220129602-1057028322.png

    二.注册页面

    1472254-20181009220203946-419930905.png

    三.题目属性页面

    1472254-20181009220255351-257399792.png

    四.题目生成页面

    1472254-20181009220335396-241646173.png

    四.描述主流的用户/软件交互步骤

    • 目前软工未完善,但希望能做到,用户对软件的使用结果对错条数记录在软件中,影响软件的出题难度。若错误题数比例下降,则上升题目难度,反之下降题目难度。这样一步步提升学生的水平,并能做到符合自身能力水平的题目。

    五.系统功能描述及验收验证标准

    • 功能:以随机的方式产生客户要求数目的小学数学题目及答案。
    • 标准:题目没有显示问题,题目数量足够,答案准确无误,不超纲。软件不会因同时使用人数大而崩溃。

    六.写出产品可能的副作用

    • 老师:可能使老师的数学计算能力下降,由于长期的作业布置方便,思维敏捷程度下降。
    • 家长:可能逐渐忘却孩子的学习进度,或不知道孩子实时的数学学习程度。
    • 学生:可能逐渐开始偷懒,不再严格自律督促自己做题,利用软件偷懒,反而因此软件耽误了计算的学习。

    七.团队协作

    • 我与队友密切合作,共同解决遇到的问题。
      1472254-20181009223647532-1106571954.png
      1472254-20181009223658692-1087574552.png

    转载于:https://www.cnblogs.com/yang1998/p/9763142.html

    展开全文
  • 迷宫游戏是非常经典游戏,在该中要求随机生成一个迷宫,并求解迷宫; 要求查找并理解迷宫生成算法,并尝试用两种不同算法来生成随机迷宫。 要求游戏支持玩家走迷宫,和系统走迷宫路径两种模式。玩家走迷宫...

    课前预习

    课程要求

    1. 迷宫游戏是非常经典的游戏,在该题中要求随机生成一个迷宫,并求解迷宫;
    2. 要求查找并理解迷宫生成的算法,并尝试用两种不同的算法来生成随机的迷宫。
    3. 要求游戏支持玩家走迷宫,和系统走迷宫路径两种模式。玩家走迷宫,通过键盘方向键控制,并在行走路径上留下痕迹;系统走迷宫路径要求基于 A*算法实现,输出走迷宫的最优路径并显示。 设计交互友好的游戏图形界面。

    题目难点

    1. 要随机生成迷宫,并且要给出解决方案。
    2. 支持玩家走迷宫和系统走迷宫两种方案。
    3. 设计友好的交互界面。

    迷宫实现所需的算法原理

    在这里,我们选择了Prime算法来作为实现随机生成迷宫的算法,下面我们先了解一下prime算法。
    Prime算法的核心步骤:
    在带权连通图中V是包含所有顶点的集合, U已经在最小生成树中的节点,从图中任意某一顶点v开始,此时集合U={v}。
    重复执行下述操作:
    在所有u∈U,w∈V-U的边(u,w)∈E中找到一条权值最小的边,将(u,w)这条边加入到已找到边的集合,并且将点w加入到集合U中,当U=V时,就找到了这颗最小生成树。
    下面我们通过图示法来演示一下工作流程:
    在这里插入图片描述
    首先,确定起始顶点。在这里以顶点A作为起始点。根据查找法则,与点A相邻的点有点B和点H,比较AB与AH,AB的权值小,因此我们选择点B,如下图。并将点B加入到U中。
    在这里插入图片描述
    继续下一步,此时集合U中有{A,B}两个点,再分别以这两点为起始点,根据查找法则(选取权值较小的边),找到边BC(当有多条边权值相等时,可选任意一条),如下图。并将点C加入到U中。
    在这里插入图片描述
    继续,此时集合U中有{A,B,C}三个点,根据查找法则,我们找到了符合要求的边CI,如下图。并将点I加入到U中。
    在这里插入图片描述
    继续,此时集合U中有{A,B,C,I}四个点,根据查找法则,找到符合要求的边CF(当C有多条边时,选择权值最小的那个,因此这里选择CF),如下图。并将点F加入到集合U中。
    在这里插入图片描述
    继续,依照查找法则我们找到边FG,如下图。并将点G加入到U中。
    在这里插入图片描述
    继续,依照查找法则我们找到边GH,如下图。并将点H加入到U中。
    在这里插入图片描述
    继续,依照查找法则我们找到边CD,如下图。并将点D加入到U中。
    在这里插入图片描述
    继续,依照查找法则我们找到边DE,如下图。并将点E加入到U中。
    在这里插入图片描述
    此时,满足U = V,即找到了这颗最小生成树。

    基于WIN32的迷宫制作

    功能实现

    本次实验只完成了随机生成迷宫和人工走迷宫,因此一共分为两大块:
    第一块是随机生成迷宫:

    struct block{
    	int row,column,direction;
    	block(int _row,int _column,int _direction){
    		row = _row;
    		column = _column;
    		direction = _direction;
    	}
    };
    
    struct point {
    	int x;
    	int y;
    }start,end;
    

    这是定义一个向量,以及初始化挖墙的矿工。

    vector<block> myblock;
    int x_num=1,y_num=1;//矿工位置
    int G[100][100];
    
    
    

    这是一个初始化函数,游戏结束后重新开始,就需初始化。

    void init() {
    	//将地图全部置为墙
    	memset(G,WALL,sizeof(G));
    	//定义起始点
    	G[0][0] = NOTHING;
    	start.x = start.y = 0;
    
    
    	m_play.len=1;
    	m_play.m_pos[0].x=1;
    	m_play.m_pos[0].y=1;
    	generatedestination();
    
    }
    

    这一部分是矿工找墙。

    void FindBlock() {
    	//找出与当前位置相邻的墙
    	if(x_num+1<=m && G[x_num+1][y_num] == WALL) {//down
    		myblock.push_back(block(x_num+1,y_num,down));
    	}
    	if(y_num+1<=n && G[x_num][y_num+1] == WALL) {//right
    		myblock.push_back(block(x_num,y_num+1,rt));
    	}
    	if(x_num-1>=1 && G[x_num-1][y_num] == WALL) {//up
    		myblock.push_back(block(x_num-1,y_num,up));
    	}
    	if(y_num-1>=1 && G[x_num][y_num-1] == WALL) {//left
    		myblock.push_back(block(x_num,y_num-1,lt));
    	}
    }
    

    这一部分是随机生成迷宫。

    void CreateMaze(){
    	//生成迷宫
    	srand((unsigned)time(NULL));//随机数种子
    	FindBlock();
    	//第一步压入两堵墙(起点右边和起点下面)进入循环
    	while(myblock.size()) {
    		int BlockSize = myblock.size();
    		//随机选择一堵墙(生成0 ~ BlockSize-1之间的随机数,同时也是vector里墙的下标)
    		int randnum = rand() % BlockSize;
    		block SelectBlock = myblock[randnum];
    		x_num = SelectBlock.row;//矿工来到我们"选择的墙"这里
    		y_num = SelectBlock.column;
    		//根据当前选择的墙的方向进行后续操作
    		//此时,起始点 选择的墙 目标块 三块区域在同一直线上
    		//我们让矿工从"选择的墙"继续前进到"目标块"
    		//矿工有穿墙能力 :)
    		switch(SelectBlock.direction) {
    			case down: {
    				x_num++;
    				break;
    			}
    			case rt: {
    				y_num++;
    				break;
    			}
    			case lt: {
    				y_num--;
    				break;
    			}
    			case up: {
    				x_num--;
    				break;
    			}
    		}
    		//目标块如果是墙
    		if(G[x_num][y_num]==WALL) {
    			//打通墙和目标块
    			G[SelectBlock.row][SelectBlock.column] = G[x_num][y_num] = NOTHING;
    			//再次找出与矿工当前位置相邻的墙
    			FindBlock();
    		}
    		else{//如果不是呢?说明我们的矿工挖到了一个空旷的通路上面 休息一下就好了
    			//relax
    		}
    		//删除这堵墙(把用不了的墙删了,对于那些已经施工过了不必再施工了,同时也是确保我们能跳出循环)
    		myblock.erase(myblock.begin()+randnum);
    	}
    }
    

    这一部分是用来在界面上生成迷宫以及展现用户自己走迷宫的路线。

    void MyPaint(HDC hdc){//生成迷宫 
    	//绘制背景
    	HBRUSH hbr=CreateSolidBrush(RGB(0,0,0));//创建画刷颜色为黑色,用来绘制背景
    	SelectObject(hdc,hbr);//通过for循环,初始化网格的背景色为黑色
    	for(int y=0;y<SIZE;y++)
    	{
    		for(int x=0;x<SIZE;x++)
    		{
    			Rectangle(hdc,x*WIDTH,y*HEIGHT,(x+1)*WIDTH,(y+1)*HEIGHT);
    		}
    	}
    	
    	CreateMaze();
    	//绘制路
    	HBRUSH hbrwhite=CreateSolidBrush(RGB(255,255,255));//创建画刷颜色为白色,用来绘制路
    	SelectObject(hdc,hbrwhite);//通过for循环,将选定坐标的对应的矩形涂满颜色
    	for(int i=1;i<SIZE;i++){
            for(int j=1;j<SIZE;j++){
    			if(G[i][j] == NOTHING)Rectangle(hdc,i*WIDTH,j*HEIGHT,(i+1)*WIDTH,(j+1)*HEIGHT);
    		}
        }
    
        //绘制走的路
    	HBRUSH hbrred=CreateSolidBrush(RGB(255,0,0));//创建画刷颜色为红色,用来绘制走的路
    	SelectObject(hdc,hbrred);//通过for循环,将选定坐标的对应的矩形涂满颜色    
    	Rectangle(hdc,1*WIDTH,1*HEIGHT,(1+1)*WIDTH,(1+1)*HEIGHT);
    	for(int z=0;z<m_play.len;z++)
    	{
    		Rectangle(hdc,m_play.m_pos[z].x*WIDTH,m_play.m_pos[z].y*HEIGHT,(m_play.m_pos[z].x+1)*WIDTH,(m_play.m_pos[z].y+1)*HEIGHT);
    	}
    
    	//绘制终点
        HBRUSH hbrblue=CreateSolidBrush(RGB(0,0,255));//创建画刷颜色为蓝色,用来绘制终点
    	SelectObject(hdc,hbrblue);
    	Rectangle(hdc,m_destination.x*WIDTH,m_destination.y*HEIGHT,(m_destination.x+1)*WIDTH,(m_destination.y+1)*HEIGHT);
    }
    //定义一个程序开始的函数
    void OnStart(HWND hWnd){
    	init();
    }
    

    第二部分是用键盘走迷宫:
    这个结构体用来表示用户自己走迷宫。

    struct play{
    	POINT m_pos[MAXSIZE];//定义结点的X,Y坐标表示用户要走的路,其中m_pos[0]表示第一个位置
    	int m_direction;//定义变量表示运行的方向
    	int len;//长度
    }m_play;
    

    下面是键盘控制部分。

         		switch(wParam)
    			{				
    			case VK_UP:
    				m_play.m_pos[0].y=m_play.m_pos[0].y-1;//向上运动
    				m_play.len++;					
    				break;
    			case VK_RIGHT:
    				m_play.m_pos[0].x=m_play.m_pos[0].x+1;//向左运动
    				m_play.len++;
    				break;
    			case VK_DOWN:
    				m_play.m_pos[0].y=m_play.m_pos[0].y+1;//向下运动
    				m_play.len++;
    				break;
    			case VK_LEFT:
    			    m_play.m_pos[0].x=m_play.m_pos[0].x-1;//向右运动
    			    m_play.len++;
    				break;
    			}
    			for(z=m_play.len-1;z>=1;z--){//更新迷宫的其他部分
    			    m_play.m_pos[z]=m_play.m_pos[z-1];
    			}
    			//到达目的地,游戏结束
    			if(m_play.m_pos[0].x==m_destination.x&&m_play.m_pos[0].y==m_destination.y){//当到达终点
    				if(IDYES==MessageBox(hWnd,"Game Over,你想重新开始吗?","提示",MB_YESNO)){//游戏结束后出现交互界面,判断是重新开始游戏还是结束游戏
    					OnStart(hWnd);
    				}
    				else{
    					PostQuitMessage(0);
    				}
    			}				
    		    hdc=GetDC(hWnd);//提取迷宫移动的方向的句柄
    			MyPaint(hdc);//用画刷展示	
    			break;
    

    成果展示

    最终的视频演示如下:
    在这里插入图片描述
    prime算法内容讲解转载博客

    展开全文
  • (五)生成试卷 在“分布表”文档工具栏上单击“生成试卷”按钮,系统将按照指定各章、各题型、各难度数量,进行 随机,组成试卷和答案初稿,分别放到“试卷”和“答 案”文档中。接下来,可以进行...
  • 1.迷宫游戏是非常经典游戏,在该中要求随机生成一个迷宫,并求解迷宫; 2.要求游戏支持玩家走迷宫,和系统走迷宫路径两种模式。玩家走迷宫,通过键盘方向键控制,并在行走路径上留下痕迹; 3

    计算机软件技术实习——迷宫算法核心

    前言

    最近都是在忙碌软件实习了,先写计算器,在干贪吃蛇,接着还有迷宫。先说一下迷宫这个项目的相关要求吧。
    1.迷宫游戏是非常经典的游戏,在该题中要求随机生成一个迷宫,并求解迷宫;
    2.要求游戏支持玩家走迷宫,和系统走迷宫路径两种模式。玩家走迷宫,通过键盘方向键控制,并在行走路径上留下痕迹;
    3.系统走迷宫路径要求基于A*算法实现,输出走迷宫的最优路径并显示。
    设计交互友好的游戏图形界面。

    一、迷宫构成的要素

    其实迷宫相较于贪吃蛇构成要素确实少了很多,基本就是墙和路,还有走迷宫的人,起点和终点,大概就没了。
    但是比贪吃蛇多了一个很重要的东西,那就是算法,我们要把哪一点设置为路,哪一点设置为墙都是需要用算法来解决的问题。有很多方法来生成这样的路吧。比如广度优先BFS,深度优先DFS,随机prim算法都可以生成墙和路。
    如果想生成的非常自然,美观的话,我们可以用prim算法来做。但请在学习prim算法的时候一定选对,我当时本来就准备用prim算法的,结果学到最后发现自己学习的好像并不是什么prim算法,反而和深度优先算法有点相似却又不完全是,所以到现在为止我生成迷宫的算法还是比较奇怪的。
    我们首先要做的事情是迷宫确定大小,很简单输入一个长和宽,然后用二维数组赋值的方法,两个循环直接赋值。边界的值,起点的值都是自己去决定的,反正都是双重循环进行遍历赋值罢了,起点的坐标可以自己决定。
    具体的广度优先遍历其实大概就是一条路走到黑,先找一条通路知道再也到达不了下一个地方,再返回起点,然后继续执行,知道所有的点都被访问过。而深度优先就是先访问周围所有可以达到的节点,然后再次判断这些点可以访问的所有节点,直到访问完成所有的节点。相当于是一层一层遍历的。
    有一点值得注意的是我们所需要的是迷宫其实最基本的东西是数组,判断一个数的值来决定是路还是墙。所以只需要生成具体的图形的话,我们所需要的操作,寻路,生成只是在最基础的数组上改变数值罢了。

    二、生成迷宫和寻路算法的实现

    1. 迷宫的生成

    我学的迷宫生成的算法核心也算是深度优先遍历吧。我们可以假设刚刚开始整个地图都是墙,然后假定一个矿工,他要挖穿一条路从起点到终点。就先要确定一个点为起点,然后开始挖,这时候如果我们定义终点的话很可能玩出来的路就只有一条,很可能不是迷宫,而是直接一条现成的路了。所以我推荐的方式是设置一个墙队列,必须判断所有的墙都试过了,那个我们假定的矿工才能休息,才能结束他辛辛苦苦挖路的工作。关于这个墙对列的选择,因为我们是在不知道墙总共有多大,所以要定义一个未知的空间来存放墙对列的横纵坐标。这时候就会想到一个可以视为容器的函数。vector函数,具体教程的链接是这个:https://www.runoob.com/w3cnote/cpp-vector-container-analysis.html。反正大概就是一个可存储任意类型的大的容器,还可以系统分配动态空间,你有多少数据,他就会给你分配多大的空间。
    有了这个函数我们就可以用来存放墙对列了,墙对列的值为非空,就会一直判断,一直挖下去。
    具体判断准则和挖路的方式是什么呢?我所想到的就是,刚开始全为墙,然后随机取一点先设置为路,接着看这个点上下左右四个方向有没有其他墙存在。判定方法如果这个点上下左右四个方向有小于或者等于一个方向上为路的话,我们就把这个点设置为路,反之,依旧为墙,接着把上下左右四个方向上的所有点放入墙对列中。然后继续取下一个墙对列中的点,继续执行判断,直到最后墙对列为空,我们就停止循环。生成在地图边界上的话是最最需要注意的,我们不可能直接把最外围的墙挖穿,那也就不符合迷宫的基本设定了,所以要想一个好办法,可以在最为外的墙四周全部设置为路,就一定可以防止最外围的墙被挖串了。
    可能会有一个疑惑,比如判断下一个墙队列中的点,这个点之前有个方向上判断依旧为墙的点还是会被放入,进行第二次判断。这个问题其实是没必要担心,之前判断为路,就根本进不去墙对列,如果之前判断为墙的话,无论剩下的点怎么变,它都一定是墙了,只能墙变成路,却不能路变成墙,这个过程是不可逆的。
    终点是没必要初始化的,一般来说起点是固定的,一般位于地图的左上角,而终点一般位于地图的右下角。终点生成的方式可以用循环尝试靠左下角的墙体,让第一个出现左边有一个为路的话,就可以直接把这个墙体挖了设置为终点。

    void initMG(int a, int b) {//初始化地图的函数,a为横坐标,b为纵坐标。 
    	system("cls");
    	for (int i = 0; i < a; i++) {
    		for (int j = 0; j < b; j++) {
    			MG[i][j] = 1;
    		}
    	}
    	for (int i = 0; i < a; i++) {
    		MG[i][0] = 4;
    		MG[i][b - 1] = 4;//第一列和最后一列都赋值为0. 
    	}
    	for (int i = 0; i < b; i++) {
    		MG[0][i] = 4;
    		MG[a - 1][i] = 4;//第一行和最后一行都初始化为0。0代表为路,这样设定可以防止外围的墙生成不全。 
    	}
    	vector<int> X;//设置一个容器为X用来存放墙队列横坐标。 
    	vector<int> Y; //设置另一个容器为Y用来存放墙队列的纵坐标。
    	X.push_back(2);//设置初始值 (注意X和Y是从0开始的)。 
    	Y.push_back(2); //初始取出墙队列中的值应该对应坐标为(3,3)的位置。 
    	while (X.size())
    	{//判断X中的墙队列还有没有内容,有的话继续执行,墙对列为空的话退出。
    		int r = rand() % X.size();//生成一个随机的数字对X的大小进行取余运算,结果一定小于X的大小,可以实现随机取出墙队列中的一点。
    		int x = X[r];//把取出来的墙的横坐标赋值给x。 
    		int y = Y[r];//同理纵坐标赋值给y。 
    		int count = 0;//判断上下左右为路的个数 
    		for (int i = x - 1; i < x + 2; i++) {//找出横坐标相邻的点。 
    			for (int j = y - 1; j < y + 2; j++) {//找出纵坐标相邻的点。 
    				if (abs(x - i) + abs(y - j) == 1 && (MG[i][j] == 0 || MG[i][j] == 4)) {//判断上下左右四个方向的值是不是为0,每有一个值为0,count就加一。 
    					++count;
    				}
    			}
    		}
    		if (count <= 1) {//判断一个墙体上下左右为路的个数小于1的话,就插入新的墙。 
    			MG[x][y] = 0;//设置为路。 
    			for (int i = x - 1; i < x + 2; i++) {//在墙队列中插入新的墙
    				for (int j = y - 1; j < y + 2; j++) {
    					if (abs(x - i) + abs(y - j) == 1 && MG[i][j] == 1) {//找出上下左右四个方向上为墙的单元,插入到墙体队列。 
    						X.push_back(i);
    						Y.push_back(j);
    					}
    				}
    			}
    		}
    		X.erase(X.begin() + r);//删除当前墙的横坐标 
    		Y.erase(Y.begin() + r);//删除当前墙的纵坐标。 
    	}
    	MG[2][1] = 2;//设置迷宫地图的起点。
    	for (int i = a - 3; i >= 0; i--) {
    		if (MG[i][b - 3] == 0) {//找出最靠近墙的那一行,靠下的位置第一个为路的点,将它右边的墙设置为终点。 
    			MG[i][b - 2] = 3;
    			break;
    		}
    	}
    }
    

    2.基于数组生成迷宫。

    用上述生成墙体的方法其实主要思想是改变数组中的值,下面就得开始打印墙体了。相对于链表和贪吃蛇的定位方法打印,迷宫确实简单地多。直接根据数组的输出就好了。

    void showing(int a, int b)
    {
    	system("cls");
    	for (int i = 0; i < a; i++) {
    		for (int j = 0; j < b; j++) {
    			if (MG[i][j] == 1)printf("■");
    			if (MG[i][j] == 0)printf("  ");
    			if (MG[i][j] == 3)printf("终");
    			if (MG[i][j] == 4)printf("  ");
    			if (MG[i][j] == 2)printf("◆");
    		}
    		printf("\n");
    	}
    }
    

    3.自己控制走迷宫。

    主要还是按键的一般思想吧,相较于贪吃蛇的移动,只有一些判断条件的改变。上下左右对应的ASCII码值和贪吃蛇一样的都是72,80,75,77。还是运用到了getch函数和kbhit函数。
    判断条件的话,我们可以想一下,如果你要向右走,那么意味着右边是不能有墙的,同理其余三个方向也是。如果向右走的话,那么在数组之中其实就是行数不变,列数加一。所以在判断了向右边走是可以的之后,就可以把原来所在数组位置的值赋为路的值,然后横坐标不变,纵坐标加一的数组位置的值,赋值为人的值,然后再次打印出来就好了。具体的话我们还需要确定现在人在数组之中的位置,直到这个的话我们才可以继续判断移动是否可行。还有一个是否达到终点的判断,就是现在人所在的这个纵横坐标是否等于终点的纵横坐标。
    代码如下:

    void move(int a, int b)
    {
    	int c=0, d=0;
    	
    	while (c!=zx||d!=zy)
    	{
    		nowxy(a, b);
    		c = nowx;
    		d = nowy;
    		/*接受键盘输入的上下左右,并以此改变方向*/
    		if (_kbhit())//kbhit()检测是否有按键按下,有按下返回键值, 
    		{
    			ch = _getch();
    			switch (ch)
    			{
    			case 72://迷宫中人向上行走。
    				if (MG[c - 1][d] == 0|| MG[c - 1][d] == 3)
    				{
    					MG[c][d] = 0;
    					MG[c - 1][d] = 2;
    				}
    				showing(a, b);
    				break;
    			case 80://迷宫中人向下行走。
    				if (MG[c + 1][d] == 0|| MG[c + 1][d] == 3)
    				{
    					MG[c][d] = 0;
    					MG[c + 1][d] = 2;
    				}
    				showing(a, b);
    				break;
    			case 75://迷宫中人向左行走。
    				if (MG[c][d-1] == 0||MG[c][d - 1] == 3)
    				{
    					MG[c][d] = 0;
    					MG[c][d - 1] = 2;
    				}
    				showing(a, b);
    				break;
    			case 77://迷宫中人向右行走。
    				if (MG[c][d + 1] == 0||MG[c][d + 1] == 3)
    				{
    					MG[c][d] = 0;
    					MG[c][d + 1] = 2;
    				}
    				showing(a, b);
    				break;
    			case 'r' :
    				initMG(a, b);
    				break;			
    			case 'R':
    				initMG(a, b);
    				break;
    			}
    		}
    	}
    

    上面的nowxy是判断现在所处的位置,具体代码在下面:

    void nowxy(int a, int b)
    {
    	for(int i=0;i<a;i++)
    		for(int j=0;j<b;j++)
    			if (MG[i][j] == 2)
    			{
    				nowx = i;
    				nowy = j;
    			}
    }
    

    4.A*算法找出最短路径。

    生成了迷宫,也可以实现自己走迷宫了,我们还需要判断一下迷宫的最短路径,也就是寻路的算法。寻路算法其实是多种多样的,但其中最为快速的就是A算法了,它的用时和所占内存运行时间都是最优选择,在理论上是时间最优的,但是也有缺点:它的空间增长是指数级别的。所以我们着重讲解一下A算法的具体实现。
    A算法的核心思想是F值来实现最短优先,这个F值是由两个值为指标相加构成的。
    F=G+H就是A
    算法的核心,那么这几个字母都代表着什么意思呢?

    • G = 从起点A,沿着产生的路径,移动到网格上指定方格的移动耗费。

    • H = 从网格上那个方格移动到终点B的预估移动耗费。
      对于G值的计算方法,我们所想到的就是先赋值一个0,然后从起点开始,每一次进行移动的操作就会增加1.
      对于H值计算的方法,我们一般采用曼哈顿距离,简单来说,就是现在你所处的这个点和终点的横纵坐标差的绝对值的和。
      有了这些还是不够,我们要怎么去比较呢?这个时候就需要用到优先队列的知识了,并且重载运算符,来让优先队列执行判断。
      思路具体就是这样的,那些必要的算法基础还是要靠学习算法和优先队列相关知识才行的。

    void A_start(int x0, int y0, int x1, int y1, int a, int b)//四个参数分别为起点和终点的横坐标,纵坐标 
    	{
    		// 初始化起点 
    		Node node(x0, y0);
    		node.G = 0;
    		node.H = Hdistance(x0, y0, x1, y1);
    		node.F = node.G + node.H;
    		valF[x0][y0] = node.F;
    		que.push(node); // 起点加入open表
    		while (!que.empty())
    		{
    			Node node_top = que.top();
    			que.pop();
    			visit[node_top.x][node_top.y] = true; // 访问该点,加入closed表 
    			if (node_top.x == x1 && node_top.y == y1) // 到达终点 
    				break;
    			// 遍历node_top周围的4个位置 
    			for (int i = 0; i < 4; i++)
    			{
    				Node node_next(node_top.x + dir[i][0], node_top.y + dir[i][1]); // 创建一个node_top周围的节点 
    				if (NodeIsLegal(node_next.x, node_next.y, a, b) && !visit[node_next.x][node_next.y]) // 该节点坐标合法,且未加入close表
    				{
    					// 计算从起点并经过node_top节点到达该节点所花费的代价 
    					node_next.G = node_top.G + dir[i][0], 2 + dir[i][1], 2;
    					// 计算该节点到终点的曼哈顿距离
    					node_next.H = Hdistance(node_next.x, node_next.y, x1, y1);
    					// 从起点经过node_top和该节点到达终点的估计代价
    					node_next.F = node_next.G + node_next.H;
    					// 说明找到了更优的路径,则进行更新 node_next.F < valF[node_next.x][node_next.y];
    					// 说明该节点还未加入open表中,则加入	valF[node_next.x][node_next.y] == 0; 
    					if (node_next.F < valF[node_next.x][node_next.y] || valF[node_next.x][node_next.y] == 0)
    					{
    						// 保存该节点的父节点 
    						path[node_next.x][node_next.y][0] = node_top.x;//根据path三维数组来确定最短优先路径在二维数组的具体位置。
    						path[node_next.x][node_next.y][1] = node_top.y;
    						valF[node_next.x][node_next.y] = node_next.F; // 修改该节点对应的valF值 
    						que.push(node_next); // 加入open表
    					}
    				}
    			}
    		}
    	}
    int Hdistance(int x, int y, int x1, int y1)
    {
    	return (abs(x - x1) + abs(y - y1));
    }
    bool NodeIsLegal(int x, int y, int m, int n)
    {
    	if (x < 0 || x >= m || y < 0 || y >= n) return false; // 判断边界 
    	if (MG[x][y] == 1) return false; // 判断障碍物 
    	return true;
    }
    

    总结

    核心的思想和算法就讲解这么多了,具体实现的话还是要有交互界面,或者初始化函数的。关键的地图生成和最短路径的查找最需要的还是算法知识,这些都是计算机最为基础的东西,努力学习算法吧,原与君共勉!

    展开全文
  • 迷宫游戏是非常经典游戏,在该中要求随机生成一个迷宫,并求解迷宫; 要求游戏支持玩家走迷宫,和系统走迷宫路径两种模式。玩家走迷宫,通过键盘方向键控制,并在行走路径上留下痕迹;系统走迷宫路径要求基于A*...
  • 1) 迷宫游戏是非常经典游戏,在该中要求随机生成一个迷宫,并求解迷宫; 2)要求查找并理解迷宫生成算法,并尝试用两种不同算法来生成随机迷宫。 3)要求游戏支持玩家走迷宫,和系统走迷宫路径两种模式。...
  • (1) 迷宫游戏是非常经典游戏,在该中要求随机生成一个迷宫,并求解迷宫; (2)要求查找并理解迷宫生成算法,并尝试用两种不同算法来生成随机迷宫。 (3)要求游戏支持玩家走迷宫,和系统走迷宫路径两种...
  • 实现功能: 1.整数和真分数四则运算, 运算数和运算结果都可以是整数或分数; 2.能生成任意个运算数算式; 3.算式个数、数范围、运算数个数... 方法成员包括两个构造函数,其中一个随机生成算式并计算结...
  • 实现功能: 1.整数和真分数四则运算, 运算数和运算结果都可以是整数或分数; 2.能生成任意个运算数算式(不超过... 方法成员包括一个初始化函数,随机生成算式并计算结果;一个输出函数,用来打印算式;以及...
  • 利用EXCEL自动生成20以内加减法

    万次阅读 2019-11-24 14:38:35
    小学开始学计算题的时候,经常需要练习10以内加减法,20以内加减法等等,每天找题目让人比较头疼,自己写又比较耗时间,于是想着利用表格中的随机函数能不能自动生成习题。在网上找了几个方法试着弄了一下成功了,...
  • 会计理论考试

    2012-03-07 21:04:40
    15.下列软件中不属于系统软件的是 ___D__ 。 A、Windows B、Visual FoxPro C、UCDOS D、WPS97 16.应用软件在计算机普及中起重要作用,下列 ___D__ 都属于应用软件。 A、WPS、DOS、Lotusl-2-3 B、WIndows95、Word、...
  • 系统中有二种方式选择练习试题,一种是自动组卷,这种方式组成练习试题是由电脑在题库中随机抽取,所以每次题目各不相同;另一种是选择设定好成套练习试题,这种方式选择试题是固定不变
  • 0-100数学出题软件

    2012-06-27 08:43:50
    1.可以生成100以内加减计算题、填空题、或随机出题 2.可以按需要生成进位加法(默认)、无进位加法,退位减法(默认)、无退位减法 3.可以将试题导出为Txt文档、Xls二种格式,导出试题文档中有当前试题类型,...
  • 超级有影响力Java面试大全文档 1.抽象: 抽象就是忽略一个主题中与当前目标无关那些方面,以便更充分地注意与当前目标有关方面。抽象并不打算了解全部问题,而只是选择其中一部分,暂时不用部分细节。...
  • 软件工程个人作业01

    2016-03-07 23:07:00
    设计思路: 30道题的设计: 1。随机生成两个float数,范围0—99。 2。随机生成第三个整数,范围1—4。用多个if。。。else语句判别1—4来分别确定四则运算符号,并且计算出两个数的运算结果。 3。需要加一个判断语句...
  • 丰富例题和习题,书中包括160多道例题,500多道思考题,240多道练习题和200多道数值计算题。 本书可作为研究生“数值分析”课程教材或参考书,对于需要解决计算问题科技人员,本书具有很高参考价值。 第1章...
  • 一、版本控制 ... 二、需求分析 1.控制台输入参数n控制四则运算题目数量。 2.随机生成四则运算题目,运算符分别使用符号+-*÷来表示。...4.每个练习要包含2种以上运算符,计算结果不得出现负数与非整...
  • 1.2.2 随机变量分布函数 1.2.3 离散型随机变量 1.2.4 连续型随机变量 1.2.5 随机向量 1.3 随机变量数字特征 1.3.1数学期望 1.3.2 方差 1.3.3 几种常用随机变量分布期望与方差 1.3.4 协方差与相关系数 ...
  • 1)题目 能自动生成小学四则运算题目(结果不出现负数); 除了整数外,还要支持真分数四...随机生成四则运算,结果不为负数; 存在真分数的计算; 可生成答案进行对比; 4) 解题思路: 小学运算只有...
  • 1.2.2 随机变量分布函数 1.2.3 离散型随机变量 1.2.4 连续型随机变量 1.2.5 随机向量 1.3 随机变量数字特征 1.3.1数学期望 1.3.2 方差 1.3.3 几种常用随机变量分布期望与方差 1.3.4 协方差与相关系数 ...
  • <p>.小学生算术运算练习软件要求ÿ...按照要求随机生成100以内加减法,能根据输入数出题,判断是否正确,最后计算分数,与合格优秀率。并将每次的计算内容与结果保存到相应文件中。</p>
  • 软件工程结对作业01

    2019-10-02 13:37:20
    用JAVA程序随机生成运算表达式String类型数组,并同时计算出每个运算表达式应得正确结果,分别将其设置到arithmetic属性中,在jsp页面可以选择题目数量和做时间。 答完提交或时间到后会显示出答题结果,...
  • Maple软件不仅具有强大...软件所建题库特色是可随机生成题目中参数和函数,能自动批阅填空和部分主观。在教学中使用Maple软件和Maple T. A.软件,可以提高教学效果,帮助学生自学、督促学生学习,减轻教师工作。
  • java 面试 总结

    2009-09-16 08:45:34
    面向对象计算始于这个基本概念,即现实世界可以被描绘成一系列完全自治、封装对象,这些对象通过一个受保护接口访问其他对象。 4. 多态性: 多态性是指允许不同类对象对同一消息作出响应。多态性包括参数化多...
  • (1)由计算机从题库文件中随机选择20道加减乘除混合算式,用户输入算式答案,程序检查答案是否正确,每道正确计5分,错误不计分,20道测试结束后给出测试总分; (2)题库文件可采用实验二方式自动生成,也...
  • 程序启动后,用户输入用户名,然后选择做什么运算(加、减、乘、除、混合)、做几位数运算,再单击“开始做”,之后计算机按要求随机生成10道题目,用户输入答案单击提交,则程序显示标准答案和用户得分,同时,...
  • 使用JAVA编写一个程序,该程序能随机生成n道四则运算,并且答案不得出现分数与小数,运算符在三到五个之间。 二、我思路 我知道计算机不能处理中缀表达式,只能处理后缀表达式。于是最开始想法是写一个...

空空如也

空空如也

1 2 3 4 5 ... 7
收藏数 134
精华内容 53
关键字:

随机生成计算题的软件