Среда, 04 Декабря 2024, 22:39

Приветствую Вас Гость

[ Новые сообщения · Игроделы · Правила · Поиск ]
Вопрос-Ответ (C++)
KornivalДата: Воскресенье, 04 Сентября 2011, 19:10 | Сообщение # 1
The Witcher
Сейчас нет на сайте
Чтобы не создавать отдельную тему на каждый глупый вопрос, предлагаю задавать их здесь.

Saitei: все вопросы по С задаём в теме Вопрос-Ответ (С). Благодарю за внимание!
VuvkДата: Четверг, 20 Июля 2017, 11:19 | Сообщение # 1521
заслуженный участник
Сейчас нет на сайте
Цитата FlyOfFly ()
в заголовочный файлах F1, есть подключен заголовочный файл F2, в которых подключен заголовочный файл F1, если в этом, то какой вариант - исправление?

попробовать выбросить #pragma once и использовать include guards
Код

#ifndef _F1_H
#define _F1_H
// содержимое хедэра
#endif // _F1_H


Сообщение отредактировал Vuvk - Четверг, 20 Июля 2017, 11:28
puksusДата: Четверг, 20 Июля 2017, 12:03 | Сообщение # 1522
Пчёлка Зоя
Сейчас нет на сайте
FlyOfFly, а зачем вам 2 класса, нельзя ли провернуть так, чтобы класс хранил указатели на элементы своего же класса?

Ну а если по теме - то может помочь <не помню точно как называется> предобъявление класса. То есть в файле GameComponent.h удалите строчку
#include "GameObject.h"
и добавьте вместо неё
class GameObject;
это даст компилятору инфу о том, что класс геймобджект определён в ином месте, при этом взаимное подключение исчезнет. Но не гарантирую, что поможет. Да и потом могут быть проблемы. Я с таким уже сталкивался, когда писал игру на 12 гамирон. Из-за этого дела потом вылезали очень непонятные ошибки в непонятных местах, когда я что-то где-то чуть-чуть менял. Поэтому следующем проекте просто сделал всё так, чтобы не было нужды в подобных вещах.
Ну а ещё, старайтесь в h файлах подключать по-минимуму, а основные подключения делать в cpp файлах.


https://vk.com/beezoya
SaiteiДата: Пятница, 21 Июля 2017, 11:09 | Сообщение # 1523
старожил
Сейчас нет на сайте
Цитата puksus ()
GameComponent.h удалите строчку
#include "GameObject.h"
и добавьте вместо неё
class GameObject;
это даст компилятору инфу о том, что класс геймобджект определён в ином месте,

+

Это называется forward declaration: https://en.wikipedia.org/wiki/Forward_declaration

На место всех include подставляются исходные коды. В твоем же случае получается своего рода рекурсия, компилятор просто не знает что делать. Поэтому действительно надо просто сослаться на класс с таким-то названием, но не подключать его файл описания

P.S. это работает с ссылками и указателями на класс, а вот просто инстансировать объект ты не сможешь:
Код
class Foo;
...
Foo a; //wrong! Error!
FlyOfFlyДата: Суббота, 22 Июля 2017, 14:41 | Сообщение # 1524
заслуженный участник
Сейчас нет на сайте
Есть массив с указателями на функциями и двухмерный массив, который хранит аргументы(то-есть на каждую функцию - своя строка массива). Я не знаю какие функции храниться и сколько аргументов в массиве, можно ли как-то вызвать функцию такую?По логике, это должно делаться через asm, то-есть отправляем аргументы через push и потом вызываем функции через call, насколько я знаю в vs можно вызвать asm код, вопрос: как передать аргументы и вызвать функцию через asm-вставки

Добавлено (22 июля 2017, 14:41)
---------------------------------------------
Так, как отправить аргументы - разобрался, другой вопрос: как через asm вызвать функцию объекта

Сообщение отредактировал FlyOfFly - Суббота, 22 Июля 2017, 14:29
Dmitriy_ZodiakДата: Воскресенье, 03 Сентября 2017, 01:05 | Сообщение # 1525
частый гость
Сейчас нет на сайте
zodiak, вот зараза. Я думал такого ника нет.

