"- After the Revolt, the Galactic Commonwealth imposed strict restrictions on higher-order metafunctions . And not only for ethical reasons; their authorities fear in general any manifestation of delusions of grandeur ..."I suggest you play tic-tac-toe with a compiler. For the game, knowledge of c ++ is not required, it is enough to have cmake, python and the c ++ compiler itself (it will pull even as ancient as gcc-3.3). Python is used only to enter user data, run the compiler after each turn, and the compiled program to get the result. All calculations (the next move, determination of the winner or statement of a draw) are made at the compilation stage, at run-time only the output of the result.
( from google search results )
git clone https://github.com/migashko/tictactoe.git cd tictactoe/ git submodule init git submodule update
./tictactoe.py
mkdir build cd ./build cmake .. make tictactoe
Level [0,1,2]: 2 Figure [X,x,1,O,o,0]: o compiling... - - - - X - - - - Move [0..8, a1..c3]: a2 compiling... - O - - X - X - - Move [0..8, a1..c3]: a3 compiling... XOO - X - X - - Move [0..8, a1..c3]: b2 BUSSY Move [0..8, a1..c3]: b1 compiling... XOO OX - X - X X winner (compiler)
echo 2 > level.inl
e,e,e, x,o,e, e,e,e
echo "e,e,e,x,o,e,e,e,e" > board.inl
$> make $> ./tictactoe - - - XO - - - X $> make $> ./tictactoe - - X XO - - - - $> make $> ./tictactoe X - - XO - - - -
$> ./tictactoe_its - - - XO - - - - X - - XO - - - - X - - XO - O - - X - X XO - O - - XOX XO - O - - XOX XO - OX - Draw
e> ./tictactoe.py Level [0,1,2]: 2 Figure [X,x,1,O,o,0]: x Move [0..8, a1..c3]: b1 compilingโฆ - - - XO - - - - Move [0..8, a1..c3]: c3 compiling... - - O XO - - - X Move [0..8, a1..c3]: c1 compiling... - - O XO - XOX Move [0..8, a1..c3]: a1 compiling... X - O XO - XOX X winner (you)
typedef fas::int_<2> level;
std::cout << fas::int_<1>::value << std::endl; // 1 std::cout << fas::plus< fas::int_<1>, fas::int_<2> >::value << std::endl; // 3
std::cout << fas::same_type<int, long>::value; // 0 std::cout << fas::same_type<int, int>::value; // 1
typedef fas::pair< fas::int_<1>, fas::int_<2> > pair; typedef fas::tuple< fas::int_<3>, fas::int_<4>, fas::int_<5> > tuple; std::cout << fas::first<pair>::type::value << std::endl; // 1 std::cout << fas::second<tuple>::type::value << std::endl; // 4 std::cout << fas::third<tuple>::type::value << std::endl; // 5
std::cout << fas::if_< fas::true_, fas::int_<42>, fas::int_<24> >::type::value << std::endl; // 42 std::cout << fas::switch_< fas::case_< fas::false_, fas::int_<24> >, fas::case_c< 1, fas::int_<42> >, fas::default_< fas::int_<44> > >::type::value << std::endl; // 42
struct empty_list { typedef metalist::empty_list metatype; }; template< typename L, typename R = empty_list > struct type_list { typedef metalist::type_list metatype; typedef L left_type; typedef R right_type; };
typedef fas::type_list<A, fas::type_list<B, fas::type_list<C, fas::type_list<D > > > > list_abcd; // [A,B,C,D,empty_list]
typedef fas::type_list<A, B > list2_ab_invalid;
typedef fas::type_list< A, B > list_ab_invalid; // [A,B] typedef fas::type_list< C, D > list_cd_invalid; // [C,D] typedef fas::type_list< list_ab_invalid, list_cd_invalid> list_abcd_invalid; // [[C,D],[C,D]] typedef fas::organize<list2_abcd_invalid>::type list_abcd; // [A,B,C,D,empty_list]
typedef fas::type_list_n<A,B,C>::type list; // [A,B,C,empty_list]
typedef fas::type_list_n< fas::type_list_n<A,B>::type, // [A,B,empty_list] fas::type_list_n<C,D>::type // [C,D,empty_list] >::type list; // [A,B,C,D,empty_list]
struct list_bc: fas::type_list<B, fas::type_list<C> > {}; // [B,C,empty_list] struct list_abc: fas::type_list<B, list_bc > {}; // [A,list_bc]
typedef fas::merge< list_bc, // [B,C,empty_list] list_abc // [A,list_bc] >::type list; // [B,C,A,list_bc]
template<int A, int B, int C> struct list123: fas::type_list_n< fas::int_<A>, fas::int_<B>, fas::int_<C> >::type {};
#include <fas/integral.hpp> #include <fas/type_list.hpp> typedef fas::type_list_n< fas::int_<1>, fas::int_<2> , fas::int_<2> >::type list1; struct list2: list1 {}; template<typename L> class test {}; int main() { // test<list2> tst; test<list1> tst; tst.doit(); }
error: 'class test<fas::type_list<fas::int_<1>, fas::type_list<fas::int_<2>, fas::type_list<fas::int_<2>, fas::empty_list> > > >' has no member named 'doit'
error: 'class test<list2>' has no member named 'doit'
template<typename L, typename R> struct length; template<typename L, typename R> struct length< type_list<L, R> > { enum { value = 1 + length<R>::value }; }; template<> struct length< empty_list > { enum { value = 0 }; };
template<typename L> struct length : length_impl<typename L::metatype, L> {}; template<typename L> struct length_impl<metalist::type_list, L> { typedef typename L::right_type tail; enum { value = 1 + length< tail>::value }; }; template<typename L> struct length_impl<metalist::empty_list, L> { enum { value = 0 }; };
template< typename T1 = empty_list, typename T2 = empty_list, typename T3 = empty_list, typename T4 = empty_list, typename T5 = empty_list, typename T6 = empty_list, typename T7 = empty_list, typename T8 = empty_list, typename T9 = empty_list, typename T10 = empty_list, typename T11 = empty_list, typename T12 = empty_list, typename T13 = empty_list, typename T14 = empty_list, typename T15 = empty_list, typename T16 = empty_list, typename T17 = empty_list, typename T18 = empty_list, typename T19 = empty_list, typename T20 = empty_list, typename T21 = empty_list, typename T22 = empty_list, typename T23 = empty_list, typename T24 = empty_list, typename T25 = empty_list, typename T26 = empty_list > struct type_list_n { typedef type_list< T1, type_list< T2, type_list< T3, type_list< T4, type_list< T5, type_list< T6, type_list< T7, type_list< T8, type_list< T9, type_list< T10, type_list< T11, type_list< T12, type_list< T13, type_list< T14, type_list< T15, type_list< T16, type_list< T17, type_list< T18, type_list< T19, type_list< T20, type_list< T21, type_list< T22, type_list< T23, type_list< T24, type_list< T25, type_list< T26 > > > > > > > > > > > > > > > > > > > > > > > > > > bar; typedef typename organize<bar>::type type; };
template<typename Head = fas::empty_list, typename ...Args > struct type_list_n { typedef typename fas::organize< fas::type_list< Head, typename type_list_n<Args...>::type > >::type type; }; template<> struct type_list_n<> { typedef fas::empty_list type; };
typedef fas::erase< fas::int_<0>, fas::type_list<char> >::type empty; typedef fas::erase_c< 0, fas::type_list<char> >::type empty;
erase<I,L>::type
erase_c<int,L>::type
head::type
index_of<T,L>::value
length::value
merge<L1,L2>::type
organize::type
normalize::type
push_back<T,L>::type
push_front<T,L>::type
reverse::type
split<I,L>::left_list
split<I,L>::right_list
split_c<int,L>::left_list
split_c<int,L>::right_list
tail::type
type_at<I,L>::type
type_at_c<int,L>::type
type_count<T,L>::value
unique::type
unique_first::type
template<typename L> struct last { typedef typename fas::type_at_c< fas::length< L >::value-1, L >::type type; };
template<int Pos, typename T, typename L> struct set_at_c { typedef fas::split_c<Pos, L> splitter; typedef typename splitter::left_list left_list; typedef typename splitter::right_list right_list; typedef typename fas::tail< right_list >::type headless; typedef typename fas::push_front< T, headless >::type pollywog; typedef typename fas::merge< left_list, pollywog >::type type; }; template<typename Pos, typename T, typename L> struct set_at : set_at_c< Pos::value, T, L> { };
template<typename L, template<typename> class F > struct transform_t;
typedef fas::type_list_n< fas::int_<1>, fas::int_<2>, fas::int_<3>, fas::int_<4> >::type lst; typedef fas::transform_t<lst2, fas::inc >::type res; // [2,3,4,5]
template<typename L, typename F > struct transform;
typedef fas::transform<lst, fas::inc< fas::_ > >::type res2;
Example | Alternative |
---|---|
foo <_> | foo <_1> |
foo <_, _> | foo <_1, _2> |
foo <_1, _, _ 2> | foo <_1, _1, _2> |
foo <_1, _, _ 2, _, _> | foo <_1, _1, _2, _2, _3> |
typedef fas::transform< lst, fas::make_int< fas::inc< fas::_ > > >::type res2;
accumulate<L, I, F<_,_>=plus >
count<T, L>
count_if<L, <_> >
erase_if<L, C<_> >
find_if<L, C<_> >
for_<I, C<_>, F<_> >
generator< T, F<_> >
generate< N, F >
index_of_if<L, C<_> >
is_sorted<L, <_,_>=less >
random_shuffle<R, L>
select< L, <_> >
shuffle< L, RL>
sort<L, <_,_>=less >
transform<L, F<_> >
transform2<L1, L2, F<_,_> >
transform_if< L, F<_>, C<_> >
transform_tail<L, F<_> >
transform_tail_if< L, F<_>, C<_> >
unique_if<L, <_,_>=same_type >
unique_first_if<L, <_,_>=same_type >
typedef fas::type_list_n< fas::int_<3>, fas::int_<2>, fas::int_<3>, fas::int_<1> >::type list1; //[3,2,3,1] typedef fas::sort_t<list1>::type res1; //[1,2,3,3] typedef fas::sort<list1>::type res2; //[1,2,3,3] typedef fas::sort_t<list1, fas::greater>::type res3; //[3,3,2,1] typedef fas::sort< list1, fas::greater< fas::_1, fas::_2> >::type res4; //[3,3,2,1] typedef fas::sort< list1, fas::greater< fas::_2, fas::_1> >::type res5; //[1,2,3,3]
struct A{}; struct B:A{}; struct C:B{}; struct D:C{}; typedef fas::type_list_n< C, B, A, A, D >::type list2; typedef fas::sort< list2, fas::f< fas::super_subclass< fas::_1, fas::_2> > >::type res5; // [A,A,B,C,D]
typedef fas::sort< list2, std::is_base_of< fas::_1, fas::_2> >::type res5; // [A,A,B,C,D] typedef fas::sort_t<list2, std::is_base_of >::type res5; // [A,A,B,C,D]
struct A; struct B; struct C; typedef fas::type_list_n< A, B, C >::type list4; typedef fas::accumulate< list4, empty_list, push_front<_2, _1> >::type res4; // [C,B,A]
struct e {}; struct x {}; struct o {};
typedef fas::int_< #include "level.inl" > level; typedef fas::type_list_n< #include "board.inl" >::type board;
typedef fas::int_< #include "rand.inl" > initial_rand;
typedef fas::type_list_n< e, e, e, e, e, e, e, e, e >::type empty_board;
std::ostream& operator<<(std::ostream& s, e) { s << "-"; } std::ostream& operator<<(std::ostream& s, o) { s << "O"; } std::ostream& operator<<(std::ostream& s, x) { s << "X"; }
template<typename L, typename R> std::ostream& operator<<(std::ostream& s, fas::type_list<L, R>) { s << L(); // int len = fas::length<R>::value; // if ( len%3 == 0 ) // , s << std::endl; else if (len != 0) // , , s << " "; s << R(); // โโ } std::ostream& operator<<(std::ostream& s, fas::empty_list) { // . }
template<typename Pos, typename Fig, typename Board> std::ostream& operator<< ( std::ostream& s, fas::tuple< Pos, Fig, Board> ) { s << Board(); // Board , enum { // nopos = fas::same_type< Pos, fas::int_<-1> >::value, // nofig = fas::same_type< e, Fig>::value, }; if ( nopos ) { // , if (nofig) s << "Draw" << std::endl; else s << Fig() << " winner (you)" << std::endl; } else if ( !nofig ) { // - s << Fig() << " winner (compiler)" << std::endl; } }
template<typename Pos, typename F, typename S, typename Tail> std::ostream& operator<<(std::ostream& s ,fas::type_list<fas::tuple< Pos, F, S>, Tail>) { s << fas::tuple<Pos, F, S>() << std::endl; s << Tail(); }
template<typename R, typename Level, typename Board> struct game;
template<typename R, typename Level, typename Board> struct game { typedef typename figure<Board>::type fig; typedef typename available_moves<R, Level, fig, Board>::type moves; typedef typename fas::head<moves>::type result_move; typedef typename fas::first<result_move>::type position; typedef typename fas::second<result_move>::type win_fig; typedef typename do_move<position, fig, Board>::type board; typedef fas::tuple< position, win_fig, board > type; };
template<typename Board> struct figure { typedef typename fas::if_c< fas::type_count< e, Board>::value % 2 == 1, x, o >::type type; };
template< typename R, typename Level, typename Fig, typename Board > struct available_moves { typedef typename fas::type_list_n< typename winner_list< Fig, Board >::type, typename winning_moves< Fig, Board >::type, typename blocking_moves< Fig, Board >::type, typename draw_list< Board >::type, typename free_moves<R, Level, Board >::type >::type type; };
x - - 0 x - - - 0
[[0,e],[1,e],[2,e]] [[3,e],[4,e],[5,e]] [[6,e],[7,e],[8,e]] [[0,e],[3,e],[6,e]] [[1,e],[4,e],[7,e]] [[2,e],[5,e],[8,e]] [[0,e],[4,e],[8,e]] [[2,e],[4,e],[6,e]]
template<typename, typename PairList3> struct winner_line { typedef typename fas::switch_< fas::case_c< is_win_line<x, PairList3>::value, fas::pair< fas::int_<-1>, x> >, fas::case_c< is_win_line<o, PairList3>::value, fas::pair< fas::int_<-1>, o> >, fas::default_< fas::empty_list > >::type type; };
template<typename Fig, typename PairList3> struct is_win_line { enum { value = fas::count_if< PairList3 , fas::same_type< Fig, fas::second<fas::_1> > >::value == 3 }; };
template<typename Fig, typename PairList3> struct has_win_pos { enum { value = fas::count_if< PairList3 , fas::same_type< e, fas::second<fas::_1> > >::value == 1 && fas::count_if< PairList3 , fas::same_type< Fig, fas::second<fas::_1> > >::value == 2 }; };
template<typename Fig, typename PairList3 > struct win_helper { typedef typename fas::if_c< has_win_pos< Fig, PairList3 >::value, typename fas::select< PairList3, fas::same_type< fas::second<fas::_1>, e> >::type, fas::empty_list >::type type; };
template<typename Fig, typename PairList3 > struct blocking_move { typedef typename fas::if_< fas::same_type<Fig, x>, o, x >::type rev_fig; typedef typename win_helper< rev_fig, PairList3 >::type type; };
template<typename Fig, typename PairList3> struct winning_move { typedef typename fas::transform< typename win_helper< Fig, PairList3 >::type, fas::pair< fas::first<fas::_1>, Fig > >::type type; };
template< template<typename, typename> class Move, typename Fig, typename Board, int P0, int P1, int P2 > struct move_t { typedef typename fas::type_list_n< fas::pair< fas::int_<P0>, typename fas::type_at_c<P0, Board>::type >, fas::pair< fas::int_<P1>, typename fas::type_at_c<P1, Board>::type >, fas::pair< fas::int_<P2>, typename fas::type_at_c<P2, Board>::type > >::type pos_list; typedef typename Move<Fig, pos_list>::type type; };
template< template<typename, typename> class Move, typename Fig, typename Board > struct moves_list_t { typedef typename fas::type_list_n < typename move_t< Move, Fig, Board, 0, 1, 2 >::type, typename move_t< Move, Fig, Board, 3, 4, 5 >::type, typename move_t< Move, Fig, Board, 6, 7, 8 >::type, typename move_t< Move, Fig, Board, 0, 3, 6 >::type, typename move_t< Move, Fig, Board, 1, 4, 7 >::type, typename move_t< Move, Fig, Board, 2, 5, 8 >::type, typename move_t< Move, Fig, Board, 0, 4, 8 >::type, typename move_t< Move, Fig, Board, 2, 4, 6 >::type >::type type; };
template<typename Fig, typename Board> struct winner_list : moves_list_t< winner_line, Fig, Board> {};
template<typename Fig, typename Board> struct winning_moves : moves_list_t< winning_move, Fig, Board> {};
template<typename Fig, typename Board> struct blocking_moves : moves_list_t< blocking_move, Fig, Board> {};
template<typename Board> struct draw_list { typedef typename fas::if_c< fas::type_count< e, Board >::value < 3, fas::pair< fas::int_<-1>, e >, fas::empty_list >::type type; };
template<typename R, typename Level> struct priority_positions;
typedef fas::int_<4> center; typedef fas::type_list_n< fas::int_<0>, fas::int_<2>, fas::int_<6>, fas::int_<8> >::type corner_list; typedef fas::type_list_n< fas::int_<1>, fas::int_<3>, fas::int_<5>, fas::int_<7> >::type edge_list;
typedef typename fas::merge< center, typename fas::merge< typename fas::random_shuffle< R, corner_list>::type, typename fas::random_shuffle< R, side_list>::type >::type >::type level2_list;
[A,B,C,D]
[10,2,44,7]
[[10,A],[2,B],[44,C],[7,D]]
[[2,B],[7,D],[10,A],[44,C]]
[B,D,A,C]
typedef fas::generator< fas::int_<1>, fas::inc< fas::_ > >::next_type result; // fas::int_<2>
typedef fas::generator< fas::int_<1>, fas::rand< fas::_> >::next_type result; // fas::int_<12461757>
template<typename R, typename L> struct random_shuffle { typedef typename generate_c< length<L>::value, generator_t<rand<R>, rand > >::type rand_list; typedef typename shuffle< L, rand_list>::type type; };
template<typename L, typename RL> struct shuffle { typedef typename transform2_t< RL, L, make_pair >::type pair_list; typedef typename sort< pair_list, less< first<_1>, first<_2> > >::type sorted_list; typedef typename transform_t< sorted_list, second >::type type; };
typedef typename fas::random_shuffle< R, level2_list >::type level0_list;
typedef typename fas::merge< corner_list, edge_list >::type side_list; typedef typename fas::merge< center, typename fas::random_shuffle< R, side_list>::type >::type level1_list;
typedef typename fas::switch_< fas::case_c< Level::value == 0, level0_list >, fas::case_c< Level::value == 1, level1_list >, fas::default_< level2_list > >::type type;
template<typename R, typename Level> struct priority_positions { typedef fas::int_<4> center; typedef fas::type_list_n< fas::int_<0>, fas::int_<2>, fas::int_<6>, fas::int_<8> >::type corner_list; typedef fas::type_list_n< fas::int_<1>, fas::int_<3>, fas::int_<5>, fas::int_<7> >::type edge_list; typedef typename fas::merge< corner_list, edge_list >::type side_list; typedef typename fas::merge< center, typename fas::merge< typename fas::random_shuffle< R, corner_list>::type, typename fas::random_shuffle< R, side_list>::type >::type >::type level2_list; typedef typename fas::merge< center, typename fas::random_shuffle< R, side_list>::type >::type level1_list; typedef typename fas::random_shuffle< R, level2_list >::type level0_list; typedef typename fas::switch_< fas::case_c< Level::value == 0, level0_list >, fas::case_c< Level::value == 1, level1_list >, fas::default_< level2_list > >::type type; };
typedef typename fas::transform < typename priority_positions< R, Level >::type, fas::pair< fas::_1, fas::type_at< fas::_1, Board> > >::type pair_list;
typedef typename fas::select< pair_list, fas::same_type< e, fas::second<fas::_> > >::type type;
template<typename R, typename Level, typename Board> struct free_moves { typedef typename fas::transform< typename priority_positions< R, Level >::type, fas::pair< fas::_1, fas::type_at< fas::_1, Board> > >::type pair_list; typedef typename fas::select< pair_list, fas::same_type< e, fas::second<fas::_> > >::type type; };
template<typename Pos, typename Fig, typename Board> struct do_move { typedef typename set_at< Pos, Fig, Board >::type type; }; template<typename Fig, typename Board> struct do_move< fas::int_<-1>, Fig, Board> { typedef fas::empty_list type; };
#include "tictactoe.hpp" #include "types.hpp" #include "show_board.hpp" #include <iostream> int main() { typedef game< initial_rand, level, board >::type result; std::cout << result() ; return 0; }
int factorial(int n) { return n > 0 ? n * factorial(n - 1) : 1; }
template<int N> struct factorial { enum { value = N * factorial<N-1>::value }; }; template<> struct factorial<1> { enum { value = 1 };};
int factorial(int i) { int result = 1; for ( ; i > 0; result*=i, --i); return result; }
int i=0; for (; i<10;i++); std::cout << i << std::endl;
typedef fas::for_< fas::int_<0>, fas::less<fas::_, fas::int_<10> >, fas::inc<fas::_> >::type result; std::cout << result::value << std::endl;
template<int I> struct factorial { typedef typename fas::for_< // fas::pair< fas::int_<I>, // fas::int_<1> // >, // ( ) fas::greater< fas::first< _1 >, int_<0> >, // ( ) fas::pair< fas::dec< fas::first< _1 > >, fas::times< fas::second< _1 >, fas::first< _1 > > > >::type result; // : ( ) typedef typename fas::second<result>::type type; // int_< I! > enum { value = type::value}; };
fas::type_list< fas::tuple< fas::empty_type, // e, // board // > >
fas::and_< fas::not_< fas::same_type< fas::int_<-1>, fas::first< last< fas::_1> > > >, fas::same_type< e, fas::second< last< fas::_1> > > >
fas::push_back< game< initial_rand, // โโ level, // fas::third< last< fas::_1> > // // ( ) >, fas::_1 // >
#include "show_board.hpp" #include "tictactoe.hpp" #include "types.hpp" int main() { typedef fas::for_< fas::type_list< fas::tuple< fas::empty_type, e, board > >, fas::and_< fas::not_< fas::same_type< fas::int_<-1>, fas::first< last< fas::_1> > > >, fas::same_type< e, fas::second< last< fas::_1> > > >, fas::push_back< game< initial_rand, level, fas::third< last< fas::_1> > >, fas::_1 > >::type result_list; typedef fas::tail<result_list>::type game_list; std::cout << board() << std::endl; std::cout << game_list() << std::endl; return 0; }
error: template instantiation depth exceeds maximum of 900
Source: https://habr.com/ru/post/228367/
All Articles