Полагаю, вы используете какой-то нестандартный тип для карточек.Итак, давайте назовем это t_card_kind
.
Вы можете сделать какое-то изменение массива, чтобы «удалить» карту из руки игрока.Но это не имеет особого смысла.
Я бы посоветовал определить перечисление как
namespace uno { enum play_status { DRAW_PILE,IN_HAND,DISCARD }; };
Таким образом, вы можете просто объявить новую структуру с определенным типом
typedef struct s {
t_card_kind card;
uno::play_status status;
} t_game_card;
... и, наконец, объявите массив, такой как
t_game_card my_cards[108];
, или вектор, такой как: vector my_cards [108];
, а затем заполните его.
Чтобы изменить статус карты, просто войдите в нее.
Например,
my_cards[i].status = uno::IN_HAND;
Этот дизайн будет выполняться намного быстрее и более элегантно.
Чтобы решить ваш второй вопроспросто реализуйте метод, подобный
unsigned int count_status(const t_game_card * my_card,
uno::play_status status_kind) {
const unsigned int DECK_SIZE = 108; //size of a standard uno deck
unsigned int matches;
for (unsigned int counter=0; counter < DECK_SIZE;counter++) {
if (t_game_card[counter].play_status==status_kind) {
matches++;
}
}
return matches;
}
... Или просто переключитесь на векторы и используйте метод erase ().
EDIT 1
Основываясь на моем предыдущем обсуждении с Джоном, ведутся споры о дизайне одного контейнера в сравнении с дизайном нескольких контейнеров.Вот мое мнение по теме:
Я полагаю, что этот дизайн использования одного вектора карт с прикрепленной информацией о состоянии является более надежным и более легким в обслуживании, чем дизайн, основанный на нескольких векторах.И вот почему.
В вашем результирующем коде у вас будет что-то вроде:
namespace uno { enum play_status { DRAW_PILE,IN_HAND,DISCARD }; };
typedef struct s { t_card_kind card; uno::play_status status; } t_game_card;
static vector<t_game_card> my_cards[108];
Где многовекторный подход будет иметь:
static t_game_card draw_pile[108];
static t_game_card in_hand;
static t_game_card discards;
... еще три элемента, хотя мой немного длиннее линии.
Как уже говорилось ранее, чтобы изменить состояние с помощью моего подхода, вы просто использовали бы что-то вроде:
my_cards[i]=uno::IN_HAND;
, тогда как свекторный метод, вам нужно сделать что-то вроде:
in_hand.append(draw_pile[i]);
draw_pile.erase(draw_pile.begin()+i);
Это длиннее , больше вычислительно интенсивно , использует больше памяти и, на мой взгляд, менее интуитивно .
Теперь давайте рассмотрим расширяемость .Допустим, вы придумали вариант uno, который включает в себя кучу «БОНУС».С моим подходом это просто - просто добавьте значение к перечислению:
namespace uno { enum play_status { DRAW_PILE,IN_HAND,DISCARD,BONUS }; };
с векторным подходом, вам нужно будет создать и поддерживать целый дополнительный вектор:
static t_game_card draw_pile[108];
static t_game_card in_hand;
static t_game_card discards;
static t_game_card bonus;
Теперь у нас есть 4 (!) Переменных с векторным подходом по сравнению с одной интуитивно понятной переменной с моим подходом.
Поддержка нескольких контейнеров для отдельных состояний занимает больше памяти, вычислительно дороже и меньшеинтуитивно понятен по сравнению с использованием одного контейнера (вектор, массив и т. д.) для хранения структур с прикрепленной информацией о состоянии.