/*
* Copyright 2016-2018, Intel Corporation
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
* panaconda.hpp -- example usage of libpmemobj C++ bindings
*/
#ifndef LIBPMEMOBJ_CPP_EXAMPLES_PANACONDA_HPP
#define LIBPMEMOBJ_CPP_EXAMPLES_PANACONDA_HPP
#include <libpmemobj++/make_persistent_array.hpp>
#include <libpmemobj++/p.hpp>
#include <libpmemobj++/pool.hpp>
#include <libpmemobj++/transaction.hpp>
#include <libpmemobj_cpp_examples_list.hpp>
class board_element;
enum direction { UNDEFINED, DOWN, RIGHT, UP, LEFT };
enum object_type { SNAKE_SEGMENT, WALL, FOOD };
enum config_file_symbol { SYM_NOTHING = '0', SYM_WALL = '1' };
enum play_state { STATE_NEW, STATE_PLAY, STATE_GAMEOVER };
enum snake_event { EV_OK, EV_COLLISION };
enum action { ACTION_NEW_GAME = 'n', ACTION_QUIT = 'q' };
typedef pmem::obj::persistent_ptr<examples::list<board_element>> element_list;
struct color_pair {
color_pair();
color_pair(const int col_fg, const int col_bg);
int color_bg;
int color_fg;
};
struct parameters {
bool use_maze;
std::string name;
std::string maze_path;
};
class helper {
public:
static color_pair get_color(const object_type obj_type);
static int parse_params(int argc, char *argv[],
struct parameters *params);
static inline void sleep(int time);
static inline void print_usage(std::string &name);
};
class point {
public:
pmem::obj::p<int> x;
pmem::obj::p<int> y;
point();
point(int x, int y);
friend bool operator==(point &point1, point &point2);
};
bool operator==(point &point1, point &point2);
class element_shape {
public:
element_shape() = default;
element_shape(int shape);
int get_val();
private:
pmem::obj::p<int> val;
int get_symbol(int shape);
};
class board_element {
public:
board_element();
board_element(int px, int py,
pmem::obj::persistent_ptr<element_shape> shape,
direction dir);
board_element(point p, pmem::obj::persistent_ptr<element_shape> shape,
direction dir);
board_element(const board_element &element);
~board_element();
pmem::obj::persistent_ptr<point> calc_new_position(const direction dir);
void print(void);
void print_double_col(void);
void print_single_double_col(void);
pmem::obj::persistent_ptr<point> get_position(void);
void set_position(const pmem::obj::persistent_ptr<point> new_point);
direction get_direction(void);
void set_direction(const direction dir);
private:
pmem::obj::persistent_ptr<point> position;
pmem::obj::persistent_ptr<element_shape> shape;
pmem::obj::p<direction> element_dir;
};
class snake {
public:
snake();
~snake();
void move(const direction dir);
void print(void);
void add_segment(void);
bool check_point_against_segments(point point);
point get_head_point(void);
direction get_direction(void);
point get_next_point(const direction dir);
private:
element_list snake_segments;
pmem::obj::p<point> last_seg_position;
pmem::obj::p<direction> last_seg_dir;
};
class game_board {
public:
game_board();
~game_board();
void print(const int score);
void print_game_over(const int score);
unsigned get_size_row(void);
void set_size_row(const unsigned size_r);
unsigned get_size_col(void);
void set_size_col(const unsigned size_c);
int creat_dynamic_layout(const unsigned row_no, char *const buffer);
int creat_static_layout(void);
bool is_snake_head_food_hit(void);
void create_new_food(void);
bool is_collision(point point);
snake_event move_snake(const direction dir);
direction get_snake_dir(void);
void add_snake_segment(void);
private:
pmem::obj::persistent_ptr<snake> anaconda;
pmem::obj::persistent_ptr<board_element> food;
element_list layout;
pmem::obj::p<unsigned> size_row;
pmem::obj::p<unsigned> size_col;
void set_new_food(const point point);
bool is_snake_collision(point point);
bool is_wall_collision(point point);
};
class game_player {
public:
game_player();
~game_player();
int get_score(void);
void update_score(void);
play_state get_state(void);
void set_state(const play_state st);
private:
pmem::obj::p<int> score;
pmem::obj::p<play_state> state;
};
class game_state {
public:
game_state();
~game_state();
pmem::obj::persistent_ptr<game_board> get_board();
pmem::obj::persistent_ptr<game_player> get_player();
void init(void);
void clean_pool(void);
private:
pmem::obj::persistent_ptr<game_board> board;
pmem::obj::persistent_ptr<game_player> player;
};
class game {
public:
game(struct parameters *par);
~game();
void init(void);
void init_colors(void);
void process_step(void);
void process_key(const int lastkey);
inline bool is_stopped(void);
void process_delay(void);
void clear_screen(void);
bool is_game_over(void);
void game_over(void);
void clear_prog(void);
private:
pmem::obj::pool<game_state> state;
int last_key;
int delay;
struct parameters *params;
direction direction_key;
void clean_pool(void);
void set_direction_key(void);
int parse_conf_create_dynamic_layout(void);
};
#endif /* LIBPMEMOBJ_CPP_EXAMPLES_PANACONDA_HPP */