• 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;
    }
  • 相关阅读:
    tomcat 调优-生产环境必备
    Spring中 BeanFactory和ApplicationContext的区别
    延迟队列DelayQueue简单入门
    RedisTemplate中opsForValue的使用 (复制粘贴的,没有练习,找时间回顾 )
    yum安装nginx的默认目录详解
    Centos 6无法使用yum解决办法
    JVM:jmap heap 堆参数分析MinHeapFreeRatio、MaxHeapFreeRatio、MaxHeapSize、NewSize、MaxNewSize
    maven下载Oracle jar包
    idea查看源代码出现/* compiled code */
    今日进度
  • 原文地址:https://www.cnblogs.com/coolbear/p/4615481.html
Copyright © 2020-2023  润新知