В ютубе и многих сайтах криво и не информативно рассказанно . Скиньте хороших мануалов плз.
bodya_WMДата: Воскресенье, 03 Сентября 2017, 08:28 | Сообщение # 1526
постоянный участник
Сейчас нет на сайте
FlyOfFly, в методах класса используется конвенция вызовов __thiscall.
Тебе нужно получить указатель на функцию в классе(например вот так):
Код

class Foo {
  void Bar();
};
...
Foo* foo = new Foo();
void* bar = Bar;
__asm {
  push foo
  call bar
}

__thiscall практически такой же как и cdecl, только ещё последним параметром добавляется указатель на экземпляр класса.
Ответ немного запоздалый но возможно поможет.


Разработчик игрового движка WaveGameEnvironment2D

Сообщение отредактировал bodya_WM - Воскресенье, 03 Сентября 2017, 08:29
SaiteiДата: Воскресенье, 03 Сентября 2017, 12:04 | Сообщение # 1527
старожил
Сейчас нет на сайте
Цитата bodya_WM ()
void* bar = Bar;

не думаю, что валидно.

Код
typedef void (Foo::*FuncPtr)();
FuncPtr bar = &Foo::Bar;
CupcakeGamesДата: Пятница, 24 Ноября 2017, 15:42 | Сообщение # 1528
уже был
Сейчас нет на сайте
Пользователь вводит Hello world!
Аргументы:
string text = "Hello world!"
string separator = " "(разделитель)
Результат:
string result[0] == "Hello"
string result[1] == "world!"



I LOVE GCUP!
allodsДата: Вторник, 12 Февраля 2019, 21:27 | Сообщение # 1529
почти ветеран
Сейчас нет на сайте
Ребят помогите
Помогите понять этот кусок когда

Код
ui16 allowedFactions = reader.readUInt8();
  // How many factions will be read from map
  ui16 totalFactions = GameConstants::F_NUMBER;

  if(mapHeader->version != EMapFormat::ROE)
   allowedFactions += reader.readUInt8() * 256;
  else
   totalFactions--; //exclude conflux for ROE

  for(int fact = 0; fact < totalFactions; ++fact)
  {
   if(!(allowedFactions & (1 << fact)))
   {
    mapHeader->players[i].allowedFactions.erase(fact);
   }
}


а именно if(!(allowedFactions & (1 << fact)))


Сообщение отредактировал allods - Вторник, 12 Февраля 2019, 21:29
drcrackДата: Вторник, 12 Февраля 2019, 22:01 | Сообщение # 1530
старожил
Сейчас нет на сайте
(1 << fact) дает число в котором бит номер fact (считая справа с нуля) установлен в 1, остальные в 0
т.е. в двоичной это 1, 10, 100, 1000 и так далее
дальше ты применяешь эту маску к allowedFactions, т.е. из этого числа остается только один бит, остальные выставляются в 0
в итоге получается проверка, чему равен определенный бит в allowedFactions
если бит был 0, получается 0 (false), если бит был 1, получается не-0, а именно 2 в степени fact (но главное что не 0, т.е. true)
и потом это еще отрицается (!)
короче, если allowedFactions например 9, т.е. 1001 в двоичной, код выполнится на 2 и 3 итерации, а на 1 и 4 нет


Сообщение отредактировал drcrack - Вторник, 12 Февраля 2019, 22:04
DivESДата: Вторник, 12 Февраля 2019, 22:11 | Сообщение # 1531
заслуженный участник
Сейчас нет на сайте
allods, объяснить в точности не смогу, но "помочь понять", как просишь - постараюсь :)
Начнём с &. Это поразрядная конъюнкция (или умножение).
То есть, если взядь два числа, например 110 и 100, то результатом 110 & 100 будет 100.
Возьмём 110 и 010, результат 110 & 010 = 10. Результат равен "умножению" чисел.
1*0 = 0, 1*1 = 1, 0*0 = 0 -> получаем 10, так как 0 слева отбрасывается. Объяснил, как смог, в остальном можешь почитать на тему конъюнкции!

