Skip to content

Commit

Permalink
add sln
Browse files Browse the repository at this point in the history
  • Loading branch information
diademoff committed May 18, 2021
0 parents commit 2366c99
Show file tree
Hide file tree
Showing 21 changed files with 1,079 additions and 0 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.vscode
bin
obj
25 changes: 25 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
BSD 2-Clause License

Copyright (c) 2021, Dmitry
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.

2. 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.

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 HOLDER 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.
43 changes: 43 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# About
![GitHub repo size](https://img.shields.io/github/repo-size/diademoff/snake-cli)
![CodeFactor Grade](https://img.shields.io/codefactor/grade/github/diademoff/snake-cli)
![GitHub](https://img.shields.io/github/license/diademoff/snake-cli)

Play your favorite game in console. Install `dotnet-runtime` to run app.

<img src="https://i.imgur.com/Yovm1S1.png" alt="drawing" width="600"/>

Platforms:
* Windows
* Gnu Linux

Features:
* Use `W`, `A`, `S`, `D` or arrows for moving
* Use `Escape` for pause
* Use `Space` for speedup

[Download](https://github.com/diademoff/snake-cli/releases)

# Build
Install `dotnet-sdk` to build.

## Linux

```
git clone https://github.com/diademoff/snake-cli && cd snake-cli
```

Build and install
```
make && sudo make install
```

Run
```
snake-cli
```

## Windows
```
dotnet publish -r win-x64 -p:PublishSingleFile=true --self-contained true
```
18 changes: 18 additions & 0 deletions games-cli.sln
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.6.30114.105
MinimumVisualStudioVersion = 10.0.40219.1
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|Any CPU = Release|Any CPU
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal
63 changes: 63 additions & 0 deletions games-cli/Apple.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
/*
Яблоко, которое змейка должна съесть
*/

using System;
using System.Drawing;
using System.Linq;

class Apple : IDrawable
{
public Point Location { get; private set; }
public char Char { get; set; } = '☼';

// Создать яблоко в поле с случайным расположением
public Apple(AppleGen applegen, ref Random rnd)
{
this.Location = applegen.GetRandomPoint(ref rnd);
}
}

struct AppleGen
{
public int Field_width;
public int Field_height;
public Point[] Avoid; // Не генерировать в заданных точках
public Padding Padding;

public AppleGen(int field_width, int field_height, Snake snake)
{
Field_width = field_width;
Field_height = field_height;
Padding = new Padding(0, 0, 0, 0);

Avoid = new Point[snake.Blocks.Count];

for (int i = 0; i < snake.Blocks.Count; i++)
{
Avoid[i] = snake.Blocks[i].Location; // не генерировать на змейке
}
}

public AppleGen(int field_width, int field_height, Snake snake, Padding p) : this(field_width, field_height, snake)
{
this.Padding = p;
}

/*
Сгенерировать место в соответствии с заданными параметрами.
*/
public Point GetRandomPoint(ref Random rnd)
{
Point point;

do
{
int x = rnd.Next(Padding.Left + 1, this.Field_width - Padding.Right - 1);
int y = rnd.Next(Padding.Top + 1, this.Field_height - Padding.Buttom - 1);
point = new Point(x, y);
} while (Avoid.ToList().Contains(point));

return point;
}
}
170 changes: 170 additions & 0 deletions games-cli/Display.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
/*
Управление содержимым экрана.
*/

using System;

class Display : IInteractive
{
/*
Находится ли голова змейки на яблоке.
*/
public bool IsAppleEaten => snake.IsEaten(apple);

/*
столкнулась ли змейка с собой или с краем.
*/
public bool IsSnakeIntersect => snake.SelfIntersect() || snake.BorderIntersect(FIELD_SIZE_WIDTH, FIELD_SIZE_HEIGHT, p);

/*
Ускорение
*/
bool speedUp = false;
/*
Высчитать задержку между кадрами исходя из текущего прогресса и
ускорения.
*/
public int FrameDelay => frameDelay();
int frameDelay()
{
if (speedUp)
{
speedUp = false;
return progress.Delay / 4;
}
return progress.Delay;
}
int FIELD_SIZE_WIDTH;
int FIELD_SIZE_HEIGHT;
int INIT_DELAY = 100;

Snake snake;
/*
Для отрисовки используется класс Drawer. Он предоставляет
возможность отрисовать IDrawable.
*/
Drawer drawer;
Apple apple;
/*
Прогресс игрока
*/
Progress progress;
Random rnd = new Random();

Padding p = new Padding(1, 1, 3, 5);
MessageBox info_paused;

public Display()
{
FIELD_SIZE_WIDTH = Console.WindowWidth;
FIELD_SIZE_HEIGHT = Console.WindowHeight;

drawer = new Drawer(FIELD_SIZE_WIDTH, FIELD_SIZE_HEIGHT);
progress = new Progress(INIT_DELAY, FIELD_SIZE_WIDTH, FIELD_SIZE_HEIGHT, 1);

Console.Title = "snake-cli";
Console.CursorVisible = false;

info_paused = new MessageBox("Press ESC to resume", 30, 5,
FIELD_SIZE_WIDTH, FIELD_SIZE_HEIGHT, p);

snake = new Snake('*', p);
drawer.CreateBorder('·', p);

RegenerateApple(p);

drawer.RedrawAll();
}

// Отрисовать окно Game over
public void GameOver()
{
MessageBox box = new MessageBox("GAME OVER", 50, 7,
FIELD_SIZE_WIDTH, FIELD_SIZE_HEIGHT, p);

drawer.Create(box);
Flush();
drawer.RedrawAll();

Console.CursorVisible = true;
}

// Отрисовать окна паузы
public void Paused()
{
drawer.Create(info_paused);
Flush();
}

/*
Удовлетворить запросы на отрисовку
*/
public void Flush()
{
drawer.DrawToConsole();
}

public void MoveSnake()
{
UnPause(); // стереть надпись паузы
RemoveSnake(); // Удалить старую змейку

snake.Move();

if (IsAppleEaten)
{
AddBlock();
}

Draw(); // добавить в очередь на отрисовку всё содержимое

Flush(); // отрисовать очередь
}

public bool IsFocused { get => true; set => throw new NotImplementedException(); }

public void HandleKey(ConsoleKey key)
{
if (key == ConsoleKey.Spacebar)
{
speedUp = true;
return;
}
snake.HandleKey(key);
}

/*
Добавить в очередь запросы на отрисовку компонентов
*/
void Draw()
{
drawer.Create(snake);
drawer.Create(apple);
drawer.Create(progress.StatusBar);
}

void AddBlock()
{
snake.AddBlock();
drawer.Remove(apple); // удалить старое яблоко
RegenerateApple(p);
progress.AppleEaten();
}

// Запрос на удаление окна паузы
void UnPause()
{
drawer.Remove(info_paused);
}

// Запрос на удаление змейки
void RemoveSnake()
{
drawer.Remove(snake); // запрос на удаление змейки
}

void RegenerateApple(Padding p)
{
apple = new Apple(new AppleGen(FIELD_SIZE_WIDTH, FIELD_SIZE_HEIGHT, snake, p), ref rnd);
}
}
57 changes: 57 additions & 0 deletions games-cli/Drawer/Border.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/*
Граница/обводка чего-либо
*/

using System.Collections.Generic;
using System.Drawing;

class Border : IDrawableElement
{
public IDrawable[] ElementContent => getContent();
List<Line> border_lines = new List<Line>();

public Border(char c, Point lt, Point rt, Point lb, Point rb)
{
fromPoints(c, lt, rt, lb, rb);
}

public Border(char c, int width, int height, Padding p)
{
/*
Создать ключевые точки с учетом отступов
*/

var lt = new Point(p.Left, p.Top); // left top
var rt = new Point(width - p.Right - 1, p.Top); // right top
var lb = new Point(p.Left, height - p.Buttom - 1); // left buttom
var rb = new Point(width - p.Right - 1, height - p.Buttom - 1); // right buttom

fromPoints(c, lt, rt, lb, rb);
}

private void fromPoints(char c, Point lt, Point rt, Point lb, Point rb)
{
Line top = new Line(c, lt, rt);
Line left = new Line(c, lt, lb);
Line right = new Line(c, rt, rb);
Line button = new Line(c, lb, rb);

border_lines.Add(top);
border_lines.Add(left);
border_lines.Add(right);
border_lines.Add(button);
}

private IDrawable[] getContent()
{
List<DrawableChar> r = new List<DrawableChar>();
foreach (Line line in border_lines)
{
foreach (DrawableChar c in line.ElementContent)
{
r.Add(c);
}
}
return r.ToArray();
}
}
Loading

0 comments on commit 2366c99

Please sign in to comment.