Files
tcg-client/Assets/TcgEngine/Scripts/AI/AIPlayerMM.cs
yaoyanwei 2f2a601227 init
2025-08-04 16:45:48 +08:00

287 lines
7.5 KiB
C#

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using TcgEngine.Gameplay;
namespace TcgEngine.AI
{
/// <summary>
/// AI player using the MinMax AI algorithm
/// </summary>
public class AIPlayerMM : AIPlayer
{
private AILogic ai_logic;
private bool is_playing = false;
public AIPlayerMM(GameLogic gameplay, int id, int level)
{
this.gameplay = gameplay;
player_id = id;
ai_level = Mathf.Clamp(level, 1, 10);
ai_logic = AILogic.Create(id, ai_level);
}
public override void Update()
{
Game game_data = gameplay.GetGameData();
Player player = game_data.GetPlayer(player_id);
if (!is_playing && game_data.IsPlayerTurn(player))
{
is_playing = true;
TimeTool.StartCoroutine(AiTurn());
}
if (!is_playing && game_data.IsPlayerMulliganTurn(player))
{
SkipMulligan();
}
if (!game_data.IsPlayerTurn(player) && ai_logic.IsRunning())
Stop();
}
private IEnumerator AiTurn()
{
yield return new WaitForSeconds(1f);
Game game_data = gameplay.GetGameData();
ai_logic.RunAI(game_data);
while (ai_logic.IsRunning())
{
yield return new WaitForSeconds(0.1f);
}
AIAction best = ai_logic.GetBestAction();
if (best != null)
{
Debug.Log("Execute AI Action: " + best.GetText(game_data) + "\n" + ai_logic.GetNodePath());
//foreach (NodeState node in ai_logic.GetFirst().childs)
// Debug.Log(ai_logic.GetNodePath(node));
ExecuteAction(best);
}
ai_logic.ClearMemory();
yield return new WaitForSeconds(0.5f);
is_playing = false;
}
private void Stop()
{
ai_logic.Stop();
is_playing = false;
}
//----------
private void ExecuteAction(AIAction action)
{
if (!CanPlay())
return;
if (action.type == GameAction.PlayCard)
{
PlayCard(action.card_uid, action.slot);
}
if (action.type == GameAction.Attack)
{
AttackCard(action.card_uid, action.target_uid);
}
if (action.type == GameAction.AttackPlayer)
{
AttackPlayer(action.card_uid, action.target_player_id);
}
if (action.type == GameAction.Move)
{
MoveCard(action.card_uid, action.slot);
}
if (action.type == GameAction.CastAbility)
{
CastAbility(action.card_uid, action.ability_id);
}
if (action.type == GameAction.SelectCard)
{
SelectCard(action.target_uid);
}
if (action.type == GameAction.SelectPlayer)
{
SelectPlayer(action.target_player_id);
}
if (action.type == GameAction.SelectSlot)
{
SelectSlot(action.slot);
}
if (action.type == GameAction.SelectChoice)
{
SelectChoice(action.value);
}
if (action.type == GameAction.SelectCost)
{
SelectCost(action.value);
}
if (action.type == GameAction.SelectMulligan)
{
SkipMulligan();
}
if (action.type == GameAction.CancelSelect)
{
CancelSelect();
}
if (action.type == GameAction.EndTurn)
{
EndTurn();
}
if (action.type == GameAction.Resign)
{
Resign();
}
}
private void PlayCard(string card_uid, Slot slot)
{
Game game_data = gameplay.GetGameData();
Card card = game_data.GetCard(card_uid);
if (card != null)
{
gameplay.PlayCard(card, slot);
}
}
private void MoveCard(string card_uid, Slot slot)
{
Game game_data = gameplay.GetGameData();
Card card = game_data.GetCard(card_uid);
if (card != null)
{
gameplay.MoveCard(card, slot);
}
}
private void AttackCard(string attacker_uid, string target_uid)
{
Game game_data = gameplay.GetGameData();
Card card = game_data.GetCard(attacker_uid);
Card target = game_data.GetCard(target_uid);
if (card != null && target != null)
{
gameplay.AttackTarget(card, target);
}
}
private void AttackPlayer(string attacker_uid, int target_player_id)
{
Game game_data = gameplay.GetGameData();
Card card = game_data.GetCard(attacker_uid);
if (card != null)
{
Player oplayer = game_data.GetPlayer(target_player_id);
gameplay.AttackPlayer(card, oplayer);
}
}
private void CastAbility(string caster_uid, string ability_id)
{
Game game_data = gameplay.GetGameData();
Card caster = game_data.GetCard(caster_uid);
AbilityData iability = AbilityData.Get(ability_id);
if (caster != null && iability != null)
{
gameplay.CastAbility(caster, iability);
}
}
private void SelectCard(string target_uid)
{
Game game_data = gameplay.GetGameData();
Card target = game_data.GetCard(target_uid);
if (target != null)
{
gameplay.SelectCard(target);
}
}
private void SelectPlayer(int tplayer_id)
{
Game game_data = gameplay.GetGameData();
Player target = game_data.GetPlayer(tplayer_id);
if (target != null)
{
gameplay.SelectPlayer(target);
}
}
private void SelectSlot(Slot slot)
{
if (slot != Slot.None)
{
gameplay.SelectSlot(slot);
}
}
private void SelectChoice(int choice)
{
gameplay.SelectChoice(choice);
}
private void SelectCost(int cost)
{
gameplay.SelectCost(cost);
}
private void CancelSelect()
{
if (CanPlay())
{
gameplay.CancelSelection();
}
}
private void SkipMulligan()
{
string[] cards = new string[0]; //Don't mulligan
SelectMulligan(cards);
}
private void SelectMulligan(string[] cards)
{
Game game_data = gameplay.GetGameData();
Player player = game_data.GetPlayer(player_id);
gameplay.Mulligan(player, cards);
}
private void EndTurn()
{
if (CanPlay())
{
gameplay.EndTurn();
}
}
private void Resign()
{
int other = player_id == 0 ? 1 : 0;
gameplay.EndGame(other);
}
}
}