1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87
|
//
// lager - library for functional interactive c++ programs
// Copyright (C) 2019 Carl Bussey
//
// This file is part of lager.
//
// lager is free software: you can redistribute it and/or modify
// it under the terms of the MIT License, as detailed in the LICENSE
// file located at the root of this source code distribution,
// or here: <https://github.com/arximboldi/lager/blob/master/LICENSE>
//
#pragma once
#include <boost/variant/variant.hpp>
#include <cstdlib>
#include <random>
#include <utility>
#include <vector>
namespace sn {
struct go_left
{};
struct go_right
{};
struct go_up
{};
struct go_down
{};
struct reset
{};
struct tick
{};
using action_t = boost::variant<go_left, go_right, go_up, go_down, reset, tick>;
using point_t = std::pair<int, int>;
inline int x(point_t p) { return p.first; }
inline int y(point_t p) { return p.second; }
enum class direction
{
left,
up,
right,
down
};
struct snake_model
{
using body_t = std::vector<point_t>;
body_t body{};
direction dir{};
};
struct game_model
{
snake_model snake;
point_t apple_pos{};
bool over;
static constexpr int width{25};
static constexpr int height{25};
};
struct app_model
{
std::mt19937 gen;
std::uniform_int_distribution<> dist;
game_model game;
};
template <typename Func>
inline point_t random_apple_pos(Func&& random)
{
return {random(), random()};
}
app_model make_initial(int seed);
app_model update(app_model m, action_t action);
} // namespace sn
|