Далее идёт <<. Это побитовый сдвиг. Тут понять проще.
01 << 1 = 10 (в двоичной) или 2 (в десятичной).
0010 << 1 = 0100.
0110 << 1 = 1100.
0110 << 2 = 1000. (биты, сдвинуты за пределы - теряются)
То есть просто перемещаем битовые значения по разрядам.

Ну а теперь мы подошли к пониманию этой условной конструкции. Она будет срабатывать до тех пор, пока значение во внутренних скобках будет равняться нулю. Ведь только в этом случае значение во внешних скобках будет принимать значение истины.
Поправьте, если ошибся ^_^

Добавлено (12 Февраля 2019, 22:25)
---------------------------------------------
(allowedFactions & (1 << fact)) - внутренние скобки;
(!(allowedFactions & (1 << fact))) - внешние.
Вот что имелось в виду :)

allodsДата: Вторник, 12 Февраля 2019, 22:27 | Сообщение # 1532
почти ветеран
Сейчас нет на сайте
спасибо за ответы , просто я только "скриптю" и там по другому многое пишется.
mapHeader->players[i].allowedFactions.erase(fact);
здесь как бы стираем часть значения из players[i].allowedFactions ?
если fact = 5 то если players[i].allowedFactions == 123456789 то получим 12346789 ?

Код
ui16 allowedFactions = reader.readUInt8();
  // How many factions will be read from map
  ui16 totalFactions = GameConstants::F_NUMBER;

а здесь почему ui16 ? в чем его фишка


Сообщение отредактировал allods - Вторник, 12 Февраля 2019, 22:29
DivESДата: Вторник, 12 Февраля 2019, 22:38 | Сообщение # 1533
заслуженный участник
Сейчас нет на сайте
allods, 123456789 в двоичной системе это 111010110111100110100010101.
Побитовые операции на то и побитовые, что работают с битами :D
То есть числа всегда прежде переводятся в соответствующую систему координат.
По поводу 111010110111100110100010101 << 5... результат такой: 11101011011110011010001010100000 (в двоичной) или 3950617248 (в десятичной). Проверил на C++ и через перевод из одной системы в другую.
Как видишь, в данном случае всё сдвинулось влево на пять знаков.
Но для правильной работы мне пришлось работать с типом long int.
В твоём же случае работа идёт с ui16, то есть unsinged int. При этом в двоичной записи там сможет поместиться лишь 16 бит, насколько я понимаю :)

Добавлено (12 Февраля 2019, 22:46)
---------------------------------------------

Цитата allods ()
а здесь почему ui16 ? в чем его фишка

Я уже успел опередить этот вопрос своим ответом, но ещё дополню.

Смотри, 65535 (десятичное) - верхний предел типа unsigned int (ui16).
В двоичном виде это 1111111111111111 (их 16).
Если мы попытаемся сдвинуть значение переменной этого типа на один влево (<< 1), то получим 1111111111111110, так как биты, сдвинутые за пределы - теряются.
1111111111111111 << 3 = 1111111111111000,
1111111111111111 << 8 = 1111111100000000 (ровно до "половины") и так далее :)

Добавлено (12 Февраля 2019, 22:50)
---------------------------------------------
Кстати, сначала меня ввело в заблуждение ui16. Потому что эта аббревеатура означает unsigned int (а он 32-ух битный).
В то время как usi16 было бы логичнее - unsigned short int :)

Добавлено (12 Февраля 2019, 22:58)
---------------------------------------------
Кстати, ui16 - это просто своего рода псевдоним типа данных.
Мы сами можем задать свой псевдоним используя typedef:

Код
typedef unsigned short int ui16;

- как в твоём случае, например :)
То есть typedef тип имя;
allodsДата: Вторник, 12 Февраля 2019, 23:03 | Сообщение # 1534
почти ветеран
Сейчас нет на сайте
в моем случае получается
UInt16 allowedFactions = r.ReadByte();
allowedFactions += (UInt16)(r.ReadByte() * 256);
и получаю 511 посмотрел это в двоичной системе 111111111
это точно то что мне надо.

собственно для проверки я могу просто разобрать 111111111 в Лист
и через цикл проверить 0 или 1 ? я правильно понял ?
просто я не знаю как мне переписать

