zoukankan      html  css  js  c++  java
  • 2048控制台程序:一份帝国理工C++作业

    #include <fstream>
    #include <vector>
    #include <iostream>
    #include <string>
    using namespace std;
    
    //打印输出数组内容到窗口
    void print_square(const vector<int> &square);
    //设置默认的初始状态数组,最后一个数是2,其他都是0
    void set_default_square(vector<int> &square);
    //计算(row,col)坐标处的元素在数组中的索引
    int coordtoidx(int row, int col);
    //提取一行4个元素
    void extract_row(const vector<int>& square, int row, vector<int>& output);
    //将移动后(左移或右移)的行数据更新到数组
    void update_row(vector<int>& square, int row, const vector<int>& newrow);
    //提取一列4个元素
    void extract_col(const vector<int>& square, int col, vector<int>& output);
    //将移动后(上移或下移)的列数据更新到数组
    void update_col(vector<int>& square, int col, const vector<int>& newcol);
    //检测某一行或列是否可以移动
    bool check_moveable(const vector<int> &rowcol);
    //检测游戏是否结束。检测方法:依次检测每一行每一列是否可移动
    bool checkgameover(const vector<int> &square);
    //向上或向左移动一列或一行数据,移动后的结果放到aftermove数组
    void move_up_or_left(const vector<int> &colrow, vector<int> &aftermove);
    //向下或向右移动一列或一行数据,移动后的结果放到aftermove数组
    void move_down_or_right(const vector<int> &colrow, vector<int> &aftermove);
    //向上移动,响应'w'键
    void moveup(vector<int> &square);
    //向下移动,响应's'键
    void movedown(vector<int> &square);
    //向左移动,响应'a'键
    void moveleft(vector<int> &square);
    //向右移动,响应'd'键
    void moveright(vector<int> &square);
    //检测响应一个按键之后,数组内容是否有变化
    bool check_state_change(const vector<int>& oldsquare, const vector<int>& newsquare);
    //移动完成之后,在空白处随机选择一处设置元素值2
    void add2random(vector<int>& square);
    
    int main()
    {
        ifstream inputfile;
        cout<< "enter initial configuration file name:" <<endl;
        string infilename;
        cin>>infilename;
        inputfile.open(infilename);
        //inputfile.open("inputconf.txt");
        //存放数组数据,总共16个整数
        vector<int> squaredata;
        int number;
        //如果能够正确打开初始数据文件,那么从中读取数据
        if (inputfile.is_open())
        {
            while (inputfile>>number)
            {
                squaredata.push_back(number);
            }
            inputfile.close();
        }
        else
        {
            cout<<"file not found, using default start configuration:"<<endl;
            //使用默认的初始数据,最后一个数是2,其他都是0
            set_default_square(squaredata);
        }
        //输出状态到屏幕
        print_square(squaredata);
    
        //接收输入的键盘命令:a,s,d,w
        char cmd;
        //游戏结束标志
        bool gameover=false;
        //存储上一次的数组状态,用来判断状态是否有更改
        vector<int> oldsquaredata;
        //循环处理用户输入的命令
        while(!gameover)
        {
            //先记录旧的数组
            oldsquaredata=squaredata;
            cin>>cmd;
            if (cmd=='w')
            {
                //上移
                moveup(squaredata);
            }
            else if (cmd=='a')
            {
                //左移
                moveleft(squaredata);
            }
            else if (cmd=='s')
            {
                //下移
                movedown(squaredata);
            }
            else if (cmd=='d')
            {
                //右移
                moveright(squaredata);
            }
            else
            {
                //提示一下只能接收awsd命令
                cout<<"note: using 'a' for left, 's' for down, 'd' for right and 'w' for up"<<endl;
            }
            //检测数组是否有变化
            bool square_change=check_state_change(oldsquaredata,squaredata);
            if (square_change)
            {
                //随机选择一个空白处增加一个元素2
                add2random(squaredata);
                //输出状态到屏幕
                print_square(squaredata);
                //检测是否game over
                gameover=checkgameover(squaredata);
            }
        }
        cout<<"game over"<<endl;
        system("pause");
    }
    
    void print_square(const vector<int> &square)
    {
        cout<<endl;
        for (unsigned int i=0; i<square.size(); i++)
        {
            cout<<square.at(i)<<"	";
            if ((i+1)%4==0)
            {
                cout<<endl;
            }
        }
        cout<<endl;
    }
    void set_default_square(vector<int> &square)
    {
        for (int i=0; i<16; i++)
        {
            square.push_back(0);
        }
        square.back()=2;
    }
    int coordtoidx(int row, int col)
    {
        return row*4+col;
    }
    void extract_row(const vector<int>& square, int row, vector<int>& output)
    {
        for (int c=0; c<4;c++)
        {
            int idx=coordtoidx(row,c);
            output.push_back(square.at(idx));
        }
    }
    void update_row(vector<int>& square, int row, const vector<int>& newrow)
    {
        for (int c=0; c<4; c++)
        {
            int idx=coordtoidx(row,c);
            square[idx]=newrow[c];
        }
    }
    void extract_col(const vector<int>& square, int col, vector<int>& output)
    {
        for (int r=0; r<4;r++)
        {
            int idx=coordtoidx(r,col);
            output.push_back(square.at(idx));
        }
    }
    void update_col(vector<int>& square, int col, const vector<int>& newcol)
    {
        for (int r=0; r<4;r++)
        {
            int idx=coordtoidx(r,col);
            square[idx]=newcol[r];
        }
    }
    bool check_moveable(const vector<int> &rowcol)
    {
        int a=rowcol[0];
        int b=rowcol[1];
        int c=rowcol[2];
        int d=rowcol[3];
        //首先检测是否含有0元素
        if(a*b*c*d==0)
            return true;
        if (a==b||b==c||c==d)
        {
            return true;
        }
        return false;
    }
    bool checkgameover(const vector<int> &square)
    {
        for (int i=0; i<4; i++)
        {
            vector<int> row,col;
            extract_row(square, i, row);
            extract_col(square, i, col);
            bool checkrow=check_moveable(row);
            bool checkcol=check_moveable(col);
            //如果有一行或者一列可以移动,说明游戏尚未结束
            if (checkrow||checkcol)
            {
                return false;
            }
        }
        return true;
    }
    void move_up_or_left(const vector<int> &colrow, vector<int> &aftermove)
    {
        vector<int> tmp;
        //将colrow中非0元素按照从上到下或者从左到右的顺序放到tmp中
        for(int i=0; i<4; i++)
        {
            if(colrow[i]!=0)
                tmp.push_back(colrow[i]);
        }
        //安顺序将相邻的同值元素相加,计算结果放在tmp2
        vector<int> tmp2;
        for (unsigned int i=0; i<tmp.size(); i++)
        {
            if (i!=tmp.size()-1&&tmp[i]==tmp[i+1])
            {
                tmp2.push_back(tmp[i]*2);
                i++;
            }
            else
            {
                tmp2.push_back(tmp[i]);
            }
        }
        //将计算结果写入aftermove
        for (int i=0; i<(int)tmp2.size(); i++)
        {
            aftermove[i]=tmp2[i];
        }
    }
    void move_down_or_right(const vector<int> &colrow, vector<int> &aftermove)
    {
        vector<int> tmp;
        //将colrow中非0元素按照从下到上或者从右到左的顺序放到tmp中
        for(int i=3; i>=0; i--)
        {
            if(colrow[i]!=0)
                tmp.push_back(colrow[i]);
        }
        //计算结果
        vector<int> tmp2;
        for (int i=0; i<(int)tmp.size(); i++)
        {
            if (i!=tmp.size()-1&&tmp[i]==tmp[i+1])
            {
                tmp2.push_back(tmp[i]*2);
                i++;
            }
            else
            {
                tmp2.push_back(tmp[i]);
            }
        }
        //将计算结果写入aftermove,注意afermove数组的索引要从后往前变化
        for (int i=0; i<(int)tmp2.size(); i++)
        {
            aftermove[3-i]=tmp2[i];
        }
    }
    void moveup(vector<int> &square)
    {
        for (int i=0; i<4; i++)
        {
            //提取一列元素到col
            vector<int> col;
            extract_col(square, i, col);
            //按照规则移动col中的元素,结果放在colaftermove
            vector<int> colaftermove(4);
            move_up_or_left(col, colaftermove);
            //将移动后的列元素更新到数组square
            update_col(square,i,colaftermove);
        }
    }
    void movedown(vector<int> &square)
    {
        for (int i=0; i<4; i++)
        {
            //提取一列元素到col
            vector<int> col;
            extract_col(square, i, col);
            //按照规则移动col中的元素,结果放在colaftermove
            vector<int> colaftermove(4);
            move_down_or_right(col, colaftermove);
            //将移动后的列元素更新到数组square
            update_col(square,i,colaftermove);
        }
    }
    void moveleft(vector<int> &square)
    {
        for (int i=0; i<4; i++)
        {
            //提取一行元素到row
            vector<int> row;
            extract_row(square, i, row);
            //按照规则移动row中的元素,结果放在rowaftermove
            vector<int> rowaftermove(4);
            move_up_or_left(row, rowaftermove);
            //将移动后的行元素更新到数组square
            update_row(square,i,rowaftermove);
        }
    }
    void moveright(vector<int> &square)
    {
        for (int i=0; i<4; i++)
        {
            //提取一行元素到row
            vector<int> row;
            extract_row(square, i, row);
            //按照规则移动row中的元素,结果放在rowaftermove
            vector<int> rowaftermove(4);
            move_down_or_right(row, rowaftermove);
            //将移动后的行元素更新到数组square
            update_row(square,i,rowaftermove);
        }
    }
    bool check_state_change(const vector<int>& oldsquare, const vector<int>& newsquare)
    {
        return oldsquare!=newsquare;
    }
    void add2random(vector<int>& square)
    {
        //统计0元素在数组中的索引
        vector<int> zeroidx;
        for (int i=0; i<16; i++)
        {
            if (square[i]==0)
            {
                zeroidx.push_back(i);
            }
        }
        //0元素的个数
        int zerocount=zeroidx.size();
        //如果没有0元素
        if (zerocount==0)
        {
            return;
        }
        //随机选一个数,当然这个数不能超过0元素的个数
        int random_number=rand()%zerocount;
        //找到这个0元素在square中的索引
        int choose_one_idx=zeroidx[random_number];
        square[choose_one_idx]=2;
    }
  • 相关阅读:
    《玩转.NET Micro Framework 移植基于STM32F10x处理器》内容介绍
    《玩转.NET Micro Framework 移植基于STM32F10x处理器》前言
    《玩转.NET Micro Framework 移植基于STM32F10x处理器》内容介绍
    《玩转.NET Micro Framework 移植基于STM32F10x处理器》微软中国.NET Micro Framework项目组工程师所作之序
    《玩转.NET Micro Framework 移植基于STM32F10x处理器》资源汇总
    《玩转.NET Micro Framework 移植基于STM32F10x处理器》微软中国.NET Micro Framework项目组工程师所作之序
    《玩转.NET Micro Framework 移植基于STM32F10x处理器》前言
    Windows、Linux、ARM、Android、iOS全平台支持的RTMP推流组件libEasyRTMP库接口调用说明
    简单高效易用Windows/Linux/ARM/Android/iOS平台实现RTMP推送组件EasyRTMPAndroid MediaCodec硬编码流程介绍
    RTSP网络监控摄像头如何实现Windows、Linux、ARM、Android、iOS全平台支持的拉RTSP流推出RTMP直播流?
  • 原文地址:https://www.cnblogs.com/coolbear/p/4615481.html
Copyright © 2011-2022 走看看