c++ - 如何在 Visual Studio 2017 中设置 SFML?

标签 c++ sfml

我不知道你们中的一些人是否遇到过这种情况。我还没有开始编程,因为“我不知道从哪里开始”。我想制作一款平台视频游戏,而且是 8 位游戏。是的,这需要很多时间和技巧,但我总是喜欢跳到复杂的东西上。

我是那种喜欢使用最新程序的人。所以我使用 Visual Studio 2017,但是 SFML 是 VS2015。有没有办法使用 SFML 是 VS2017?我能做什么?

最佳答案

首先,恭喜您开始编程之旅!

但是,作为指导过许多有相同抱负的 child (例如学习 C++ 来制作视频游戏)的人,我建议您从一条更简单的道路开始。

我不会尝试学习 C# 或 Java 或其他一些语言,因为我和许多其他人实际上是从 C 开始的;这不是关于学习特定的语言,而是关于理解整个系统。线程、对象、循环或函数的概念不会改变,不同语言的使用方式不同。

I'm the kind of person that likes to use the latest of the latest programs.

虽然这通常对大多数程序都有好处,但由于错误修复或其他增强功能,这对开发环境而言并非如此。更新 Visual Studio 时,通常会更新整个工具链:编译器、链接器、SDK 等。

这意味着可能会引入有缺陷的编译器,或者将代码标记为已弃用,以及其他需要考虑的问题。尤其是在开发游戏之类的东西时。

I haven't started programming because "I don't know where to start"

这是一个简单的 "war"模拟 2 位玩家的纸牌游戏;它会自动进行 war ,直到赢得比赛。它重复此操作直到收到中断信号 (CTRL+C) 并打印出任何游戏中的最大回合数以及最小回合数我们的“自动玩家”玩的任何游戏。

它是用 C++ 编写的,可以进行修改以获取二十一点或扑克游戏的用户输入,并且您可以在任何系统上简单地构建它。

此代码用于教学,因此您可以使用此代码、修改它、构建它、运行它,并了解每个步骤中发生的情况。

从那里,您可以了解更多信息,提出更多问题,最终您将能够使用 SFML 制作您的 2D 平台游戏。 .

war .cpp

#include <iostream>
#include <string>
#include <sstream>
#include <deque>
#include <algorithm>
#include <ctime>
#include <cstdlib>
#include <csignal>

#define print(v) std::cout << v
#define printl(v) std::cout << v << std::endl

namespace util {
    class random {
        public:
            random() { std::srand(std::time(0)); }
            int get(int max_val) { return std::rand() % max_val; }
    };
}

namespace battle {
    class suit {
        public:
            typedef enum enum_t {
                HEART,
                DIAMOND,
                CLUB,
                SPADE,
                END
            } enum_t;

            suit() : m_val(END) {}
            suit(const suit& cp) : m_val(cp.m_val) {}
            explicit suit(enum_t val) : m_val(val) {}

            suit& operator=(const suit& other)
            {
                this->m_val = other.m_val;
                return *this;
            }
            suit& operator=(const enum_t& other)
            {
                this->m_val = other;
                return *this;
            }

            bool operator==(const enum_t& other) { return (this->m_val == other); }
            bool operator!=(const enum_t& other) { return (this->m_val != other); }
            bool operator<(const enum_t& other) { return (this->m_val < other); }
            bool operator>(const enum_t& other) { return (this->m_val > other); }
            operator int() const { return static_cast<int>(this->m_val); }
            operator enum_t() const { return this->m_val; }
            
            friend std::ostream& operator<<(std::ostream& os, const battle::suit& val)
            {
                switch (val.m_val) {
                    case battle::suit::HEART: os << "♥"; break;
                    case battle::suit::DIAMOND: os << "♦"; break;
                    case battle::suit::CLUB: os << "♣"; break;
                    case battle::suit::SPADE: os << "♠"; break;
                    default: os << '?'; break;
                }
                return os;
            }

        private:
            enum_t m_val;
    };
    
    class value {
        public:
            typedef enum enum_t {
                ACE,
                ONE,
                TWO,
                THREE,
                FOUR,
                FIVE,
                SIX,
                SEVEN,
                EIGHT,
                NINE,
                JACK,
                QUEEN,
                KING,
                END
            } enum_t;

            value() : m_val(END) {}
            value(const value& cp) : m_val(cp.m_val) {}
            explicit value(enum_t val) : m_val(val) {}

            value& operator=(const value& other)
            {
                this->m_val = other.m_val;
                return *this;
            }
            value& operator=(const enum_t& other)
            {
                this->m_val = other;
                return *this;
            }

