An End-to-End Card Game Simulation Project
Card Game Sim is an ambitious project aimed at creating a realistic card game experience from data collection to game play.
The first phase of the project involves using Python and Selenium to scrape card data from the Union Arena Card List page. This step includes:
Note: If you want to run the code yourself, simply change
the chrome_driver_path
variable in the code to match the location
of ChromeDriver on your computer.
# Ask user for the number of cards to scrape
num_cards_to_scrape = int(input("Enter number of cards to scrape: "))
cards_data = []
def scrape_current_card():
# Wait for the detail iframe to load and switch into it
iframe = WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.CSS_SELECTOR, ".fancybox-iframe"))
)
driver.switch_to.frame(iframe)
time.sleep(1)
html = driver.page_source
soup = BeautifulSoup(html, "html.parser")
# Extract details...
card_name = soup.find("h2", class_="cardNameCol").get_text(strip=True)
card_number = soup.select_one("div.cardNumCol span.cardNumData").get_text(strip=True)
img_dd = soup.find("dd", class_="cardDataImgCol")
img_tag = img_dd.find("img") if img_dd else None
image_url = ("https://www.unionarena-tcg.com" + img_tag.get("src")) if img_tag and img_tag.get("src").startswith("/") else None
bp = soup.select_one("dl.cardDataCol.bpData dd.cardDataContents").get_text(strip=True)
effect_dd = soup.select_one("dl.cardDataCol.effectData dd.cardDataContents")
if effect_dd:
effect_img = effect_dd.find("img")
effect_label = effect_img.get("alt", "").strip() if effect_img else ""
effect_text = effect_dd.get_text(strip=True).replace(effect_label, "").strip()
effect = effect_label + " - " + effect_text if effect_label else effect_text
else:
effect = "N/A"
trigger = soup.select_one("dl.cardDataCol.triggerData dd.cardDataContents").get_text(strip=True)
ap_cost = soup.select_one("dl.cardDataCol.apData dd.cardDataContents").get_text(strip=True)
driver.switch_to.default_content()
return {
"Card Name": card_name,
"Card Number": card_number,
"Image URL": image_url,
"BP": bp,
"Effect": effect,
"Trigger": trigger,
"AP Cost": ap_cost
}
# Click on the first card and scrape its details
first_card_link = WebDriverWait(driver, 10).until(
EC.element_to_be_clickable((By.CSS_SELECTOR, "li.cardImgCol:not([style*='display: none']) a.modalCardDataOpen"))
)
first_card_link.click()
time.sleep(2)
cards_data.append(scrape_current_card())
print("Scraped card 1.")
# Loop through subsequent cards using the Next button in the modal
for i in range(1, num_cards_to_scrape):
next_button = WebDriverWait(driver, 10).until(
EC.element_to_be_clickable((By.CSS_SELECTOR, "div.fancybox-navigation button[data-fancybox-next]"))
)
next_button.click()
time.sleep(2)
cards_data.append(scrape_current_card())
print(f"Scraped card {i+1}.")
This code snippet shows the complete Step 1 process. It first applies the filter, then clicks the first card, scrapes its details, and then iterates through the desired number of cards by clicking the Next button.
Once the data is scraped, it will be stored in a PostgreSQL database. The main tasks here include:
psycopg2
or SQLAlchemy
for database interactions.A well-designed database is essential for serving data quickly and reliably to the game’s API.
The next phase focuses on building a RESTful API with FastAPI in Python. This API will:
FastAPI’s performance and asynchronous support make it an ideal choice for managing real-time game interactions.
With the backend in place, the focus shifts to the game interface. This step includes:
This phase transforms raw data and logic into an immersive, interactive game environment.
The final phase is to integrate multiplayer functionality, focusing on turn-based gameplay. This involves:
This step is aims to deliver a seamless multiplayer experience.
Card Game Sim is a work in progress. As each phase is developed, additional features and optimizations will be implemented to improve data accuracy, game mechanics, and user experience. Stay tuned for more updates as the project evolves!