zoukankan      html  css  js  c++  java
  • 实验3 类和对象 小球游戏,三角形,分数类

    开幕雷击:本文非常非常非常长,请做好心理准备再阅读!推荐跳过小球游戏,直接阅读分数类的实现!可以直接点击右侧列表实现跳转。

    实验结论

    小球移动游戏

    代码极其垃圾,写法极其鬼畜,阅读前请做好准备。正确的写法应该是再写一个类控制小球的移动,但是我当时一时脑抽,写出了如下产物。切勿模仿!!!!!!!!!

    源码

    main.cpp
    #include <iostream>
    #include <random>
    #include <conio.h>
    #include "canvas.h"
    #include <ctime>
    
    using namespace std;
    
    mt19937 gen(static_cast<unsigned int>(time(nullptr)));
    
    int main() {
        int score=0;
        cout << "Press any key to start,'Q' to quit." << endl;
        if (getch() == 'q' || getch() == 'Q')
            return 0;
        Canvas canvas1("0", "A", 25, 25);
    
        uniform_int_distribution<> enemyX(1, canvas1.getX());
        uniform_int_distribution<> enemyY(1, canvas1.getY());
    
        canvas1.generateBalls(1, 1);
        canvas1.generateBalls(enemyX(gen), enemyY(gen),'$');
        while (true) {
            switch (getch()) {
                case 'W':
                case 'w':
                    canvas1.getBalls()[0].up();
                    canvas1.refreshBalls();
                    break;
                case 'A':
                case 'a':
                    canvas1.getBalls()[0].left();
                    canvas1.refreshBalls();
                    break;
                case 'S':
                case 's':
                    canvas1.getBalls()[0].down();
                    canvas1.refreshBalls();
                    break;
                case 'D':
                case 'd':
                    canvas1.getBalls()[0].right();
                    canvas1.refreshBalls();
                    break;
                case 'Q':
                case 'q':
                    return 0;
            }
            if (canvas1.getBalls()[0].getx() == canvas1.getBalls()[1].getx() &&
                canvas1.getBalls()[0].gety() == canvas1.getBalls()[1].gety()) {
                score++;
                canvas1.deleteLastBall();
                canvas1.generateBalls(enemyX(gen), enemyY(gen),'$');
                canvas1.refreshBalls();
            }
            cout<<"Score:"<<score<<endl;
        }
    }
    
    canvas.h
    #ifndef CANVAS_H
    #define CANVAS_H
    
    #include <vector>
    #include <string>
    #include "ball.h"
    
    using std::string;
    using std::vector;
    
    class Canvas {
    public:
        Canvas(string bg0 = "0", string fg0 = "A", int x = 50, int y = 50);
        void changeCanvasBg(string &bg0);
        void changeCanvasFg(string &fg0);
        void changeCanvasColor(string &bg0, string &fg0);
        void refreshG();
        void refreshBalls();
        void generateBalls(int x0, int y0, char ch0='o');
        void deleteLastBall();
        vector<Ball>& getBalls();
        int getX() const;
        int getY() const;
    
    private:
        int X;
        int Y;
        char **blocks;
        string bg;
        string fg;
        vector<Ball> balls;
    };
    
    #endif
    
    
    canvas.cpp
    #include <utility>
    #include "canvas.h"
    #include <cstdlib>
    #include <iostream>
    
    Ball ball(1, 1, 1, 1);
    
    Canvas::Canvas(string bg0, string fg0, int x, int y) : bg(std::move(bg0)), fg(std::move(fg0)), X(x), Y(y) {
        blocks = new char *[Y];
        for (int i = 0; i < Y; ++i) {
            blocks[i] = new char[X]{' '};
        }
        refreshG();
    }
    
    void Canvas::changeCanvasBg(string &bg0) {
        bg = bg0; // 更新画布背景色
        refreshG();
    
    }
    
    void Canvas::changeCanvasFg(string &fg0) {
        fg = fg0; // 更新画布前景色
        refreshG();
    }
    
    void Canvas::changeCanvasColor(string &bg0, string &fg0) {
        bg = bg0;  // 更新画布背景色
        fg = fg0;   // 更新画布前景色
        refreshG();
    }
    
    void Canvas::refreshG() {
        string color = "color ";
        color += bg;
        color += fg;
        system(color.c_str());
    }
    
    void Canvas::refreshBalls() {
        system("cls");
        for (int j = 0; j < Y; ++j) {
            for (int i = 0; i < X; ++i) {
                blocks[j][i]=' ';
            }
        }
        for (int i = 0; i < balls.size(); ++i) {
            blocks[balls[i].gety()-1][balls[i].getx()-1]=balls[i].getCh();
        }
        for (int j = 0; j < Y; ++j) {
            for (int i = 0; i < X; ++i) {
                std::cout<<blocks[j][i];
            }
            std::cout<<std::endl;
        }
    }
    
    void Canvas::generateBalls(int x0, int y0,char ch0) {
        balls.push_back(ball);
        balls.back().setX(X);
        balls.back().setY(Y);
        balls.back().setx(x0);
        balls.back().sety(y0);
        balls.back().setCh(ch0);
    }
    
    vector<Ball>& Canvas::getBalls() {
        return balls;
    }
    
    int Canvas::getX() const {
        return X;
    }
    
    int Canvas::getY() const {
        return Y;
    }
    
    void Canvas::deleteLastBall() {
        balls.pop_back();
    }
    
    ball.h
    #ifndef BALL_H
    #define BALL_H
    
    class Ball {
    public:
        Ball(int x0, int y0, int X0, int Y0);   // 在坐标(X,Y)处构造一个小球(小球用字符O表示)
        void left(int step = 1);    // 左移step
        void right(int step = 1);        // 右移step
        void up(int step = 1);        // 上移step
        void down(int step = 1);        // 下移step
        void setx(int x0);
        void sety(int y0);
        void setX(int X0);
        void setY(int Y0);
        int getX() const;
        int getY() const;
        int gety() const;
        int getx() const;
        char getCh() const;
        void setCh(char ch='o');
    
    private:
        char ch;
        int x;
        int y;
        int X;
        int Y;
    };
    
    #endif
    
    ball.cpp
    #include "ball.h"
    #include "canvas.h"
    #include <iostream>
    
    using std::cout;
    using std::endl;
    
    Ball::Ball(int x0, int y0, int X0, int Y0) : x(x0), y(y0), X(X0), Y(Y0) {
    }
    
    void Ball::left(int step) {
        x = x - step;
        if (x <= 1)
            x = 1;
    }
    
    void Ball::right(int step) {
        x = x + step;
        if (x >= X)
            x = X;
    }
    
    void Ball::up(int step) {
        y = y - step;
        if (y <= 1)
            y = 1;
    }
    
    void Ball::down(int step) {
        y = y + step;
        if (y >= Y)
            y = Y;
    }
    
    void Ball::setY(int Y0) {
        Y = Y0;
    }
    
    void Ball::setx(int x0) {
        x = x0;
    }
    
    void Ball::sety(int y0) {
        y = y0;
    }
    
    void Ball::setX(int X0) {
        X = X0;
    }
    
    int Ball::getx() const {
        return x;
    }
    
    int Ball::gety() const {
        return y;
    }
    
    int Ball::getX() const {
        return X;
    }
    
    int Ball::getY() const {
        return Y;
    }
    
    void Ball::setCh(char ch0) {
        ch = ch0;
    }
    
    char Ball::getCh() const {
        return ch;
    }
    

    运行截图

    画三角形

    因为上一part里已经做过控制小球移动的内容了,本part的实现基本一样,所以咕咕咕了也没什么问题吧。(笑

    源码

    main.cpp
    #include <iostream>
    #include "graph.h"
    
    using namespace std;
    
    int main() {
        Graph graph1('*', 5);
        graph1.draw();
        Graph graph2('$', 7);
        graph2.draw();
        cin.get();
        return 0;
    }
    
    graph.h
    #ifndef GRAPH_H
    #define GRAPH_H
    
    // 类Graph的声明 
    class Graph {
    public:
        Graph(char ch, int n);   // 带有参数的构造函数
        void draw();    // 绘制图形
    private:
        char symbol;
        int size;
    };
    
    #endif
    
    graph.cpp
    // 类graph的实现
    
    #include "graph.h"
    #include <iostream>
    
    using namespace std;
    
    // 带参数的构造函数的实现 
    Graph::Graph(char ch, int n) : symbol(ch), size(n) {
    }
    
    // 成员函数draw()的实现
    // 功能:绘制size行,显示字符为symbol的指定图形样式 
    void Graph::draw() {
        for (int i = 0; i < size; ++i) {
            for (int j = 0; j < size - i - 1; ++j) {
                cout << ' ';
            }
            for (int k = 0; k < 2 * (i + 1) - 1; k++) {
                cout << symbol;
            }
            cout << endl;
        }
    }
    

    运行截图

    Fraction类的实现

    源码

    main.cpp
    #include <iostream>
    #include "Fraction.h"
    
    using namespace std;
    
    int main() {
        Fraction a(-1, 2);
        Fraction b(4, -3);
        Fraction c(-5, -20);
        Fraction d(5, 1);
        Fraction e(1, -5);
        a.show();
        cout << a << endl;
        cout << a.add(b) << endl;
        cout << a + b << endl;
        cout << b.minus(c) << endl;
        cout << b - c << endl;
        cout << c.multiply(d) << endl;
        cout << c * d << endl;
        cout << d.division(e) << endl;
        cout << d / e << endl;
        cout << d.compare(e) << endl;
        cout << d.compare(d) << endl;
        cout << e.compare(d) << endl;
        return 0;
    }
    
    Fraction.h
    //
    // Created by KOKODA on 2019/4/21.
    //
    
    #ifndef FRACTION_H
    #define FRACTION_H
    
    #include<iostream>
    
    class Fraction {
    private:
        int top;
        int bottom;
    public:
        Fraction(int top = 0, int bottom = 1);
        Fraction add(Fraction &a);
        Fraction minus(Fraction &a);
        Fraction multiply(Fraction &a);
        Fraction division(Fraction &a);
        Fraction operator*(Fraction &a);
        Fraction operator+(Fraction &a);
        Fraction operator-(Fraction &a);
        Fraction operator/(Fraction &a);
        int compare(Fraction &a);
        friend std::ostream& operator << (std::ostream&,Fraction);
        void show();
        double Decimal();
    };
    #endif //FRACTION_H
    
    Fraction.cpp
    //
    // Created by KOKODA on 2019/4/21.
    //
    
    #include "Fraction.h"
    #include <iostream>
    
    int gcd(int a0, int b0) {
        int a = std::abs(a0);
        int b = std::abs(b0);
        if (a < b) {
            std::swap(a, b);
        }
        if (b == 0) {
            return a;
        } else {
            return gcd(b, a % b);
        }
    }
    
    int lcm(int a, int b) {
        return std::abs(a * b) / gcd(a, b);
    }
    
    Fraction::Fraction(int top0, int bottom0) : top(top0 / gcd(top0, bottom0)), bottom(bottom0 / gcd(top0, bottom0)) {
        if (top * bottom > 0) {
            top = abs(top);
            bottom = abs(bottom);
        } else if (bottom < 0) {
            top = -top;
            bottom = -bottom;
        }
    }
    
    Fraction Fraction::operator+(Fraction &a) {
        return {top * (lcm(bottom, a.bottom) / bottom) + a.top * (lcm(bottom, a.bottom) / a.bottom), lcm(bottom, a.bottom)};
    }
    
    Fraction Fraction::add(Fraction &a) {
        return {top * (lcm(bottom, a.bottom) / bottom) + a.top * (lcm(bottom, a.bottom) / a.bottom), lcm(bottom, a.bottom)};
    }
    
    Fraction Fraction::operator-(Fraction &a) {
        return {top * (lcm(bottom, a.bottom) / bottom) - a.top * (lcm(bottom, a.bottom) / a.bottom), lcm(bottom, a.bottom)};
    }
    
    Fraction Fraction::minus(Fraction &a) {
        return {top * (lcm(bottom, a.bottom) / bottom) - a.top * (lcm(bottom, a.bottom) / a.bottom), lcm(bottom, a.bottom)};
    }
    
    Fraction Fraction::operator*(Fraction &a) {
        return {top * a.top, bottom * a.bottom};
    }
    
    Fraction Fraction::multiply(Fraction &a) {
        return {top * a.top, bottom * a.bottom};
    }
    
    Fraction Fraction::operator/(Fraction &a) {
        return {top * a.bottom, bottom * a.top};
    }
    
    Fraction Fraction::division(Fraction &a) {
        return {top * a.bottom, bottom * a.top};
    }
    
    void Fraction::show() {
        if (top / bottom == (double) top / (double) bottom)
            std::cout << top / bottom << std::endl;
        else
            std::cout << top << '/' << bottom << std::endl;
    }
    
    std::ostream &operator<<(std::ostream &output, Fraction a) {
        if (a.top / a.bottom == (double) a.top / (double) a.bottom)
            output << a.top / a.bottom;
        else
            output << a.top << '/' << a.bottom;
        return output;
    }
    
    double Fraction::Decimal() {
        return (double) top / (double) bottom;
    }
    
    int Fraction::compare(Fraction &a) {
        if(((*this)-a).bottom*((*this)-a).top<0)
            return -1;
        else if(((*this)-a).bottom*((*this)-a).top==0)
            return 0;
        else
            return 1;
    }
    

    运行截图

    实验总结与体会

    part1

    这一part的话,正确的做法是使用一个新的类来控制小球的移动,但是因为我当时没想到而且我就想用给的两个类来着,于是写了这么个不伦不类的东西,总之大家不要学我。但还是基本写出了个框架可以实现多个小球同台竞技了,加球也还算简单吧(心虚。

    part2

    找出公式就好了,没什么说的。

    part3

    最最最重要的部分来了,分数类的设计用到了运算符重载,不过这不关键,主要是在构造函数的设计上我采用了将输入直接约分的形式,保证所有分数类对象在创建的时候是以最简形式出现的,然后在进行 +-*/ 的运算时,返回值时会调用构造函数,也就保证了所有运算得出的值都是最简形式,计划通!完美,这样做得话不但完美解决了最简形式的问题,而且代码简洁又工整,看起来很舒服。那么说完了最关键的部分,我来提一手分数类实现的功能。

    1. 实现了 add()minus()multiply()division()函数用以进行加减乘除运算。
    2. 运用运算符重载实现分数类对象使用 +-*/运算符进行运算。
    3. 实现了返回分数对应的小数值的函数
    4. 实现了两个分数的比较 例:a.compare(b)若a > b则返回1,a = b则返回0,a < b则返回-1

    值得一提的是 compare()的实现我使用了this指针这样就可以利用之前实现的-运算符重载直接比较两者的大小

    ps:也可以直接重载> <号来实现直接比较,但我就没有去做了,有兴趣的同学可以试着写写看。

  • 相关阅读:
    ubuntu下安装maven
    159.Longest Substring with At Most Two Distinct Characters
    156.Binary Tree Upside Down
    155.Min Stack
    154.Find Minimum in Rotated Sorted Array II
    153.Find Minimum in Rotated Sorted Array
    152.Maximum Product Subarray
    151.Reverse Words in a String
    150.Evaluate Reverse Polish Notation
    149.Max Points on a Line
  • 原文地址:https://www.cnblogs.com/KOKODA/p/10749482.html
Copyright © 2011-2022 走看看