            bool operator==(const enum_t& other) { return (this->m_val == other); }
            bool operator!=(const enum_t& other) { return (this->m_val != other); }
            bool operator<(const enum_t& other) { return (this->m_val < other); }
            bool operator>(const enum_t& other) { return (this->m_val > other); }
            operator int() const { return static_cast<int>(this->m_val); }
            operator enum_t() const { return this->m_val; }

            friend std::ostream& operator<<(std::ostream& os, const battle::value& val)
            {
                switch (val.m_val) {
                    case battle::value::ACE: os << 'A'; break;
                    case battle::value::JACK: os << 'J'; break;
                    case battle::value::QUEEN: os << 'Q'; break;
                    case battle::value::KING: os << 'K'; break;
                    default: os << static_cast<int>(val); break;
                }
                return os;
            }

        private:
            enum_t m_val;
    };

    class card {
        public:
            card() : m_val(value::END), m_suit(suit::END) {}
            card(const card& cp) : m_val(cp.m_val), m_suit(cp.m_suit) {}
            card(int suit, int val) : m_val(static_cast<value::enum_t>(val)), m_suit(static_cast<suit::enum_t>(suit)) {}
            card(suit::enum_t suit, value::enum_t val) : m_val(val), m_suit(suit) {}
            ~card() {}
            
            card& operator=(const card& other)
            {
                this->m_val = other.m_val;
                this->m_suit = other.m_suit;
                return *this;
            }
            
            bool operator==(const card& other)
            {
                return (this->m_val == other.m_val && this->m_suit == other.m_suit);
            }
            
            bool operator!=(const card& other)
            {
                return !(this->m_val == other.m_val && this->m_suit == other.m_suit);
            }
            
            bool operator<(const card& other)
            {
                if (this->m_val == value::ACE) {
                    return false;
                }
                return (this->m_val < other.m_val);
            }
            
            bool operator>(const card& other)
            {
                if (this->m_val == value::ACE) {
                    return (other.m_val != value::ACE);
                }
                return (this->m_val > other.m_val);
            }
            
            bool empty() const
            {
                return (this->m_val == value::END ||
                        this->m_suit == suit::END);
            }
            
            friend std::ostream& operator<<(std::ostream& os, const card& obj)
            {
                os << obj.m_val << obj.m_suit;
                return os;
            }
            
            int suit() const
            {
                return this->m_suit;
            }
            
            value::enum_t value() const
            {
                return this->m_val;
            }
            
        private:      
            battle::value m_val;
            battle::suit m_suit;
    };

    class deck {
        public:
            static const std::size_t DECK_SIZE = 52;
            static const std::size_t HALF_DECK = 26;

            deck() : m_rand(), m_deck() {}
            
            ~deck() {}
            
            bool add(card& c)
            {
                if (c.empty()) { return false; }
                const std::size_t idx = static_cast<std::size_t>(c.suit());
                itr_t cv = std::find(this->m_deck.begin(), this->m_deck.end(), c);
                bool found = (cv != this->m_deck.end());
                if (!found) {
                    this->m_deck.insert(this->m_deck.begin(), c);
                    return true;
                }
                return false;
            }
            
            void add_init(card c)
            {
                const std::size_t idx = static_cast<std::size_t>(c.suit());
                this->m_deck.push_back(c);
            }

            card deal()
            {
                if (!this->empty()) {
                    std::size_t cnt = this->m_deck.size();
                    if ((cnt == 0) || ((cnt - 1) == 0)) {
                        card ret(this->m_deck[0]);
                        this->m_deck.erase(this->m_deck.begin());
                        return ret;
                    }
                    cnt = this->m_rand.get(cnt);
                    card ret = this->m_deck[cnt];
                    this->remove_it(ret);
                    return ret;
                }
                return card();
            }
            
            bool empty() const
            {
                return this->m_deck.empty();
            }

            void fill()
            {
                printl("Filling deck");
                for (int s = suit::HEART; s < suit::END; ++s) {
                    for (int v = value::ACE; v < value::END; ++v) {
                        this->add_init(battle::card(s, v));
                    }
                }
            }

            void top_to_back()
            {
                card& c = this->m_deck[this->m_deck.size()-1];
                for (itr_t s = this->m_deck.begin(); s != this->m_deck.end(); ++s) {
                    if ((*s) == c) {
                        this->m_deck.erase(s);
                        break;
                    }
                }
                this->m_deck.insert(this->m_deck.begin(), c);
            }

            void remove(const card& c)
            {
                if (!this->empty()) {
                    this->remove_it(c);
                }
            }
            
            std::size_t size() const
            {
                return this->m_deck.size();
            }

            card operator[](std::size_t idx) const
            {
                return this->m_deck[idx];
            }
            
        private:
            deck(const deck& cp); // = delete
            deck& operator=(const deck& other); // = delete

