Hello, Habrachelovek!
I decided somehow that it would be nice to learn how to write “Hello world!” In bash. After all, I have been working on ubunt for half a year already, I’m ashamed not to be able to do that. I searched on Habré and realized that it’s not fashionable to read manuals now; you need to write your game. It remains to choose which one.
Chess ,
Xonix ,
Sokoban ,
Sea battle has already been written, Tetris also seems (although I did not find the links), what should I choose? The first idea was a strategy, but it was abandoned due to complete insanity (although I hope that one of those who continue the history of topics about games on bash will write it). Therefore, I stopped at a shooter.

*
The picture shows a corridor and a monster a few steps ahead.')
Link to the script:
github.com/EvilTosha/labirinth/blob/master/lab2.shUnder the cut you will find
an absolutely uninteresting and unnecessary description of the inside of the game.
Sketches, perspective and general idea
It all started with sketches on a piece of paper.

This had to be somehow translated into a form acceptable to the terminal. As it turned out, the perspective of the corridor, pleasant to the eye, is not so easy to draw. Therefore, a small program was written in C ++. Subsequently, it was modified to generate different layers of the displayed image.
UPDI will answer the often arising claim. This code is not used in the script, it is needed only for preliminary preparation of data that will be entered into the script during the initialization of variables and arrays.
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <cmath>
#include <vector>
using namespace std;
// p ,
// p1 p2
bool overLine(pair< int , int > p1, pair< int , int > p2, pair< int , int > p){
return (p1.second - p2.second) * p.first + (p2.first - p1.first) * p.second >
-(p1.first * p2.second - p2.first * p1.second);
}
const int width = 128;
const int height = 36;
//
const int delta_ceil = 20;
const int delta_floor = 20;
int main(){
freopen( ".out" , "w" , stdout);
char field[height][width];
//
pair< int , int > p3(11, width / 2), p6(12, width / 2);
//
pair< int , int > p1(0, delta_ceil), p2(0, width - delta_ceil);
pair< int , int > p4(height, delta_floor), p5(height, width - delta_floor);
//
int depths[8] = {10, 27, 39, 48, 54, 58, 61, 65};
for ( int x = 0; x < height; ++x){
for ( int y = 0; y < width; ++y){
pair< int , int > p(x, y);
//
if (!overLine(p2, p3, p) && !overLine(p3, p1, p))
field[x][y] = 'c' ;
//
else if (overLine(p6, p4, p) && overLine(p5, p6, p))
field[x][y] = 'f' ;
//
else {
int wall = min(y, width - y);
int d = 0;
while (wall > depths[d])
++d;
field[x][y] = '0' + d;
}
}
}
//
for ( int x = 0; x < height; ++x){
for ( int y = 0; y < width; ++y){
cout << field[x][y];
}
cout << endl;
}
return 0;
}
* This source code was highlighted with Source Code Highlighter .
Then there were reflections: to make the walls flat (use the space between two adjacent cells of the field) or occupying 1 cell. In the first version it was not clear what to draw when the corridor turns, and immediately again in the opposite direction. (I don’t really want to do honest geometry on a bash, and it would work more slowly than a turtle)

Therefore, it was decided to make some cells of the field walls. But even here there are some problems with rendering. What for example to do in this situation?

Therefore, a restriction is imposed on the generated maze - there should not be a single square 2 * 2 without walls. Now this maze needs to be generated.
Maze Generation
It uses an algorithm similar to the
search in depth . Those. we fill the entire field with walls, choose the starting point, and begin to bypass the field as a graph, just sorting all the neighbors not by a certain order, but by chance. In addition, we check whether a “forbidden” square was formed 2 * 2. We get something like this

The generation works for quite a long time (for 20 * 20 about a couple of seconds), presumably, turning recursion to the stack would give a tangible increase in speed, but why do we need such big mazes?
Fast rendering
Initially, each "pixel" was derived by its own echo. With a screen size of 36 * 128, drawing a single frame took almost a second, and I really didn’t like it. If you draw only those "pixels" that have changed, the speed drops even more. Therefore, the following steps were taken: we put all the characters in an array, and then call
echo -ne "$ {screen [*]}"
to display all items. But with such a call, the elements of the array are separated by spaces. The screen for output from me also consists only of multi-colored spaces, so I could close my eyes to this, but I wanted some versatility. The solution was this: change the IFS (Internal Field Separator, internal field separator), which is initially equal to "\ n \ t" (line feed, tab and space) to empty, and at the end of the script change back (so you can continue without rediscover terminal). This completely solved the problem. But, by the way, more than 5 FPS could not be obtained, therefore the “realtime-mode” is initially disabled and the shooter is obtained step-by-step. But if you want to make fun of the screen “flicker” over your eyes, you can turn it on in constants.
By the way, the entire script uses only standard 8 colors for text and background. If you get stuck with a lot of colors, you can make beautiful gradient lighting, and even more natural colors ...
Creating a monster, the ability to shoot and other trifles will not describe, everything is simple and boring.
Conclusion
There are a lot of things that I wanted to do, but I didn’t have enough patience (or rather, the interest disappeared before they were realized). These are for example several monsters instead of one, the correct work of lives (now they are displayed only for beauty), a change of weapon (and, accordingly, different characteristics), a console (iddqd, but what? =)) And, of course, a network game.
I wanted to upload more video of the gameplay, but when I installed the necessary software for recording, the ubunt on the virtual box broke down. = (
Thank you for your attention, I will be glad to any criticism!