diff options
| author | Cara Salter <cara@devcara.com> | 2023-01-07 23:24:04 -0500 | 
|---|---|---|
| committer | Cara Salter <cara@devcara.com> | 2023-01-07 23:24:04 -0500 | 
| commit | 36d4f4741cd2559362de7e64820ca4b29b022121 (patch) | |
| tree | 172537aa08f946e2a6dc65bc4bec40985f6e1f95 /src | |
| download | cpp-rl-master.tar.gz cpp-rl-master.zip | |
Diffstat (limited to 'src')
| -rw-r--r-- | src/frame.cpp | 216 | ||||
| -rw-r--r-- | src/frame.hpp | 76 | ||||
| -rw-r--r-- | src/main.cpp | 71 | ||||
| -rw-r--r-- | src/mob.cpp | 43 | ||||
| -rw-r--r-- | src/mob.hpp | 34 | ||||
| -rw-r--r-- | src/noise.cpp | 100 | ||||
| -rw-r--r-- | src/noise.hpp | 32 | ||||
| -rw-r--r-- | src/screen.cpp | 49 | ||||
| -rw-r--r-- | src/screen.hpp | 33 | 
9 files changed, 654 insertions, 0 deletions
| diff --git a/src/frame.cpp b/src/frame.cpp new file mode 100644 index 0000000..48b5687 --- /dev/null +++ b/src/frame.cpp @@ -0,0 +1,216 @@ +/* + * ===================================================================================== + * + *       Filename:  frame.cpp + * + *    Description:  Implementation of frames  + * + *        Version:  1.0 + *        Created:  01/07/2023 10:11:54 PM + *       Revision:  none + *       Compiler:  gcc + * + *         Author:  Cara Salter (muirrum), cara@devcara.com + *   Organization:   + * + * ===================================================================================== + */ + +#include <stdlib.h> +#include "frame.hpp" +#include "noise.hpp" +#include <ncurses.h> + +Frame::Frame(int nr_rows, int nr_cols, int row_0, int col_0) { +        _has_super = FALSE; +        _super = NULL; +        _w = newwin(nr_rows, nr_cols, row_0, col_0); +        _height = nr_rows; +        _width = nr_cols; +        _row = row_0; +        _col = col_0; +} + +Frame::Frame(Frame &sw, int nr_rows, int nr_cols, int row_0, int col_0) { +    _has_super = TRUE; +    _super = sw.win(); + +    _w = derwin(sw.win(), nr_rows, nr_cols, row_0, col_0); +    _height = nr_rows; +    _width = nr_cols; +    _row = row_0; +    _col = col_0; +} + +Frame::~Frame() { +    delwin(_w); +} + +// Place a mob in the window +void Frame::place_mob(Mob &x) { +    mvwaddch(_w, x.row(), x.col(), x.symbol()); +} + +void Frame::place_mob(Mob &x, int row_0, int col_0) { +    if ((row_0 >= 0 && row_0 < _height) && (col_0 >= 0 && col_0 < _width)) { +        // Get element at target position +        char target = mvwinch(_w, row_0, col_0); +        if (target == '~' || target == '#' || target == 'S') { +            return; +        } +        erase(x); +        mvwaddch(_w, row_0, col_0, x.symbol()); +        x.move(row_0, col_0); +    } +} + +void Frame::erase(Mob &x) { +    mvwaddch(_w, x.row(), x.col(), ' '); +} + +void Frame::center(Mob &x) { +	if(_has_super) { +		int rr = _row, cc = _col, hh, ww; +		int _r = x.row() - _height/2; +		int _c = x.col() - _width/2; + +		getmaxyx(_super, hh, ww); + +		if(_c + _width >= ww) { +			int delta = ww - (_c + _width); +			cc = _c + delta; +		} +		else { +			cc = _c; +		} + +		if(_r +_height >= hh) { +			int delta = hh - (_r +_height); +			rr = _r + delta; +		} +		else { +			rr = _r; +		} + +		if (_r < 0) { +			rr = 0; +		} + +		if (_c < 0) { +			cc = 0; +		} + + +		move(rr, cc); +	} +} + +// Refresh window +void Frame::refresh() { +    if (_has_super) { +        touchwin(_super); +    } +    wrefresh(_w); +} + +// Move a window to a new position +void Frame::move(int r, int c) { +    if (_has_super) { +        mvderwin(_w, r, c); +        _row = r; +        _col = c; +        ::refresh(); +    } +} + +void Frame::fill_window() { +    int mid_x = _width/2; +    int mid_y = _height/2; + +    // first region w 0s +    for (int y = 0; y < mid_y; ++y) { +        for(int x = 0; x < mid_x; ++x) { +            mvwaddch(_w, y, x, '0'); +        } +    } +    for (int y = 0; y < mid_y; ++y) { +        for(int x = mid_x; x < _width; ++x) { +            mvwaddch(_w, y, x, '1'); +        } +    } +    for (int y = mid_y; y < _height; ++y) { +        for(int x = 0; x < mid_x; ++x) { +            mvwaddch(_w, y, x, '2'); +        } +    } +    for (int y = mid_y; y < _height; ++y) { +        for(int x = mid_x; x < _width; ++x) { +            mvwaddch(_w, y, x, '3'); +        } +    } + +    for (int y = 0; y < _height; ++y) { +        mvwaddch(_w, y, 0, '|'); +        mvwaddch(_w, y, _width - 1, '|'); +    } + +    for (int x = 0; x < _width; ++ x) { +        mvwaddch(_w, 0, x, '-'); +        mvwaddch(_w, _height - 1, x, '-'); +    } +} + +void Frame::gen_Perlin(const unsigned int &seed) { +    PerlinNoise pn(seed); + +    for (int i = 0; i < _height; ++i) { +        for (int j = 0; j < _width; ++j) { +            double x = (double)j/((double)_width); +            double y = (double)i/((double) _height); + +            double n = pn.noise(10 * x, 10 * y, 0.8); + +            // Water +            if (n < 0.35) { +                mvwaddch(_w, i, j, '~'); +            } else if (n >= 0.35 && n < 0.6) { +                // Floors +                mvwaddch(_w, i, j, '.'); +            } else if (n >= 0.6 && n < 0.8) { +                // Walls +                mvwaddch(_w, i, j, '#'); +            } else { +                // Ice +                mvwaddch(_w, i, j, 'S'); +            } +        } +    } +} + +WINDOW* Frame::win() { +    return _w; +} + +WINDOW* Frame::super() { +    return _super; +} + +bool Frame::has_super() { +    return _has_super; +} + +int Frame::height() { +    return _height; +} + +int Frame::width() { +    return _width; +} + +int Frame::row() { +    return _row; +} + +int Frame::col() { +    return _col; +} diff --git a/src/frame.hpp b/src/frame.hpp new file mode 100644 index 0000000..378619e --- /dev/null +++ b/src/frame.hpp @@ -0,0 +1,76 @@ +/* + * ===================================================================================== + * + *       Filename:  frame.hpp + * + *    Description:  Abstractions around NCurses windows  + * + *        Version:  1.0 + *        Created:  01/07/2023 09:55:52 PM + *       Revision:  none + *       Compiler:  gcc + * + *         Author:  Cara Salter (muirrum), cara@devcara.com + *   Organization:   + * + * ===================================================================================== + */ + +#pragma once + +#include <ncurses.h> + +#include "mob.hpp" + +class Frame { +    // dimensions +    int _height, _width; +    // Position +    int _row, _col; +    // FALSE when root window and TRUE for a subwindow +    bool _has_super; +    // Pointer to an ncurses window +    WINDOW* _w; +    // The super-window, if exists +    WINDOW* _super; + +    public: +        // Init with no parent +        Frame(int nr_rows, int nr_cols, int row_0, int col_0); +        // Init with parent window +        Frame(Frame &super, int nr_rows, int nr_cols, int row_0, int col_0); +        ~Frame(); + +        // Get window type +        bool has_super(); + +        WINDOW* win(); +        WINDOW *super(); + +        // Get height of window +        int height(); +        int width(); +        int row(); +        int col(); + +        void refresh(); +        void move(int r, int c); + +        // Fill a window with numbers, for debugging +        // Will look like this: +        //      0 | 1 +        //      ----- +        //      2 | 3 +        void fill_window(); + +        void move_window(int r, int c); + +        void erase(Mob &x); +        // Add a mob to the window +        void place_mob(Mob &x); +        void place_mob(Mob &x, int row_0, int col_0); +        // Center viewport around mob +        void center(Mob &x); + +        void gen_Perlin(const unsigned int &seed); +}; diff --git a/src/main.cpp b/src/main.cpp new file mode 100644 index 0000000..7a27f82 --- /dev/null +++ b/src/main.cpp @@ -0,0 +1,71 @@ +/* + * ===================================================================================== + * + *       Filename:  main.cpp + * + *    Description:  Entrypoint  + * + *        Version:  1.0 + *        Created:  01/07/2023 09:36:42 PM + *       Revision:  none + *       Compiler:  gcc + * + *         Author:  Cara Salter (muirrum), cara@devcara.com + *   Organization:   + * + * ===================================================================================== + */ +#include <stdlib.h> +#include <ncurses.h> + +#include "screen.hpp" +#include "mob.hpp" +#include "frame.hpp" + +void game_loop(Frame &map, Frame &viewport, Mob &character, int ch); + +int main() { +    Screen scr; +     +    scr.add("Welcome to the game!\nPress any key to start."); + +    int ch = getch(); +     +    Frame game_map(2*scr.height(), 2*scr.width(), 0, 0); + +    Frame viewport(game_map, scr.height(), scr.width(), 0, 0); + +    Mob character('@', game_map.height()/2, game_map.width()/2); + +    game_map.gen_Perlin(237); + +    game_loop(game_map, viewport, character, ch); + +    return 0; +} + +void game_loop(Frame &map, Frame &viewport, Mob &character, int ch) { +    if (ch == 'q' || ch == 'Q') return; + +    map.place_mob(character); +    viewport.center(character); +    viewport.refresh(); + +    for(;;) { +        ch = getch(); + +        if (ch == 'h') { +            map.place_mob(character, character.row(), character.col() -1);  +        } else if (ch == 'j') { +            map.place_mob(character, character.row() + 1, character.col()); +       } else if (ch == 'k') { +           map.place_mob(character, character.row() - 1, character.col()); +        } else if (ch == 'l') { +            map.place_mob(character, character.row(), character.col() + 1); +        } else if (ch == 'q') { +            break; +        } +        viewport.center(character); +        viewport.refresh(); +    } +} diff --git a/src/mob.cpp b/src/mob.cpp new file mode 100644 index 0000000..0da7b34 --- /dev/null +++ b/src/mob.cpp @@ -0,0 +1,43 @@ +/* + * ===================================================================================== + * + *       Filename:  mob.cpp + * + *    Description:  Implements a mobile entity  + * + *        Version:  1.0 + *        Created:  01/07/2023 10:02:44 PM + *       Revision:  none + *       Compiler:  gcc + * + *         Author:  Cara Salter (muirrum), cara@devcara.com + *   Organization:   + * + * ===================================================================================== + */ +#include <stdlib.h> +#include <ncurses.h> +#include "mob.hpp" + +Mob::Mob(char symbol, int row_0, int col_0) { +    _symbol = symbol; +    _row = row_0; +    _col = col_0; +} + +void Mob::move(int row_0, int col_0) { +    _row = row_0; +    _col = col_0; +} + +int Mob::row() { +    return _row; +} + +int Mob::col() { +    return _col; +} + +char Mob::symbol() { +    return _symbol; +} diff --git a/src/mob.hpp b/src/mob.hpp new file mode 100644 index 0000000..496a7bd --- /dev/null +++ b/src/mob.hpp @@ -0,0 +1,34 @@ +/* + * ===================================================================================== + * + *       Filename:  mob.hpp + * + *    Description:  Defines a mobile entity  + * + *        Version:  1.0 + *        Created:  01/07/2023 09:54:14 PM + *       Revision:  none + *       Compiler:  gcc + * + *         Author:  Cara Salter (muirrum), cara@devcara.com + *   Organization:   + * + * ===================================================================================== + */ + +#pragma once +class Mob { +    int _row, _col; +    char _symbol; +    public: +        // Create a mob +        Mob(char symbol, int row_0, int col_0); +        // Change mob position +        void move(int row_0, int col_0); +        // Get character's row (y) position +        int row(); +        // Get mob's col (x) position +        int col(); +        // Get the symbol that represents this mob +        char symbol(); +}; diff --git a/src/noise.cpp b/src/noise.cpp new file mode 100644 index 0000000..d91345b --- /dev/null +++ b/src/noise.cpp @@ -0,0 +1,100 @@ +/* + * ===================================================================================== + * + *       Filename:  noise.cpp + * + *    Description:  Implementation of Perlin Noise  + * + *        Version:  1.0 + *        Created:  01/07/2023 10:55:49 PM + *       Revision:  none + *       Compiler:  gcc + * + *         Author:  Cara Salter (muirrum), cara@devcara.com + *   Organization:   + * + * ===================================================================================== + */ +#include <stdlib.h> +#include <iostream> +#include <cmath> +#include <random> +#include <algorithm> +#include "noise.hpp" + +PerlinNoise::PerlinNoise() { +    // Magic numbers... magic numbers everywhere +    p = { +        		151,160,137,91,90,15,131,13,201,95,96,53,194,233,7,225,140,36,103,30,69,142, +		8,99,37,240,21,10,23,190, 6,148,247,120,234,75,0,26,197,62,94,252,219,203,117, +		35,11,32,57,177,33,88,237,149,56,87,174,20,125,136,171,168, 68,175,74,165,71, +		134,139,48,27,166,77,146,158,231,83,111,229,122,60,211,133,230,220,105,92,41, +		55,46,245,40,244,102,143,54, 65,25,63,161,1,216,80,73,209,76,132,187,208, 89, +		18,169,200,196,135,130,116,188,159,86,164,100,109,198,173,186, 3,64,52,217,226, +		250,124,123,5,202,38,147,118,126,255,82,85,212,207,206,59,227,47,16,58,17,182, +		189,28,42,223,183,170,213,119,248,152, 2,44,154,163, 70,221,153,101,155,167,  +		43,172,9,129,22,39,253, 19,98,108,110,79,113,224,232,178,185, 112,104,218,246, +		97,228,251,34,242,193,238,210,144,12,191,179,162,241, 81,51,145,235,249,14,239, +		107,49,192,214, 31,181,199,106,157,184, 84,204,176,115,121,50,45,127, 4,150,254, +		138,236,205,93,222,114,67,29,24,72,243,141,128,195,78,66,215,61,156,180 }; + +    // Duplicate +    p.insert(p.end(), p.begin(), p.end()); +} + +PerlinNoise::PerlinNoise(unsigned int seed) { +    p.resize(256); + +    // fill p with values from 0 to 255 +    std::iota(p.begin(), p.end(), 0); + +    std::default_random_engine engine(seed); + +    std::shuffle(p.begin(), p.end(), engine); + +    p.insert(p.end(), p.begin(), p.end()); +} + +double PerlinNoise::noise(double x, double y, double z) { +    // Find the unit cube that contains the input +    int X = (int) floor(x) & 255; +    int Y = (int) floor(y) & 255; +    int Z = (int) floor(z) & 255; + +    // find relative x, y, z in cube +    x -= floor(x); +    y -= floor(y); +    z -= floor(z); + +    // Fade curves! +    double u = fade(x); +    double v = fade(y); +    double w = fade(z); + +    // hash coordinates +	int A = p[X] + Y; +	int AA = p[A] + Z; +	int AB = p[A + 1] + Z; +	int B = p[X + 1] + Y; +	int BA = p[B] + Z; +	int BB = p[B + 1] + Z; + +    // Blend! +    double res = lerp(w, lerp(v, lerp(u, grad(p[AA], x, y, z), grad(p[BA], x-1, y, z)), lerp(u, grad(p[AB], x, y-1, z), grad(p[BB], x-1, y-1, z))),	lerp(v, lerp(u, grad(p[AA+1], x, y, z-1), grad(p[BA+1], x-1, y, z-1)), lerp(u, grad(p[AB+1], x, y-1, z-1),	grad(p[BB+1], x-1, y-1, z-1)))); +	return (res + 1.0)/2.0; +} + +double PerlinNoise::fade(double t) { +    return t * t * t * (t * (t * 6 - 15) + 10); +} + +double PerlinNoise::lerp(double t, double a, double b) { +    return a + t * (b - a); +} + +double PerlinNoise::grad(int hash, double x, double y, double z) { +    int h = hash & 15; +	double u = h < 8 ? x : y, +		   v = h < 4 ? y : h == 12 || h == 14 ? x : z; +	return ((h & 1) == 0 ? u : -u) + ((h & 2) == 0 ? v : -v); +} diff --git a/src/noise.hpp b/src/noise.hpp new file mode 100644 index 0000000..c127e7f --- /dev/null +++ b/src/noise.hpp @@ -0,0 +1,32 @@ +/* + * ===================================================================================== + * + *       Filename:  noise.hpp + * + *    Description:  Defining Perlin Noise  + * + *        Version:  1.0 + *        Created:  01/07/2023 10:52:51 PM + *       Revision:  none + *       Compiler:  gcc + * + *         Author:  Cara Salter (muirrum), cara@devcara.com + *   Organization:   + * + * ===================================================================================== + */ +#include <vector> +#include <stdlib.h> + +class PerlinNoise { +    // permutation vector +    std::vector<int> p; +    public: +        PerlinNoise(); +        PerlinNoise(unsigned int seed); +        double noise(double x, double y, double z); +    private: +        double fade(double t); +        double lerp(double t, double a, double b); +        double grad(int hash, double x, double y, double z); +}; diff --git a/src/screen.cpp b/src/screen.cpp new file mode 100644 index 0000000..9bff98f --- /dev/null +++ b/src/screen.cpp @@ -0,0 +1,49 @@ +/* + * ===================================================================================== + * + *       Filename:  screen.cpp + * + *    Description:  Defines an NCurses screen  + * + *        Version:  1.0 + *        Created:  01/07/2023 09:52:27 PM + *       Revision:  none + *       Compiler:  gcc + * + *         Author:  Cara Salter (muirrum), cara@devcara.com + *   Organization:   + * + * ===================================================================================== + */ + +#include <ncurses.h> +#include <stdlib.h> +#include "screen.hpp" + +Screen::Screen() { +    initscr(); +    clear(); +    noecho(); +    cbreak(); +    keypad(stdscr, TRUE); +    curs_set(0); + +    getmaxyx(stdscr, _height, _width); +} + +Screen::~Screen() { +    endwin(); +} + +// Print a message +void Screen::add(const char* message) { +    printw(message); +} + +int Screen::height() { +    return _height; +} + +int Screen::width() { +    return _width; +} diff --git a/src/screen.hpp b/src/screen.hpp new file mode 100644 index 0000000..d9324a2 --- /dev/null +++ b/src/screen.hpp @@ -0,0 +1,33 @@ +/* + * ===================================================================================== + * + *       Filename:  screen.hpp + * + *    Description:  NCurses screen  + * + *        Version:  1.0 + *        Created:  01/07/2023 09:52:54 PM + *       Revision:  none + *       Compiler:  gcc + * + *         Author:  Cara Salter (muirrum), cara@devcara.com + *   Organization:   + * + * ===================================================================================== + */ + + +class Screen { +    int _height, _width; +    public: +        // Initialize NCurses +        Screen(); +        // Clear NCurses +        ~Screen(); +        // Print a message on the screen +        void add(const char* message); +        // Get the screen height +        int height(); +        // Get the screen width +        int width(); +}; | 
