Asking AI to recommend a Clash Royale deck is not difficult. The truly valuable questions are: Why choose these eight cards? How do they work together? How should cards be played when attacking and defending? And how should the recommendation be validated?
Using a Giant counter-push deck with an average elixir cost of 3.5 as an example, this article introduces how to turn natural-language requirements into structured strategic analysis, then use code validation and image generation to produce a teaching plan that can be understood, practiced, and iterated on.
The entire process is not about having the model casually provide the “strongest deck,” but about dividing the work into four parts:
Clarify constraints → Analyze the deck → Validate the results → Create a visual tutorial.
¶ I. First clarify: What problem do we want AI to solve?
“Help me build a deck that is easy to win with” may seem clear, but it actually lacks many necessary conditions: Which arena is the player in? Which cards have they unlocked? Are their card levels similar? Are evolved cards, Hero abilities, or special Tower Troops being used? Is the player more familiar with fast cycle decks, or counter-pushes? Does “easy” mean simple to operate, or clearly advantageous against specific opponents?
If this information is not provided, the model can easily give a deck that is theoretically reasonable but not actually suitable for the player’s account. Therefore, this case first sets the following boundaries:
| Dimension | Constraints for This Case |
|---|---|
| Card selection | Prioritize basic, common Common and Rare cards |
| Card form | Standard forms, without relying on Evolutions or Hero abilities |
| Tower Troop conditions | Standard Princess Tower |
| Level conditions | Assume both sides have similar card levels |
| Operational goal | Clear roles, suitable for learning |
| Tactical direction | Organize a counter-push after a successful defense |
| Evaluation boundaries | Do not claim to be the strongest in the live version, and do not fabricate win rates |
These constraints determine the direction of the subsequent analysis: we are looking for a basic solution that is easy to understand and has complementary roles, rather than an untested “guaranteed-win formula.”
¶ II. Let GPT-6 Astra handle the analysis, and let programs handle the validation
This case calls GPT-6 Astra through AceDataCloud’s Chat Completions API, with the model identifier gpt-6-astra in the request. The API endpoint, authentication method, and message structure follow the platform integration documentation; model availability and parameters should be based on the platform configuration at the time of the call. The model identifier used here is provided by the platform and does not imply the availability of other service endpoints.
| Tool | Work It Is Responsible For | Work It Should Not Be Responsible For |
|---|---|---|
| GPT-6 Astra | Explain card roles, analyze synergies, organize offensive and defensive steps | Prove win rates in place of real battle data |
| Python | Validate card count, duplicates, costs, and combination costs | Judge real-game strength based only on addition |
| GPT Image 2 | Turn the tactical plan into a teaching poster | Serve as an authoritative source for game mechanics |
It is also necessary to distinguish between the historical process and the reproduction method: the eight-card deck in this case was formed during earlier analysis, and GPT-6 Astra was then actually called to conduct a structured review of it; Astra was not asked to search the full card pool for a globally optimal solution. The teaching poster was generated by Image 2.0.
Recording the process this way both makes reproduction easier and avoids exaggerating “the model participated in the analysis” into “the model proved the solution was optimal.”
¶ III. Prompt design: Turning “recommend a deck” into “reasoning under constraints”
¶ 1. Open-ended deck-building prompt
If starting from your own card collection, you can use the following template:
你是一名严谨的《皇室战争》教学分析助手。
目标:
从我提供的可用卡牌中,选择一套适合基础玩家的八张卡组。
条件:
1. 只使用我已解锁的卡牌。
2. 不依赖进化或英雄技能。
3. 默认普通公主塔,卡牌等级接近。
4. 优先职责互补、操作简单、方便学习的体系。
5. 必须说明主要拆塔手段、对空、清群和防守方式。
输入:
- 我的竞技场与杯数:……
- 可用卡牌及等级:……
- 常见对手:……
- 我的操作偏好:……
输出:
- 八张卡牌及职责
- 总费用与平均费用
- 选择理由
- 进攻与防守步骤
- 明确的弱点和替换代价
不得编造胜率。
若没有实时资料,不得声称这是当前版本最强卡组。
The key is not how long the prompt is, but whether it provides the permitted selection range, optimization objectives, and limitations that must be acknowledged.
¶ 2. The review prompt used in this case
To examine an existing plan, this task further narrows the scope. Below is an organized version of the actual review requirements:
请复核以下卡组,而不是重新寻找全卡池最优解:
巨人5、迷你皮卡4、火枪手4、炸弹兵2、
亡灵3、加农炮3、万箭齐发3、火球4。
默认:
卡等接近、普通公主塔、普通形态,
无进化、无英雄技能。
请返回一个有效的 json 对象,包含:
deck、total_elixir、average_elixir、
advantages、attack_steps、defense_cases、
limitations、validation_note。
要求:
- 说明每张卡的职责。
- 区分“利用防守残兵”和“免费获得单位”。
- 不得把11费组合说成满10费即可立即全部部署。
- 不承诺无伤防守。
- 不提供没有来源的精确伤害或胜率。
The core conclusion obtained from this actual call is: the deck has clear role divisions and is suitable for practicing defensive counterattacks, but air units need protection, and resources for responding to attacks on the other side must also be retained during the push phase. This is theoretical analysis based on the given mechanics, and does not equal simulator testing or ladder statistics.
¶ IV. Obtaining Structured Analysis Through the API
The Chat Completions API uses Bearer Token authentication, and the generated text can be read from choices[0].message.content.
Below is a streamlined Python reproduction example. Install requests before running it, and configure ACEDATACLOUD_API_KEY in your own runtime environment. Do not write the key into a code repository or browser frontend. The actual case used an MCP tool call; the code below demonstrates the corresponding HTTP integration method and does not claim that this script has been tested in the reader's environment.
import json
import os
import requests
URL = "https://api.acedata.cloud/openai/chat/completions"
# 本案例已核对的输入快照。
# 实际项目应维护版本化卡牌资料,不要依赖模型猜测费用。
cards = [
{"name": "巨人", "elixir": 5, "role": "只攻击建筑的高血量前排"},
{"name": "迷你皮卡", "elixir": 4, "role": "地面单体高伤"},
{"name": "火枪手", "elixir": 4, "role": "远程对地对空"},
{"name": "炸弹兵", "elixir": 2, "role": "地面范围伤害"},
{"name": "亡灵", "elixir": 3, "role": "空中部队,可对地对空"},
{"name": "加农炮", "elixir": 3, "role": "仅对地的防守建筑"},
{"name": "万箭齐发", "elixir": 3, "role": "清理脆皮群"},
{"name": "火球", "elixir": 4, "role": "范围伤害与补伤害"},
]
task = """
请复核输入卡组,返回有效的 json 对象。
输出字段:
deck(每项包含 name、elixir、role)、
total_elixir、average_elixir、advantages、
attack_steps、defense_cases、limitations、validation_note。
默认卡等接近、普通公主塔、普通形态,无进化无英雄。
这是已有卡组复核,不是全卡池最优搜索。
没有实时对战数据,不得编造胜率、无伤承诺或精确伤害。
"""
response = requests.post(
URL,
headers={
"Authorization": f"Bearer {os.environ['ACEDATACLOUD_API_KEY']}",
"Content-Type": "application/json",
},
json={
"model": "gpt-6-astra",
"messages": [
{
"role": "system",
"content": (
"Return a valid json object. "
"你是严谨的游戏教学助手,只基于给定事实分析。"
),
},
{
"role": "user",
"content": task + "\n输入卡组:\n"
+ json.dumps(cards, ensure_ascii=False),
},
],
"response_format": {"type": "json_object"},
"max_tokens": 2200,
},
timeout=(10, 180),
)
response.raise_for_status()
body = response.json()
if body.get("error"):
raise RuntimeError(body["error"])
choice = body["choices"][0]
if choice.get("finish_reason") != "stop":
raise RuntimeError("输出未正常结束,请检查返回状态或调整输出预算")
content = choice["message"].get("content")
if not content:
raise RuntimeError("没有获得可解析的分析内容")
result = json.loads(content)
print(json.dumps(result, ensure_ascii=False, indent=2))
¶ An Interface Detail Actually Encountered
In this call, the first JSON mode request was rejected by the server, with an error indicating that the input message needed to include json. After explicitly adding the English instruction Return a valid json object. to the message, the request succeeded.
There is no need to infer that the failure was necessarily caused by capitalization or other factors. A more robust engineering approach is to explicitly require JSON output, set the response format at the same time, check the completion status, and continue validating fields and values after parsing.
Being parseable as JSON only means that the syntax is valid; it does not mean the game analysis is correct.
¶ V. Final Deck: 3.5-Elixir Giant Defensive Counterattack
The plan for this case is as follows. The elixir costs come from the corresponding card data, while the roles and combinations are used to explain the design of this deck.
| Card | Elixir | Main Role | Usage Notes |
|---|---|---|---|
| Giant | 5 | Soaking damage, pushing, attacking buildings | Does not clear enemy troops |
| Mini P.E.K.K.A | 4 | Handling high-health ground targets | Easily surrounded or pulled away by small troops |
| Musketeer | 4 | Ranged damage, primary anti-air | Needs protection; avoid clumping with other backline units |
| Bomber | 2 | Clearing ground swarms | Cannot target air |
| Minions | 3 | Second anti-air option, supplemental damage | Vulnerable to Arrows and area damage |
| Cannon | 3 | Central pulling, defensive support | Cannot attack air units |
| Arrows | 3 | Clearing fragile swarms | Should be used against actual targets |
| Fireball | 4 | Hitting clustered backlines, finishing damage | Does not automatically one-shot same-level Musketeers |
The value of this deck is not the rarity of individual cards, but the complementary roles: Giant provides the primary tower-taking pressure, Mini P.E.K.K.A handles ground threats, Bomber clears troops that interfere with single-target damage, Musketeer and Minions provide two sustained anti-air options, Cannon creates time for damage output, and the two spells handle clearing and finishing damage.
¶ Verifying Elixir Costs with Code
Do not only read the model-returned average_elixir. A more reliable method is to: recalculate using the verified input data and cross-check it against the model output.
Append the following code after the preceding example:
trusted_costs = {card["name"]: card["elixir"] for card in cards}
deck = result["deck"]
names = [card["name"] for card in deck]
if len(names) != 8 or len(set(names)) != 8:
raise ValueError("卡组必须恰好包含8张不同卡牌")
if set(names) != set(trusted_costs):
raise ValueError("模型更改了本次要求复核的卡组")
for card in deck:
if card["elixir"] != trusted_costs[card["name"]]:
raise ValueError(f"费用不一致:{card['name']}")
total = sum(trusted_costs[name] for name in names)
average = total / len(names)
if result["total_elixir"] != total:
raise ValueError("模型返回的总费用不一致")
if abs(float(result["average_elixir"]) - average) > 1e-9:
raise ValueError("模型返回的平均费用不一致")
print(f"总费用:{total},平均费用:{average}")
The independent cost check result for this example is:
Total cost: 5 + 4 + 4 + 2 + 3 + 3 + 3 + 4 = 28
Average cost: 28 ÷ 8 = 3.5
You can also continue checking common combinations:
| Combination | Total Cost | Purpose |
|---|---|---|
| Giant + Bomber | 7 | A light push against ground swarms |
| Giant + Musketeer | 9 | A standard push with anti-air capability |
| Mini P.E.K.K.A + Bomber | 6 | Handle tanks and ground swarms respectively |
| Cannon + Musketeer | 7 | Kiting and ranged damage output |
| Giant + Musketeer + Bomber | 11 | Gradually form a full push by using surviving troops or regenerating Elixir |
The final item is especially worth noting: an 11-Elixir combination cannot be fully deployed immediately when you have only 10 Elixir. It is more suitable for combining a surviving defensive Musketeer or Bomber with a newly deployed Giant, rather than stacking all three cards at once. Combination cost is only the investment cost; it does not prove that you can consistently gain an Elixir advantage.
¶ VI. Transform the Analysis into an Executable Offensive and Defensive Plan
¶ Offense: Defend First, Then Turn Surviving Troops into Pressure
The main line of this deck is not to deploy the Giant at the start, but rather:
- Use the Cannon or troops to deal with the enemy's attack.
- Observe the health, position, and current Elixir of surviving units.
- When conditions are suitable, place a Giant in front of the surviving troops.
- After seeing the opponent's response cards, decide whether to add troops or use a spell.
- Retain the ability to deal with an attack on the other lane.
For example, if the Musketeer survives after defending, deploy the Giant before she crosses the bridge, allowing the Giant to absorb damage first while the Musketeer continues dealing damage. The resource gain here comes from one already-paid unit participating in both defense and counterattack, rather than somehow obtaining a free Musketeer out of nowhere.
¶ Defense: Choose Components Based on the Threat
| Opponent Threat | Priority Response Approach |
|---|---|
| Building-targeting units such as Hog Rider | Use the Cannon in the center to kite in time, and add cards depending on supporting units |
| High-health ground targets | Use Mini P.E.K.K.A together with tower damage; if necessary, use a building first to alter the path |
| Ground swarms | Handle them with Bomber, or use Arrows at the appropriate time |
| Air attacks | Deploy Musketeer and Minions separately to avoid both being cleared by area damage |
| Clustered backline support | Use Fireball for additional damage, then let troops take over |
All of these plans depend on positioning, levels, timing, and enemy support, and cannot be understood as fixed, damage-free formulas. Although the Cannon can attract air units that only target buildings, it cannot deal anti-air damage itself.
¶ Weaknesses That Must Be Retained
A qualified AI strategy output should clearly tell players when the deck will be difficult to play:
- After the Musketeer and Minions are removed, anti-air pressure will increase significantly.
- This deck has no reset spell, so you cannot blindly stack troops against Inferno-type defenses.
- After deploying the Giant, the other lane may become a target for the opponent's pressure.
- A 3.5-Elixir average does not mean an extremely fast cycle; when key defensive cards are out of rotation, they may not return to hand in time.
Therefore, the model provides a starting point for practice, and further adjustments should still be made based on your own card levels, common opponents, and battle records.
¶ VII. Generate a 4K Teaching Poster from the Tactical Plan
Text is suitable for explaining reasons, while images are more suitable for showing positional relationships and card-play order. This case does not use a mechanical arrangement of eight large cards, but instead designs the image as three connected teaching stages:
Low-cost defense → Giant in front, surviving troops follow → Identify response cards clearly, add support.
The image below is the teaching poster generated by Image 2.0 this time. The image file was checked and found to have dimensions of 3840×2160, 16:9.

Image: An AI-generated tactical teaching illustration, not an in-game battle screenshot, and not intended to represent precise attack ranges or grid-by-grid positioning.
¶ Prompts Should Describe “Teaching Relationships,” Not Just “Visual Style”
“4K, rich details, cinematic feel” can only describe the visual direction; it cannot guarantee that the generated result has teaching value. Therefore, prompts should also include:
- Role relationships: The Giant is in front, with the Musketeer and Bomber behind.
- Phase relationships: Defend on the left, counterattack on the right, connected with arrows.
- Mechanic constraints: The Giant only attacks buildings; the Cannon and Bomber cannot target air units.
- Information hierarchy: Title, three-step tutorial, deck list, costs, notes.
- Boundary statement: Standard-form tutorial; effectiveness is affected by card levels and execution.
Below is a concise prompt suitable for reproducing the concept, not a word-for-word record of the original long prompt:
制作一张16:9横版、3840×2160的中文战术教学海报。
主题:皇室战争“3.5费巨人防守反击”。
画面不是卡牌网格,而是生动的3D卡通竞技场教学场景。
左侧:加农炮中场拉扯,迷你皮卡处理地面肉盾,
火枪手对空,炸弹兵清理地面小兵。
右侧:巨人在最前方向敌方建筑推进,
防守存活的火枪手和炸弹兵在后方分散跟进,
亡灵提供空中支援。
用清晰箭头表达:
低费防守 → 补巨人反击 → 看清解牌再补支援。
底部展示八张卡及费用:
巨人5、迷你皮卡4、火枪手4、炸弹兵2、
亡灵3、加农炮3、万箭齐发3、火球4。
标注:
平均圣水3.5;
巨人+炸弹兵=7费;
巨人+火枪手=9费。
提醒:
保留防守圣水、后排分散站位、先看解牌再交法术。
确保中文清晰、战术指向准确。
不要画巨人攻击部队,不要画加农炮或炸弹兵攻击空中。
¶ Image API Configuration
The image generation API documentation supports specifying pixel dimensions through size; the 16:9 4K specification is 3840x2160. Writing only “4K” in the prompt cannot replace the size parameter.
The core request body configuration is as follows, where prompt should be replaced with the complete poster description:
{
"model": "gpt-image-2",
"prompt": "此处填写完整的战术教学海报提示词",
"size": "3840x2160",
"quality": "high",
"n": 1,
"output_format": "png",
"response_format": "url"
}
The corresponding endpoint is:
POST https://api.acedata.cloud/openai/images/generations
¶ Failures and Switching During the Actual Generation Process
Image 2.5 was initially used for this attempt, but the task ended with a clear upstream service error and produced no image. After confirming the switch, gpt-image-2 was used instead, retaining the 4K and 16:9 specifications, and generation was ultimately successful.
There is an important engineering principle here:
While a task is still running, query the same task; only after the task clearly fails should you decide whether to retry or switch models.
The MCP image tool used this time runs through asynchronous tasks: obtain a task ID after submission, then query until success or failure. When directly calling the HTTP API, handle synchronous responses or asynchronous callbacks according to the relevant documentation, and do not mix the response structures of different calling methods.
¶ 8. How Can It Be Further Developed into a Sustainably Iterative Tool?
To expand this case into a real deck assistant, three layers of capability can be added.
¶ 1. Versioned Data
Record card names, costs, attack targets, levels, and data update times. For data that changes easily, such as damage, health, and range, use sourced information rather than relying on model memory.
¶ 2. User Card Collection Constraints
Use the cards unlocked by the user and their levels as inputs. When level differences are large, a theoretically reasonable combination does not necessarily mean better actual performance.
¶ 3. Battle Feedback
Continuously record the opponent’s primary offensive methods, at which stage you lose the elixir advantage, whether key anti-air cards are mistimed, and whether the problem comes from deck structure or placement and timing.
Then let the model make adjustment suggestions that change only one or two variables at a time based on these records, rather than replacing the entire deck after every lost match.
The poster should also undergo independent acceptance checks: verify whether all eight cards are present, whether the Chinese is correct, whether the costs are consistent, and whether the arrows point to the correct targets. Successful generation does not mean the content has passed acceptance, and correct resolution does not mean the tactical diagram is fully accurate.
¶ Conclusion
What this case demonstrates is not “AI automatically calculates the strongest deck,” but a more reliable method of use:
Use constraints to define the task, use GPT-6 Astra to explain combinations, use code to verify numbers, use Image 2.0 to present tactics, and then use battle feedback to refine the plan.
The core idea of the resulting Giant deck can be condensed into one sentence:
Use the Cannon to pull units, Mini P.E.K.K.A to deal with tanks, Musketeer for air defense, and Bomber to clear swarms; after defending successfully, put the Giant in front.
Compared with merely obtaining the names of eight cards, the greater value of this approach is that players not only know “what to bring,” but can also understand “why to bring it this way, and when to play it this way.”
¶ References
- Chat Completions API Integration Guide
- Chat Completions API Parameter Documentation
- GPT Image Generation Integration Guide
- Image Generation API Parameter Documentation
- For card cost references, see the card information links for each card in the deck table; actual battle values and available features are subject to the current in-game information.
This article is an AI-assisted strategy and development practice case, not an official Supercell guide. The cover and tutorial poster are AI-generated illustrative images; characters and trademarks related to Clash Royale belong to their respective rights holders.

