Files
WhaleAdventure_VR/Assets/02_Scripts/Blackjack/CardSpawnTest.cs
2026-06-16 10:37:45 +09:00

497 lines
11 KiB
C#

using System.Collections;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using UnityEngine;
using UnityEngine.UI;
using TMPro;
public class CardSpawnTest : MonoBehaviour
{
[Header("Card Prefabs")]
public GameObject[] cardPrefabs;
[Header("Card Setting")]
public float cardScale = 2f;
public Vector3 frontRotation = new Vector3(-90f, 0f, 90f);
public Vector3 backRotation = new Vector3(90f, 0f, 90f);
[Header("Player Start Cards")]
public Transform playerCardPos1;
public Transform playerCardPos2;
[Header("Dealer Start Cards")]
public Transform dealerOpenCardPos;
public Transform dealerHiddenCardPos;
[Header("Player Hit Card Positions")]
public Transform[] playerHitPositions;
[Header("Dealer Hit Card Positions")]
public Transform[] dealerHitPositions;
[Header("UI Buttons")]
public Button hitButton;
public Button standButton;
[Header("Score UI")]
public TMP_Text playerScoreText;
public TMP_Text dealerScoreText;
public TMP_Text resultText;
[Header("Win Mark UI")]
public GameObject[] playerWinMarks;
public GameObject[] dealerWinMarks;
[Header("Match Setting")]
public int targetWinCount = 3;
public float nextRoundDelay = 2f;
private List<GameObject> deck = new List<GameObject>();
private List<GameObject> spawnedCards = new List<GameObject>();
private List<string> playerCards = new List<string>();
private List<string> dealerCards = new List<string>();
private int playerHitIndex = 0;
private int dealerHitIndex = 0;
private int playerWinCount = 0;
private int dealerWinCount = 0;
private GameObject dealerHiddenCard;
private bool isPlayerTurn = true;
private bool isGameOver = false;
private bool isMatchOver = false;
void Start()
{
StartMatch();
}
void StartMatch()
{
playerWinCount = 0;
dealerWinCount = 0;
isMatchOver = false;
HideAllWinMarks();
StartRound();
}
void StartRound()
{
ClearSpawnedCards();
BuildDeck();
isPlayerTurn = true;
isGameOver = false;
playerHitIndex = 0;
dealerHitIndex = 0;
playerCards.Clear();
dealerCards.Clear();
if (resultText != null)
{
resultText.gameObject.SetActive(false);
}
if (hitButton != null)
{
hitButton.interactable = true;
}
if (standButton != null)
{
standButton.interactable = true;
}
DealPlayerCard(playerCardPos1);
DealPlayerCard(playerCardPos2);
DealDealerCard(dealerOpenCardPos, false);
dealerHiddenCard = DealDealerCard(dealerHiddenCardPos, true);
UpdateScoreUI(false);
Debug.Log("New Round Start");
Debug.Log("Player Score: " + CalculateScore(playerCards));
Debug.Log("Dealer Open Card Score: " + GetCardValue(dealerCards[0]));
}
void BuildDeck()
{
deck.Clear();
foreach (GameObject card in cardPrefabs)
{
if (card != null)
{
deck.Add(card);
}
}
Debug.Log("Deck Count: " + deck.Count);
}
GameObject DrawRandomCard()
{
if (deck.Count == 0)
{
Debug.LogWarning("Deck is empty.");
return null;
}
int index = Random.Range(0, deck.Count);
GameObject selectedCard = deck[index];
deck.RemoveAt(index);
return selectedCard;
}
void DealPlayerCard(Transform pos)
{
GameObject prefab = DrawRandomCard();
if (prefab == null)
{
return;
}
playerCards.Add(prefab.name);
SpawnCard(prefab, pos, false);
}
GameObject DealDealerCard(Transform pos, bool faceDown)
{
GameObject prefab = DrawRandomCard();
if (prefab == null)
{
return null;
}
dealerCards.Add(prefab.name);
return SpawnCard(prefab, pos, faceDown);
}
public void Hit()
{
if (isGameOver || isMatchOver)
{
return;
}
if (!isPlayerTurn)
{
Debug.Log("You already stood. Hit is disabled.");
return;
}
if (playerHitIndex >= playerHitPositions.Length)
{
Debug.Log("No more player card positions.");
return;
}
DealPlayerCard(playerHitPositions[playerHitIndex]);
playerHitIndex++;
UpdateScoreUI(false);
int playerScore = CalculateScore(playerCards);
Debug.Log("Player Score After Hit: " + playerScore);
if (playerScore > 21)
{
Debug.Log("Player Bust! Dealer wins this round.");
EndRound(-1, "Player Bust!\nDealer Wins Round!");
}
}
public void Stand()
{
if (isGameOver || isMatchOver)
{
return;
}
if (!isPlayerTurn)
{
return;
}
isPlayerTurn = false;
if (dealerHiddenCard != null)
{
dealerHiddenCard.transform.rotation = Quaternion.Euler(frontRotation);
}
UpdateScoreUI(true);
Debug.Log("Stand: Dealer hidden card opened.");
Debug.Log("Dealer Score: " + CalculateScore(dealerCards));
DealerTurn();
}
void DealerTurn()
{
while (CalculateScore(dealerCards) < 17)
{
if (dealerHitIndex >= dealerHitPositions.Length)
{
Debug.Log("No more dealer card positions.");
break;
}
DealDealerCard(dealerHitPositions[dealerHitIndex], false);
dealerHitIndex++;
UpdateScoreUI(true);
Debug.Log("Dealer draws a card. Dealer Score: " + CalculateScore(dealerCards));
}
JudgeResult();
}
void JudgeResult()
{
int playerScore = CalculateScore(playerCards);
int dealerScore = CalculateScore(dealerCards);
Debug.Log("Final Player Score: " + playerScore);
Debug.Log("Final Dealer Score: " + dealerScore);
if (dealerScore > 21)
{
EndRound(1, "Dealer Bust!\nPlayer Wins Round!");
}
else if (playerScore > dealerScore)
{
EndRound(1, "Player Wins Round!");
}
else if (playerScore < dealerScore)
{
EndRound(-1, "Dealer Wins Round!");
}
else
{
EndRound(0, "Draw!\nNo Score");
}
}
void EndRound(int winner, string message)
{
isGameOver = true;
isPlayerTurn = false;
if (hitButton != null)
{
hitButton.interactable = false;
}
if (standButton != null)
{
standButton.interactable = false;
}
if (winner == 1)
{
if (playerWinCount < playerWinMarks.Length)
{
playerWinMarks[playerWinCount].SetActive(true);
}
playerWinCount++;
}
else if (winner == -1)
{
if (dealerWinCount < dealerWinMarks.Length)
{
dealerWinMarks[dealerWinCount].SetActive(true);
}
dealerWinCount++;
}
ShowResult(message);
if (playerWinCount >= targetWinCount)
{
isMatchOver = true;
ShowResult("Final Result\nPlayer Wins!");
Debug.Log("Final Result: Player Wins!");
return;
}
if (dealerWinCount >= targetWinCount)
{
isMatchOver = true;
ShowResult("Final Result\nDealer Wins!");
Debug.Log("Final Result: Dealer Wins!");
return;
}
StartCoroutine(StartNextRoundAfterDelay());
}
IEnumerator StartNextRoundAfterDelay()
{
yield return new WaitForSeconds(nextRoundDelay);
if (!isMatchOver)
{
StartRound();
}
}
void UpdateScoreUI(bool showDealerFullScore)
{
int playerScore = CalculateScore(playerCards);
if (playerScoreText != null)
{
playerScoreText.text = "Player: " + playerScore;
}
if (dealerScoreText != null)
{
if (showDealerFullScore)
{
dealerScoreText.text = "Dealer: " + CalculateScore(dealerCards);
}
else
{
dealerScoreText.text = "Dealer: ?";
}
}
}
void ShowResult(string message)
{
if (resultText != null)
{
resultText.gameObject.SetActive(true);
resultText.text = message;
}
}
void HideAllWinMarks()
{
foreach (GameObject mark in playerWinMarks)
{
if (mark != null)
{
mark.SetActive(false);
}
}
foreach (GameObject mark in dealerWinMarks)
{
if (mark != null)
{
mark.SetActive(false);
}
}
}
void ClearSpawnedCards()
{
foreach (GameObject card in spawnedCards)
{
if (card != null)
{
Destroy(card);
}
}
spawnedCards.Clear();
}
int CalculateScore(List<string> cards)
{
int total = 0;
int aceCount = 0;
foreach (string cardName in cards)
{
int value = GetCardValue(cardName);
if (IsAce(cardName))
{
aceCount++;
}
total += value;
}
while (total > 21 && aceCount > 0)
{
total -= 10;
aceCount--;
}
return total;
}
int GetCardValue(string cardName)
{
string lowerName = cardName.ToLower();
if (lowerName.Contains("ace"))
{
return 11;
}
if (lowerName.Contains("jack") || lowerName.Contains("queen") || lowerName.Contains("king"))
{
return 10;
}
Match match = Regex.Match(cardName, @"\d+");
if (match.Success)
{
return int.Parse(match.Value);
}
Debug.LogWarning("Card value not found: " + cardName);
return 0;
}
bool IsAce(string cardName)
{
return cardName.ToLower().Contains("ace");
}
GameObject SpawnCard(GameObject prefab, Transform pos, bool faceDown)
{
if (prefab == null || pos == null)
{
Debug.LogWarning("Card prefab or position is missing.");
return null;
}
GameObject card = Instantiate(prefab, pos.position, Quaternion.identity);
spawnedCards.Add(card);
card.transform.localScale = prefab.transform.localScale * cardScale;
if (faceDown)
{
card.transform.rotation = Quaternion.Euler(backRotation);
}
else
{
card.transform.rotation = Quaternion.Euler(frontRotation);
}
return card;
}
}