added double jump and sitting state

This commit is contained in:
nihonium 2023-02-25 19:34:24 +03:00
parent 2e5c5a8dde
commit 90d07dde3f
Signed by: nihonium
GPG key ID: 0251623741027CFC
148 changed files with 13050 additions and 0 deletions

View file

@ -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;
}

View file

@ -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);
};

View file

@ -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;
}

View file

@ -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;
}

View file

@ -0,0 +1,37 @@
#pragma once
/*
Поля x и y сделаны приватными
Конкретно для этого класса их можно было сделать публичными
Так как пользователь всё-равно будет иметь доступ без ограничений к этим полям через геттеры и сеттеры
Но они сделаны приватными для образовательных целей
*/
class Point
{
private:
float mx, my;
public:
Point(float x, float y);
Point();
float getX() const;
float getY() const;
void setX(float x);
void setY(float y);
void normalize();
float distance(const Point& p) const;
float norm() const;
Point operator+(const Point& right) const;
Point operator*(float a) const;
friend Point operator*(float a, const Point& p);
friend std::ostream& operator<<(std::ostream& left, const Point& right);
};

View file

@ -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"));
}

View file

@ -0,0 +1,343 @@
#include <iostream>
#include <iomanip>
#include <cstring>
#include "number.h"
Number::Number(int a)
{
#ifdef _DEBUG_CONSTRUCTOR
std::cout << "(Number constructor " << a << " -> ";
#endif
// Находим размер необходимой памяти под это число
int temp = a;
capacity = 0;
while (temp != 0) {
temp /= base;
capacity += 1;
}
// Отдельно обрабатываем случай, когда число равно 0
if (capacity == 0)
capacity = 1;
// Выделяем память и записывем число a в массив data
// Например, число 12345678 представится в виде массива [78, 56, 34, 12]
data = new char[capacity];
for (int i = 0; i < capacity; ++i) {
data[i] = a % base;
a /= base;
}
// В данном случае размер будет равен вместимости
size = capacity;
#ifdef _DEBUG_CONSTRUCTOR
std::cout << *this << ")" << std::endl;
#endif
}
// Конструктор по умолчанию
Number::Number():Number(0){}
// Конструктор копирования
Number::Number(const Number & n)
{
size = n.size;
capacity = n.capacity;
data = new char[capacity];
for (int i = 0; i < size; i++) {
data[i] = n.data[i];
}
}
Number::Number(const char *str)
{
int len = std::strlen(str);
size = (len + len % 2) / 2;
capacity = size;
data = new char[capacity];
char buf[2];
for (int i = 0; i < size; i++) {
buf[1] = str[len - 2 * i - 1];
if (len - 2 * i - 1 > 0) {
buf[0] = str[len - 2 * i - 2];
} else {
buf[0] = '0';
}
data[i] = std::stoi(buf);
}
}
Number::~Number()
{
delete[]data;
}
Number & Number::operator=(const Number & right)
{
capacity = right.capacity;
size = right.size;
data = new char[capacity];
for (int i = 0; i < size; i++) {
data[i] = right.data[i];
}
return *this;
}
Number Number::operator+(Number a)
{
#ifdef _DEBUG_ADD
std::cout << "arg1=" << a << "capacity=" << a.
capacity << ",size=" << a.size << std::endl;
std::cout << "arg2=" << *this << "capacity=" << this->
capacity << ",size=" << this->size << std::endl;
#endif
Number result;
Number temp;
int i;
int carry = 0;
if (size < a.size) {
temp = *this;
*this = a;
a = temp;
}
result.capacity = size + 1;
//result.data = new char[capacity];
result.data = (char *) calloc(result.capacity, sizeof(char));
for (i = 0; i < a.size; ++i) {
result.data[i] = (data[i] + a.data[i] + carry) % base;
carry = (data[i] + a.data[i] + carry) / base;
}
for (; i < size; ++i) {
result.data[i] = (data[i] + carry) % base;
carry = (data[i] + carry) / base;
}
if (carry) {
#ifdef _DEBUG_ADD
std::cout << "applied carry" << std::endl;
#endif
result.data[i] = carry;
result.size = size + 1;
} else {
result.size = size;
}
#ifdef _DEBUG_ADD
std::cout << result << " capacity=" << result.
capacity << ",size=" << result.size << std::endl;
#endif
return result;
}
void Number::operator+=(const Number & a)
{
*this = *this + a;
}
bool Number::isEven() const
{
if (data[0] % 2) {
return false;
}
return true;
}
Number Number::operator*(const Number & right) const
{
#ifdef _DEBUG_MUL
std::
cout << "arg1=" << *this << "(capacity=" << capacity << ",size=" <<
size << ")" << " " << "arg2=" << right << "(capacity=" << right.
capacity << ",size=" << right.size << ")" << std::endl;
#endif
if (*this == Number("0") || right == Number("0"))
return Number("0");
int i, j;
int temp;
Number result;
result.capacity = capacity + right.capacity;
int *carry = (int *) std::calloc(result.capacity, sizeof(int));
result.data = (char *) calloc(result.capacity, sizeof(char));
#ifdef _DEBUG_MUL
std::cout << "carry:[" << carry[0];
for (int k = 1; k < result.capacity; ++k) {
std::cout << "," << carry[k];
}
std::cout << "]" << std::endl;
#endif
for (i = 0; i < size; ++i) {
for (j = 0; j < right.size; ++j) {
#ifdef _DEBUG_MUL
std::cout << i + j << ":" << static_cast <
int >(result.data[i + j]) << " + " << static_cast <
int >(data[i]) << " * " << static_cast <
int >(right.data[j]) << " + " << carry[i + j] << std::endl;
#endif
temp =
(result.data[i + j] + data[i] * right.data[j] +
carry[i + j]);
result.data[i + j] = temp % base;
carry[i + j + 1] += temp / base;
carry[i + j] = 0;
}
}
#ifdef _DEBUG_MUL
std::cout << "result before applying carry:" << result << std::endl;
std::cout << "carry:[" << carry[0];
for (int k = 1; k < result.capacity; ++k) {
std::cout << "," << carry[k];
}
std::cout << "]" << std::endl;
#endif
if (carry[i + j - 1]) {
result.data[i + j - 1] = carry[i + j - 1];
result.size = i + j;
} else {
result.size = i + j - 1;
}
#ifdef _DEBUG_MUL
std::cout << "before correcting capacity, result=" << result << std::
endl;
#endif
// correcting capacity
/*char* temp_data = (char *)calloc(result.size, sizeof(char));
for (i = 0; i < result.size; ++i) {
temp_data[i] = result.data[i];
}
free(result.data);
result.capacity = result.size;
result.data = (char*)calloc(result.size,sizeof(char));
for (i = 0; i < result.size; ++i) {
result.data[i] = temp_data[i];
}
free(temp_data); */
free(carry);
#ifdef _DEBUG_MUL
std::cout << "return value=" << result << "(capacity=" << result.
capacity << ",size=" << result.
size << ")" << std::endl << "======" << std::endl;
#endif
return result;
}
void Number::operator*=(const Number & a)
{
*this = *this * a;
}
bool Number::operator==(const Number & a) const
{
if (size != a.size) {
return false;
}
for (int i = 0; i < size; ++i) {
if (data[i] != a.data[i]) {
return false;
}
}
return true;
}
bool Number::operator!=(const Number & a) const
{
return not(*this == a);
}
bool Number::operator>(const Number & a) const
{
#ifdef _DEBUG_COMP
std::
cout << "comp " << *this << "(size=" << size << ") and " << a <<
"(size=" << a.size << ")" << std::endl;
#endif
if (size > a.size) {
#ifdef _DEBUG_COMP
std::cout << "size > a.size => true" << std::endl;
#endif
return true;
}
if (size < a.size) {
#ifdef _DEBUG_COMP
std::cout << "size < a.size => false" << std::endl;
#endif
return false;
}
for (int i = size - 1; i >= 0; --i) {
if (data[i] > a.data[i]) {
return true;
#ifdef _DEBUG_COMP
std::cout << static_cast <
int >(data[i]) << ">" << static_cast <
int >(a.data[i]) << std::endl;
#endif
}
if (data[i] < a.data[i]) {
#ifdef _DEBUG_COMP
std::cout << static_cast <
int >(data[i]) << "<" << static_cast <
int >(a.data[i]) << std::endl;
#endif
return false;
}
}
#ifdef _DEBUG_COMP
std::cout << "using final false" << std::endl;
#endif
return false;
}
bool Number::operator<(const Number & a) const
{
return not(*this > a) and(*this != a);
}
void Number::div2()
{
#ifdef _DEBUG_DIV2
std::cout << "n = " << *this << std::endl;
#endif
int carry = 0;
int temp;
for (int i = size - 1; i >= 0; --i) {
temp = data[i] + carry * base;
data[i] = temp / 2;
carry = temp % 2;
}
if (data[size - 1] == 0) {
--size;
}
#ifdef _DEBUG_DIV2
std::cout << "unstripped result " << *this << std::endl;
#endif
}
std::ostream & operator<<(std::ostream & stream, const Number & right)
{
#ifdef _DEBUG_COUT
stream << "[";
for (std::size_t i = 0; i < right.size; ++i) {
stream << static_cast <
int >(right.data[right.size - 2 - i]) << ",";
}
stream << "]";
#else
// Печатаем самый большой разряд
stream << (int) right.data[right.size - 1];
// Печатаем остальные разряды с заполнением нулями до 2-х цифр
// setfill и setw это то же самое, что и в языке C спецификатор %02d
for (std::size_t i = 0; i < right.size - 1; ++i)
stream << std::setfill('0') << std::setw(2) << (int) right.
data[right.size - 2 - i];
#endif
return stream;
}

View file

@ -0,0 +1,63 @@
#pragma once
/*
Класс Number -- класс положительных больших чисел
Большое число будет храниться в динамическом массиве data
Каждый элемент этого массива содержит разряд числа в 100-ричной системе счисления
(так как base = 100)
По сути, каждый элемент data хранит две цифры числа в десятичной записи
Значение 100 для системы счисления выбрано как компромис между
эффективностью и удобством написания программы.
Если выбрать значения базы 10 - то программа будет не так эффективна по памяти
Если выбрать значения базы 256 (максимально эффективное использование памяти для типа char),
то алгоритм печати на экран сильно усложнится
В качестве альтернативы, можно было выбрать базу 1e9,
изменив при этом тип элементов c char на int
capacity - размер массива data
size - сколько ячеек занимет число в массиве data
size <= capacity
Для удобства разряды числа хранятся в обратном порядке
Например, число 12345678 соответствует массиву
data = {78, 56, 34, 12}
(это упрощает многие алгоритмы с такими числами)
*/
class Number {
private:
static const int base = 100;
std::size_t size;
std::size_t capacity;
char *data;
public:
Number(int a);
Number();
// Конструктор копирования
Number(const Number & n);
Number(const char *str);
~Number();
Number & operator=(const Number & right);
Number operator+(Number a);
void operator+=(const Number & a);
bool isEven() const;
Number operator*(const Number & right) const;
void operator*=(const Number & a);
bool operator==(const Number & a) const;
bool operator!=(const Number & a) const;
bool operator>(const Number & a) const;
bool operator<(const Number & a) const;
void div2();
friend std::ostream & operator<<(std::ostream & stream,
const Number & right);
};
std::ostream & operator<<(std::ostream & stream, const Number & right);