Вход

Просмотр полной версии : [Вопрос] Запутался в системе



Сергей
07.12.2018, 12:16
Доброго времени суток. Прошу помощи в написании, запутался в системе)

Я пытался сделать такую вот интересную систему.

Отправляем запрос в базу данных, туда мы отправляем ид нашей фракции, и ранг который нам нужен будет.

Далее получаем ответ:

Как оказывается в базе данных есть такой номер фракции с таким же номером ранга.
НО
Их имеется трое образно говоря
Test1 | Ранг: 1 | Фракция: 1 | automat_assig: 1
Test2 | Ранг: 1 | Фракция: 1 | automat_assig: 1
Test3 | Ранг: 1 | Фракция: 1 | automat_assig: 0

Теперь нам нужно загрузить automat_assig
Она и есть наша главная цель.
- Загрузили.

Мы видим, что у нас 3 названия это (Test1,Test2,Test3) и у них имеется automat_assig: 1
Только у Test3 automat_assig: 0
Делаем следующий вывод, нам нужно рандомно назначит игрока на должности где: automat_assig: 1
Т.е назначит на Test1 или Test2 при этом всём сделать это нужно рандомно.

Перейдем к следующему этапу:

Если же Test1,Test3,имеют automat_assig: 0
А Test2 имеет automat_assig: 1
То назначаем игрока на должность Test2
Если же Test1,Test2,Test3 имеют: automat_assig: 0
Не назначаем игрока некуда.

new frac_id = 1;
new frac_rank = 1;
new mysql_Str[90];
format(mysql_Str,sizeof(mysql_Str), "SELECT * FROM `baza_danih` WHERE `id_frack`='%d' AND `rank_frack`='%d'", frac_id,frac_rank);
mysql_function_query(MysqlConnect,mysql_Str, true, "CallBack","ddd",playerid,frac_id,frac_rank);


Параметр: number_ids отвечает за то на какую должность ставить.


forward CallBack(playerid,rank_ids,frac_ids);
public CallBack(playerid,rank_ids,frac_ids)
{
new rows, fields;
cache_get_data(rows, fields,MysqlConnect);
cache_get_row_count(rows);
new rand = random(2);
new bool:auto_s[6];
new number_ids[6];
for(new i = 0; i < rows; i++)
{
auto_s[frac_ids] = bool:cache_get_field_content_int(i, !"automat_assig", MysqlConnect);
number_ids[frac_ids] = cache_get_field_content_int(i, !"number_id", MysqlConnect);
}
if(auto_s[frac_ids] == true)
{
switch(rand)
{
case 0: printf("Назначаем на 0 должность");
case 1: printf("Назначаем на 1 должность");
}
}
return 1;
}

DeimoS
07.12.2018, 14:06
Во-первых, если я правильно понял суть системы, то проще один раз загрузить ранги и уже потом работать с загруженными данными, а не каждый раз обращаться к базе.
Во-вторых, то, что ты хочешь сделать, выглядит как-то так:
#define MAX_RANK_IN_TABLE 6// Максимально возможное количество названий для ранга

forward CallBack(playerid,rank_ids,frac_ids);
public CallBack(playerid,rank_ids,frac_ids)
{
new rows, fields;
cache_get_data(rows, fields, MysqlConnect);
cache_get_row_count(rows);
if(!rows)
return;
if(rows > MAX_RANK_IN_TABLE)
rows = MAX_RANK_IN_TABLE;

new bool:auto_s[MAX_RANK_IN_TABLE];
new number_ids[MAX_RANK_IN_TABLE];
new count;

for(new i = 0; i < rows; i++)
{
auto_s[i] = bool:cache_get_field_content_int(i, !"automat_assig", MysqlConnect);
number_ids[i] = cache_get_field_content_int(i, !"number_id", MysqlConnect);

if(auto_s[i] == true)
{
count++;
}
}
if(count > 0)// Если количество "разрешённых" рангов не равно нулю
{
new rand = random(count);// Получаем рандомный порядковый номер ранга
for(new i = 0, c; i < MAX_RANK_IN_TABLE; i++)// По новой запускаем цикл
{
if(auto_s[i] == true)// Если ранг "разрешён"
{
if(c++ == rand)// Проверяем, равен ли его номер рандомному номеру, полученному ранее
{
printf("Назначаем на %d должность", i);
return;
}
}
}
}
else
{
print("Не назначаем никуда");
}
return;
}

Сергей
07.12.2018, 14:34
Я сделал чуть-чуть теперь по иному, вообщем, а что будет если загрузить их сначала в массив? automat_assig = 1 я имею ввиду, и потом уже работать только с этим массивом? Только вот вынуть теперь из массива не получается, и само назначение произвести...



#define MAX_FRAC_IDS 6

forward CallBack(frac_ids);
public CallBack(frac_ids)
{
new rows, fields;
cache_get_data(rows, fields,MysqlConnect);
new bool:auto_s[MAX_FRAC_IDS][3];
new idsi[MAX_FRAC_IDS][3];
new count;
if(rows)
{
for(new i = 0; i < rows; i++)
{
auto_s[frac_ids][i] = bool:cache_get_field_content_int(i, !"automat_assig", MysqlConnect);
if(auto_s[frac_ids][i] == true)
{
idsi[frac_ids][i] = auto_s[frac_ids][i];
count++;
}
if(count > 0)
{
if(auto_s[frac_ids][i] == true)
{
new rand = random(idsi[frac_ids][i]);
}
}
}
}
printf("%d | %d | %d",idsi[frac_ids][0],idsi[frac_ids][1],idsi[frac_ids][2]);
}

По последнему printf вот такие вот данные
1 | 1 | 0

DeimoS
07.12.2018, 15:09
Эмм, твой текущий код вообще непонятно что делает.
Во-первых, зачем ты в цикле делаешь проверку if(count > 0)? Как только загрузится хоть один "разрешённый" ранг, эта проверка будет срабатывать для всех последующих итераций.
Во-вторых, ты нигде не используешь rand.

Мой код - это то, что тебе нужно. Только значение MAX_RANK_IN_TABLE замени на 3 вместо 6 и всё


Касаемо загрузки данных в массив - это будет более оптимизированый вариант, если вкратце.

Сергей
07.12.2018, 16:04
Так а если сделать вот через массив? Это же будет более оптимальный вариант
Касаемо этого всего, я же не просто так загружаю:

number_ids[i] = cache_get_field_content_int(i, !"number_id", MysqlConnect);
Я конкретно хочу назначить игрока на конкретную должность

Вот как оно всё в бд
ссылка на скрин (https://imgur.com/a/odXmvft)

DeimoS
07.12.2018, 17:28
Ну так мой вариант и позволяет назначить на конкретную должность. Вот расписал более подробно пример работы с данными
#define MAX_RANK_IN_TABLE 6// Максимально возможное количество названий для ранга

forward CallBack(playerid,rank_ids,frac_ids);
public CallBack(playerid,rank_ids,frac_ids)
{
new rows, fields;
cache_get_data(rows, fields, MysqlConnect);
cache_get_row_count(rows);
if(!rows)
return;
if(rows > MAX_RANK_IN_TABLE)
rows = MAX_RANK_IN_TABLE;

new bool:auto_s[MAX_RANK_IN_TABLE];
new number_ids[MAX_RANK_IN_TABLE];
new count;

for(new i = 0; i < rows; i++)
{
auto_s[i] = bool:cache_get_field_content_int(i, !"automat_assig", MysqlConnect);
number_ids[i] = cache_get_field_content_int(i, !"number_id", MysqlConnect);

if(auto_s[i] == true)
{
count++;
}
}
if(count > 0)
{
new rand = random(count);
for(new i = 0, c; i < MAX_RANK_IN_TABLE; i++)
{
if(auto_s[i] == true)
{
if(c++ == rand)
{
printf("Назначаем на %d должность (%d | %d)", i, auto_s[i], number_ids[i]);// Вот обращаемся к конкретному рангу и работаем с его данными
return;
}
}
}
}
else
{
print("Не назначаем никуда");
}
return;
}

Ну а касаемо загрузки в массив - для начала кинь скрин структуры таблицы и объясни что ты хочешь сделать

Сергей
07.12.2018, 17:56
Я хочу вот что сделать:
Назначит игрока на одну из рандомных должностей. При условии, если в базе данных automat_assig для конкретной фракции и для конкретного ранга стоит на значении 1
Если в базе данных создано 2 должности под конкретный ранг, допустим 1, и там значение automat_assig == 1 то мы сделаем рандом.
Скрин 1 (https://imgur.com/a/gz6bcd6)
Скрин 2 (https://imgur.com/a/JC5Dy61)

Как собственно ставит на должность, мы записуем игроку number_id должности которая у нас выбралась или рандомно или же нет.

Сергей
07.12.2018, 20:56
Вообщем, просто прошу посмотреть, что я написал(нарыгал, только глаза себе не выдавливайте)


forward CallBack(frac_ids);
public CallBack(frac_ids)
{
new rows, fields;
cache_get_data(rows, fields, MysqlConnect);
cache_get_row_count(rows);
if(!rows) return 1;

new bool:auto_s[6];
new idsi[6][4];
new count;
new number_ids[6];
new number_idis[6][4];
for(new i = 0; i < rows; i++)
{
auto_s[frac_ids] = bool:cache_get_field_content_int(i, !"automat_assig", MysqlConnect);
number_ids[frac_ids] = cache_get_field_content_int(i, !"number_id", MysqlConnect);
if(auto_s[frac_ids] == true)
{
idsi[frac_ids][i] = auto_s[frac_ids];
number_idis[frac_ids][i] = number_ids[frac_ids];
count++;
}
}
if(count >= 2)
{
if(idsi[frac_ids][0] != 0 || idsi[frac_ids][1] != 0 || idsi[frac_ids][2] != 0)
{
printf("%d || %d || %d",number_idis[frac_ids][0],number_idis[frac_ids][1],number_idis[frac_ids][2]);
}
}
else if(count == 1)
{
printf("Назначим только на ту, где есть 1");
}
else if(count == 0) print("Нетрогаем игрока");
printf("=============%d | %d | %d=================",idsi[frac_ids][0],idsi[frac_ids][1],idsi[frac_ids][2]);
return 1;
}

DeimoS
08.12.2018, 13:39
Зачем ты создаёшь массив для всех 6-и фракций, если всегда грузишь информацию только одной фракции?

Сергей
08.12.2018, 15:28
Зачем ты создаёшь массив для всех 6-и фракций, если всегда грузишь информацию только одной фракции?

Да это пробный вариант, потому-что пока-что нехватает меня сделать по нормальному.
Поможете сделать по нормальному? Ибо не получается... .

DeimoS
08.12.2018, 19:30
Распиши предназначение каждого столбца в таблице и дай примеры того, как ты хочешь информацию из них использовать.

Сергей
08.12.2018, 19:36
Распиши предназначение каждого столбца в таблице и дай примеры того, как ты хочешь информацию из них использовать.

Смысл от этого? Если уже почти всё сделал, осталось только сделать рандом




forward test_CallBack(frac_ids);
public test_Callback(frac_ids)
{
new rows, fields;
cache_get_data(rows, fields, MysqlConnect);
cache_get_row_count(rows);
if(!rows) return 1;

new bool:auto_s[6];
new idsi[6][4];
new count;
new number_ids[6];
new number_idis[6][4];
for(new i = 0; i < rows; i++)
{
auto_s[frac_ids] = bool:cache_get_field_content_int(i, !"automat_assig", MysqlConnect);// загружаем автоматическое назначение
number_ids[frac_ids] = cache_get_field_content_int(i, !"number_id", MysqlConnect); // загружаем номер должности
if(auto_s[frac_ids] == true)//
{
idsi[frac_ids][i] = auto_s[frac_ids]; // дальше нам пригодиться для того, чтобы отсеять все остальные с 0
number_idis[frac_ids][i] = number_ids[frac_ids]; // номер должности для назначения
count++;
}
}
if(count >= 2)
{
new test_frac[2] = 0;

for(new i = 0; i < 3; i++)
{
if(idsi[frac_ids][i] != 0)// делаем отсеивание
{
if(number_idis[frac_ids][i] != 0)// отсекаем
{
//И тут уже бы сделать рандом, из тех кто остался, и назначить на должность number_idis[frac_ids][i]
// т.е нам нужно вытащить ид должности отсюда number_idis[frac_ids][i] в 2 переменные, и потом уже сделать рандом
// допустим вытянули иды должностей первый ид: 2 второй ид: 4
// Делаем рандом: В рандоме выигрывает ID: 4 вот его и присваиваем игроку
}
}
}
}
else if(count == 1)
{
printf("Назначим только на ту, где есть 1");
}
else if(count == 0) print("Нетрогаем игрока");
return 1;
}

Ну т.е чтобы оно примерно вот так получилось

Ну тут уже тип готовый вариант, без того, что я хотел добиться, а добиться хотел этого:
Использую цикл для того, чтобы найти в какой конкретно number_idis[frac_ids][тут id] записан ид должности у который automat_assig == 1 и вот как только мы выяснили, записываем эти иды должностей в другие переменные, и потом уже делаем рандом из них, и потом только ставим игрока на должность.

Что конкретно у меня сейчас не получается выяснить:
- Я не могу записать в другую переменную номер должности у которой automat_assig == 1
Я привёл пример, как бы оно в идеале должно было выглядеть, но на деле....


if(count >= 2)
{
new test_frac[2] = 0;

for(new i = 0; i < 6; i++)
{
if(idsi[frac_ids][i] != 0 && number_idis[frac_ids][i] != 0)
{
test_frac[0] = number_idis[frac_ids][0];
test_frac[1] = number_idis[frac_ids][2];
printf("ids1: %d",test_frac[0]);// тут получили ID должности 2
printf("ids2: %d",test_frac[1]);// тут получили ID должности 4
}
}
new rand = random(2);
switch(rand)
{
case 0: printf("Ставим на должность ID: %d",test_frac[0]);
case 1: printf("Ставим на должность ID: %d",test_frac[1]);
}
}

Сергей
09.12.2018, 19:57
Вообщем, всё, я смастерил, спасибо за помощь. На вашем примере, и своём упорстве всё же сделал.
Тему можно закрывать.