Код
if(!(allowedFactions & (1 << fact)))
   {
    mapHeader->players[i].allowedFactions.erase(fact);
   }


players[i].allowedFactions.erase(fact); и еще что такое erase
я посмотрел и насколько я понял оно убирает значение == fact ?

вообщем странно немного. С этим кодом что я написал в самом начале. Я получаю не в двоичной системе не 111111111 а 511
в итоге все остальне не работает. Так как я не вижу преобразования 511 в 111111111
В итоге если преобразовать в двоичую систему все сходится. Или я что то не понял


Сообщение отредактировал allods - Вторник, 12 Февраля 2019, 23:14
DivESДата: Вторник, 12 Февраля 2019, 23:14 | Сообщение # 1535
заслуженный участник
Сейчас нет на сайте
Цитата allods ()
собственно для проверки я могу просто разобрать 111111111 в Лист
и через цикл проверить 0 или 1 ? я правильно понял ?

Разобрать конечно можно и проверить тоже, если это требуется.
Но по идее, двоичный 0 он и в Африке - ноль (в десятичной системе, имеется в виду).
То есть, 0 (в десятичной) = 0 (тут и далее - в двоичной) = 00 = 000 = 0000 =...
То есть, проверка if (двоичное число) будет срабатывать только в том случае, когда в этом двоичном числе есть хотя бы одна единичка :)

Добавлено (12 Февраля 2019, 23:23)
---------------------------------------------

Цитата allods ()
players[i].allowedFactions.erase(fact); и еще что такое erase
я посмотрел и насколько я понял оно убирает значение == fact ?

По этому поводу ничего не скажу, не совсем понимаю, с чем мы работаем. Но судя по названию функции/ метода она и правда "стирает" значение.
Цитата allods ()
вообщем странно немного. С этим кодом что я написал в самом начале. Я получаю не в двоичной системе не 111111111 а 511
в итоге все остальне не работает. Так как я не вижу преобразования 511 в 111111111
В итоге если преобразовать в двоичую систему все сходится. Или я что то не понял

Преобразовывать не нужно, по идее. Раньше ведь всё работало?
allodsДата: Вторник, 12 Февраля 2019, 23:27 | Сообщение # 1536
почти ветеран
Сейчас нет на сайте
Цитата DivES ()
Разобрать конечно можно и проверить тоже, если это требуется.
Но по идее, двоичный 0 он и в Африке - ноль (в десятичной системе, имеется в виду).
То есть, 0 (в десятичной) = 0 (тут и далее - в двоичной) = 00 = 000 = 0000 =...
То есть, проверка if (двоичное число) будет срабатывать только в том случае, когда в этом двоичном числе есть хотя бы одна единичка :)


Хорошо тогда я объясню задачу потому что я что то не уловил.

У меня есть список Замков их 9 в виде bool (либо есть на выбор либо нет) то есть у 1 игрока может быть 1,2,5,7 замок на выбор у другого 1,5,6,8,9
у третьего все 1,2,3,4,5,6,7,8,9 то есть все.
они хранятся в таком виде 1 ,2,4,8,16,32,64,128,256 в битах
в итоге у первого игрока 1+2+16+64
у второго 1+16+128+256
у третьего в итоге 511 то есть 111111111 то есть все замки true
то есть если переделать тот код то можно не убирать 0 и в итоге проверять наличие замка на выбор чере 1 либо 0
не парясь с маской.

Тот код не мой и да он работает это точно . Мне нужно его понять и написать уже свое. Поэтому я и рассказываю тот как я понял и то как я бы сделал. Просто хочу понять правильно в итоге я понял тот код или нет. Конечно благодаря тому что вы мне рассказали про двоичный код и то как работает тот код я смог написать свой. И кстате в итоге то что я теперь уже написал сам работает. Просто немного по другому но в целом получается получить данные и правильно их растолковать!

-------------
Точнее код не проверял но судя по двоичному allowedFactions если не стирать нули то все сходится.


