Skip to content

Instantly share code, notes, and snippets.

Created September 12, 2015 19:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save anonymous/ebc48e289d97fcae887d to your computer and use it in GitHub Desktop.
Save anonymous/ebc48e289d97fcae887d to your computer and use it in GitHub Desktop.
/*
Name: MagicFigures.cpp
Copyright: just for study
Author: beginner
Date: 09.09.15 21:09
Description: class MagicFigures realization
*/
#include "MagicFigures.h"
#include <iostream>
#include <iomanip>
const WORD colors[] = { 0x02, // темно-зеленый
0x04, // темно-красный
0x06, // темно-желтый
0x09 }; // темно-синий
// конструктор по умолчанию
MagicFigures::MagicFigures()
{
for (int i = 0; i < positions; i++) {
coordPos[i].x = 0;
coordPos[i].y = 0;
}
figureSize.width = 0;
figureSize.height = 0;
for (int i = 0; i < positions; i++) {
sizePos[i].width = 0;
sizePos[i].height = 0;
}
figureSpeed.maximumSpeed = 0;
figureSpeed.minimumSpeed = 0;
figureSpeed.step = 0;
fill = ' ';
speedFlag = true;
milliseconds = 0;
} // конец MagicFigures
// конструктор
MagicFigures::MagicFigures(const Size & size, const Speed & speed, char ch)
{
for (int i = 0; i < positions; i++) {
coordPos[i].x = 0;
coordPos[i].y = 0;
}
// проверка входных параметров size на отрицательные значения
if (size.width < 0 || size.height < 0) {
figureSize.width = 0;
figureSize.height = 0;
}
else {
figureSize.width = size.width;
figureSize.height = size.height;
}
for (int i = 0; i < positions; i++) {
sizePos[i].width = 0;
sizePos[i].height = 0;
}
// проверка входных параметров speed на отрицательные значения
if (figureSpeed.maximumSpeed < 0 || figureSpeed.minimumSpeed < 0 || figureSpeed.step < 0) {
figureSpeed.maximumSpeed = 0;
figureSpeed.minimumSpeed = 0;
figureSpeed.step = 0;
}
else {
figureSpeed.maximumSpeed = speed.maximumSpeed;
figureSpeed.minimumSpeed = speed.minimumSpeed;
figureSpeed.step = speed.step;
}
fill = ch;
speedFlag = true;
milliseconds = speed.maximumSpeed;
} // конец MagicFigures
// вращать квадрат по часовой стрелке
void MagicFigures::rotateSqureClockwise()
{
for (int i = 0; i < positions; i++) {
screen.setConsTextAttr(::colors[i]);
drawSquare(i, fill);
screen.delay(milliseconds);
changeSpeed();
drawSquare(i);
}
} // конец rotateSqureClockwise
// вращать квадрат против часовой стрелки
void MagicFigures::rotateSqureAnticlockwise()
{
for (int i = positions; i ; i--) {
screen.setConsTextAttr(::colors[i - 1]);
drawSquare(i - 1, fill);
screen.delay(milliseconds);
changeSpeed();
drawSquare(i - 1);
}
} // конец rotateSqureAnticlockwise
// позиционирование по х и у с учетом ширины рабочего пространства (файл Screen.h) и ширины прямоугольника
void MagicFigures::calculatePositions(const Coord & coord)
{
calculateCoordinates(coord);
for (int i = 0; i < positions; i++) {
// вычисление ширины отображаемой фигуры и начальной координаты отображения по х
if (coordPos[i].x + figureSize.width < ::xBuffBegin) {
sizePos[i].width = 0;
coordPos[i].x = ::xBuffBegin;
}
else if (coordPos[i].x < ::xBuffBegin && coordPos[i].x + figureSize.width <= ::xBuffEnd) {
sizePos[i].width = figureSize.width - (::xBuffBegin - coordPos[i].x);
coordPos[i].x = ::xBuffBegin;
}
else if (coordPos[i].x <= ::xBuffBegin && coordPos[i].x + figureSize.width > ::xBuffEnd){
sizePos[i].width = figureSize.width - (::xBuffBegin - coordPos[i].x);
coordPos[i].x = ::xBuffBegin;
}
else if (coordPos[i].x > ::xBuffBegin && coordPos[i].x + figureSize.width <= ::xBuffEnd) {
sizePos[i].width = figureSize.width;
}
else if (coordPos[i].x <= ::xBuffEnd && coordPos[i].x + figureSize.width > ::xBuffEnd) {
sizePos[i].width = ::xBuffEnd - (coordPos[i].x);
}
else if (coordPos[i].x > ::xBuffEnd) {
sizePos[i].width = 0;
coordPos[i].x = ::xBuffEnd;
}
// вычисление высоты отображаемой фигуры и начальной координаты отображения по у
if (coordPos[i].y + figureSize.height < ::yBuffBegin) {
sizePos[i].height = 0;
coordPos[i].y = ::yBuffBegin;
}
else if (coordPos[i].y < ::yBuffBegin && coordPos[i].y + figureSize.height <= ::yBuffEnd) {
sizePos[i].height = figureSize.height - (::yBuffBegin - coordPos[i].y);
coordPos[i].y = ::yBuffBegin;
}
else if (coordPos[i].y <= ::yBuffBegin && coordPos[i].y + figureSize.height > ::yBuffEnd){
sizePos[i].height = figureSize.height - (::yBuffBegin - coordPos[i].y);
coordPos[i].y = ::yBuffBegin;
}
else if (coordPos[i].y > ::yBuffBegin && coordPos[i].y + figureSize.height <= ::yBuffEnd) {
sizePos[i].height = figureSize.height;
}
else if (coordPos[i].y <= ::yBuffEnd && coordPos[i].y + figureSize.height > ::yBuffEnd) {
sizePos[i].height = ::yBuffEnd - (coordPos[i].y);
}
else if (coordPos[i].y > ::yBuffEnd) {
sizePos[i].height = 0;
coordPos[i].y = ::yBuffEnd;
}
}
} // конец calculatePositions
// отображение таблицы значений координат по х и у для каждой позиции
void MagicFigures::reportList()
{
screen.setOldConsTextAttr();
screen.setCursPos(::xBuffEnd + 3, 5);
std::cout << std::left << std::setw(4) << "Pos | 1| 2| 3| 4";
screen.setCursPos(::xBuffEnd + 3, 6);
std::cout << "----+---+---+---+---";
screen.setCursPos(::xBuffEnd + 3, 7);
std::cout << std::left << std::setw(4) << " x | | | | ";
screen.setCursPos(::xBuffEnd + 3, 8);
std::cout << std::left << std::setw(4) << " y | | | | ";
} // конец reportList
// отображение значений координат по х и у для каждой позиции
void MagicFigures::displayReportList()
{
screen.setOldConsTextAttr();
screen.setCursPos(::xBuffEnd + 8, 7);
std::cout << std::setw(3) << std::right << coordPos[0].x;
screen.setCursPos(::xBuffEnd + 12, 7);
std::cout << std::setw(3) << std::right << coordPos[1].x;
screen.setCursPos(::xBuffEnd + 16, 7);
std::cout << std::setw(3) << std::right << coordPos[2].x;
screen.setCursPos(::xBuffEnd + 20, 7);
std::cout << std::setw(3) << std::right << coordPos[3].x;
screen.setCursPos(::xBuffEnd + 8, 8);
std::cout << std::setw(3) << std::right << coordPos[0].y;
screen.setCursPos(::xBuffEnd + 12, 8);
std::cout << std::setw(3) << std::right << coordPos[1].y;
screen.setCursPos(::xBuffEnd + 16, 8);
std::cout << std::setw(3) << std::right << coordPos[2].y;
screen.setCursPos(::xBuffEnd + 20, 8);
std::cout << std::setw(3) << std::right << coordPos[3].y;
} // конец displayReportList
// вычислить координаты для каждой из четырех позиций отображения прямоугольника
void MagicFigures::calculateCoordinates(const Coord & coord)
{
for (int i = 0; i < positions; i++) {
if (0 == i) {
coordPos[i].x = coord.x;
coordPos[i].y = coord.y;
}
else if (1 == i) {
coordPos[i].x = coord.x + figureSize.width;
coordPos[i].y = coord.y;
}
else if (2 == i) {
coordPos[i].x = coord.x + figureSize.width;
coordPos[i].y = coord.y + figureSize.height;
}
else {
coordPos[i].x = coord.x;
coordPos[i].y = coord.y + figureSize.height;
}
}
} // конец calculateCoordinates
// отрисовка или очистка прямоугольника
void MagicFigures::drawSquare(int position, char ch)
{
for (int j = 0; j < sizePos[position].height; j++) {
screen.setCursPos(coordPos[position].x, coordPos[position].y + j);
for (int i = 0; i < sizePos[position].width; i++) {
std::cout << ch;
}
}
} // конец drawSqure
// проверка скорости
void MagicFigures::changeSpeed()
{
if (speedFlag) {
milliseconds += figureSpeed.step;
speedFlag = (milliseconds <= figureSpeed.minimumSpeed);
}
else {
milliseconds -= figureSpeed.step;
speedFlag = (milliseconds <= figureSpeed.maximumSpeed);
}
} // конец changeSpeed
/*
Name: MagicFigures.h
Copyright: just for study
Author: beginner
Date: 09.09.15 21:54
Description: class MagicFigures
*/
#ifndef MAGICFIGURES_H_
#define MAGICFIGURES_H_
#include "Screen.h"
#include <ostream>
struct Speed
{
int maximumSpeed; // максимальная скорость
int minimumSpeed; // минимальная скорость
int step; // шаг изменения задержки
};
struct Size
{
int width; // ширина прямоугольника
int height; // высота прямоугольника
};
class MagicFigures
{
public:
MagicFigures(); // конструктор по умолчанию
MagicFigures(const Size & size, const Speed & speed, char ch = '*'); // конструктор
void rotateSqureClockwise(); // вращение прямоугольника по часовой стрелке
void rotateSqureAnticlockwise(); // вращение прямоугольника против часовой стрелки
// позиционирование по х и у с учетом ширины рабочего пространства (файл Screen.h) и ширины прямоугольника
void calculatePositions(const Coord & coord);
void reportList(); // отображение сетки таблицы координат
void displayReportList(); // отображение координат в таблице
private:
// вычисление начальных координат для каждой из четырех позиций прямоугольника
void calculateCoordinates(const Coord & coord);
void drawSquare(int position, char ch = ' '); // отрисовка или очистка прямоугольника
void changeSpeed(); // изменение скорости вращения
static const int positions = 4; // количество позиций отрисовки прямоугольника
Coord coordPos[positions]; // начальные координаты для каждой из четырех позиций
Size figureSize; // размер прямоугольника
Size sizePos[positions]; // размеры прямоугольника для каждой из четырех позиций
Speed figureSpeed; // скорость и шаг изменения скорости
Screen screen;
char fill; // заполнитель (по умолчанию '*')
bool speedFlag; // флаг контроля скорости
DWORD milliseconds; // задержка экрана в милисекундах
};
#endif // MAGICFIGURES_H_
/*
Name: mainMagicFigures.cpp
Copyright: just for study
Author: beginner
Date: 09.09.15 00:11
Description: 1. Объект класса MagicFigures получает начальные параметры размер прямоугольника
и параметры задержки на экране и шаг по которому изменяется скорость.
2. Объект при помощи методов rotateSqureClockwise и rotateSqureAnticlockwise
вращает прямоугольник по часовой стрелке и против часовой стрелки соотв.
3. Отрисовка прямоугольника начинается с левого верхнего угла.
*/
#include "Screen.h"
#include "MagicFigures.h"
typedef MagicFigures MF;
const int counter = 21; // кол-во циклов
int main()
{
Screen screen;
screen.setCursVisible(); // скрыть курсор
Coord coord = { -13, 18 }; // начальные координаты по х и у
Coord coord2 = { -12, 20 };
Coord coord3 = { -16, 18 };
Size size = { 7, 5 }; // размер прямоугольника
Size size2 = { 5, 4 };
Speed speed = { 50, 200, 10 }; // скорость: макс, мин, шаг в милисекундах
MF mf(size, speed);
MF mf2(size2, speed);
mf.reportList(); // отображение таблицы
for (int i = 0; i < ::counter; i++) {
mf.calculatePositions(coord);
mf.displayReportList();
mf.rotateSqureClockwise();
coord3.x += 3;
coord3.y -= 1;
mf2.calculatePositions(coord2);
mf2.displayReportList();
mf2.rotateSqureClockwise();
coord2.x += 3;
coord2.y -= 1;
mf.calculatePositions(coord3);
mf.displayReportList();
mf.rotateSqureClockwise();
coord.x += 3;
coord.y -= 1;
mf2.calculatePositions(coord2);
mf2.displayReportList();
mf2.rotateSqureClockwise();
}
for (int i = 0; i < ::counter; i++) {
mf.calculatePositions(coord3);
mf.displayReportList();
mf.rotateSqureAnticlockwise();
coord3.x -= 3;
coord3.y += 1;
mf2.calculatePositions(coord2);
mf2.displayReportList();
mf2.rotateSqureAnticlockwise();
coord2.x -= 3;
coord2.y += 1;
mf.calculatePositions(coord);
mf.displayReportList();
mf.rotateSqureAnticlockwise();
coord.x -= 3;
coord.y += 1;
mf2.calculatePositions(coord2);
mf2.displayReportList();
mf2.rotateSqureAnticlockwise();
}
return 0;
}
/*
Name: Screen.cpp
Copyright: just for study
Author: beginner
Date: 25.07.15 23:30
Description: class Screen realization
*/
#include "Screen.h"
// конструктор по умолчанию
Screen::Screen()
{
hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
GetConsoleCursorInfo(hStdOut, &oldCurInfo);
curCurInfo.dwSize = oldCurInfo.dwSize;
curCurInfo.bVisible = oldCurInfo.bVisible;
CONSOLE_SCREEN_BUFFER_INFO csbi;
GetConsoleScreenBufferInfo(hStdOut, &csbi);
oldTextAttr = csbi.wAttributes;
} // конец Screen
// деструктор
Screen::~Screen()
{
SetConsoleTextAttribute(hStdOut, oldTextAttr);
SetConsoleCursorInfo(hStdOut, &oldCurInfo);
} // конец ~Screen
// установка позиции курсора
void Screen::setCursPos(int x, int y)
{
COORD coord = { static_cast<SHORT>(x), static_cast<SHORT>(y) };
SetConsoleCursorPosition(hStdOut, coord);
} // конец функции setCursPos
// установка начального цвета для фона и шрифта
void Screen::setOldConsTextAttr()
{
SetConsoleTextAttribute(hStdOut, oldTextAttr);
} // конец функции setOldConsTextAtrr
// установка цвета для фона и шрифта
void Screen::setConsTextAttr(WORD attr)
{
SetConsoleTextAttribute(hStdOut, attr);
} // конец функции setConsTextAttr
// установка видимости курсора
void Screen::setCursVisible(bool visible) {
curCurInfo.bVisible = visible;
SetConsoleCursorInfo(hStdOut, &curCurInfo);
} // конец функции setCursVisible
/*
Name: Screen.h
Copyright: just for study
Author: beginner
Date: 25.07.15 23:28
Description: class Screen
*/
#ifndef ASCREEN_H_
#define ASCREEN_H_
#include <windows.h>
#include <cstdlib>
struct Coord
{
int x;
int y;
};
const int xBuffBegin = 4; // начало буфера экрана по х
const int yBuffBegin = 4; // начало буфера экрана по у
const int xBuffEnd = 48; // конец буфера экрана по х
const int yBuffEnd = 21; // конеу буфера экрана по у
class Screen
{
public:
Screen(); // конструктор
~Screen(); // деструктор
void setCursPos(int x, int y); // установка позиции курсора
void setOldConsTextAttr(); // установка начального цвета для фона и шрифта
void setConsTextAttr(WORD attr); // установка цвета для фона и шрифта
void setCursVisible(bool visible = false); // установка видимости курсора
void delay(DWORD d) { Sleep(d); } // задержка экрана
private:
HANDLE hStdOut;
WORD oldTextAttr;
CONSOLE_CURSOR_INFO oldCurInfo, curCurInfo;
}; // конец класса Screen
#endif // ASCREEN_H_
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment