Как лучше всего хранить колоду карт в базе данных? - PullRequest
1 голос
/ 14 апреля 2011

Я работаю над приложением, которое должно хранить колоду рук в базе данных.Я не уверен, что это лучший способ представить это в базе данных.

Колода будет предварительно сдана в 4 руки, каждая из которых будет иметь по 13 карт в приложении.После этого мне нужно хранить руки и дополнительные данные, такие как распределение костюма и т. Д. *

. Лучше ли создать отдельный ряд для каждой руки и связать его с колодой?Или, может быть, было бы лучше держать их в одном ряду?

Также я не уверен, стоит ли мне хранить их в виде текста или числа.Вот пример:

Sorted by suit and separated by dot
AK.32.6543.AKQ98

Или

(52 = Largest rank or largest suit or 02 = 2 of smallest suit)
405251282717161514012322200908

Есть идеи?

PS: Есть причина хранить карты.Нам нужно проанализировать распределение рук, высокие карты и т.д. ...

Ответы [ 3 ]

4 голосов
/ 14 апреля 2011

Я думаю, что наиболее естественным было бы создание таблицы для карт, в которой была бы одна запись для каждой карты в колоде, а затем запись для рук, в которой была бы одна запись для каждой карты в руке.,Если есть данные о руке в целом - имя игрока?где он сидит за столом?сколько у него фишек?что угодно - тогда вам понадобится отдельный стол для руки, а не карты в руке.Я бы также создал таблицу соответствия для костюмов.

(Мы могли бы обсудить здесь использование синтетических ключей по сравнению с естественными ключами, но это уже другая тема.)

card (cardid, suitid, rank)
suit (suitid, suitname)
hand (handid, playername, whatever)
handcard (handcardid, handid, cardid)

Мой первый импульс был бысделать «ранжирование» числом от 1 до 13, и перевести 1 в «туз» и 11–13 в «джек», «ферзь» и «король» во время вывода.Вы можете сохранить их в виде текста, но тогда будет сложно сравнить ранги, если в этом есть необходимость.т.е. решить, легко ли 13> 10 для базы данных;Король> 10. Не так уж и много.

Я бы определенно НЕ пытался втиснуть идентификацию нескольких карт в одно поле, независимо от того, разделены ли они точками или идентификаторами фиксированной длины или чем-то еще.Для этого потребуется, чтобы в вашей программе был код, разбирающий это поле для получения нужных вам данных, а не просто позволяющий базе данных получать нужные вам данные, для чего и нужны базы данных.

Я не знаю, что вы хотите сделать с этими карточными руками, но большинство вещей, которые вы, вероятно, захотите сделать, довольно легко с такой структурой, как я описываю, довольно сложно, если вы соберетесписок карт в одном поле.Мол, у кого есть пиковый король?Легко:

select playername
from hand
join handcard using (handid)
join card using (cardid)
join suit using (suitid)
where suit.name='Spades' and card.rank=13

Или «Сколько лицевых карт у каждого игрока?»

select playername, count(*)
from hand
join handcard using (handid)
join card using (cardid)
where card.rank between 11 and 13

Конечно, «Какие карты у игрока №3?»это также просто:

select rank, suitname
from handcard
join card using (cardid)
join suit using (suitid)
where handid=3

Выполнение этих запросов в упакованном формате потребует сложных вызовов извлечения строк.А манипуляции со струнами - это всегда боль.Как вы всегда сталкиваетесь с проблемами, например, если я ищу 2 в тексте, как я могу исключить 2, которые являются частью 12?и т.д.

4 голосов
/ 14 апреля 2011

Это зависит от вида анализа, который вы хотите сделать.Если бы это был я, я бы, вероятно, по умолчанию принял что-то вроде (игнорируя неосновные ограничения)

CREATE TABLE card (
  card_id NUMBER PRIMARY KEY,
  suit    VARCHAR2(10) NOT NULL,
  value   VARCHAR2(1)  NOT NULL
);

CREATE TABLE hand (
  hand_id   NUMBER PRIMARY KEY,
  player_id NUMBER NOT NULL
);

CREATE TABLE hand_element (
  hand_element_id NUMBER PRIMARY KEY,
  hand_id         NUMBER NOT NULL,
  card_id         NUMBER NOT NULL
);

Каждый HAND будет иметь 13 строк в HAND_ELEMENTЯ бы не стал хранить информацию о распределении костюма, я бы просто вычислил распределение раздачи, т.е.

SELECT suit, count(*)
  FROM hand JOIN hand_element USING (hand_id)
            JOIN card         USING (card_id)
 WHERE hand_id = :some_hand_id
0 голосов
/ 14 мая 2016

Я также работаю над аналогичным проектом для 3-карточного покера.Я настроил свой SQL следующим образом:

CREATE TABLE cards 
(

    id int AUTO_INCREMENT,
    suite varchar(30) NOT NULL,
    rank int NOT NULL,
    dealt BOOLEAN DEFAULT false,
    PRIMARY KEY (id)

);

Затем запустите команды для заполнения базы данных следующим образом:

INSERT INTO cards (suite,rank) VALUES ('spades',1);

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

...