deck.js 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  1. import { writable } from "svelte/store";
  2. import { parseYdke } from './utils';
  3. import { getCardDb, getAltId, cardLimit } from './card_db';
  4. let deck = writable({main: [], extra: [], side: []});
  5. let deckState = {main: [], extra: [], side: []};
  6. let defaultFormat = 'none';
  7. let format = writable(defaultFormat);
  8. let formatState = defaultFormat;
  9. function sanitizeDeck(cardCnt, deck) {
  10. let cardDb = getCardDb();
  11. let altId = getAltId();
  12. let ret = [];
  13. for (let id of deck) {
  14. if (altId[id] !== undefined) {
  15. id = altId[id];
  16. }
  17. if (cardDb[id] === undefined) {
  18. continue;
  19. }
  20. if (!cardCnt.has(id)) {
  21. cardCnt.set(id, 0);
  22. }
  23. if (cardCnt.get(id) >= 3) {
  24. continue;
  25. }
  26. ret.push(id);
  27. cardCnt.set(id, cardCnt.get(id) + 1);
  28. }
  29. return ret;
  30. }
  31. function groupAndSort(arr) {
  32. const seen = {};
  33. const count = {};
  34. const uniqueList = [];
  35. for (const num of arr) {
  36. if (!(num in seen)) {
  37. seen[num] = true;
  38. uniqueList.push(num);
  39. }
  40. count[num] = (count[num] || 0) + 1;
  41. }
  42. const result = [];
  43. for (const num of uniqueList) {
  44. const times = count[num];
  45. for (let i = 0; i < times; i++) {
  46. result.push(num);
  47. }
  48. }
  49. return result;
  50. }
  51. function setDeck(d) {
  52. let cardCnt = new Map();
  53. d.main = sanitizeDeck(cardCnt, d.main);
  54. d.main = groupAndSort(d.main);
  55. d.side = sanitizeDeck(cardCnt, d.side);
  56. d.side= groupAndSort(d.side);
  57. d.extra = sanitizeDeck(cardCnt, d.extra);
  58. d.extra= groupAndSort(d.extra);
  59. deckState = d;
  60. deck.set(d);
  61. localStorage.setItem('cachedDeck', JSON.stringify(d));
  62. };
  63. function canAdd(d, id) {
  64. let count = 0;
  65. for (let c of d.main) {
  66. if (c === id) count += 1;
  67. }
  68. for (let c of d.side) {
  69. if (c === id) count += 1;
  70. }
  71. for (let c of d.extra) {
  72. if (c === id) count += 1;
  73. }
  74. if (count + 1 > cardLimit(id, formatState)) return false;
  75. return true;
  76. }
  77. let deckOps = {
  78. "deleteCard": (from, idx) => {
  79. if (from === 'main') {
  80. deckState.main.splice(idx, 1);
  81. setDeck(deckState);
  82. } else if (from === 'side') {
  83. deckState.side.splice(idx, 1);
  84. setDeck(deckState);
  85. } else if (from === 'extra') {
  86. deckState.extra.splice(idx, 1);
  87. setDeck(deckState);
  88. }
  89. },
  90. "move": (from, to, fromIdx, toIdx) => {
  91. let cardDb = getCardDb();
  92. let id = deckState[from][fromIdx];
  93. if (cardDb[id].isExtra && to === 'main') return;
  94. if (!cardDb[id].isExtra && to === 'extra') return;
  95. if (from === to) {
  96. let count = 0;
  97. for (let c of deckState[from]) {
  98. if (c === id) count += 1;
  99. }
  100. deckState[from] = deckState[from].map((x) => x === id ? null : x);
  101. if (to === 'main') {
  102. for (let i = 0; i < count; i++) {
  103. deckOps.add2main(id, toIdx);
  104. }
  105. } else if (to === 'extra') {
  106. for (let i = 0; i < count; i++) {
  107. deckOps.add2extra(id, toIdx);
  108. }
  109. } else if (to === 'side') {
  110. for (let i = 0; i < count; i++) {
  111. deckOps.add2side(id, toIdx);
  112. }
  113. }
  114. deckState[from] = deckState[from].filter((x) => x !== null);
  115. } else {
  116. if (to === 'extra') {
  117. deckState[from][fromIdx] = null;
  118. deckOps.add2extra(id, toIdx);
  119. deckState[from] = deckState[from].filter((x) => x !== null);
  120. } else if (to === 'main') {
  121. deckState[from][fromIdx] = null;
  122. deckOps.add2main(id, toIdx);
  123. deckState[from] = deckState[from].filter((x) => x !== null);
  124. } else if (to === 'side') {
  125. deckState[from][fromIdx] = null;
  126. deckOps.add2side(id, toIdx);
  127. deckState[from] = deckState[from].filter((x) => x !== null);
  128. }
  129. }
  130. setDeck(deckState);
  131. },
  132. "add2extra": (id, targetIdx) => {
  133. let cardDb = getCardDb();
  134. if (!cardDb[id].isExtra) return;
  135. let d = deckState;
  136. if (canAdd(d, id)) {
  137. if (targetIdx === -1)
  138. d.extra.push(id);
  139. else if (d.extra.includes(id)) {
  140. d.extra.push(id);
  141. d.extra = groupAndSort(d.extra);
  142. } else {
  143. d.extra.splice(targetIdx, 0, id);
  144. }
  145. setDeck(d);
  146. }
  147. },
  148. "add2main": (id, targetIdx) => {
  149. let cardDb = getCardDb();
  150. if (cardDb[id].isExtra) return;
  151. let d = deckState;
  152. if (canAdd(d, id)) {
  153. if (targetIdx === -1)
  154. d.main.push(id);
  155. else if (d.main.includes(id)) {
  156. d.main.push(id);
  157. d.main= groupAndSort(d.main);
  158. } else {
  159. d.main.splice(targetIdx, 0, id);
  160. }
  161. setDeck(d);
  162. }
  163. },
  164. "add2side": (id, targetIdx) => {
  165. let d = deckState;
  166. if (canAdd(d, id)) {
  167. if (targetIdx === -1)
  168. d.side.push(id);
  169. else if (d.side.includes(id)) {
  170. d.side.push(id);
  171. d.side= groupAndSort(d.side);
  172. } else {
  173. d.side.splice(targetIdx, 0, id);
  174. }
  175. setDeck(d);
  176. }
  177. }
  178. };
  179. function initDeck() {
  180. let url = window.location.href.split('#');
  181. if (url.length === 2) {
  182. let deck = parseYdke(url[1]);
  183. if (deck.main.length > 0 || deck.extra.length > 0 || deck.extra.length > 0) {
  184. setDeck(deck);
  185. window.location.href = url[0];
  186. return;
  187. }
  188. }
  189. let cachedDeck = localStorage.getItem('cachedDeck');
  190. if (cachedDeck !== null) {
  191. cachedDeck = JSON.parse(cachedDeck);
  192. setDeck(cachedDeck)
  193. }
  194. let cachedFormat = localStorage.getItem('format');
  195. if (cachedFormat !== null) {
  196. setFormat(cachedFormat);
  197. }
  198. }
  199. function setFormat(newFormat) {
  200. if (newFormat === 'none' || newFormat === 'ocg') {
  201. localStorage.setItem('format', newFormat);
  202. formatState = newFormat;
  203. format.set(newFormat);
  204. setDeck(deckState);
  205. }
  206. }
  207. export {
  208. deck,
  209. format,
  210. setFormat,
  211. setDeck,
  212. deckOps,
  213. initDeck,
  214. };