Сообщение отредактировал allods - Вторник, 12 Февраля 2019, 23:39
DivESДата: Вторник, 12 Февраля 2019, 23:39 | Сообщение # 1537
заслуженный участник
Сейчас нет на сайте
allods, а как ты преобразовываешь тот код, что уже показывал?
Я вот лично пока что не вижу реализации твоей идеи через тот код :(

Добавлено (12 Февраля 2019, 23:40)
---------------------------------------------

Цитата allods ()
если не стирать нули

Где именно стирать?
allodsДата: Среда, 13 Февраля 2019, 00:03 | Сообщение # 1538
почти ветеран
Сейчас нет на сайте
Цитата DivES ()
allods, а как ты преобразовываешь тот код, что уже показывал?
Я вот лично пока что не вижу реализации твоей идеи через тот код :(


собственно вот тот код под вопросом
Код
for(int fact = 0; fact < totalFactions; ++fact)
  {
   if(!(allowedFactions & (1 << fact)))
   {
    mapHeader->players[i].allowedFactions.erase(fact);
   }

totalFactions = количество всех замков
allowedFactions = биты замков которые я считываю из файла. Всего есть 511 байтов = 111111111. К примеру 510 ровняется замки от 2-9 так как 511-510 = 1. А 1 байт это замок номер 1. то есть 011111111 я знаю что этого замка в списке уже нет. Если 255 то значит 511-255 = 256 а это последний замок. то значит 111111110. значит нет 9го замка.

То есть считав сколько байтов я уже благодаря преобразованию в двоичную систему знаю какие замки доступны.

Что касается той функици
Мы смотрим все 1и0 в allowedFactions и если 0 то убираем замок под индексом fact из списка замков оставляя в списке только доступные.
то есть в итоге если 110111101 то мы уберем замки под индексом 8 и 3
Благодаря вашим ответам я пришел к этому выводу. Это логично все сходится. Завтра закину вам еще + так как без вас я бы еще сидел щеки надувал


Сообщение отредактировал allods - Среда, 13 Февраля 2019, 00:08
DivESДата: Среда, 13 Февраля 2019, 00:10 | Сообщение # 1539
заслуженный участник
Сейчас нет на сайте
Цитата allods ()
А 1 байт это замок номер 1. то есть 011111111 я знаю что этого замка в списке уже нет. Если 255 то значит 511-255 = 256 а это последний замок. то значит 111111110.

В двоичной системе исчисления самый старший разряд - крайний левый (то есть в 0111 1111 самым старшим является 0, самым младшим - крайняя справа единица).
Так что отсутствие замка под номером один (обозначаемого 1 битом) будет выглядеть как 111111110.
Так же как и отсутствие десятого замка (256 бит) будет выглядеть как 011111111.
Возможно, подтолкнёт на какие-либо мысли. Если, конечно, ещё есть неразрешённые вещи в этом твоём коде :)


Сообщение отредактировал DivES - Среда, 13 Февраля 2019, 00:13
allodsДата: Среда, 13 Февраля 2019, 00:27 | Сообщение # 1540
почти ветеран
Сейчас нет на сайте
Цитата DivES ()
В двоичной системе исчисления самый старший разряд - крайний левый (то есть в 0111 1111 самым старшим является 0, самым младшим - крайняя справа единица).
Так что отсутствие замка под номером один (обозначаемого 1 битом) будет выглядеть как 111111110.
Так же как и отсутствие десятого замка (256 бит) будет выглядеть как 011111111.


Да я это учел и просто инвертирую ну или читаю в другую сторону. Хотя я еще не написал код а в процессе. И если мне у меня получится правильно считать данные то вопросов не останется точно =) хотя возможно в дальнейшем будут еще в таком духе =).

Добавлено (13 Февраля 2019, 01:39)
---------------------------------------------
В итоге вот мой аналог

Код
for (int fact = 0; fact < totalFactions; fact++)
{
        if ((allowedFactions % 2) != 0)
                    this.allowedFactions.Add((Faction)fact);
       allowedFactions = allowedFactions / 2;
}


Спасибо за разъяснения DivES и drcrack

Все работает


Сообщение отредактировал allods - Среда, 13 Февраля 2019, 01:50
Поиск:

Все права сохранены. GcUp.ru © 2008-2024 Рейтинг