• 记中兴软件园一个月实训(三)


        前两天只是简单复习了下C语言的基础知识,到第三天就采用项目驱动的方式,带着我们一个班的学生做项目----Popstar游戏

    其实还是很倾向于项目驱动的方式来学习的,老师在上边一边讲一边敲代码,我们就只要听,和抄下投影仪上的代码。带着我们走过一遍流程以后,再让我们自己写一个小游戏,老师只提供技术难点帮助。

        话不多说,给各位君看看记录的东西。

        首先做了一个控制台下的Popstar,用于测试算法的正确性,由于Popstar涉及到选择附近四个方向的同颜色的星星,因此要用到扩展查找算法。因为是学习,老师展示了递归、非递归方式来实现查找的过程。

        开始定义了一系列的数据对象

        就是想一下需要用到哪些数据对象,头文件要用头文件卫士#ifndef……这是编程规范

    data.h

     1 #ifndef _DATA_H_//以文件名命名
     2 #define _DATA_H_
     3 
     4 //pragma once
     5 
     6 #include <windows.h>
     7 #include <stdio.h>
     8 #include <string.h>
     9 #include <stdlib.h>
    10 
    11 #define ROW 10
    12 #define COLUMN 10
    13 
    14 typedef struct pos
    15 {
    16     int _x;
    17     int _y;
    18 }POS;
    19 
    20 typedef enum color
    21 {
    22     RED = 0,
    23     BLUE = 1,
    24     GREEN = 2,
    25     YELLOW = 3,
    26     PURPLE = 4
    27 }eCOLOR;
    28 
    29 typedef struct star
    30 {
    31     eCOLOR _color;//颜色
    32     POS _pos;    //位置
    33     BOOL _isSelect;
    34 }sSTAR;
    35 
    36 typedef enum directory
    37 {
    38     UP,
    39     DOWN,
    40     LEFT,
    41     RIGHT
    42 }eDIRECT;
    43 
    44 #endif;

    接着写了fun.cpp

    定义了一个sSTAR类型的数据对象 g_arrStars[row][column]

    并且对数据对象进行了初始化:

    void InitDataObj(void)
    {
        int row = 0;
        int column = 0;
        srand((unsigned)time(0));
    
        for(row = 0; row < ROW; row++)
        {
            for(column = 0; column < COLUMN; column++)
            {
                g_arrStars[row][column]._color = (eCOLOR)(rand()%5);
                g_arrStars[row][column]._isSelect = FALSE;
                g_arrStars[row][column]._pos._x = row;
                g_arrStars[row][column]._pos._y = column;
            }
        }
    }

    判断是否越界:

     1 BOOL IsOutOfBorder(eDIRECT direct,int x,int y)
     2 {
     3     switch(direct)
     4     {
     5     case UP:
     6         case DOWN:
     7         {
     8             if(x<0 || x>ROW-1)
     9             {
    10                 return TRUE;
    11             }
    12             else return FALSE;
    13             break;
    14         }
    15     
    16     case LEFT:
    17     case RIGHT:
    18         {
    19             if(y<0 || y>COLUMN-1)
    20             {
    21                 return TRUE;
    22             }
    23             else
    24             {
    25                 return FALSE;
    26             }
    27             break;
    28         }
    29     default:
    30         {
    31             return FALSE;
    32             break;
    33         }
    34     }
    35 }

    接着用了递归方式实现了选择星星的过程

     1 void SelectStar(const int x,const int y,int* pCount)
     2 {
     3     g_arrStars[x][y]._isSelect = TRUE;
     4     (*pCount)++;
     5 
     6     //如果 没越界 四个方向某个颜色相等  并且没有被选择
     7     //每次递归调用自己 上下左右依次判断
     8     if(!IsOutOfBorder(UP,x-1,y) && 
     9         g_arrStars[x-1][y]._color == g_arrStars[x][y]._color &&
    10         g_arrStars[x-1][y]._isSelect == FALSE
    11         )
    12     {
    13         SelectStar(x-1,y,pCount);
    14     }
    15 
    16     if(!IsOutOfBorder(DOWN,x+1,y) && 
    17         g_arrStars[x+1][y]._color == g_arrStars[x][y]._color &&
    18         g_arrStars[x+1][y]._isSelect == FALSE
    19         )
    20     {
    21         SelectStar(x+1,y,pCount);
    22     }
    23 
    24     if(!IsOutOfBorder(LEFT,x,y-1) && 
    25         g_arrStars[x][y-1]._color == g_arrStars[x][y]._color &&
    26         g_arrStars[x][y-1]._isSelect == FALSE
    27         )
    28     {
    29         SelectStar(x,y-1,pCount);
    30     }
    31 
    32     if(!IsOutOfBorder(RIGHT,x,y+1) && 
    33         g_arrStars[x][y+1]._color == g_arrStars[x][y]._color &&
    34         g_arrStars[x][y+1]._isSelect == FALSE
    35         )
    36     {
    37         SelectStar(x,y+1,pCount);
    38     }
    39 }

    这样在main函数中写上这样一段:

     1 int x = 0, y =0, count = 0;
     2     ////初始化数据对象
     3     InitDataObject();
     4     ////显示星星
     5     Display();
     6     ////选取星星
     7     printf("Please Input x And y :");
     8     scanf_s("%d%d", &x, &y);
     9     //SelectStart(x, y, &count);
    10     
    11     SelectStarMethod1(x,y,&count);
    12     printf("%d
    ", count);
    13     Display();

    就可以进行星星的选择了。。。。。。。

    再接着就忙着用非递归的方式实现扩展查找

    非递归方式需要用到栈与队列,因此写了两个版本的栈与队列,一个是C语言版,一个是C++版的模版

    这里我就忽略实现过程,直接上查找过程的函数了。

     1 int SelectStarMethod2(int x,int y)
     2 {
     3     SEQUEN_QUEUE queue;
     4     SEQUEN_STACK stack;
     5     InitSequenStack(&stack);
     6     InitSequenQueue(&queue);
     7     sSTAR *p = NULL;
     8 
     9     EnQueue(&queue,&g_arr[x][y]);
    10     int currx = 0,curry = 0;
    11     while(!IsEmptyQueue(&queue))
    12     {
    13         DelQueue(&queue,&p);
    14         Push(&stack,p);
    15         p->_isSelect = true;
    16 
    17         currx = p->_pos._x;
    18         curry = p->_pos._y;
    19         if(!IsOutOfBorder(UP,currx-1,curry) &&
    20             g_arr[currx-1][curry]._color == g_arr[currx][curry]._color &&
    21             g_arr[currx-1][curry]._isSelect == false)
    22         {
    23             EnQueue(&queue,&g_arr[currx-1][curry]);
    24         }
    25 
    26         if(!IsOutOfBorder(DOWN,currx+1,curry) &&
    27             g_arr[currx+1][curry]._color == g_arr[currx][curry]._color &&
    28             g_arr[currx+1][curry]._isSelect == false)
    29         {
    30             EnQueue(&queue,&g_arr[currx+1][curry]);
    31         }
    32 
    33         if(!IsOutOfBorder(LEFT,currx,curry-1) &&
    34             g_arr[currx][curry-1]._color == g_arr[currx][curry]._color &&
    35             g_arr[currx][curry-1]._isSelect == false)
    36         {
    37             EnQueue(&queue,&g_arr[currx][curry-1]);
    38         }
    39 
    40         if(!IsOutOfBorder(UP,currx,curry + 1) &&
    41             g_arr[currx][curry + 1]._color == g_arr[currx][curry]._color &&
    42             g_arr[currx][curry + 1]._isSelect == false)
    43         {
    44             EnQueue(&queue,&g_arr[currx][curry + 1]);
    45         }
    46     }
    47     return GetSequenLength(&stack);
    48 }

    非递归方式实现扩展查找,其实这里是有一点小问题的,就是当我星星同色的形成一个正方形的时候,选择就会出错。会多几个数字。解决办法就是在 if 判断之后加上

    g_arr[currx-1][curry]._isSelect == true

    这个扩展查找的非递归方式还是由你们自己去理解吧,在纸上模拟一下进队出队的过程你就明白了

    还有就是用C++模版写的版本

     1 int SelectStarMethod3(int x,int y)
     2 {
     3     CSequenStack<sSTAR,MAX_SIZE> stack;
     4     SequenQueue<sSTAR,MAX_SIZE> queue;
     5     sSTAR obj;
     6     int currx = 0,curry = 0;
     7     queue.EnQueue(g_arr[x][y]);
     8     
     9     while(!queue.IsEmpty())
    10     {
    11         queue.DelQueue(obj);
    12         currx = obj._pos._x;
    13         curry = obj._pos._y;
    14         stack.Push(g_arr[currx][curry]);//
    15         g_arr[currx][curry]._isSelect = true;//次两处不可以用obj,因为其为值,不为地址引用
    16         
    17         if(!IsOutOfBorder(UP,currx-1,curry) &&
    18             g_arr[currx-1][curry]._color == g_arr[currx][curry]._color &&
    19             g_arr[currx-1][curry]._isSelect == false)
    20         {
    21             queue.EnQueue(g_arr[currx-1][curry]);
    22         }
    23 
    24         if(!IsOutOfBorder(DOWN,currx+1,curry) &&
    25             g_arr[currx+1][curry]._color == g_arr[currx][curry]._color &&
    26             g_arr[currx+1][curry]._isSelect == false)
    27         {
    28             queue.EnQueue(g_arr[currx+1][curry]);
    29         }
    30 
    31         if(!IsOutOfBorder(LEFT,currx,curry-1) &&
    32             g_arr[currx][curry-1]._color == g_arr[currx][curry]._color &&
    33             g_arr[currx][curry-1]._isSelect == false)
    34         {
    35             queue.EnQueue(g_arr[currx][curry-1]);
    36         }
    37 
    38         if(!IsOutOfBorder(RIGHT,currx,curry + 1) &&
    39             g_arr[currx][curry + 1]._color == g_arr[currx][curry]._color &&
    40             g_arr[currx][curry + 1]._isSelect == false)
    41         {
    42             queue.EnQueue(g_arr[currx][curry+1]);
    43         }
    44     }
    45     return stack.GetLength();
    46 }

    最后:

        我个人觉得编写软件就像盖一座房子,我们看别人写好的代码,为什么这么难?这时因为别人的代码已经是完成了的一个项目,经过不断重构之后,就像建好的一座

    房子,我们外来的人在房子里边跑啊跑啊,想知道这房子到底是怎么盖的啊,从楼上跑到楼下一无所获。看不懂就是这样的一个过程。所以,如果没有人带着你写东西,那么你需要花费更多的精力来将整个房子一点点拆开,理解为什么这样做,这样的一个过程是一个很长的过程。因此看别人构建好的代码不能着急,原著都写了三五天,你想一天就看懂,那怎么能符合逻辑呢?

        对一些新的冷的知识更是如此,如果你一点都看不懂学不会,那么不如去找一下视频,跟着别人学一遍,走一边构建整个房子的流程,那么再写东西,看代码就如鱼得水了。

    代码下载:点击

  • 相关阅读:
    C#如何用OpenFileDialog控件打开图片显示到PictureBox这个控件
    C# winform 禁止窗体移动
    linux 硬链接和软链接(转)
    linux 源码编译(转)
    linux 压缩与解压缩
    硬盘分区(来自百度百科)
    arp:地址解析协议(Address Resolution Protocol)(来自维基百科)
    c++学习笔记(1)
    ProbS CF matlab源代码(二分系统)(原创作品,转载注明出处,谢谢!)
    [eclipse]UML之AmaterasUML 插件
  • 原文地址:https://www.cnblogs.com/ccccnzb/p/4636287.html
Copyright © 2020-2023  润新知