            util::random m_rand;
            std::deque<card> m_deck;
            typedef std::deque<card>::iterator itr_t;
            
            void remove_it(const card& c)
            {
                for (itr_t s = this->m_deck.begin(); s != this->m_deck.end(); ++s) {
                    if ((*s) == c) {
                        this->m_deck.erase(s);
                        break;
                    }
                }
            }
    };

    class player {
        public:
            player() : m_hand(), m_name("NaN"), m_id(), m_tot_add(0), m_tot_rem(0), m_won(0), m_other(0) {}
            player(std::size_t id) : m_hand(), m_name(), m_id(id), m_tot_add(0), m_tot_rem(0), m_won(0), m_other(0)
            {
                std::stringstream ss;
                ss << "Player " << id;
                this->m_name = ss.str();
            }
        
            void add_init(card c)
            {
                this->m_hand.add_init(c);
            }
        
            bool add_card(card c)
            {
                ++this->m_tot_add;
                return this->m_hand.add(c);
            }
            
            void add_cards(const std::deque<card>& cards)
            {
                std::deque<card>::const_iterator start = cards.begin();
                while (start != cards.end()) {
                    this->add_card(*start);
                    ++start;
                }
            }
            
            bool empty() const
            {
                return this->m_hand.empty();
            }

            std::deque<card> battle_group() const
            {
                std::deque<card> ret;
                if (!this->empty()) {
                    std::size_t top_idx = this->m_hand.size()-1;
                    for (std::size_t i = 0; i < 4 && top_idx > 0; ++i) {
                        ret.push_back(this->m_hand[--top_idx]);
                    }
                }
                return ret;
            }
            
            std::size_t hand_size() const
            {
                return this->m_hand.size();
            }

            std::size_t id() const
            {
                return this->m_id;
            }
            
            std::string name() const
            {
                return this->m_name;
            }
            
            void print_hand() const
            {
                for (std::size_t i = 0; i < this->m_hand.size(); ++i) {
                    std::cout << this->m_hand[i] << std::endl;
                }
            }
            
            void remove_card(card c)
            {
                ++this->m_tot_rem;
                this->m_hand.remove(c);
            }
            
            void remove_cards(const std::deque<card>& cards)
            {
                std::deque<card>::const_iterator start = cards.begin();
                while (start != cards.end()) {
                    this->remove_card(*start);
                    ++start;
                }
            }
            
            void print_stats()
            {
                printl("---" << this->name() << "---");
                printl("Hand: " << this->m_hand.size());
                printl("Wins: " << this->m_won);
                printl("Took: " << this->m_tot_add);
                printl("Lost: " << this->m_tot_rem);
            }
            
            void set_other_play(player& other)
            {
                this->m_other = &other;
            }

            void takes(card& c)
            {
                printl(this->m_name << " takes " << c);
                this->m_hand.top_to_back();
                this->m_other->remove_card(c);
                this->add_card(c);
            }

            card top_card() const
            {
                if (this->empty()) { return card(); }
                return this->m_hand[this->m_hand.size()-1];
            }

            void won_battle(card& c)
            {
                printl(this->m_name << " won the battle!");
                this->takes(c);
                ++this->m_won;
            }

            void won_battle(const std::deque<card>& cards)
            {
                std::deque<card>::const_iterator start = cards.begin();
                this->m_hand.top_to_back();
                print(this->m_name << " won the battle, takes");
                while (start != cards.end()) {
                    print(" " << *start);
                    this->m_other->remove_card(*start);
                    this->add_card(*start);
                    ++start;
                }
                printl("");
                ++this->m_won;
            }

        private:
            deck m_hand;
            std::string m_name;
            std::size_t m_id;
            std::size_t m_tot_add;
            std::size_t m_tot_rem;
            std::size_t m_won;
            player* m_other;
    };

    class game {
        public:
            game() : m_deck(), m_p1(1), m_p2(2), m_turns(0), m_battles(0)
            {
                this->m_p1.set_other_play(this->m_p2);
                this->m_p2.set_other_play(this->m_p1);
                this->m_deck.fill();
                printl("Dealing cards");
                for (std::size_t i = 0; i < deck::HALF_DECK; ++i) {
                    this->m_p1.add_init(this->m_deck.deal());
                    this->m_p2.add_init(this->m_deck.deal());
                }
            }

            std::size_t dobattle(battle::card& c1, battle::card& c2)
            {
                printl("BATTLE!!!!");
                ++this->m_battles;
                std::size_t sz1 = this->m_p1.hand_size();
                std::size_t sz2 = this->m_p2.hand_size();
                if (sz2 <= 1 && sz1 > 1) {
                    this->m_p1.won_battle(c2);
                    return this->m_p1.id();
                }
                if (sz1 <= 1 && sz2 > 1) {
                    this->m_p2.won_battle(c1);
                    return this->m_p2.id();
                }

                std::deque<battle::card> t1 = this->m_p1.battle_group();
                std::deque<battle::card> t2 = this->m_p2.battle_group();
                printl(this->m_p1.name() << ": " << t1.back() << ", " << this->m_p2.name() << ": " << t2.back());
                if (t1.back() > t2.back()) {
                    this->m_p1.won_battle(t2);
                    return this->m_p1.id();
                } else if (t1.back() < t2.back()) {
                    this->m_p2.won_battle(t1);
                    return this->m_p2.id();
                } else { // another battle

                    this->m_p1.remove_card(c1); this->m_p1.remove_cards(t1);
                    this->m_p2.remove_card(c2); this->m_p2.remove_cards(t2);

                    if (this->dobattle(t1.back(), t2.back()) == this->m_p1.id()) {
                        this->m_p1.add_card(c1); this->m_p1.add_cards(t1);
                        this->m_p2.add_card(c2); this->m_p2.add_cards(t2);

                        this->m_p1.won_battle(t2);
                        return this->m_p1.id();
                    } else {
                        this->m_p1.add_card(c1); this->m_p1.add_cards(t1);
                        this->m_p2.add_card(c2); this->m_p2.add_cards(t2);

                        this->m_p2.won_battle(t1);
                        return this->m_p2.id();
                    }
                }
                return 0;
            }

            void play()
            {
                battle::card c1, c2;
                while (true) {
                    if (this->check_win()) break;
                    c1 = this->m_p1.top_card();
                    c2 = this->m_p2.top_card();
                    printl(this->m_p1.name() << ": " << c1 << ", " << this->m_p2.name() << ": " << c2);
                    if (c1 < c2) {
                        this->m_p2.takes(c1);
                    } else if (c1 > c2) {
                        this->m_p1.takes(c2);
                    } else { // c1 == c2
                        this->dobattle(c1, c2);
                    }
                    ++this->m_turns;
                    if (this->check_win()) break;   
                }
                printl("");
                printl("Game over!");
                printl("");
            }

            void print_stats()
            {
                printl("----Stats----");
                printl("Turns: " << this->m_turns);
                printl("Battles: " << this->m_battles);
                this->m_p1.print_stats();
                this->m_p2.print_stats();
            }

            std::size_t turns() const { return this->m_turns; }
            std::size_t battles() const { return this->m_battles; }

        private:
            deck m_deck;
            player m_p1;
            player m_p2;
            std::size_t m_turns;
            std::size_t m_battles;

            bool check_win() const
            {
                if (this->m_p1.empty() || this->m_p2.empty()) {
                    if (this->m_p1.empty() && !this->m_p2.empty()) {
                        printl(this->m_p2.name() << " WINS!");
                    } else if (!this->m_p1.empty() && this->m_p2.empty()) {
                        printl(this->m_p1.name() << " WINS!");
                    } else {
                        printl("TIE?");
                    }
                    return true;
                }
                return false;
            }
    };
}

static volatile bool m_stop;

static void sig_hand(int sig) {
    if (sig == SIGINT) { m_stop = true; }
}

int main(int argc, char* argv[])
{
    std::size_t x = ~0;
    std::size_t n = 0;
    std::size_t g = 0;
    const std::size_t MAX = 8; // 7*4 = 28

    std::signal(SIGINT, sig_hand);

    while ((x > MAX) && !m_stop) {
        battle::game game;
        game.play();
        ++g;
        game.print_stats();
        if (game.turns() < x) {
            x = game.turns();
            std::cerr << "least: " << x << std::endl;
        }
        if (n < game.turns()) {
            n = game.turns();
            std::cerr << "most: " << n << std::endl;
        }
    }
    //printl("Done! Games played: " << g << ", Least turns: " << x << ", Most turns: " << n);

    std::cerr << "Done! Games played: " << g << ", Least turns: " << x << ", Most turns: " << n << std::endl;
    return 0;
}

希望对您有所帮助。

关于c++ - 如何在 Visual Studio 2017 中设置 SFML?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48305279/

相关文章:

c++ - 在 linux (ubuntu) 上编译 SFML

c++ - 使用 Cereal 序列化/反序列化 SFML Vectors 类

c - 如何在Csfml中为 map 充电

c++ - 在 SFML 2.4 中使用字体 Sprite 表作为字体

c++ - 静态链接 libtcod

c++ - 如何一次定义几个仅名称不同的函数(不使用宏)?

c++ - 如何在 Win32 上使用 C++ 安装硬件驱动程序?

c++ - 当前类成员函数的指针数组

c++ - 从 dock 启动进程与 OS X 上的命令行有什么区别

c++ - SFML 纹理内存管理