added double jump and sitting state
parent
2e5c5a8dde
commit
90d07dde3f
Binary file not shown.
@ -0,0 +1,14 @@
|
||||
#include <iostream>
|
||||
using std::cout;
|
||||
|
||||
namespace myspace {
|
||||
void print_n_times(char str[], int n = 10) {
|
||||
for (int i = 0; i < n; ++i)
|
||||
cout << str;
|
||||
}
|
||||
}
|
||||
|
||||
int main() {
|
||||
char s[] = "nya\n";
|
||||
myspace::print_n_times(s);
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
#include <iostream>
|
||||
using std::cout, std::endl;
|
||||
|
||||
int cubeV(int x) {
|
||||
return x * x * x;
|
||||
}
|
||||
|
||||
int main() {
|
||||
int x = 3;
|
||||
cout << cubeV(x) << endl;
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
#include <iostream>
|
||||
|
||||
using std::cout, std::endl;
|
||||
|
||||
int cubeR(int& x) {
|
||||
return x * x * x;
|
||||
}
|
||||
|
||||
int main() {
|
||||
int x = 3;
|
||||
cout << cubeR(x) << endl;
|
||||
}
|
@ -0,0 +1,26 @@
|
||||
#include <iostream>
|
||||
using std::cout, std::endl;
|
||||
|
||||
void count_letters(char str[], int& n_letters, int& n_digits, int& n_other) {
|
||||
while (*str) {
|
||||
if (*str >= 'a' && *str <= 'z' || *str >= 'A' && *str <= 'Z') {
|
||||
n_letters += 1;
|
||||
}
|
||||
else if (*str >= '0' && *str <= '9') {
|
||||
n_digits += 1;
|
||||
}
|
||||
else {
|
||||
n_other += 1;
|
||||
}
|
||||
str += 1;
|
||||
}
|
||||
}
|
||||
|
||||
int main() {
|
||||
int n_letters = 0, n_digits = 0, n_other = 0;
|
||||
|
||||
char s[] = "1n!2y#3a$";
|
||||
count_letters(s, n_letters, n_digits, n_other);
|
||||
|
||||
cout << "letters: " << n_letters << endl << "digits: " << n_digits << endl << "n_other: " << n_other << endl;
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
#include <iostream>
|
||||
|
||||
using std::cout, std::endl;
|
||||
|
||||
struct Book {
|
||||
char title[100];
|
||||
int pages;
|
||||
float price;
|
||||
};
|
||||
|
||||
void addPrice(Book& b, float x) {
|
||||
b.price += x;
|
||||
}
|
||||
|
||||
int main() {
|
||||
Book b = {"One Hundred Years of Solitude", 456, 1200};
|
||||
float x = 15.6;
|
||||
addPrice(b, x);
|
||||
cout << b.price << endl;
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
#include <iostream>
|
||||
using std::cout, std::endl;
|
||||
|
||||
struct Book {
|
||||
char title[100];
|
||||
int pages;
|
||||
float price;
|
||||
};
|
||||
|
||||
bool isExpensive(const Book& b) {
|
||||
if (b.price > 1000) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
int main() {
|
||||
Book b = {"One Hundred Years of Solitude", 456, 1200};
|
||||
cout << isExpensive(b) << endl;
|
||||
}
|
@ -0,0 +1,38 @@
|
||||
#include <iostream>
|
||||
#include "vector3f.h"
|
||||
using namespace std;
|
||||
|
||||
int main() {
|
||||
Vector3f a = {1.0, 2.0, -2.0};
|
||||
Vector3f b = {4.0, -1.0, 3.0};
|
||||
cout << "a = " << a << endl << "b = " << b << endl;
|
||||
cout << "a + b = " << a + b << endl;
|
||||
cout << "a - b = " << a - b << endl;
|
||||
|
||||
cout << "0.5 * a = " << 0.5 * a << endl;
|
||||
cout << "a * 0.5 = " << a * 0.5 << endl;
|
||||
|
||||
cout << "(a, b) = " << a * b << endl;
|
||||
|
||||
cout << "a / 5 = " << a / 5 << endl;
|
||||
|
||||
cout << "-a = " << -a << endl;
|
||||
cout << "+a = " << +a << endl;
|
||||
|
||||
cout << "a == b = " << (a == b) << endl;
|
||||
cout << "a != b = " << (a != b) << endl;
|
||||
|
||||
a += b;
|
||||
cout << "a += b: " << a << endl;
|
||||
|
||||
a -= b;
|
||||
cout << "a -= b: " << a << endl;
|
||||
|
||||
a *= 2;
|
||||
cout << "a *= 2: " << a << endl;
|
||||
a /= 2;
|
||||
cout << "a /= 2: " << a << endl;
|
||||
|
||||
normalize(a);
|
||||
cout << "normalize(a): " << a << " |a| = " << norm(a) << endl;
|
||||
}
|
@ -0,0 +1,96 @@
|
||||
#pragma once
|
||||
#include <cmath>
|
||||
#include <iostream>
|
||||
|
||||
struct Vector3f {
|
||||
float x;
|
||||
float y;
|
||||
float z;
|
||||
};
|
||||
|
||||
Vector3f operator+(const Vector3f& a, const Vector3f& b) {
|
||||
Vector3f result = {a.x + b.x, a.y + b.y, a.z + b.z};
|
||||
return result;
|
||||
}
|
||||
|
||||
Vector3f operator-(const Vector3f& a, const Vector3f& b) {
|
||||
Vector3f result = {a.x - b.x, a.y - b.y, a.z - b.z};
|
||||
return result;
|
||||
}
|
||||
|
||||
Vector3f operator*(const Vector3f& a, float f) {
|
||||
Vector3f result = {f * a.x, f * a.y, f * a.z};
|
||||
return result;
|
||||
}
|
||||
|
||||
Vector3f operator*(float f, const Vector3f& a) {
|
||||
Vector3f result = {f * a.x, f * a.y, f * a.z};
|
||||
return result;
|
||||
}
|
||||
|
||||
int operator*(const Vector3f& a, const Vector3f& b) {
|
||||
return a.x * b.x + a.y * b.y + a.z * b.z;
|
||||
}
|
||||
|
||||
Vector3f operator/(const Vector3f& a, float f) {
|
||||
Vector3f result = {a.x / f, a.y / f, a.z / f};
|
||||
return result;
|
||||
}
|
||||
|
||||
Vector3f operator+(const Vector3f& a) {
|
||||
return a;
|
||||
}
|
||||
|
||||
Vector3f operator-(const Vector3f& a) {
|
||||
Vector3f result = {-a.x, -a.y, -a.z};
|
||||
return result;
|
||||
}
|
||||
|
||||
bool operator==(const Vector3f& a, const Vector3f& b) {
|
||||
if (a.x == b.x && a.y == b.y && a.z == b.z) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool operator!=(const Vector3f& a, const Vector3f& b) {
|
||||
return not (a == b);
|
||||
}
|
||||
|
||||
void operator+=(Vector3f& a, const Vector3f& b) {
|
||||
a = a + b;
|
||||
}
|
||||
|
||||
void operator-=(Vector3f& a, const Vector3f& b) {
|
||||
a = a - b;
|
||||
}
|
||||
|
||||
void operator*=(Vector3f& a, float f) {
|
||||
a = f * a;
|
||||
}
|
||||
|
||||
void operator/=(Vector3f& a, float f) {
|
||||
a = a / f;
|
||||
}
|
||||
|
||||
float squared_norm(const Vector3f& a) {
|
||||
return a * a;
|
||||
}
|
||||
|
||||
float norm(const Vector3f& a) {
|
||||
return sqrt(squared_norm(a));
|
||||
}
|
||||
|
||||
void normalize(Vector3f& a) {
|
||||
a /= norm(a);
|
||||
}
|
||||
|
||||
std::istream& operator>>(std::istream& in, Vector3f& a) {
|
||||
in >> a.x >> a.y >> a.z;
|
||||
return in;
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& out, const Vector3f& a) {
|
||||
out << "(" << a.x << ", " << a.y << ", " << a.z << ")";
|
||||
return out;
|
||||
}
|
@ -0,0 +1,63 @@
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <cmath>
|
||||
#include "complex.h"
|
||||
using namespace std;
|
||||
|
||||
// Это программа создаёт анимацию (набор картинок)
|
||||
// которая задаётся как меняющееся во времени
|
||||
// комплексная функция (описана в функции func)
|
||||
|
||||
|
||||
struct Color {
|
||||
unsigned char r, g, b;
|
||||
};
|
||||
|
||||
Complex func(Complex z, int time) {
|
||||
Complex f = 100/(z - (0.02f*time))*exp(z*sin(z));
|
||||
f.re = fabs(f.re);
|
||||
f.im = fabs(f.im);
|
||||
if (f.re > 255)
|
||||
f.re = 255;
|
||||
if (f.im > 255)
|
||||
f.im = 255;
|
||||
return f;
|
||||
}
|
||||
|
||||
|
||||
int main() {
|
||||
int width = 800, height = 800;
|
||||
float x0 = -2.0f, x1 = 2.0f;
|
||||
float y0 = -2.0f, y1 = 2.0f;
|
||||
Color* data = (Color*)malloc(sizeof(Color) * width * height);
|
||||
|
||||
// Повторяем 200 раз
|
||||
int max_time_steps = 200;
|
||||
for (int time = 0; time < max_time_steps; time++)
|
||||
{
|
||||
// Задаём изображение в массиве data
|
||||
for (int j = 0; j < height; j++)
|
||||
{
|
||||
for (int i = 0; i < width; i++)
|
||||
{
|
||||
Complex z = {x0 + (x1-x0) / width * i, y0 + (y1-y0) / width * j};
|
||||
Complex f = func(z, time);
|
||||
data[i + width * j].r = 0;
|
||||
data[i + width * j].g = f.re;
|
||||
data[i + width * j].b = f.im;
|
||||
}
|
||||
}
|
||||
|
||||
// Создаём в строке filename имя изображения
|
||||
// Папка animation должна существовать!
|
||||
char filename[100];
|
||||
sprintf(filename, "animation/complex_%03d.ppm", time);
|
||||
|
||||
// Сохраняем изображение в картинке по имени filename
|
||||
FILE* file = fopen(filename, "wb");
|
||||
fprintf(file, "P6\n%d %d\n255\n", width, height);
|
||||
fwrite(data, sizeof(Color), height * width, file);
|
||||
fclose(file);
|
||||
}
|
||||
free(data);
|
||||
}
|
Binary file not shown.
@ -0,0 +1,38 @@
|
||||
#include <iostream>
|
||||
#include "complex.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
// Тут мы тестируем нашу реализацию комплексных чисел
|
||||
|
||||
int main() {
|
||||
Complex a;
|
||||
Complex b;
|
||||
|
||||
cin >> a >> b;
|
||||
|
||||
cout << "a = " << a << endl
|
||||
<< "b = " << b << endl
|
||||
<< "a + b = " << a + b << endl
|
||||
<< "a - b = " << a - b << endl
|
||||
<< "a * b = " << a * b << endl
|
||||
<< "a / b = " << a / b << endl
|
||||
<< "-a = " << -a << endl
|
||||
<< "+a = " << +a << endl
|
||||
<< "*a = " << *a << endl
|
||||
<< "a + 5 = " << a + 5 << endl
|
||||
<< "5 + a = " << 5 + a << endl
|
||||
<< "a * 5 = " << a * 5 << endl
|
||||
<< "5 * a = " << 5 * a << endl
|
||||
<< "Exp(a) = " << exp(a) << endl
|
||||
<< "Sin(a) = " << sin(a) << endl
|
||||
<< "Cos(a) = " << cos(a) << endl
|
||||
<< "Exp((a + b) / a) * Cos(a - b) = " << exp((a + b) / a) * cos(a - b) << endl;
|
||||
|
||||
a += b;
|
||||
cout << "a += b; a = " << a << endl;
|
||||
|
||||
// Оператор = мы не перегружали, но это всё равно работает
|
||||
b = a;
|
||||
cout << "b = a; b = " << b << endl;
|
||||
}
|
@ -0,0 +1,64 @@
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <cmath>
|
||||
#include "complex.h"
|
||||
using namespace std;
|
||||
|
||||
struct Color {
|
||||
unsigned char r, g, b;
|
||||
};
|
||||
|
||||
Complex func(Complex z, Complex c) {
|
||||
return z * z + c;
|
||||
}
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
Complex c = {0, 0};
|
||||
int n = 20;
|
||||
int width = 800, height = 800;
|
||||
float x0 = -2.0f, x1 = 2.0f;
|
||||
float y0 = -2.0f, y1 = 2.0f;
|
||||
|
||||
if (argc < 4) {
|
||||
cout << "usage: julia [re] [im] [n]" << endl
|
||||
<< "using default values: 0 + 0i, n = 20 "<< endl;
|
||||
}
|
||||
else {
|
||||
cout << argv[1] << " + " << argv[2] << "i" << endl << "n = " << n << endl;
|
||||
sscanf(argv[1], "%f", &c.re);
|
||||
sscanf(argv[2], "%f", &c.im);
|
||||
sscanf(argv[3], "%d", &n);
|
||||
}
|
||||
|
||||
Color* data = (Color*)malloc(sizeof(Color) * width * height);
|
||||
|
||||
for (int j = 0; j < height; j++) {
|
||||
for (int i = 0; i < width; i++) {
|
||||
Complex z = {x0 + (x1-x0) / width * i, y0 + (y1-y0) / width * j};
|
||||
for (int k = 0; k < n; ++k) {
|
||||
z = func(z, c);
|
||||
}
|
||||
|
||||
float r = abs(z.re);
|
||||
float b = abs(z.im);
|
||||
if (r > 255) {
|
||||
r = 255;
|
||||
}
|
||||
if (b > 255) {
|
||||
b = 255;
|
||||
}
|
||||
|
||||
data[i + width * j].r = 255 - r;
|
||||
data[i + width * j].g = 0;
|
||||
data[i + width * j].b = 255 - b;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
FILE* file = fopen("julia.ppm", "wb");
|
||||
fprintf(file, "P6\n%d %d\n255\n", width, height);
|
||||
fwrite(data, sizeof(Color), height * width, file);
|
||||
fclose(file);
|
||||
|
||||
free(data);
|
||||
}
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -0,0 +1,60 @@
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <cmath>
|
||||
#include "complex.h"
|
||||
using namespace std;
|
||||
|
||||
struct Color {
|
||||
unsigned char r, g, b;
|
||||
};
|
||||
|
||||
Complex func(Complex z, Complex c) {
|
||||
return z * z + c;
|
||||
}
|
||||
|
||||
|
||||
int main() {
|
||||
int width = 800, height = 800;
|
||||
float x0 = -2.0f, x1 = 2.0f;
|
||||
float y0 = -2.0f, y1 = 2.0f;
|
||||
int n = 20;
|
||||
|
||||
Color* data = (Color*)malloc(sizeof(Color) * width * height);
|
||||
|
||||
int max_time_steps = 500;
|
||||
for (int time = 0; time < max_time_steps; time++)
|
||||
{
|
||||
Complex c = {-1.5 + (1.5 / max_time_steps) * time, -1.5 + (1.5 / max_time_steps) * time + 1};
|
||||
for (int j = 0; j < height; j++)
|
||||
{
|
||||
for (int i = 0; i < width; i++)
|
||||
{
|
||||
Complex z = {x0 + (x1-x0) / width * i, y0 + (y1-y0) / width * j};
|
||||
for (int k = 0; k < n; ++k) {
|
||||
z = func(z, c);
|
||||
}
|
||||
|
||||
float r = abs(z.re);
|
||||
float b = abs(z.im);
|
||||
if (r > 255) {
|
||||
r = 255;
|
||||
}
|
||||
if (b > 255) {
|
||||
b = 255;
|
||||
}
|
||||
data[i + width * j].r = 255 - r;
|
||||
data[i + width * j].g = 0;
|
||||
data[i + width * j].b = 255 - b;
|
||||
}
|
||||
}
|
||||
|
||||
char filename[100];
|
||||
sprintf(filename, "animation/complex_%03d.ppm", time);
|
||||
|
||||
FILE* file = fopen(filename, "wb");
|
||||
fprintf(file, "P6\n%d %d\n255\n", width, height);
|
||||
fwrite(data, sizeof(Color), height * width, file);
|
||||
fclose(file);
|
||||
}
|
||||
free(data);
|
||||
}
|
@ -0,0 +1,54 @@
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <cmath>
|
||||
#include "complex.h"
|
||||
using namespace std;
|
||||
|
||||
struct Color {
|
||||
unsigned char r, g, b;
|
||||
};
|
||||
|
||||
Complex func(Complex z, Complex c) {
|
||||
return z * z + c;
|
||||
}
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
int n = 20;
|
||||
Complex z = {0, 0};
|
||||
int width = 800, height = 800;
|
||||
float x0 = -2.0f, x1 = 2.0f;
|
||||
float y0 = -2.0f, y1 = 2.0f;
|
||||
|
||||
|
||||
Color* data = (Color*)malloc(sizeof(Color) * width * height);
|
||||
|
||||
for (int j = 0; j < height; j++) {
|
||||
for (int i = 0; i < width; i++) {
|
||||
z = {0, 0};
|
||||
Complex c = {x0 + (x1-x0) / width * i, y0 + (y1-y0) / width * j};
|
||||
for (int k = 0; k < n; ++k) {
|
||||
z = func(z, c);
|
||||
}
|
||||
|
||||
float r = abs(z.re);
|
||||
float b = abs(z.im);
|
||||
if (r > 255) {
|
||||
r = 255;
|
||||
}
|
||||
if (b > 255) {
|
||||
b = 255;
|
||||
}
|
||||
data[i + width * j].r = 255 - r;
|
||||
data[i + width * j].g = 0;
|
||||
data[i + width * j].b = 255 - b;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
FILE* file = fopen("mandelbrot.ppm", "wb");
|
||||
fprintf(file, "P6\n%d %d\n255\n", width, height);
|
||||
fwrite(data, sizeof(Color), height * width, file);
|
||||
fclose(file);
|
||||
|
||||
free(data);
|
||||
}
|
Binary file not shown.
Binary file not shown.
@ -0,0 +1,39 @@
|
||||
#include <iostream>
|
||||
#include <math.h>
|
||||
#include <cstdlib>
|
||||
#include "circle.h"
|
||||
#include "point.h"
|
||||
|
||||
Circle::Circle(const Point& acenter, float aradius) {
|
||||
mCenter = acenter;
|
||||
mRadius = aradius;
|
||||
}
|
||||
Circle::Circle() {
|
||||
mCenter = Point {0, 0};
|
||||
mRadius = 1;
|
||||
}
|
||||
Circle::Circle(const Circle& circle) {
|
||||
mCenter = circle.mCenter;
|
||||
mRadius = circle.mRadius;
|
||||
}
|
||||
Point Circle::getCenter() const { return mCenter; }
|
||||
float Circle::getRadius() const { return mRadius; }
|
||||
|
||||
void Circle::setCenter(const Point& p) {
|
||||
mCenter = p;
|
||||
}
|
||||
void Circle::setRadius(float radius) {
|
||||
mRadius = radius > 0 ? radius : 0;
|
||||
}
|
||||
float Circle::getArea() const {
|
||||
return abs(mRadius * mRadius * M_PI);
|
||||
}
|
||||
float Circle::getDistance(const Point& p) {
|
||||
return mCenter.distance(p) - mRadius;
|
||||
}
|
||||
bool Circle::isColliding(const Circle& c) const {
|
||||
return (mCenter.distance(c.getCenter()) - (mRadius + c.getRadius()) > 0) ? false : true;
|
||||
}
|
||||
void Circle::move(const Point& p) {
|
||||
mCenter = mCenter + p;
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
#include "point.h"
|
||||
class Circle
|
||||
{
|
||||
private:
|
||||
Point mCenter;
|
||||
float mRadius;
|
||||
|
||||
public:
|
||||
Circle(const Point& acenter, float aradius);
|
||||
Circle();
|
||||
Circle(const Circle& circle);
|
||||
Point getCenter() const;
|
||||
float getRadius() const;
|
||||
|
||||
void setCenter(const Point& p);
|
||||
void setRadius(float radius);
|
||||
float getArea() const;
|
||||
float getDistance(const Point& p);
|
||||
bool isColliding(const Circle& c) const;
|
||||
void move(const Point& p);
|
||||
};
|
||||
|
||||
|
@ -0,0 +1,44 @@
|
||||
#include <iostream>
|
||||
#include "point.h"
|
||||
#include "circle.h"
|
||||
|
||||
using std::cout, std::endl;
|
||||
|
||||
|
||||
int main()
|
||||
{
|
||||
Point p = {7, -1};
|
||||
Point q = {-4, 2};
|
||||
cout << "Point p = " << p << endl;
|
||||
cout << "Point q = " << q << endl;
|
||||
cout << "p + q = " << p + q << endl;
|
||||
|
||||
|
||||
Circle a {{4, 1}, 3};
|
||||
Circle b;
|
||||
// b = a;
|
||||
|
||||
cout << "Circle a: center: " << a.getCenter() << " radius: " << a.getRadius() << endl;
|
||||
cout << "Circle b: center: " << b.getCenter() << " radius: " << b.getRadius() << endl;
|
||||
|
||||
cout << "Area of a = " << a.getArea() << endl;
|
||||
cout << "Distance from point p to circle a = " << a.getDistance(p) << endl;
|
||||
|
||||
|
||||
|
||||
cout << "Collisions:" << endl;
|
||||
if (a.isColliding(b))
|
||||
cout << "Yes, a is colliding b" << endl;
|
||||
else
|
||||
cout << "No, a isn't colliding b" << endl;
|
||||
|
||||
|
||||
|
||||
cout << "Moving b by {1, 1}:" << endl;
|
||||
b.move({1, 1});
|
||||
if (a.isColliding(b))
|
||||
cout << "Yes, a is colliding b" << endl;
|
||||
else
|
||||
cout << "No, a isn't colliding b" << endl;
|
||||
|
||||
}
|
@ -0,0 +1,82 @@
|
||||
#include <iostream>
|
||||
#include <cmath>
|
||||
|
||||
#include "point.h"
|
||||
|
||||
|
||||
Point::Point(float x, float y)
|
||||
{
|
||||
mx = x;
|
||||
my = y;
|
||||
}
|
||||
|
||||
Point::Point()
|
||||
{
|
||||
mx = 0;
|
||||
my = 0;
|
||||
}
|
||||
|
||||
|
||||
float Point::getX() const
|
||||
{
|
||||
return mx;
|
||||
}
|
||||
|
||||
float Point::getY() const
|
||||
{
|
||||
return my;
|
||||
}
|
||||
|
||||
void Point::setX(float x)
|
||||
{
|
||||
mx = x;
|
||||
}
|
||||
|
||||
void Point::setY(float y)
|
||||
{
|
||||
my = y;
|
||||
}
|
||||
|
||||
float Point::norm() const
|
||||
{
|
||||
return std::sqrt(mx * mx + my * my);
|
||||
}
|
||||
|
||||
void Point::normalize()
|
||||
{
|
||||
float pnorm = norm();
|
||||
mx /= pnorm;
|
||||
my /= pnorm;
|
||||
}
|
||||
|
||||
float Point::distance(const Point& p) const
|
||||
{
|
||||
return std::sqrt((p.mx - mx) * (p.mx - mx) + (p.my - my) * (p.my - my));
|
||||
}
|
||||
|
||||
Point Point::operator+(const Point& right) const
|
||||
{
|
||||
Point result = {mx + right.mx, my + right.my};
|
||||
return result;
|
||||
}
|
||||
|
||||
Point Point::operator*(float a) const
|
||||
{
|
||||
Point result = {a * mx, a * my};
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
Point operator*(float a, const Point& p)
|
||||
{
|
||||
Point result = {a * p.mx, a * p.my};
|
||||
return result;
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& left, const Point& right)
|
||||
{
|
||||
left << "(" << right.mx << ", " << right.my << ")";
|
||||
return left;
|
||||
}
|
@ -0,0 +1,75 @@
|
||||
#include <iostream>
|
||||
#include <cstring>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
#include "number.h"
|
||||
|
||||
Number fib(int n)
|
||||
{
|
||||
Number a = 0; // F0
|
||||
Number b = 1; // F1
|
||||
for (int i = 1; i <= n; ++i) {
|
||||
if (i % 2) {
|
||||
a += b;
|
||||
} else {
|
||||
b += a;
|
||||
}
|
||||
}
|
||||
if (n % 2) {
|
||||
return b;
|
||||
}
|
||||
return a;
|
||||
}
|
||||
|
||||
Number factorial(int n)
|
||||
{
|
||||
Number result {
|
||||
1};
|
||||
for (int i = 2; i < n + 1; ++i) {
|
||||
result = Number(i) * result;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void grad(Number n)
|
||||
{
|
||||
|
||||
std::cout << "n = " << n;
|
||||
Number max = n;
|
||||
unsigned long long int steps = 0;
|
||||
while (n != Number(1)) {
|
||||
if (n > max) {
|
||||
#ifdef _DEBUG_COMP
|
||||
std::cout << n << " is greater than " << max << std::endl;
|
||||
#endif
|
||||
max = n;
|
||||
}
|
||||
if (n.isEven()) {
|
||||
n.div2();
|
||||
} else {
|
||||
n = Number(3) * n + Number(1);
|
||||
}
|
||||
#ifdef _DEBUG_GRAD
|
||||
if (steps > 100) {
|
||||
std::cout << "break" << std::endl;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
++steps;
|
||||
}
|
||||
std::cout << " steps = " << steps << " max = " << max << std::endl;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
std::cout << "===FIB===" << std::endl;
|
||||
std::cout << "F(1000) = " << fib(1000) << std::endl;
|
||||
std::cout << "===FAC===" << std::endl;
|
||||
std::cout << "1000! = " << factorial(1000) << std::endl;
|
||||
std::cout << "===GRAD===" << std::endl;
|
||||
grad(Number("7"));
|
||||
grad(Number("256"));
|
||||
grad(Number("1117065"));
|
||||
grad(Number("4761963248413673697"));
|
||||
grad(Number("90560792656972947582439785608972465789628974587264056284658721771"));
|
||||
}
|
Binary file not shown.
@ -0,0 +1,22 @@
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <cctype>
|
||||
|
||||
using namespace std;
|
||||
|
||||
string letter_case_switch(const string & str)
|
||||
{
|
||||
string result = str;
|
||||
if (str.size() == 0)
|
||||
return result;
|
||||
result[0] =
|
||||
isupper(result[0]) ? tolower(result[0]) : toupper(result[0]);
|
||||
return result;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
string meow;
|
||||
cin >> meow;
|
||||
cout << letter_case_switch(meow) << endl;
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <cctype>
|
||||
|
||||
using namespace std;
|
||||
|
||||
string letter_case_switch(const string& str) {
|
||||
string result = str;
|
||||
if (str.size() == 0)
|
||||
return result;
|
||||
result[0] = isupper(result[0]) ? tolower(result[0]) : toupper(result[0]);
|
||||
return result;
|
||||
}
|
||||
|
||||
int main() {
|
||||
string meow;
|
||||
cin >> meow;
|
||||
cout << letter_case_switch(meow) << endl;
|
||||
}
|
Binary file not shown.
@ -0,0 +1,48 @@
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
|
||||
using namespace std;
|
||||
|
||||
string repeat1(string_view s)
|
||||
{
|
||||
return string {
|
||||
s}
|
||||
+string {
|
||||
s};
|
||||
}
|
||||
|
||||
void repeat2(string & s)
|
||||
{
|
||||
s += s;
|
||||
}
|
||||
|
||||
void repeat3(string * s)
|
||||
{
|
||||
*s += *s;
|
||||
}
|
||||
|
||||
string *repeat4(string_view s)
|
||||
{
|
||||
string *result = new string;
|
||||
*result = string {
|
||||
s} +string {
|
||||
s};
|
||||
return result;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
string meow;
|
||||
cin >> meow;
|
||||
|
||||
cout << "test of repeat1:" << endl << repeat1(meow) << endl;
|
||||
|
||||
repeat2(meow);
|
||||
cout << "test of repeat2:" << endl << meow << endl;
|
||||
|
||||
repeat3(&meow);
|
||||
cout << "test of repeat3:" << endl << meow << endl;
|
||||
|
||||
cout << "test of repeat4:" << endl << *repeat4(meow) << endl;
|
||||
}
|
@ -0,0 +1,38 @@
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
|
||||
using namespace std;
|
||||
|
||||
string repeat1(string_view s) {
|
||||
return string{s} + string{s};
|
||||
}
|
||||
|
||||
void repeat2(string& s) {
|
||||
s += s;
|
||||
}
|
||||
|
||||
void repeat3(string* s) {
|
||||
*s += *s;
|
||||
}
|
||||
|
||||
string* repeat4(string_view s) {
|
||||
string* result = new string;
|
||||
*result = string{s} + string{s};
|
||||
return result;
|
||||
}
|
||||
|
||||
int main() {
|
||||
string meow;
|
||||
cin >> meow;
|
||||
|
||||
cout << "test of repeat1:" << endl << repeat1(meow) << endl;
|
||||
|
||||
repeat2(meow);
|
||||
cout << "test of repeat2:" << endl << meow << endl;
|
||||
|
||||
repeat3(&meow);
|
||||
cout << "test of repeat3:" << endl << meow << endl;
|
||||
|
||||
cout << "test of repeat4:" << endl << *repeat4(meow) << endl;
|
||||
}
|
@ -0,0 +1,24 @@
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
using namespace std;
|
||||
|
||||
string operator*(const string str, int n) {
|
||||
string result;
|
||||
for (int i = 0; i < n; ++i)
|
||||
result += str;
|
||||
return result;
|
||||
}
|
||||
|
||||
string operator*(int n, const string str) {
|
||||
string result;
|
||||
for (int i = 0; i < n; ++i)
|
||||
result += str;
|
||||
return result;
|
||||
}
|
||||
|
||||
int main() {
|
||||
string meow;
|
||||
cin >> meow;
|
||||
cout << 3 * meow << endl;
|
||||
}
|
@ -0,0 +1,22 @@
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
using namespace std;
|
||||
|
||||
void truncateToDot(string& s) {
|
||||
s.resize(s.find('.'));
|
||||
s.shrink_to_fit();
|
||||
}
|
||||
|
||||
int main() {
|
||||
std::string a = "cat.dog.mouse.elephant.tiger.lion";
|
||||
std::string b = "wikipedia.org";
|
||||
std::string c = ".com";
|
||||
truncateToDot(a);
|
||||
truncateToDot(b);
|
||||
truncateToDot(c);
|
||||
|
||||
cout << a << endl
|
||||
<< b << endl
|
||||
<< c << endl;
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
#include <iostream>
|
||||
#include <cstdio>
|
||||
#include <string>
|
||||
|
||||
using namespace std;
|
||||
|
||||
int string_sum(const string& str) {
|
||||
int res = 0;
|
||||
int x;
|
||||
int n = str.size();
|
||||
int i = 0;
|
||||
while (i < n) {
|
||||
switch (str[i]) {
|
||||
case '[':
|
||||
case ',' :
|
||||
sscanf((str.c_str()) + i + 1, "%d", &x);
|
||||
res += x;
|
||||
break;
|
||||
case ']' :
|
||||
return res;
|
||||
case ' ':
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
++i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int main() {
|
||||
string meow;
|
||||
getline(cin, meow);
|
||||
cout << string_sum(meow) << endl;
|
||||
}
|
@ -0,0 +1,34 @@
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
|
||||
using namespace std;
|
||||
|
||||
int main() {
|
||||
int *x = new int{123};
|
||||
cout << *x << endl;
|
||||
|
||||
string *str = new string{"Cats and Dogs"};
|
||||
cout << *str << endl;
|
||||
|
||||
int *xs = new int[]{10, 20, 30, 40, 50};
|
||||
for (int i = 0; i < 5; ++i)
|
||||
cout << xs[i] << " ";
|
||||
cout << endl;
|
||||
|
||||
string *strs = new string[]{"Cat", "Dog", "Mouse"};
|
||||
for (int i = 0; i < 3; ++i)
|
||||
cout << strs[i] << " ";
|
||||
cout << endl;
|
||||
|
||||
string_view *str_views = new string_view[]{strs[0], strs[1], strs[2]};
|
||||
for (int i = 0; i < 3; ++i)
|
||||
cout << str_views[i] << " ";
|
||||
cout << endl;
|
||||
|
||||
delete x;
|
||||
delete str;
|
||||
delete[] xs;
|
||||
delete[] strs;
|
||||
delete[] str_views;
|
||||
}
|
@ -0,0 +1,22 @@
|
||||
#include <iostream>
|
||||
#include "miptstring.cpp"
|
||||
|
||||
using std::cout, std::endl;
|
||||
|
||||
int main() {
|
||||
mipt::String stack{"Cat"};
|
||||
cout << stack << endl;
|
||||
|
||||
mipt::String* heap = new mipt::String{"Dog"};
|
||||
cout << *heap << endl;
|
||||
|
||||
char *x = (char*)malloc(sizeof(mipt::String));
|
||||
mipt::String* px = new(x) mipt::String{"Elephant"};
|
||||
|
||||
cout << *px << endl;
|
||||
|
||||
px->~String();
|
||||
free(px);
|
||||
delete heap;
|
||||
|
||||
}
|
@ -0,0 +1,215 @@
|
||||
#pragma once
|
||||
|
||||
#include <iostream>
|
||||
#include <cstring>
|
||||
|
||||
namespace mipt{
|
||||
|
||||
class String
|
||||
{
|
||||
private:
|
||||
|
||||
std::size_t mSize {0};
|
||||
std::size_t mCapacity {0};
|
||||
char* mpData {nullptr};
|
||||
|
||||
public:
|
||||
|
||||
String(const char* str)
|
||||
{
|
||||
std::size_t strSize = std::strlen(str);
|
||||
resize(strSize);
|
||||
std::memcpy(mpData, str, mSize);
|
||||
|
||||
std::cout << "mipt::String Constructor (" << mpData << ")" << std::endl;
|
||||
}
|
||||
|
||||
String() : String("") {}
|
||||
String(const String& s) : String(s.cStr()) {}
|
||||
|
||||
String(std::size_t n, char a)
|
||||
{
|
||||
resize(n);
|
||||
|
||||
for (std::size_t i = 0; i < mSize; ++i)
|
||||
mpData[i] = a;
|
||||
|
||||
std::cout << "mipt::String Constructor (" << mpData << ")" << std::endl;
|
||||
}
|
||||
|
||||
~String()
|
||||
{
|
||||
std::cout << "mipt::String Destructor (" << mpData << ")" << std::endl;
|
||||
delete [] mpData;
|
||||
}
|
||||
|
||||
void reserve(std::size_t capacity)
|
||||
{
|
||||
if (capacity <= mCapacity)
|
||||
return;
|
||||
|
||||
mCapacity = std::max(2 * mCapacity, capacity);
|
||||
char* newData = new char[mCapacity]; // errorCheckedMalloc(mCapacity);
|
||||
|
||||
if (mpData)
|
||||
std::memcpy(newData, mpData, mSize + 1);
|
||||
|
||||
delete [] mpData;
|
||||
mpData = newData;
|
||||
}
|
||||
|
||||
|
||||
void resize(std::size_t size)
|
||||
{
|
||||
reserve(size + 1);
|
||||
mSize = size;
|
||||
mpData[mSize] = '\0';
|
||||
}
|
||||
|
||||
|
||||
String& operator=(const String& right)
|
||||
{
|
||||
if (this == &right)
|
||||
return *this;
|
||||
|
||||
mSize = right.mSize;
|
||||
resize(mSize);
|
||||
|
||||
std::memcpy(mpData, right.mpData, mSize + 1);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
String operator+(const String& b)
|
||||
{
|
||||
String result;
|
||||
result.resize(mSize + b.mSize);
|
||||
|
||||
std::memcpy(result.mpData, mpData, mSize);
|
||||
std::memcpy(result.mpData + mSize, b.mpData, b.mSize);
|
||||
result.mpData[result.mSize] = '\0';
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
String& operator+=(const String& right)
|
||||
{
|
||||
*this = *this + right;
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool operator==(const String& right) const
|
||||
{
|
||||
if (mSize != right.mSize)
|
||||
return false;
|
||||
|
||||
std::size_t i = 0;
|
||||
while (i < mSize && mpData[i] == right.mpData[i])
|
||||
i++;
|
||||
|
||||
return i == mSize;
|
||||
}
|
||||
|
||||
bool operator<(const String& right) const
|
||||
{
|
||||
std::size_t i = 0;
|
||||
while (i < mSize && i < right.mSize && mpData[i] == right.mpData[i])
|
||||
i++;
|
||||
|
||||
return mpData[i] < right.mpData[i];
|
||||
}
|
||||
|
||||
bool operator<=(const String& right) const
|
||||
{
|
||||
std::size_t i = 0;
|
||||
while (i < mSize && i < right.mSize && mpData[i] == right.mpData[i])
|
||||
i++;
|
||||
|
||||
return mpData[i] <= right.mpData[i];
|
||||
}
|
||||
|
||||
bool operator!=(const String& right) const
|
||||
{
|
||||
return !(*this == right);
|
||||
}
|
||||
|
||||
bool operator>(const String& right) const
|
||||
{
|
||||
return !(*this <= right);
|
||||
}
|
||||
|
||||
bool operator>=(const String& right) const
|
||||
{
|
||||
return !(*this < right);
|
||||
}
|
||||
|
||||
char& operator[](std::size_t i)
|
||||
{
|
||||
return mpData[i];
|
||||
}
|
||||
|
||||
const char& operator[](std::size_t i) const
|
||||
{
|
||||
return mpData[i];
|
||||
}
|
||||
|
||||
char& at(std::size_t i)
|
||||
{
|
||||
if (i >= mSize)
|
||||
throw std::out_of_range{"mipt::String::at: index >= this->size()"};
|
||||
return mpData[i];
|
||||
}
|
||||
|
||||
const char& at(std::size_t i) const
|
||||
{
|
||||
if (i >= mSize)
|
||||
throw std::out_of_range{"mipt::String::at: index >= this->size()"};
|
||||
return mpData[i];
|
||||
}
|
||||
|
||||
void clear()
|
||||
{
|
||||
delete [] mpData;
|
||||
|
||||
mSize = 0;
|
||||
mCapacity = 1;
|
||||
mpData = new char[mCapacity];
|
||||
mpData[0] = '\0';
|
||||
}
|
||||
|
||||
void addCharacter(char c)
|
||||
{
|
||||
if (mSize + 1 == mCapacity)
|
||||
reserve(2 * mCapacity);
|
||||
|
||||
mpData[mSize] = c;
|
||||
resize(mSize + 1);
|
||||
}
|
||||
|
||||
|
||||
std::size_t getSize() const {return mSize;}
|
||||
std::size_t getCapacity() const {return mCapacity;}
|
||||
const char* cStr() const {return mpData;}
|
||||
};
|
||||
|
||||
|
||||
std::ostream& operator<<(std::ostream& out, const String& s)
|
||||
{
|
||||
out << s.cStr();
|
||||
return out;
|
||||
}
|
||||
|
||||
std::istream& operator>>(std::istream& in, String& s)
|
||||
{
|
||||
s.clear();
|
||||
while (true)
|
||||
{
|
||||
char x = in.get();
|
||||
if (std::isspace(x))
|
||||
break;
|
||||
s.addCharacter(x);
|
||||
}
|
||||
return in;
|
||||
}
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
#include <iostream>
|
||||
#include "miptstring.h"
|
||||
#include "miptstringview.h"
|
||||
using namespace std;
|
||||
|
||||
int main() {
|
||||
mipt::String a = "abcd";
|
||||
mipt::String b = "abce";
|
||||
mipt::StringView av = a;
|
||||
mipt::StringView bv = b;
|
||||
//cout << (b < a) << endl;
|
||||
//cout << (bv < av) << endl;
|
||||
cout << av.substr(1,10) << endl;
|
||||
av.remove_suffix(2);
|
||||
cout << av << endl;
|
||||
mipt::String meow = av;
|
||||
cout << "sv to string: " << meow << endl;
|
||||
}
|
@ -0,0 +1,218 @@
|
||||
#include <iostream>
|
||||
#include <algorithm>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include "miptstring.h"
|
||||
#include "miptstringview.h"
|
||||
using std::cout, std::cin, std::endl, std::size_t;
|
||||
|
||||
namespace mipt{
|
||||
|
||||
char* errorCheckedMalloc(size_t newCapacity)
|
||||
{
|
||||
char* result = static_cast<char*>(std::malloc(newCapacity * sizeof(char)));
|
||||
if (result == NULL)
|
||||
{
|
||||
cout << "Error! Out of memory" << endl;
|
||||
std::exit(1);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
String::String(const char* str)
|
||||
{
|
||||
size_t strSize = std::strlen(str);
|
||||
resize(strSize);
|
||||
std::memcpy(mpData, str, mSize);
|
||||
}
|
||||
|
||||
String::String() : String("") {}
|
||||
String::String(const String& s) : String(s.cStr()) {}
|
||||
String::String(const StringView& sv) {
|
||||
mSize = sv.size();
|
||||
(*this).reserve(mSize);
|
||||
for(int i = 0; i < mSize; ++i)
|
||||
mpData[i] = sv[i];
|
||||
mpData[mSize] = '\0';
|
||||
|
||||
}
|
||||
|
||||
String::String(size_t n, char a)
|
||||
{
|
||||
resize(n);
|
||||
|
||||
for (size_t i = 0; i < mSize; ++i)
|
||||
mpData[i] = a;
|
||||
}
|
||||
|
||||
String::~String()
|
||||
{
|
||||
std::free(mpData);
|
||||
}
|
||||
|
||||
void String::reserve(size_t capacity)
|
||||
{
|
||||
if (capacity <= mCapacity)
|
||||
return;
|
||||
|
||||
mCapacity = std::max(2 * mCapacity, capacity);
|
||||
char* newData = errorCheckedMalloc(mCapacity);
|
||||
|
||||
if (mpData)
|
||||
std::memcpy(newData, mpData, mSize + 1);
|
||||
|
||||
std::free(mpData);
|
||||
mpData = newData;
|
||||
}
|
||||
|
||||
|
||||
void String::resize(size_t size)
|
||||
{
|
||||
reserve(size + 1);
|
||||
mSize = size;
|
||||
mpData[mSize] = '\0';
|
||||
}
|
||||
|
||||
|
||||
String& String::operator=(const String& right)
|
||||
{
|
||||
if (this == &right)
|
||||
return *this;
|
||||
|
||||
mSize = right.mSize;
|
||||
resize(mSize);
|
||||
|
||||
std::memcpy(mpData, right.mpData, mSize + 1);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
String String::operator+(const String& b)
|
||||
{
|
||||
String result;
|
||||
result.resize(mSize + b.mSize);
|
||||
|
||||
std::memcpy(result.mpData, mpData, mSize);
|
||||
std::memcpy(result.mpData + mSize, b.mpData, b.mSize);
|
||||
result.mpData[result.mSize] = '\0';
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
String& String::operator+=(const String& right)
|
||||
{
|
||||
*this = *this + right;
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool String::operator==(const String& right) const
|
||||
{
|
||||
if (mSize != right.mSize)
|
||||
return false;
|
||||
|
||||
size_t i = 0;
|
||||
while (i < mSize && mpData[i] == right.mpData[i])
|
||||
i++;
|
||||
|
||||
return i == mSize;
|
||||
}
|
||||
|
||||
bool String::operator<(const String& right) const
|
||||
{
|
||||
size_t i = 0;
|
||||
while (i < mSize && i < right.mSize && mpData[i] == right.mpData[i])
|
||||
i++;
|
||||
|
||||
return mpData[i] < right.mpData[i];
|
||||
}
|
||||
|
||||
bool String::operator<=(const String& right) const
|
||||
{
|
||||
size_t i = 0;
|
||||
while (i < mSize && i < right.mSize && mpData[i] == right.mpData[i])
|
||||
i++;
|
||||
|
||||
return mpData[i] <= right.mpData[i];
|
||||
}
|
||||
|
||||
bool String::operator!=(const String& right) const
|
||||
{
|
||||
return !(*this == right);
|
||||
}
|
||||
|
||||
bool String::operator>(const String& right) const
|
||||
{
|
||||
return !(*this <= right);
|
||||
}
|
||||
|
||||
bool String::operator>=(const String& right) const
|
||||
{
|
||||
return !(*this < right);
|
||||
}
|
||||
|
||||
char& String::operator[](size_t i)
|
||||
{
|
||||
return mpData[i];
|
||||
}
|
||||
|
||||
const char& String::operator[](size_t i) const
|
||||
{
|
||||
return mpData[i];
|
||||
}
|
||||
|
||||
char& String::at(size_t i)
|
||||
{
|
||||
if (i >= mSize)
|
||||
{
|
||||
cout << "Error! Index is out of bounds." << endl;
|
||||
}
|
||||
return mpData[i];
|
||||
}
|
||||
|
||||
void String::clear()
|
||||
{
|
||||
std::free(mpData);
|
||||
|
||||
mSize = 0;
|
||||
mCapacity = 1;
|
||||
mpData = errorCheckedMalloc(mCapacity);
|
||||
mpData[0] = '\0';
|
||||
}
|
||||
|
||||
void String::addCharacter(char c)
|
||||
{
|
||||
if (mSize + 1 == mCapacity)
|
||||
reserve(2 * mCapacity);
|
||||
|
||||
mpData[mSize] = c;
|
||||
resize(mSize + 1);
|
||||
}
|
||||
|
||||
|
||||
size_t String::getSize() const {return mSize;}
|
||||
size_t String::getCapacity() const {return mCapacity;}
|
||||
const char* String::cStr() const {return mpData;}
|
||||
|
||||
|
||||
|
||||
std::ostream& operator<<(std::ostream& out, const String& s)
|
||||
{
|
||||
out << s.cStr();
|
||||
return out;
|
||||
}
|
||||
|
||||
std::istream& operator>>(std::istream& in, String& s)
|
||||
{
|
||||
s.clear();
|
||||
while (true)
|
||||
{
|
||||
char x = in.get();
|
||||
if (x == ' ' || x == '\n' || x == '\t')
|
||||
break;
|
||||
s.addCharacter(x);
|
||||
}
|
||||
return in;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,43 @@
|
||||
#pragma once
|
||||
#include <iostream>
|
||||
|
||||
namespace mipt {
|
||||
|
||||
class StringView;
|
||||
class String
|
||||
{
|
||||
private:
|
||||
size_t mSize {0};
|
||||
size_t mCapacity {0};
|
||||
char* mpData {nullptr};
|
||||
public:
|
||||
String(const char* str);
|
||||
String();
|
||||
String(const String& s);
|
||||
String(const mipt::StringView& sv);
|
||||
String(size_t n, char a);
|
||||
~String();
|
||||
void reserve(size_t capacity);
|
||||
void resize(size_t size);
|
||||
String& operator=(const String& right);
|
||||
String operator+(const String& b);
|
||||
String& operator+=(const String& right);
|
||||
bool operator==(const String& right) const;
|
||||
bool operator<(const String& right) const;
|
||||
bool operator<=(const String& right) const;
|
||||
bool operator!=(const String& right) const;
|
||||
bool operator>(const String& right) const;
|
||||
bool operator>=(const String& right) const;
|
||||
char& operator[](size_t i);
|
||||
const char& operator[](size_t i) const;
|
||||
char& at(size_t i);
|
||||
void clear();
|
||||
void addCharacter(char c);
|
||||
size_t getSize() const;
|
||||
size_t getCapacity() const;
|
||||
const char* cStr() const;
|
||||
};
|
||||
|
||||
std::ostream& operator<<(std::ostream& out, const String& s);
|
||||
std::istream& operator>>(std::istream& in, String& s);
|
||||
}
|
@ -0,0 +1,81 @@
|
||||
#include <iostream>
|
||||
#include <algorithm>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include "miptstring.h"
|
||||
#include "miptstringview.h"
|
||||
using std::cout, std::cin, std::endl, std::size_t;
|
||||
|
||||
namespace mipt {
|
||||
|
||||
StringView::StringView() {;
|
||||
mSize = 0;
|
||||
mpData = nullptr;
|
||||
}
|
||||
StringView::StringView(const StringView& str) {
|
||||
mSize = str.mSize;
|
||||
mpData = str.mpData;
|
||||
}
|
||||
StringView::StringView(const mipt::String& s) {
|
||||
mSize = s.getSize();
|
||||
mpData = s.cStr();
|
||||
}
|
||||
StringView::StringView(const char* s) {
|
||||
mpData = s;
|
||||
mSize = strlen(s);
|
||||
}
|
||||
const char& StringView::at(size_t i)
|
||||
{
|
||||
if (i >= mSize)
|
||||
{
|
||||
throw std::out_of_range("Error! Index is out of bounds.");
|
||||
std::exit(1);
|
||||
}
|
||||
return mpData[i];
|
||||
}
|
||||
const char& StringView::operator[](size_t i) const
|
||||
{
|
||||
return mpData[i];
|
||||
}
|
||||
bool StringView::operator<(const StringView& right) const
|
||||
{
|
||||
size_t i = 0;
|
||||
while (i < mSize && i < right.mSize && mpData[i] == right.mpData[i])
|
||||
i++;
|
||||
|
||||
return mpData[i] < right.mpData[i];
|
||||
}
|
||||
size_t StringView::size() const {
|
||||
return mSize;
|
||||
}
|
||||
StringView StringView::substr(size_t pos, size_t count) {
|
||||
if (pos > mSize)
|
||||
throw std::out_of_range("Error! Index is out of bounds.");
|
||||
if (pos + count > mSize)
|
||||
count = mSize - pos;
|
||||
StringView result;
|
||||
result.mpData = mpData + pos;
|
||||
result.mSize = count;
|
||||
return result;
|
||||
}
|
||||
void StringView::remove_prefix(size_t n) {
|
||||
mSize -= n;
|
||||
}
|
||||
void StringView::remove_suffix(size_t n) {
|
||||
mSize -= n;
|
||||
mpData += n;
|
||||
}
|
||||
/*std::ostream& StringView::operator<<(std::ostream& out, mipt::StringView sv) {
|
||||
size_t size = sv.size();
|
||||
for (int i = 0; i < size; ++i)
|
||||
out << sv[i];
|
||||
return out;
|
||||
}*/
|
||||
std::ostream& operator<<(std::ostream& out, const mipt::StringView& sv) {
|
||||
size_t size = sv.size();
|
||||
for (int i = 0; i < size; ++i)
|
||||
out << sv[i];
|
||||
return out;
|
||||
}
|
||||
};
|
||||
|
@ -0,0 +1,28 @@
|
||||
#pragma once
|
||||
|
||||
#include <iostream>
|
||||
|
||||
namespace mipt {
|
||||
class String;
|
||||
class StringView
|
||||
{
|
||||
private:
|
||||
const char* mpData;
|
||||
size_t mSize;
|
||||
public:
|
||||
StringView();
|
||||
StringView(const StringView& str);
|
||||
StringView(const mipt::String& s);
|
||||
StringView(const char* s);
|
||||
const char& at(size_t i);
|
||||
const char& operator[](size_t i) const;
|
||||
bool operator<(const StringView& right) const;
|
||||
size_t size() const;
|
||||
StringView substr(size_t pos, size_t count);
|
||||
void remove_prefix(size_t n);
|
||||
void remove_suffix(size_t n);
|
||||
};
|
||||
|
||||
std::ostream& operator<<(std::ostream& out, const StringView& sv);
|
||||
|
||||
}
|
Binary file not shown.
@ -0,0 +1,18 @@
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
using std::cout, std::endl;
|
||||
|
||||
int sumEven(const std::vector<int>& v) {
|
||||
int sum = 0;
|
||||
size_t s = v.size();
|
||||
for (int i = 0; i < s; ++i)
|
||||
if (v[i] % 2 == 0)
|
||||
sum += v[i];
|
||||
return sum;
|
||||
}
|
||||
|
||||
int main() {
|
||||
std::vector<int> v {4, 8, 15, 16, 23, 42};
|
||||
cout << sumEven(v) << endl;
|
||||
}
|
@ -0,0 +1,58 @@
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <span>
|
||||
|
||||
using std::cout, std::endl, std::vector, std::span;
|
||||
|
||||
vector<int> lastDigits1(const vector<int>& v) {
|
||||
vector<int> result;
|
||||
size_t size = v.size();
|
||||
for(int i = 0; i < size; ++i) {
|
||||
result.push_back(v[i] % 10);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
void lastDigits2(vector<int>& v) {
|
||||
size_t size = v.size();
|
||||
for(int i = 0; i < size; ++i) {
|
||||
v[i] %= 10;
|
||||
}
|
||||
}
|
||||
|
||||
void lastDigits3(vector<int>* pv) {
|
||||
size_t size = pv->size();
|
||||
for(int i = 0; i < size; ++i)
|
||||
(*pv)[i] %= 10;
|
||||
}
|
||||
|
||||
void lastDigits4(span<int> sp) {
|
||||
size_t size = sp.size();
|
||||
for(int i = 0; i < size; ++i)
|
||||
sp[i] %= 10;
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& out, const vector<int>& v) {
|
||||
cout << "[";
|
||||
size_t size = v.size();
|
||||
for(int i = 0; i < size; ++i)
|
||||
cout << v[i] << (i == size - 1 ? "]" : " ");
|
||||
return out;
|
||||
}
|
||||
|
||||
int main() {
|
||||
vector<int> meow{1, 2, 3, 12, 45, 32,313123,3245};
|
||||
vector<int> result1 = lastDigits1(meow);
|
||||
cout << result1 << endl;
|
||||
|
||||
vector<int> result2 = meow;
|
||||
lastDigits2(result2);
|
||||
cout << result2 << endl;
|
||||
|
||||
vector<int> result3 = meow;
|
||||
lastDigits3(&result3);
|
||||
cout << result3 << endl;
|
||||
|
||||
span<int> sp = meow;
|
||||
lastDigits4(sp);
|
||||
cout << meow << endl;
|
||||
}
|
@ -0,0 +1,52 @@
|
||||
#include <iostream>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
#include <cmath>
|
||||
|
||||
using std::cout, std::endl, std::pair, std::vector;
|
||||
|
||||
vector<pair<int, int>> factorization(int n) {
|
||||
if (n == 1) {
|
||||
return vector<pair<int,int>>{{1, 1}};
|
||||
}
|
||||
int d = 2;
|
||||
int c;
|
||||
vector<pair<int, int>> result;
|
||||
|
||||
while(n != 1) {
|
||||
c = 0;
|
||||
while(n % d == 0) {
|
||||
c++;
|
||||
n /= d;
|
||||
}
|
||||
if (c)
|
||||
result.push_back(pair{d, c});
|
||||
d++;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& out, pair<int,int> p) {
|
||||
out << "{" << p.first << ", " << p.second << "}";
|
||||
return out;
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& out, vector<pair<int,int>> v) {
|
||||
out << "{";
|
||||
size_t size = v.size();
|
||||
for(int i = 0; i < size; ++i) {
|
||||
out << v[i] << (i == size - 1 ? "}" : ", ");
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
int main() {
|
||||
vector<pair<int, int>> res = factorization(60);
|
||||
cout << res << endl;
|
||||
res = factorization(626215995);
|
||||
cout << res << endl;
|
||||
res = factorization(107);
|
||||
cout << res << endl;
|
||||
res = factorization(1);
|
||||
cout << res << endl;
|
||||
}
|
@ -0,0 +1,27 @@
|
||||
#include <iostream>
|
||||
#include "time.h"
|
||||
#include <string_view>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
using std::cout, std::endl, std::string, std::string_view, std::vector;
|
||||
|
||||
int main()
|
||||
{
|
||||
string t1s = "23:59:59";
|
||||
string_view t1sv = t1s;
|
||||
string t2s = "23:59:59";
|
||||
string_view t2sv = t2s;
|
||||
|
||||
Time t1 = t1sv;
|
||||
Time t2 = t2sv;
|
||||
cout << t1 + t2 << endl;
|
||||
|
||||
string tss = "23:59:59 23:59:59 23:59:59";
|
||||
string_view tssv = tss;
|
||||
vector < Time > tsv = getTimesFromString(tss);
|
||||
for (int i = 0, size = tsv.size(); i < size; ++i) {
|
||||
cout << tsv[i] << endl;
|
||||
}
|
||||
cout << sumTimes(tsv) << endl;
|
||||
}
|
@ -0,0 +1,78 @@
|
||||
#include "time.h"
|
||||
#include <string>
|
||||
#include <iomanip>
|
||||
#include <vector>
|
||||
|
||||
using std::cout, std::endl, std::vector, std::string_view, std::string;
|
||||
|
||||
Time::Time(int hours, int minutes, int seconds)
|
||||
{
|
||||
mHours = hours;
|
||||
mMinutes = minutes;
|
||||
mSeconds = seconds;
|
||||
}
|
||||
|
||||
Time::Time(string_view s)
|
||||
{
|
||||
string buf;
|
||||
buf = s.substr(0, 2);
|
||||
mHours = stoi(buf);
|
||||
buf = s.substr(3, 2);
|
||||
mMinutes = stoi(buf);
|
||||
buf = s.substr(6, 2);
|
||||
mSeconds = stoi(buf);
|
||||
}
|
||||
|
||||
Time::Time():Time(0, 0, 0)
|
||||
{
|
||||
};
|
||||
|
||||
Time Time::operator+(Time b) const
|
||||
{
|
||||
return Time((mHours + b.mHours + (mMinutes + b.mMinutes) / 60) % 24,
|
||||
(mMinutes + b.mMinutes +
|
||||
(mSeconds + b.mSeconds) / 60) % 60,
|
||||
(mSeconds + b.mSeconds) % 60);
|
||||
}
|
||||
|
||||
int Time::hours() const
|
||||
{
|
||||
return mHours;
|
||||
}
|
||||
|
||||
int Time::minutes() const
|
||||
{
|
||||
return mMinutes;
|
||||
}
|
||||
|
||||
int Time::seconds() const
|
||||
{
|
||||
return mSeconds;
|
||||
}
|
||||
|
||||
vector < Time > getTimesFromString(string_view s)
|
||||
{
|
||||
vector < Time > res;
|
||||
for (int i = 0, size = s.size(); i < size; i += 9) {
|
||||
res.push_back(Time(s.substr(i, 9)));
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
Time sumTimes(const vector < Time > &v)
|
||||
{
|
||||
Time res;
|
||||
for (int i = 0, size = v.size(); i < size; ++i) {
|
||||
res = res + v[i];
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
std::ostream & operator<<(std::ostream & out, Time t)
|
||||
{
|
||||
out << std::setw(2) << std::setfill('0') << t.mHours
|
||||
<< ":"
|
||||
<< std::setw(2) << std::setfill('0') << t.mMinutes
|
||||
<< ":" << std::setw(2) << std::setfill('0') << t.mSeconds;
|
||||
return out;
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
#pragma once
|
||||
#include <string_view>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
using std::string_view, std::vector;
|
||||
|
||||
class Time {
|
||||
private:
|
||||
int mHours = 0, mMinutes = 0, mSeconds = 0;
|
||||
public:
|
||||
Time(int hours, int minutes, int seconds);
|
||||
Time();
|
||||
Time(string_view s);
|
||||
Time operator+(Time b) const;
|
||||
int hours() const; int minutes() const; int seconds() const;
|
||||
friend std::ostream& operator<<(std::ostream& out, Time t);
|
||||
};
|
||||
|
||||
Time sumTimes(const vector<Time>& v);
|
||||
vector<Time> getTimesFromString(string_view s);
|
@ -0,0 +1,34 @@
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
using std::string, std::pair, std::cout, std::endl, std::vector;
|
||||
|
||||
template <typename T>
|
||||
T maximum(const vector<T>& v) {
|
||||
T max{};
|
||||
for(int i = 0, size = v.size(); i < size; ++i) {
|
||||
if (v[i] > max)
|
||||
max = v[i];
|
||||
}
|
||||
return max;
|
||||
}
|
||||
|
||||
int main() {
|
||||
vector<int> int_v {1,3,5,3,23,113,34,54};
|
||||
cout << maximum(int_v) << endl;
|
||||
vector<float> float_v {1.5,5.64,5.67,45.65,113,67.5,98.12};
|
||||
cout << maximum(float_v) << endl;
|
||||
vector<string> string_v {"aaaa", "dfg", "dsfdgjb", "meow", "dsfewvcv", "klafdn"};
|
||||
cout << maximum(string_v) << endl;
|
||||
vector<pair<int, int>> pair_v {
|
||||
{113, 1},
|
||||
{12, 3},
|
||||
{45, 34},
|
||||
{113, 113},
|
||||
{112, 12233}
|
||||
};
|
||||
pair<int, int> res = maximum(pair_v);
|
||||
cout << "(" << res.first << ", " << res.second << ")" << endl;
|
||||
}
|
@ -0,0 +1,42 @@
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
template <typename T>
|
||||
class Manager {
|
||||
private:
|
||||
T* mPtr;
|
||||
public:
|
||||
Manager() {
|
||||
mPtr = nullptr;
|
||||
}
|
||||
void allocate() {
|
||||
mPtr = (T*)malloc(sizeof(T));
|
||||
}
|
||||
void construct(const T& t) {
|
||||
new(mPtr) T{t};
|
||||
}
|
||||
T& get() {
|
||||
return *mPtr;
|
||||
}
|
||||
void destruct() {
|
||||
mPtr->~T();
|
||||
}
|
||||
void deallocate() {
|
||||
free(mPtr);
|
||||
}
|
||||
};
|
||||
|
||||
int main() {
|
||||
Manager<std::string> a;
|
||||
a.allocate();
|
||||
a.construct("Cats and dogs");
|
||||
a.get() += " and elephants";
|
||||
std::cout << a.get() << std::endl;
|
||||
a.destruct();
|
||||
|
||||
a.construct("Sapere aude");
|
||||
std::cout << a.get() << std::endl;
|
||||
|
||||
a.destruct();
|
||||
a.deallocate();
|
||||
}
|
@ -0,0 +1,74 @@
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
using std::cout, std::endl, std::string, std::vector;
|
||||
|
||||
template <typename T>
|
||||
class Ref {
|
||||
private:
|
||||
T* mPtr;
|
||||
public:
|
||||
Ref(T& t) {
|
||||
mPtr = &t;
|
||||
}
|
||||
Ref(Ref& t) {
|
||||
mPtr = t.mPtr;
|
||||
}
|
||||
Ref() {
|
||||
mPtr = nullptr;
|
||||
}
|
||||
T& get() {
|
||||
return *mPtr;
|
||||
}
|
||||
T operator=(const T& t) {
|
||||
new(mPtr) T{t};
|
||||
return *mPtr;
|
||||
}
|
||||
T operator+(const T& t) {
|
||||
return *mPtr + t;
|
||||
}
|
||||
T operator+=(const T& t) {
|
||||
*mPtr = *mPtr + t;
|
||||
return *mPtr;
|
||||
}
|
||||
T* operator->() {
|
||||
return mPtr;
|
||||
}
|
||||
template <typename U>
|
||||
friend std::ostream& operator<<(std::ostream& out, Ref<U> r);
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
std::ostream& operator<<(std::ostream& out, Ref<T> r) {
|
||||
out << *(r.mPtr);
|
||||
return out;
|
||||
}
|
||||
|
||||
void toUpper(Ref<string> r) {
|
||||
for(size_t i = 0; i < r->size(); ++i)
|
||||
r.get()[i] = toupper(r.get()[i]);
|
||||
}
|
||||
|
||||
int main() {
|
||||
int a = 10;
|
||||
Ref<int> ra = a;
|
||||
cout << ra << endl;
|
||||
|
||||
string s = "Cat";
|
||||
Ref<string> rs = s;
|
||||
rs = "Mouse";
|
||||
rs += "Elephant";
|
||||
cout << rs << endl;
|
||||
cout << s << endl;
|
||||
|
||||
toUpper(s);
|
||||
cout << s << endl;
|
||||
|
||||
vector<string> animals {"Cat", "Dogs", "Elephants", "Worms"};
|
||||
vector<Ref<string>> refs {animals.begin(), animals.end()};
|
||||
|
||||
for (int i = 0; i < refs.size(); ++i)
|
||||
cout << animals[i] << " ";
|
||||
cout << endl;
|
||||
}
|
Binary file not shown.
@ -0,0 +1,22 @@
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
#include <algorithm>
|
||||
|
||||
using std::cout, std::endl, std::vector, std::cin;
|
||||
|
||||
int main() {
|
||||
size_t n;
|
||||
cin >> n;
|
||||
vector<int> v(n);
|
||||
for (int i = 0; i < n; ++i)
|
||||
cin >> v[i];
|
||||
|
||||
vector<int>::iterator max = std::max_element(v.begin(), v.end());
|
||||
std::sort(v.begin(), max);
|
||||
std::sort(max, v.end());
|
||||
std::reverse(max, v.end());
|
||||
|
||||
for (int i = 0; i < v.size(); ++i)
|
||||
cout << v[i] << (i == v.size() - 1 ? "": " ");
|
||||
cout << endl;
|
||||
}
|
@ -0,0 +1,27 @@
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
|
||||
using std::cout, std::endl, std::string, std::vector;
|
||||
|
||||
void string_vector_reverse(vector<string>& sv) {
|
||||
std::for_each(sv.begin(), sv.end(), [](string& s){ std::reverse(s.begin(), s.end()); });
|
||||
std::reverse(sv.begin(), sv.end());
|
||||
}
|
||||
|
||||
int main() {
|
||||
|
||||
vector<string> sv1 {"cat", "dog", "mouse", "elephant"};
|
||||
vector<string> sv2 {"a", "bc"};
|
||||
|
||||
string_vector_reverse(sv1);
|
||||
string_vector_reverse(sv2);
|
||||
|
||||
for (int i = 0; i < sv1.size(); ++i)
|
||||
cout << sv1[i] << (i == sv1.size() - 1 ? "" : " ");
|
||||
cout << endl;
|
||||
for (int i = 0; i < sv2.size(); ++i)
|
||||
cout << sv2[i] << (i == sv2.size() - 1 ? "" : " ");
|
||||
cout << endl;
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
#include <algorithm>
|
||||
#include <iostream>
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
#include <numeric>
|
||||
#include <cctype>
|
||||
|
||||
using std::string, std::cin, std::cout, std::endl;
|
||||
|
||||
bool strIsUpper(const string& s) {
|
||||
return std::accumulate(s.begin(), s.end(), true, [](bool res, char c) {return res && (!isalpha(c) || isupper(c)); });
|
||||
}
|
||||
|
||||
int main() {
|
||||
string s;
|
||||
getline(cin, s);
|
||||
cout << strIsUpper(s) << endl;
|
||||
}
|
@ -0,0 +1,22 @@
|
||||
#include <iostream>
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <cctype>
|
||||
|
||||
using std::cout, std::endl, std::string, std::string_view;
|
||||
|
||||
bool isIdentifier(string_view sv) {
|
||||
bool is = true;
|
||||
if (!(std::isalpha(sv[0]) || sv[0] == '_'))
|
||||
return false;
|
||||
if (std::all_of(sv.begin(), sv.end(), [](const char c){ return isalpha(c) || isdigit(c) || c == '_' ;}))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
int main() {
|
||||
string s;
|
||||
getline(std::cin, s);
|
||||
cout << isIdentifier(s) << endl;
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <algorithm>
|
||||
|
||||
using std::cout, std::string, std::endl;
|
||||
|
||||
void move_spaces(string& s) {
|
||||
std::stable_sort(s.begin(), s.end(), [](const char& a, const char& b){ return (b == ' '); });
|
||||
}
|
||||
|
||||
int main() {
|
||||
string s;
|
||||
std::getline(std::cin, s);
|
||||
move_spaces(s);
|
||||
// So we can see spaces
|
||||
cout << s << "###" << endl;
|
||||
|
||||
}
|
Binary file not shown.
@ -0,0 +1,2 @@
|
||||
balls:
|
||||
g++ ./balls.cpp -std=c++11 -o balls.exe -I../../../3rdparty/SFML-2.5.1/include -L ../../../3rdparty/SFML-2.5.1/lib/ -lsfml-graphics -lsfml-window -lsfml-system
|
@ -0,0 +1,2 @@
|
||||
balls:
|
||||
g++ ./balls.cpp -std=c++11 -o balls.exe -I../../../3rdparty/SFML-2.5.1/include -L ../../../3rdparty/SFML-2.5.1/lib/ -lsfml-graphics -lsfml-window -lsfml-system
|
@ -0,0 +1,89 @@
|
||||
#include <SFML/Graphics.hpp>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <cstdlib>
|
||||
#include <ctime>
|
||||
#include <cmath>
|
||||
|
||||
using namespace std;
|
||||
|
||||
const int min_distance = 5;
|
||||
const float G = 500;
|
||||
|
||||
struct Ball
|
||||
{
|
||||
float radius;
|
||||
float mass = 1;
|
||||
sf::Vector2f position;
|
||||
sf::Vector2f velocity;
|
||||
};
|
||||
|
||||
|
||||
int main()
|
||||
{
|
||||
srand(time(0));
|
||||
|
||||
const int width = 1000;
|
||||
const int height = 800;
|
||||
const int n_balls = 15;
|
||||
|
||||
// Шаг по времени
|
||||
const float delta_t = 0.1;
|
||||
sf::RenderWindow window(sf::VideoMode(width, height), "My window");
|
||||
window.setFramerateLimit(60);
|
||||
sf::CircleShape circle(50.0f);
|
||||
circle.setFillColor({200, 216, 200});
|
||||
std::vector<Ball> balls;
|
||||
balls.resize(n_balls);
|
||||
for (int i = 0; i < n_balls; i++)
|
||||
{
|
||||
balls[i].radius = 4 + rand() % 8;
|
||||
balls[i].position = {(float)(rand() % width), (float)(rand() % height)};
|
||||
balls[i].velocity = {(float)(rand() % 100 - 50), (float)(rand() % 100 - 50)};
|
||||
}
|
||||
while (window.isOpen())
|
||||
{
|
||||
sf::Event event;
|
||||
while (window.pollEvent(event))
|
||||
{
|
||||
if (event.type == sf::Event::Closed)
|
||||
window.close();
|
||||
}
|
||||
|
||||
window.clear(sf::Color::Black);
|
||||
|
||||
for (int i = 0; i < n_balls; i++)
|
||||
{
|
||||
|
||||
balls[i].position += balls[i].velocity * delta_t;
|
||||
for (int j = 0; j < n_balls; ++j) {
|
||||
if (i == j)
|
||||
continue;
|
||||
float distance = std::sqrt((balls[j].position.x - balls[i].position.x) * (balls[j].position.x - balls[i].position.x) + (balls[j].position.y - balls[i].position.y) * (balls[j].position.y - balls[i].position.y));
|
||||
if (distance < min_distance)
|
||||
continue;
|
||||
auto direction = balls[j].position - balls[i].position;
|
||||
balls[i].velocity += (direction * G * delta_t * balls[j].mass) / (distance * distance);
|
||||
}
|
||||
|
||||
if (((balls[i].position.x - balls[i].radius) < 0) || (balls[i].position.x + balls[i].radius> width)) {
|
||||
balls[i].velocity.x = -balls[i].velocity.x;
|
||||
balls[i].position.x = (balls[i].position.x - balls[i].radius < 0 ? balls[i].radius : width - balls[i].radius);
|
||||
}
|
||||
if ((balls[i].position.y - balls[i].radius < 0) || (balls[i].position.y + balls[i].radius > height)) {
|
||||
balls[i].velocity.y = -balls[i].velocity.y;
|
||||
balls[i].position.y = (balls[i].position.y - balls[i].radius < 0 ? balls[i].radius : height - balls[i].radius);
|
||||
}
|
||||
|
||||
circle.setRadius(balls[i].radius);
|
||||
circle.setOrigin(balls[i].radius, balls[i].radius);
|
||||
circle.setPosition(balls[i].position);
|
||||
|
||||
window.draw(circle);
|
||||
}
|
||||
|
||||
window.display();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
@ -0,0 +1,95 @@
|
||||
#include <SFML/Graphics.hpp>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <cstdlib>
|
||||
#include <ctime>
|
||||
#include <cmath>
|
||||
|
||||
using namespace std;
|
||||
|
||||
const int min_distance = 5;
|
||||
const float G = 500;
|
||||
|
||||
struct Ball
|
||||
{
|
||||
float radius;
|
||||
float mass;
|
||||
sf::Vector2f position;
|
||||
sf::Vector2f velocity;
|
||||
};
|
||||
|
||||
|
||||
int main()
|
||||
{
|
||||
srand(time(0));
|
||||
|
||||
const int width = 1000;
|
||||
const int height = 800;
|
||||
const int n_balls = 15;
|
||||
|
||||
// Шаг по времени
|
||||
const float delta_t = 0.1;
|
||||
sf::RenderWindow window(sf::VideoMode(width, height), "My window");
|
||||
window.setFramerateLimit(60);
|
||||
sf::CircleShape circle(50.0f);
|
||||
circle.setFillColor({200, 216, 200});
|
||||
std::vector<Ball> balls;
|
||||
balls.resize(n_balls);
|
||||
for (int i = 0; i < n_balls; i++)
|
||||
{
|
||||
balls[i].radius = 4 + rand() % 8;
|
||||
balls[i].mass = balls[i].radius * balls[i].radius / 100;
|
||||
balls[i].position = {(float)(rand() % width), (float)(rand() % height)};
|
||||
balls[i].velocity = {(float)(rand() % 100 - 50), (float)(rand() % 100 - 50)};
|
||||
}
|
||||
/* balls[0].radius = 15;
|
||||
balls[0].mass = 1000;
|
||||
balls[0].position = {(float)(rand() % width), (float)(rand() % height)};
|
||||
balls[0].velocity = {(float)(rand() % 100 - 50), (float)(rand() % 100 - 50)};
|
||||
*/
|
||||
while (window.isOpen())
|
||||
{
|
||||
sf::Event event;
|
||||
while (window.pollEvent(event))
|
||||
{
|
||||
if (event.type == sf::Event::Closed)
|
||||
window.close();
|
||||
}
|
||||
|
||||
window.clear(sf::Color::Black);
|
||||
|
||||
for (int i = 0; i < n_balls; i++)
|
||||
{
|
||||
|
||||
balls[i].position += balls[i].velocity * delta_t;
|
||||
for (int j = 0; j < n_balls; ++j) {
|
||||
if (i == j)
|
||||
continue;
|
||||
float distance = std::sqrt((balls[j].position.x - balls[i].position.x) * (balls[j].position.x - balls[i].position.x) + (balls[j].position.y - balls[i].position.y) * (balls[j].position.y - balls[i].position.y));
|
||||
if (distance < min_distance)
|
||||
continue;
|
||||
auto direction = balls[j].position - balls[i].position;
|
||||
balls[i].velocity += (direction * G * delta_t * balls[j].mass) / (distance * distance);
|
||||
}
|
||||
|
||||
if (((balls[i].position.x - balls[i].radius) < 0) || (balls[i].position.x + balls[i].radius> width)) {
|
||||
balls[i].velocity.x = -balls[i].velocity.x;
|
||||
balls[i].position.x = (balls[i].position.x - balls[i].radius < 0 ? balls[i].radius : width - balls[i].radius);
|
||||
}
|
||||
if ((balls[i].position.y - balls[i].radius < 0) || (balls[i].position.y + balls[i].radius > height)) {
|
||||
balls[i].velocity.y = -balls[i].velocity.y;
|
||||
balls[i].position.y = (balls[i].position.y - balls[i].radius < 0 ? balls[i].radius : height - balls[i].radius);
|
||||
}
|
||||
|
||||
circle.setRadius(balls[i].radius);
|
||||
circle.setOrigin(balls[i].radius, balls[i].radius);
|
||||
circle.setPosition(balls[i].position);
|
||||
|
||||
window.draw(circle);
|
||||
}
|
||||
|
||||
window.display();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
@ -0,0 +1,99 @@
|
||||
#include <SFML/Graphics.hpp>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <cstdlib>
|
||||
#include <ctime>
|
||||
#include <cmath>
|
||||
|
||||
using namespace std;
|
||||
|
||||
const int min_distance = 5;
|
||||
const float K = 25;
|
||||
|
||||
struct Ball
|
||||
{
|
||||
float radius;
|
||||
float charge;
|
||||
sf::Vector2f position;
|
||||
sf::Vector2f velocity;
|
||||
};
|
||||
|
||||
|
||||
int main()
|
||||
{
|
||||
srand(time(0));
|
||||
|
||||
const int width = 1000;
|
||||
const int height = 800;
|
||||
int n_balls = 4;
|
||||
|
||||
const float delta_t = 0.1;
|
||||
sf::RenderWindow window(sf::VideoMode(width, height), "My window");
|
||||
window.setFramerateLimit(60);
|
||||
sf::CircleShape circle(50.0f);
|
||||
|
||||
std::vector<Ball> balls;
|
||||
balls.resize(n_balls);
|
||||
for (int i = 0; i < n_balls; i++)
|
||||
{
|
||||
balls[i].radius = 4 + rand() % 8;
|
||||
balls[i].charge = (rand() % 8 - rand() % 8) * balls[i].radius * balls[i].radius;
|
||||
while (!balls[i].charge) {
|
||||
balls[i].charge = (rand() % 8 - rand() % 8) * balls[i].radius * balls[i].radius;
|
||||
}
|
||||
balls[i].position = {(float)(rand() % width), (float)(rand() % height)};
|
||||
balls[i].velocity = {(float)(rand() % 100 - 50), (float)(rand() % 100 - 50)};
|
||||
}
|
||||
while (window.isOpen())
|
||||
{
|
||||
sf::Event event;
|
||||
while (window.pollEvent(event))
|
||||
{
|
||||
if (event.type == sf::Event::Closed)
|
||||
window.close();
|
||||
}
|
||||
|
||||
window.clear(sf::Color::Black);
|
||||
|
||||
for (int i = 0; i < n_balls; i++)
|
||||
{
|
||||
|
||||
balls[i].position += balls[i].velocity * delta_t;
|
||||
for (int j = 0; j < n_balls; ++j) {
|
||||
if (i == j)
|
||||
continue;
|
||||
float distance = std::sqrt((balls[j].position.x - balls[i].position.x) * (balls[j].position.x - balls[i].position.x) + (balls[j].position.y - balls[i].position.y) * (balls[j].position.y - balls[i].position.y));
|
||||
if (distance < min_distance)
|
||||
continue;
|
||||
auto direction = balls[j].position - balls[i].position;
|
||||
if (balls[i].charge * balls[j].charge > 0)
|
||||
balls[i].velocity -= (direction * K * delta_t * std::abs(balls[j].charge)) / (distance * distance);
|
||||
else
|
||||
balls[i].velocity += (direction * K * delta_t * std::abs(balls[j].charge)) / (distance * distance);
|
||||
}
|
||||
|
||||
if (((balls[i].position.x - balls[i].radius) < 0) || (balls[i].position.x + balls[i].radius> width)) {
|
||||
balls[i].velocity.x = -balls[i].velocity.x;
|
||||
balls[i].position.x = (balls[i].position.x - balls[i].radius < 0 ? balls[i].radius : width - balls[i].radius);
|
||||
}
|
||||
if ((balls[i].position.y - balls[i].radius < 0) || (balls[i].position.y + balls[i].radius > height)) {
|
||||
balls[i].velocity.y = -balls[i].velocity.y;
|
||||
balls[i].position.y = (balls[i].position.y - balls[i].radius < 0 ? balls[i].radius : height - balls[i].radius);
|
||||
}
|
||||
|
||||
circle.setRadius(balls[i].radius);
|
||||
circle.setOrigin(balls[i].radius, balls[i].radius);
|
||||
circle.setPosition(balls[i].position);
|
||||
|
||||
if (balls[i].charge > 0)
|
||||
circle.setFillColor({static_cast<unsigned char>(balls[i].charge/1152 * 255 + 100), 0, 0});
|
||||
else
|
||||
circle.setFillColor({0, 0, static_cast<unsigned char>(std::abs(balls[i].charge)/1152 * 255 + 100)});
|
||||
window.draw(circle);
|
||||
}
|
||||
|
||||
window.display();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
@ -0,0 +1,114 @@
|
||||
#include <SFML/Graphics.hpp>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <cstdlib>
|
||||
#include <ctime>
|
||||
#include <cmath>
|
||||
|
||||
using namespace std;
|
||||
|
||||
const int min_distance = 5;
|
||||
const float K = 5;
|
||||
|
||||
struct Ball
|
||||
{
|
||||
float radius;
|
||||
float charge;
|
||||
sf::Vector2f position;
|
||||
sf::Vector2f velocity;
|
||||
};
|
||||
|
||||
|
||||
int main()
|
||||
{
|
||||
srand(time(0));
|
||||
|
||||
const int width = 1000;
|
||||
const int height = 800;
|
||||
int n_balls = 0;
|
||||
|
||||
char sign = 1;
|
||||
|
||||
// Шаг по времени
|
||||
const float delta_t = 0.1;
|
||||
sf::RenderWindow window(sf::VideoMode(width, height), "My window");
|
||||
window.setFramerateLimit(60);
|
||||
sf::CircleShape circle(50.0f);
|
||||
|
||||
std::vector<Ball> balls;
|
||||
balls.resize(n_balls);
|
||||
while (window.isOpen())
|
||||
{
|
||||
sf::Event event;
|
||||
while (window.pollEvent(event))
|
||||
{
|
||||
if (event.type == sf::Event::Closed)
|
||||
window.close();
|
||||
if (event.type == sf::Event::KeyPressed) {
|
||||
if (event.key.code == sf::Keyboard::LShift) {
|
||||
sign = -1;
|
||||
}
|
||||
}
|
||||
if (event.type == sf::Event::KeyReleased) {
|
||||
if (event.key.code == sf::Keyboard::LShift) {
|
||||
sign = 1;
|
||||
}
|
||||
}
|
||||
if(event.type == sf::Event::MouseButtonPressed) {
|
||||
Ball b;
|
||||
if(event.mouseButton.button == sf::Mouse::Right)
|
||||
b.radius = 15;
|
||||
else if(event.mouseButton.button == sf::Mouse::Left)
|
||||
b.radius = 5;
|
||||
b.charge = sign * b.radius * b.radius;
|
||||
b.position = {(float)(event.mouseButton.x), (float)(event.mouseButton.y)};
|
||||
b.velocity = {(float)(0), (float)(0)};
|
||||
balls.push_back(b);
|
||||
n_balls++;
|
||||
}
|
||||
}
|
||||
|
||||
window.clear(sf::Color::Black);
|
||||
|
||||
for (int i = 0; i < n_balls; i++)
|
||||
{
|
||||
|
||||
balls[i].position += balls[i].velocity * delta_t;
|
||||
for (int j = 0; j < n_balls; ++j) {
|
||||
if (i == j)
|
||||
continue;
|
||||
float distance = std::sqrt((balls[j].position.x - balls[i].position.x) * (balls[j].position.x - balls[i].position.x) + (balls[j].position.y - balls[i].position.y) * (balls[j].position.y - balls[i].position.y));
|
||||
if (distance < min_distance)
|
||||
continue;
|
||||
auto direction = balls[j].position - balls[i].position;
|
||||
if (balls[i].charge * balls[j].charge > 0)
|
||||
balls[i].velocity -= (direction * K * delta_t * std::abs(balls[j].charge)) / (distance * distance);
|
||||
else
|
||||
balls[i].velocity += (direction * K * delta_t * std::abs(balls[j].charge)) / (distance * distance);
|
||||
}
|
||||
|
||||
if (((balls[i].position.x - balls[i].radius) < 0) || (balls[i].position.x + balls[i].radius> width)) {
|
||||
balls[i].velocity.x = -balls[i].velocity.x;
|
||||
balls[i].position.x = (balls[i].position.x - balls[i].radius < 0 ? balls[i].radius : width - balls[i].radius);
|
||||
}
|
||||
if ((balls[i].position.y - balls[i].radius < 0) || (balls[i].position.y + balls[i].radius > height)) {
|
||||
balls[i].velocity.y = -balls[i].velocity.y;
|
||||
balls[i].position.y = (balls[i].position.y - balls[i].radius < 0 ? balls[i].radius : height - balls[i].radius);
|
||||
}
|
||||
|
||||
circle.setRadius(balls[i].radius);
|
||||
circle.setOrigin(balls[i].radius, balls[i].radius);
|
||||
circle.setPosition(balls[i].position);
|
||||
|
||||
if (balls[i].charge > 0)
|
||||
circle.setFillColor({200, 0, 0});
|
||||
else
|
||||
circle.setFillColor({0, 0, 200});
|
||||
window.draw(circle);
|
||||
}
|
||||
|
||||
window.display();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
@ -0,0 +1 @@
|
||||
07_n_bodies_charges_mouse
|
Binary file not shown.
@ -0,0 +1,9 @@
|
||||
#path = ../../../3rdparty/SFML-2.5.1
|
||||
#select_move_delete:
|
||||
# g++ ./select_move_delete.cpp -std=c++11 -o select_move_delete.exe -I $(path)/include -L $(path)/lib/ -lsfml-graphics -lsfml-window -lsfml-system
|
||||
#select_move_delete:
|
||||
# g++ ./select_move_delete.cpp -std=c++11 -o select_move_delete.exe -I $(path)/include -L $(path)/lib/ -lsfml-graphics -lsfml-window -lsfml-system
|
||||
build:
|
||||
g++ ./select_move_delete.cpp -std=c++11 -o select_move_delete -lsfml-graphics -lsfml-window -lsfml-system
|
||||
build_debug:
|
||||
g++ ./select_move_delete.cpp -std=c++11 -o select_move_delete -lsfml-graphics -lsfml-window -lsfml-system -D_DEBUG
|
Binary file not shown.
@ -0,0 +1,11 @@
|
||||
!_TAG_FILE_FORMAT 2 /extended format; --format=1 will not append ;" to lines/
|
||||
!_TAG_FILE_SORTED 1 /0=unsorted, 1=sorted, 2=foldcase/
|
||||
!_TAG_OUTPUT_EXCMD mixed /number, pattern, mixed, or combineV2/
|
||||
!_TAG_OUTPUT_FILESEP slash /slash or backslash/
|
||||
!_TAG_OUTPUT_MODE u-ctags /u-ctags or e-ctags/
|
||||
!_TAG_PATTERN_LENGTH_LIMIT 96 /0 for no limit/
|
||||
!_TAG_PROC_CWD /home/nihonium/projects/mipt_cpp/seminar11_events/01_select_move_delete/ //
|
||||
!_TAG_PROGRAM_AUTHOR Universal Ctags Team //
|
||||
!_TAG_PROGRAM_NAME Universal Ctags /Derived from Exuberant Ctags/
|
||||
!_TAG_PROGRAM_URL https://ctags.io/ /official site/
|
||||
!_TAG_PROGRAM_VERSION 5.9.0 /p5.9.20220828.0/
|
@ -0,0 +1,6 @@
|
||||
build:
|
||||
g++ ./slider.cpp -std=c++11 -o slider -lsfml-graphics -lsfml-window -lsfml-system
|
||||
build_debug:
|
||||
g++ ./slider.cpp -std=c++11 -o slider -lsfml-graphics -lsfml-window -lsfml-system -D_DEBUG
|
||||
build_circle:
|
||||
g++ ./circle.cpp -std=c++11 -o circle -lsfml-graphics -lsfml-window -lsfml-system
|
@ -0,0 +1,57 @@
|
||||
#include <iostream>
|
||||
#include <SFML/Window.hpp>
|
||||
#include <SFML/Graphics.hpp>
|
||||
#include "slider.hpp"
|
||||
|
||||
int main()
|
||||
{
|
||||
int result;
|
||||
unsigned char r, g, b;
|
||||
|
||||
sf::RenderWindow window(sf::VideoMode(800, 600), "Slider");
|
||||
window.setFramerateLimit(60);
|
||||
|
||||
sf::Font font;
|
||||
if (!font.loadFromFile("consolas.ttf")) {
|
||||
std::cout << "Can't load button font" << std::endl;
|
||||
}
|
||||
|
||||
Slider slider(window, font, sf::Vector2f{200, 100}, 10, 250);
|
||||
|
||||
Slider slider_r(window, font, sf::Vector2f{800, 200}, 0, 255);
|
||||
Slider slider_g(window, font, sf::Vector2f{800, 300}, 0, 255);
|
||||
Slider slider_b(window, font, sf::Vector2f{800, 400}, 0, 255);
|
||||
|
||||
sf::CircleShape circle(10);
|
||||
circle.setPosition(sf::Vector2f{400, 400});
|
||||
|
||||
while (window.isOpen()) {
|
||||
sf::Event event;
|
||||
while (window.pollEvent(event)) {
|
||||
if (event.type == sf::Event::Closed) {
|
||||
window.close();
|
||||
}
|
||||
|
||||
result = slider.handleEvent(event);
|
||||
|
||||
/* Centering of the circle */
|
||||
circle.setPosition(circle.getPosition() + sf::Vector2f{circle.getRadius() - result, circle.getRadius() - result});
|
||||
circle.setRadius(result);
|
||||
|
||||
r = slider_r.handleEvent(event);
|
||||
g = slider_g.handleEvent(event);
|
||||
b = slider_b.handleEvent(event);
|
||||
circle.setFillColor(sf::Color{r, g, b});
|
||||
}
|
||||
window.clear(sf::Color::Black);
|
||||
|
||||
slider.draw();
|
||||
slider_r.draw();
|
||||
slider_g.draw();
|
||||
slider_b.draw();
|
||||
|
||||
window.draw(circle);
|
||||
window.display();
|
||||
}
|
||||
return 0;
|
||||
}
|
Binary file not shown.
@ -0,0 +1,36 @@
|
||||
#include <iostream>
|
||||
#include <SFML/Window.hpp>
|
||||
#include <SFML/Graphics.hpp>
|
||||
#include "slider.hpp"
|
||||
|
||||
int main()
|
||||
{
|
||||
int result;
|
||||
|
||||
sf::RenderWindow window(sf::VideoMode(800, 600), "Slider");
|
||||
window.setFramerateLimit(60);
|
||||
|
||||
sf::Font font;
|
||||
if (!font.loadFromFile("consolas.ttf")) {
|
||||
std::cout << "Can't load button font" << std::endl;
|
||||
}
|
||||
|
||||
Slider slider(window, font);
|
||||
|
||||
while (window.isOpen()) {
|
||||
sf::Event event;
|
||||
while (window.pollEvent(event)) {
|
||||
if (event.type == sf::Event::Closed) {
|
||||
window.close();
|
||||
}
|
||||
|
||||
result = slider.handleEvent(event);
|
||||
std::cout << result << std::endl;
|
||||
}
|
||||
window.clear(sf::Color::Black);
|
||||
|
||||
slider.draw();
|
||||
window.display();
|
||||
}
|
||||
return 0;
|
||||
}
|
@ -0,0 +1,113 @@
|
||||
#pragma once
|
||||
#include <SFML/Window.hpp>
|
||||
#include <SFML/Graphics.hpp>
|
||||
#include <sstream>
|
||||
|
||||
class Slider
|
||||
{
|
||||
private:
|
||||
const int kCharacterSize = 14;
|
||||
|
||||
int mMinValue;
|
||||
int mMaxValue;
|
||||
float mSliderPosition = 0;
|
||||
|
||||
sf::RenderWindow& mRenderWindow;
|
||||
sf::RectangleShape mSlider;
|
||||
sf::RectangleShape mAxis;
|
||||
sf::Text mText;
|
||||
|
||||
bool mIsPressed = false;
|
||||
|
||||
void onMousePressed(const sf::Event& event)
|
||||
{
|
||||
if (event.mouseButton.button == sf::Mouse::Left) {
|
||||
sf::Vector2f mousePosition = mRenderWindow.mapPixelToCoords({event.mouseButton.x, event.mouseButton.y});
|
||||
if (mSlider.getGlobalBounds().contains(mousePosition))
|
||||
mIsPressed = true;
|
||||
else if (mAxis.getGlobalBounds().contains(mousePosition))
|
||||
{
|
||||
mIsPressed = true;
|
||||
if (mousePosition.x + mSlider.getSize().x <= mAxis.getPosition().x + mAxis.getSize().x) {
|
||||
mSlider.setPosition({mousePosition.x, mSlider.getPosition().y});
|
||||
mSliderPosition = (mSlider.getPosition().x - mAxis.getPosition().x) / (mAxis.getSize().x - mSlider.getSize().x);
|
||||
}
|
||||
else {
|
||||
mSlider.setPosition({mAxis.getPosition().x + mAxis.getSize().x - mSlider.getSize().x, mSlider.getPosition().y});
|
||||
mSliderPosition = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void onMouseMove(const sf::Event& event)
|
||||
{
|
||||
if (!mIsPressed) {
|
||||
return;
|
||||
}
|
||||
sf::Vector2f mousePosition = mRenderWindow.mapPixelToCoords({event.mouseMove.x, event.mouseMove.y});
|
||||
if ((mousePosition.x >= mAxis.getPosition().x) && (mousePosition.x + mSlider.getSize().x <= mAxis.getPosition().x + mAxis.getSize().x)) {
|
||||
mSlider.setPosition({mousePosition.x, mSlider.getPosition().y});
|
||||
}
|
||||
else if (mousePosition.x < mAxis.getPosition().x) {
|
||||
mSlider.setPosition({mAxis.getPosition().x, mSlider.getPosition().y});
|
||||
}
|
||||
else if (mousePosition.x + mSlider.getSize().x > mAxis.getPosition().x + mAxis.getSize().x) {
|
||||
mSlider.setPosition({mAxis.getPosition().x + mAxis.getSize().x - mSlider.getSize().x, mSlider.getPosition().y});
|
||||
}
|
||||
|
||||
mSliderPosition = (mSlider.getPosition().x - mAxis.getPosition().x) / (mAxis.getSize().x - mSlider.getSize().x);
|
||||
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
Slider(sf::RenderWindow& window, const sf::Font& font, sf::Vector2f position = {100,200},int min = 0, int max = 100) : mRenderWindow(window)
|
||||
{
|
||||
mSlider.setFillColor(sf::Color::Red);
|
||||
mSlider.setSize({10,30});
|
||||
mSlider.setPosition(position - sf::Vector2f{0, 10});
|
||||
mSlider.setOutlineColor(sf::Color::Black);
|
||||
mSlider.setOutlineThickness(2);
|
||||
|
||||
mAxis.setFillColor(sf::Color::White);
|
||||
mAxis.setSize({500,10});
|
||||
mAxis.setPosition(position);
|
||||
|
||||
std::stringstream ss;
|
||||
ss << mMinValue;
|
||||
mText.setString(ss.str());
|
||||
mText.setFont(font);
|
||||
mText.setCharacterSize(kCharacterSize);
|
||||
mText.setFillColor(sf::Color::White);
|
||||
mText.setPosition(position + sf::Vector2f{mAxis.getSize().x + 10, -4});
|
||||
|
||||
mMinValue = min;
|
||||
mMaxValue = max;
|
||||
mIsPressed = false;
|
||||
}
|
||||
|
||||
void draw()
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << mMinValue + (mMaxValue - mMinValue) * mSliderPosition;
|
||||
mText.setString(ss.str());
|
||||
|
||||
mRenderWindow.draw(mAxis);
|
||||
mRenderWindow.draw(mSlider);
|
||||
mRenderWindow.draw(mText);
|
||||
}
|
||||
|
||||
int handleEvent(const sf::Event& event) {
|
||||
if (event.type == sf::Event::MouseMoved) {
|
||||
onMouseMove(event);
|
||||
}
|
||||
else if (event.type == sf::Event::MouseButtonPressed) {
|
||||
onMousePressed(event);
|
||||
}
|
||||
else if (event.type == sf::Event::MouseButtonReleased) {
|
||||
mIsPressed = false;
|
||||
}
|
||||
return mMinValue + (mMaxValue - mMinValue) * mSliderPosition;
|
||||
}
|
||||
};
|
@ -0,0 +1,11 @@
|
||||
!_TAG_FILE_FORMAT 2 /extended format; --format=1 will not append ;" to lines/
|
||||
!_TAG_FILE_SORTED 1 /0=unsorted, 1=sorted, 2=foldcase/
|
||||
!_TAG_OUTPUT_EXCMD mixed /number, pattern, mixed, or combineV2/
|
||||
!_TAG_OUTPUT_FILESEP slash /slash or backslash/
|
||||
!_TAG_OUTPUT_MODE u-ctags /u-ctags or e-ctags/
|
||||
!_TAG_PATTERN_LENGTH_LIMIT 96 /0 for no limit/
|
||||
!_TAG_PROC_CWD /home/nihonium/projects/mipt_cpp/seminar11_events/02_slider/ //
|
||||
!_TAG_PROGRAM_AUTHOR Universal Ctags Team //
|
||||
!_TAG_PROGRAM_NAME Universal Ctags /Derived from Exuberant Ctags/
|
||||
!_TAG_PROGRAM_URL https://ctags.io/ /official site/
|
||||
!_TAG_PROGRAM_VERSION 5.9.0 /p5.9.20220828.0/
|
Binary file not shown.
@ -0,0 +1,3 @@
|
||||
path = ../../../../3rdparty/SFML-2.5.1
|
||||
arkanoid:
|
||||
g++ -Wall -Wextra arkanoid.cpp bonus.cpp main.cpp ball.cpp brick_grid.cpp paddle.cpp -std=c++17 -o arkanoid -lsfml-graphics -lsfml-window -lsfml-system
|
Binary file not shown.
@ -0,0 +1,258 @@
|
||||
#include <SFML/Window.hpp>
|
||||
#include <SFML/Graphics.hpp>
|
||||
#include <list>
|
||||
#include <cmath>
|
||||
#include <iostream>
|
||||
|
||||
#include "arkanoid.hpp"
|
||||
#include "bonus.hpp"
|
||||
|
||||
const double pi = 3.14159265358979323846;
|
||||
|
||||
void Arkanoid::addRandomBonus(sf::Vector2f position)
|
||||
{
|
||||
if (m_bonuses.size() > kMaxNumBonuses)
|
||||
return;
|
||||
int max_rand = 10000;
|
||||
if ((rand() % max_rand) * 1.0f / max_rand < m_bonusProbability)
|
||||
{
|
||||
int max = 4; int min = 1;
|
||||
int range = max - min + 1;
|
||||
int num = rand() % range + min;
|
||||
switch (num) {
|
||||
case 1:
|
||||
m_bonuses.push_back(new TripleBallBonus(position));
|
||||
break;
|
||||
case 2:
|
||||
m_bonuses.push_back(new EnlargePaddleBonus(position));
|
||||
break;
|
||||
case 3:
|
||||
m_bonuses.push_back(new ShrinkPaddleBonus(position));
|
||||
break;
|
||||
case 4:
|
||||
m_bonuses.push_back(new SlowingBonus(position));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Функция, которая обрабатывает все столкновения шарика
|
||||
void Arkanoid::handleBallCollisions(Ball& ball)
|
||||
{
|
||||
ball.handleWallsCollision(m_border);
|
||||
ball.handlePaddleCollision(m_paddle);
|
||||
|
||||
auto indexes = ball.handleBrickGridCollision(m_brickGrid);
|
||||
if (indexes.first == -1)
|
||||
return;
|
||||
m_brickGrid.deactivateBrick(indexes);
|
||||
addRandomBonus(ball.position);
|
||||
}
|
||||
|
||||
|
||||
Arkanoid::Arkanoid(sf::FloatRect border, sf::Font& font) :
|
||||
m_time{0.0},
|
||||
m_border{border},
|
||||
m_paddle{{m_border.left + m_border.width / 2, m_border.top + m_border.height - 100}, {120, 20}},
|
||||
m_gameState{GameState::stuck},
|
||||
m_numLives{7}
|
||||
{
|
||||
float gap = border.width / 10;
|
||||
m_brickGrid = BrickGrid({border.left + gap, border.top + gap, border.width - 2 * gap, border.height / 2}, 50, 30);
|
||||
m_bonusProbability = 0.1;
|
||||
|
||||
m_endText.setFont(font);
|
||||
m_endText.setString("You Win!");
|
||||
m_endText.setCharacterSize(100);
|
||||
m_endText.setFillColor(sf::Color::White);
|
||||
sf::FloatRect textRect = m_endText.getLocalBounds();
|
||||
m_endText.setOrigin(textRect.left + textRect.width / 2.0f, textRect.top + textRect.height / 2.0f);
|
||||
m_endText.setPosition({border.left + border.width / 2, border.top + border.height / 2});
|
||||
}
|
||||
|
||||
sf::FloatRect Arkanoid::getBorder() const
|
||||
{
|
||||
return m_border;
|
||||
}
|
||||
|
||||
const Paddle& Arkanoid::getPaddle() const
|
||||
{
|
||||
return m_paddle;
|
||||
}
|
||||
|
||||
const BrickGrid& Arkanoid::getBrickGrid() const
|
||||
{
|
||||
return m_brickGrid;
|
||||
}
|
||||
|
||||
void Arkanoid::addBall(const Ball& ball)
|
||||
{
|
||||
if (m_balls.size() < kMaxNumBalls)
|
||||
m_balls.push_back(ball);
|
||||
}
|
||||
|
||||
bool Arkanoid::isMaxBalls()
|
||||
{
|
||||
return m_balls.size() == kMaxNumBalls - 1;
|
||||
}
|
||||
|
||||
// Эта функция вызывается каждый кадр
|
||||
void Arkanoid::update(const sf::RenderWindow& window, float dt)
|
||||
{
|
||||
m_time += dt;
|
||||
|
||||
// Устанавливаем положение ракетки
|
||||
sf::Vector2f mousePosition = window.mapPixelToCoords(sf::Mouse::getPosition(window));
|
||||
m_paddle.position.x = mousePosition.x;
|
||||
|
||||
// Обрабатываем шарики
|
||||
for (std::list<Ball>::iterator it = m_balls.begin(); it != m_balls.end();)
|
||||
{
|
||||
(*it).update(dt);
|
||||
handleBallCollisions(*it);
|
||||
if ((*it).position.y > m_border.top + m_border.height)
|
||||
{
|
||||
it = m_balls.erase(it);
|
||||
}
|
||||
else
|
||||
{
|
||||
it++;
|
||||
}
|
||||
}
|
||||
|
||||
// Если шариков нет, то переходи в режим начала игры и уменьшаем кол-во жизней
|
||||
if (m_gameState == GameState::running && m_balls.size() == 0)
|
||||
{
|
||||
m_effects.clear();
|
||||
m_gameState = GameState::stuck;
|
||||
m_numLives--;
|
||||
}
|
||||
|
||||
// Если жизни кончились, то переходим в состояние конца игры (проигрыш)
|
||||
if (m_numLives < 0)
|
||||
{
|
||||
m_gameState = GameState::endLose;
|
||||
}
|
||||
|
||||
// Если блоки кончились, то переходим в состояние конца игры (победа)
|
||||
if (m_brickGrid.getNumActiveBricks() == 0)
|
||||
{
|
||||
m_gameState = GameState::endWin;
|
||||
}
|
||||
|
||||
// Обрабатываем бонусы
|
||||
for (auto it = m_bonuses.begin(); it != m_bonuses.end();)
|
||||
{
|
||||
(*it)->update(dt);
|
||||
if ((*it)->isColiding(m_paddle))
|
||||
{
|
||||
(*it)->activate(*this);
|
||||
delete *it;
|
||||
it = m_bonuses.erase(it);
|
||||
}
|
||||
else if ((*it)->m_position.y > m_border.top + m_border.height)
|
||||
{
|
||||
delete (*it);
|
||||
it = m_bonuses.erase(it);
|
||||
}
|
||||
else
|
||||
{
|
||||
it++;
|
||||
}
|
||||
|
||||
}
|
||||
/* Обработка эффектов */
|
||||
for (auto it = m_effects.begin(); it != m_effects.end();)
|
||||
{
|
||||
if ((*it)->isExpired(m_time))
|
||||
{
|
||||
(*it)->deactivate(*this);
|
||||
delete *it;
|
||||
it = m_effects.erase(it);
|
||||
}
|
||||
else {
|
||||
it++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Arkanoid::draw(sf::RenderWindow& window)
|
||||
{
|
||||
// Рисуем задний прямоугольник
|
||||
static sf::RectangleShape background {{m_border.width, m_border.height}};
|
||||
background.setPosition({m_border.left, m_border.top});
|
||||
background.setFillColor(kBackgroundColor);
|
||||
window.draw(background);
|
||||
|
||||
// Рисуем блоки
|
||||
m_brickGrid.draw(window);
|
||||
|
||||
// Рисуем шарики
|
||||
for (Ball& ball : m_balls)
|
||||
{
|
||||
ball.draw(window);
|
||||
}
|
||||
|
||||
// Рисуем ракетку
|
||||
m_paddle.draw(window);
|
||||
|
||||
// Если мы в режиме начала игры, то рисуем шарик на ракетке
|
||||
if (m_gameState == GameState::stuck)
|
||||
{
|
||||
m_initialBall.position = {m_paddle.position.x, m_paddle.position.y - m_paddle.size.y / 2 - m_initialBall.radius};
|
||||
m_initialBall.position = {m_paddle.position.x, m_paddle.position.y - m_paddle.size.y / 2 - m_initialBall.radius};
|
||||
m_initialBall.draw(window);
|
||||
}
|
||||
|
||||
// Рисуем кол-во жизней вверху слева
|
||||
for (int i = 0; i < m_numLives; i++)
|
||||
{
|
||||
m_initialBall.position = {m_initialBall.radius * (3 * i + 2), 2 * m_initialBall.radius};
|
||||
m_initialBall.draw(window);
|
||||
}
|
||||
|
||||
// Рисуем бонусы
|
||||
for (Bonus* pbonus : m_bonuses)
|
||||
{
|
||||
pbonus->draw(window);
|
||||
}
|
||||
|
||||
// При завершении игры рисуем надпись
|
||||
if (m_gameState == GameState::endWin)
|
||||
{
|
||||
m_endText.setString("You Win!");
|
||||
window.draw(m_endText);
|
||||
}
|
||||
|
||||
// При завершении игры рисуем надпись
|
||||
if (m_gameState == GameState::endLose)
|
||||
{
|
||||
m_endText.setString("You Lose!");
|
||||
window.draw(m_endText);
|
||||
}
|
||||
}
|
||||
|
||||
void Arkanoid::onMousePressed(sf::Event& event)
|
||||
{
|
||||
switch (m_gameState)
|
||||
{
|
||||
case GameState::stuck:
|
||||
if (event.mouseButton.button == sf::Mouse::Left)
|
||||
{
|
||||
m_gameState = GameState::running;
|
||||
float velocityAngle = (rand() % 100 + 40) * pi / 180;
|
||||
float velocityNorm = Ball::initialVelocity;
|
||||
sf::Vector2f newPosition = {m_paddle.position.x, m_paddle.position.y - m_paddle.size.y / 2.0f - m_initialBall.radius};
|
||||
sf::Vector2f newVelocity = {-velocityNorm * cosf(velocityAngle), -velocityNorm * sinf(velocityAngle)};
|
||||
addBall({m_initialBall.radius, newPosition, newVelocity});
|
||||
}
|
||||
break;
|
||||
|
||||
case GameState::running:
|
||||
break;
|
||||
case GameState::endLose:
|
||||
break;
|
||||
case GameState::endWin:
|
||||
break;
|
||||
}
|
||||
}
|
@ -0,0 +1,31 @@
|
||||
#pragma once
|
||||
#include <SFML/Window.hpp>
|
||||
#include <SFML/Graphics.hpp>
|
||||
|
||||
class BrickGrid;
|
||||
class Paddle;
|
||||
|
||||
struct Ball
|
||||
{
|
||||
inline static const float initialVelocity = 700;
|
||||
inline static const sf::Color color {246, 213, 92};
|
||||
float radius;
|
||||
sf::Vector2f position;
|
||||
sf::Vector2f velocity;
|
||||
|
||||
Ball(float radius, sf::Vector2f position, sf::Vector2f velocity);
|
||||
|
||||
void update(float dt);
|
||||
|
||||
void draw(sf::RenderWindow& window);
|
||||
|
||||
std::pair<sf::Vector2f, bool> findClosestPoint(const sf::FloatRect& rect) const;
|
||||
|
||||
bool handleRectCollision(const sf::FloatRect& rect);
|
||||
|
||||
void handleWallsCollision(sf::FloatRect boundary);
|
||||
|
||||
std::pair<int, int> handleBrickGridCollision(const BrickGrid& brickGrid);
|
||||
|
||||
void handlePaddleCollision(const Paddle& paddle);
|
||||
};
|
@ -0,0 +1,221 @@
|
||||
#include <cmath>
|
||||
#include <iostream>
|
||||
|
||||
#include "bonus.hpp"
|
||||
#include "arkanoid.hpp"
|
||||
#include "ball.hpp"
|
||||
#include "paddle.hpp"
|
||||
|
||||
/* =============
|
||||
* ===Bonuses===
|
||||
* =============
|
||||
* */
|
||||
|
||||
Bonus::Bonus(sf::Vector2f position): m_position(position)
|
||||
{
|
||||
m_time = 0;
|
||||
}
|
||||
|
||||
void Bonus::update(float dt)
|
||||
{
|
||||
m_time += dt;
|
||||
m_position.y += speed * dt;
|
||||
}
|
||||
|
||||
bool Bonus::isColiding(const Paddle& paddle) const
|
||||
{
|
||||
bool result = paddle.getBorder().intersects({m_position.x - radius, m_position.y - radius, 2 * radius, 2 * radius});
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* TripleBallBonus
|
||||
* */
|
||||
void TripleBallBonus::draw(sf::RenderWindow& window) const
|
||||
{
|
||||
static sf::CircleShape shape(radius);
|
||||
shape.setOrigin(radius, radius);
|
||||
shape.setFillColor(sf::Color{100, 200, 100});
|
||||
shape.setPosition(m_position);
|
||||
window.draw(shape);
|
||||
|
||||
float angle = 0;
|
||||
|
||||
static Ball ball {5, {0, 0}, {0, 0}};
|
||||
float ballRotationRadius = 7;
|
||||
ball.position = m_position + ballRotationRadius * sf::Vector2f(std::cos(angle), std::sin(angle));
|
||||
ball.draw(window);
|
||||
angle += 2.0 * M_PI / 3.0;
|
||||
ball.position = m_position + ballRotationRadius * sf::Vector2f(std::cos(angle), std::sin(angle));
|
||||
ball.draw(window);
|
||||
angle += 2.0 * M_PI / 3.0;
|
||||
ball.position = m_position + ballRotationRadius * sf::Vector2f(std::cos(angle), std::sin(angle));
|
||||
ball.draw(window);
|
||||
}
|
||||
|
||||
void TripleBallBonus::activate(Arkanoid& game)
|
||||
{
|
||||
int numBalls = game.m_balls.size();
|
||||
std::list<Ball>::iterator it = game.m_balls.begin();
|
||||
|
||||
bool isSlowed = false;
|
||||
bool toApply = true;
|
||||
|
||||
Effect* slowing_effect = nullptr;
|
||||
for (auto it = game.m_effects.begin(); it != game.m_effects.end();) {
|
||||
if ((*it)->effectId == _EFFECT_SLOWING_ID) {
|
||||
isSlowed = true;
|
||||
slowing_effect = *it;
|
||||
break;
|
||||
}
|
||||
it++;
|
||||
}
|
||||
for (int i = 0; i < numBalls; i++)
|
||||
{
|
||||
float angle, vx, vy;
|
||||
if (game.isMaxBalls()) {
|
||||
toApply = false;
|
||||
}
|
||||
|
||||
if (toApply) {
|
||||
angle = rand() % 1000 * (2 * M_PI / 1000);
|
||||
vx = Ball::initialVelocity * sin(angle);
|
||||
vy = Ball::initialVelocity * cos(angle);
|
||||
game.addBall({game.m_initialBall.radius, (*it).position, {vx, vy}});
|
||||
|
||||
if (isSlowed) {
|
||||
slowing_effect->activate(game.m_balls.back());
|
||||
}
|
||||
}
|
||||
|
||||
if (game.isMaxBalls()) {
|
||||
toApply = false;
|
||||
}
|
||||
|
||||
if (toApply) {
|
||||
angle = rand() % 1000 * (2 * M_PI / 1000);
|
||||
vx = Ball::initialVelocity * sin(angle);
|
||||
vy = Ball::initialVelocity * cos(angle);
|
||||
game.addBall({game.m_initialBall.radius, (*it).position, {vx, vy}});
|
||||
if (isSlowed) {
|
||||
slowing_effect->activate(game.m_balls.back());
|
||||
}
|
||||
}
|
||||
|
||||
it++;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* EnlargePaddleBonus
|
||||
* */
|
||||
void EnlargePaddleBonus::draw(sf::RenderWindow& window) const
|
||||
{
|
||||
static sf::CircleShape shape(radius);
|
||||
shape.setOrigin(radius, radius);
|
||||
shape.setFillColor(sf::Color{100, 200, 100});
|
||||
shape.setPosition(m_position);
|
||||
window.draw(shape);
|
||||
|
||||
static sf::RectangleShape rect(sf::Vector2f{radius, radius / 2});
|
||||
rect.setFillColor(sf::Color::Green);
|
||||
rect.setPosition(m_position - sf::Vector2f{radius /2, radius / 4});
|
||||
window.draw(rect);
|
||||
}
|
||||
|
||||
void EnlargePaddleBonus::activate(Arkanoid& game)
|
||||
{
|
||||
if (game.m_paddle.size.x < 300) {
|
||||
game.m_paddle.size.x *= 1.5;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* ShrinkPaddleBonus
|
||||
* */
|
||||
void ShrinkPaddleBonus::draw(sf::RenderWindow& window) const
|
||||
{
|
||||
static sf::CircleShape shape(radius);
|
||||
shape.setOrigin(radius, radius);
|
||||
shape.setFillColor(sf::Color{100, 200, 100});
|
||||
shape.setPosition(m_position);
|
||||
window.draw(shape);
|
||||
|
||||
static sf::RectangleShape rect(sf::Vector2f{radius, radius / 2});
|
||||
rect.setFillColor(sf::Color::Red);
|
||||
rect.setPosition(m_position - sf::Vector2f{radius /2, radius / 4});
|
||||
window.draw(rect);
|
||||
}
|
||||
void ShrinkPaddleBonus::activate(Arkanoid& game)
|
||||
{
|
||||
if (game.m_paddle.size.x > 40) {
|
||||
game.m_paddle.size.x *= 0.8;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* SlowingBonus
|
||||
* */
|
||||
|
||||
void SlowingBonus::draw(sf::RenderWindow& window) const
|
||||
{
|
||||
static sf::CircleShape shape(radius);
|
||||
shape.setOrigin(radius, radius);
|
||||
shape.setFillColor(sf::Color{100, 200, 100});
|
||||
shape.setPosition(m_position);
|
||||
window.draw(shape);
|
||||
|
||||
static sf::CircleShape clock(radius / 2);
|
||||
clock.setOutlineColor(sf::Color::Red);
|
||||
clock.setOutlineThickness(3);
|
||||
clock.setPosition(m_position - sf::Vector2f{radius /2, radius / 2});
|
||||
window.draw(clock);
|
||||
}
|
||||
|
||||
void SlowingBonus::activate(Arkanoid& game)
|
||||
{
|
||||
bool isAlreadySlowed = false;
|
||||
for (auto it = game.m_effects.begin(); it != game.m_effects.end();) {
|
||||
if ((*it)->effectId == _EFFECT_SLOWING_ID) {
|
||||
(*it)->mDuration += mDuration;
|
||||
isAlreadySlowed = true;
|
||||
break;
|
||||
}
|
||||
it++;
|
||||
}
|
||||
if (!isAlreadySlowed) {
|
||||
game.m_effects.push_back(new SlowingEffect(game.m_time, mDuration));
|
||||
game.m_effects.back()->activate(game);
|
||||
}
|
||||
}
|
||||
|
||||
/* =============
|
||||
* ===Effects===
|
||||
* =============
|
||||
* */
|
||||
|
||||
Effect::Effect(char id, double start_time, double duration) : effectId(id), mStartTime(start_time), mDuration(duration) {};
|
||||
|
||||
bool Effect::isExpired(double time) {
|
||||
if (mStartTime + mDuration > time)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
SlowingEffect::SlowingEffect(double start_time, double duration) : Effect(_EFFECT_SLOWING_ID, start_time, duration) {};
|
||||
|
||||
void SlowingEffect::activate(Arkanoid& game) {
|
||||
for (Ball& ball : game.m_balls) {
|
||||
ball.velocity = sf::Vector2f{ball.velocity.x * mSlowingFactor, ball.velocity.y * mSlowingFactor};
|
||||
}
|
||||
}
|
||||
void SlowingEffect::activate(Ball& ball) {
|
||||
ball.velocity = sf::Vector2f{ball.velocity.x * mSlowingFactor, ball.velocity.y * mSlowingFactor};
|
||||
}
|
||||
|
||||
void SlowingEffect::deactivate(Arkanoid& game) {
|
||||
for (Ball& ball : game.m_balls) {
|
||||
ball.velocity = sf::Vector2f{ball.velocity.x / mSlowingFactor, ball.velocity.y / mSlowingFactor};
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,92 @@
|
||||
#pragma once
|
||||
#include <SFML/Window.hpp>
|
||||
#include <SFML/Graphics.hpp>
|
||||
class Paddle;
|
||||
class Ball;
|
||||
class Arkanoid;
|
||||
|
||||
class Bonus
|
||||
{
|
||||
protected:
|
||||
inline static const float speed = 120;
|
||||
inline static const float radius = 15;
|
||||
|
||||
sf::Vector2f m_position;
|
||||
float m_time;
|
||||
|
||||
public:
|
||||
Bonus(sf::Vector2f position);
|
||||
void update(float dt);
|
||||
virtual void draw(sf::RenderWindow& window) const = 0;
|
||||
virtual void activate(Arkanoid& game) = 0;
|
||||
virtual ~Bonus() = default;
|
||||
|
||||
bool isColiding(const Paddle& paddle) const;
|
||||
// Класс Arkanoid должен быть дружественным, так как он может менять внутреннее объекта-бонуса
|
||||
friend class Arkanoid;
|
||||
};
|
||||
|
||||
class TripleBallBonus : public Bonus {
|
||||
public:
|
||||
TripleBallBonus(sf::Vector2f position): Bonus(position) {};
|
||||
void draw(sf::RenderWindow& window) const;
|
||||
void activate(Arkanoid& game);
|
||||
};
|
||||
|
||||
class EnlargePaddleBonus : public Bonus {
|
||||
public:
|
||||
EnlargePaddleBonus(sf::Vector2f position): Bonus(position) {};
|
||||
void draw(sf::RenderWindow& window) const;
|
||||
void activate(Arkanoid& game);
|
||||
};
|
||||
|
||||
class ShrinkPaddleBonus : public Bonus {
|
||||
public:
|
||||
ShrinkPaddleBonus(sf::Vector2f position): Bonus(position) {};
|
||||
void draw(sf::RenderWindow& window) const;
|
||||
void activate(Arkanoid& game);
|
||||
};
|
||||
|
||||
class SlowingBonus : public Bonus {
|
||||
private:
|
||||
double mDuration = 10;
|
||||
public:
|
||||
SlowingBonus(sf::Vector2f position): Bonus(position) {};
|
||||
void draw(sf::RenderWindow& window) const;
|
||||
void activate(Arkanoid& game);
|
||||
};
|
||||
|
||||
/*
|
||||
* Effects
|
||||
* */
|
||||
#define _EFFECT_SLOWING_ID 0
|
||||
class Effect {
|
||||
protected:
|
||||
char effectId;
|
||||
double mStartTime;
|
||||
double mDuration;
|
||||
public:
|
||||
Effect(char id, double start_time, double duration);
|
||||
virtual ~Effect() = default;
|
||||
|
||||
virtual void activate(Arkanoid& game) = 0;
|
||||
virtual void activate(Ball& ball) = 0;
|
||||
virtual void deactivate(Arkanoid& game) = 0;
|
||||
bool isExpired(double time);
|
||||
|
||||
|
||||
friend class SlowingBonus;
|
||||
friend class TripleBallBonus;
|
||||
friend class Arkanoid;
|
||||
};
|
||||
|
||||
class SlowingEffect : public Effect {
|
||||
private:
|
||||
float mSlowingFactor = 0.1;
|
||||
char id = _EFFECT_SLOWING_ID;
|
||||
public:
|
||||
SlowingEffect(double start_time, double duration);
|
||||
void activate(Arkanoid& game);
|
||||
void activate(Ball& ball);
|
||||
void deactivate(Arkanoid& game);
|
||||
};
|
@ -0,0 +1,5 @@
|
||||
#pragma once
|
||||
struct Brick
|
||||
{
|
||||
bool isActive;
|
||||
};
|
@ -0,0 +1,63 @@
|
||||
#include <vector>
|
||||
#include "brick_grid.hpp"
|
||||
|
||||
BrickGrid::BrickGrid() {}
|
||||
BrickGrid::BrickGrid(sf::FloatRect borders, int numBrickColumns, int numBrickRows) :
|
||||
m_border(borders),
|
||||
m_numBrickColumns(numBrickColumns),
|
||||
m_numBrickRows(numBrickRows),
|
||||
m_numActiveBricks(numBrickColumns * numBrickRows)
|
||||
{
|
||||
m_bricks.resize(m_numBrickColumns * m_numBrickRows, Brick{true});
|
||||
m_brickShape.setSize(getBrickSizes());
|
||||
m_brickShape.setOutlineColor(sf::Color::Black);
|
||||
m_brickShape.setOutlineThickness(0.5);
|
||||
m_brickShape.setFillColor(color);
|
||||
}
|
||||
|
||||
sf::FloatRect BrickGrid::getBorder() const
|
||||
{
|
||||
return m_border;
|
||||
}
|
||||
|
||||
sf::Vector2i BrickGrid::getGridSizes() const
|
||||
{
|
||||
return {m_numBrickColumns, m_numBrickRows};
|
||||
}
|
||||
|
||||
sf::Vector2f BrickGrid::getBrickSizes() const
|
||||
{
|
||||
return {m_border.width / m_numBrickColumns, m_border.height / m_numBrickRows};
|
||||
}
|
||||
|
||||
bool BrickGrid::isBrickActive(std::pair<int, int> indexes) const
|
||||
{
|
||||
return m_bricks[indexes.first + indexes.second * m_numBrickColumns].isActive;
|
||||
}
|
||||
|
||||
void BrickGrid::deactivateBrick(std::pair<int, int> indexes)
|
||||
{
|
||||
m_bricks[indexes.first + indexes.second * m_numBrickColumns].isActive = false;
|
||||
m_numActiveBricks--;
|
||||
}
|
||||
|
||||
int BrickGrid::getNumActiveBricks() const
|
||||
{
|
||||
return m_numActiveBricks;
|
||||
}
|
||||
|
||||
void BrickGrid::draw(sf::RenderWindow& window)
|
||||
{
|
||||
auto [brickWidth, brickHeight] = getBrickSizes();
|
||||
|
||||
for (int j = 0; j < m_numBrickRows; ++j)
|
||||
{
|
||||
for (int i = 0; i < m_numBrickColumns; ++i)
|
||||
{
|
||||
if (!isBrickActive({i, j}))
|
||||
continue;
|
||||
m_brickShape.setPosition({m_border.left + i * brickWidth, m_border.top + j * brickHeight});
|
||||
window.draw(m_brickShape);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,37 @@
|
||||
#pragma once
|
||||
#include <SFML/Window.hpp>
|
||||
#include <SFML/Graphics.hpp>
|
||||
#include "brick.hpp"
|
||||
|
||||
class BrickGrid
|
||||
{
|
||||
private:
|
||||
inline static const sf::Color color {100, 200, 250};
|
||||
|
||||
sf::FloatRect m_border;
|
||||
int m_numBrickColumns;
|
||||
int m_numBrickRows;
|
||||
|
||||
std::vector<Brick> m_bricks;
|
||||
sf::RectangleShape m_brickShape;
|
||||
|
||||
int m_numActiveBricks;
|
||||
|
||||
public:
|
||||
BrickGrid();
|
||||
BrickGrid(sf::FloatRect borders, int numBrickColumns, int numBrickRows);
|
||||
|
||||
sf::FloatRect getBorder() const;
|
||||
|
||||
sf::Vector2i getGridSizes() const;
|
||||
|
||||
sf::Vector2f getBrickSizes() const;
|
||||
|
||||
bool isBrickActive(std::pair<int, int> indexes) const;
|
||||
|
||||
void deactivateBrick(std::pair<int, int> indexes);
|
||||
|
||||
int getNumActiveBricks() const;
|
||||
|
||||
void draw(sf::RenderWindow& window);
|
||||
};
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue