Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
W
Windbot-408
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Locked Files
Issues
0
Issues
0
List
Boards
Labels
Service Desk
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Security & Compliance
Security & Compliance
Dependency List
License Compliance
Packages
Packages
List
Container Registry
Analytics
Analytics
CI / CD
Code Review
Insights
Issues
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
神之吹息
Windbot-408
Commits
53ab0e7a
Commit
53ab0e7a
authored
Aug 06, 2024
by
YSP
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Update AI
parent
f5103dc4
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
138 additions
and
34 deletions
+138
-34
Game/AI/DefaultExecutor.cs
Game/AI/DefaultExecutor.cs
+100
-19
Game/AI/Executor.cs
Game/AI/Executor.cs
+20
-7
Game/GameAI.cs
Game/GameAI.cs
+18
-8
No files found.
Game/AI/DefaultExecutor.cs
View file @
53ab0e7a
...
...
@@ -5,6 +5,10 @@ using YGOSharp.OCGWrapper.Enums;
using
WindBot
;
using
WindBot.Game
;
using
WindBot.Game.AI
;
using
System.Runtime.Remoting.Messaging
;
using
System.Web.UI
;
using
static
WindBot
.
Game
.
AI
.
Decks
.
TimeThiefExecutor
;
using
System.IO
;
namespace
WindBot.Game.AI
{
...
...
@@ -137,26 +141,85 @@ namespace WindBot.Game.AI
protected
DefaultExecutor
(
GameAI
ai
,
Duel
duel
)
:
base
(
ai
,
duel
)
{
AddExecutor
(
ExecutorType
.
Activate
,
_CardId
.
ChickenGame
,
DefaultChickenGame
);
AddExecutor
(
ExecutorType
.
Activate
,
_CardId
.
ChickenGame
,
DefaultChickenGame
);
AddExecutor
(
ExecutorType
.
Activate
,
_CardId
.
VaylantzWorld_ShinraBansho
,
DefaultVaylantzWorld_ShinraBansho
);
AddExecutor
(
ExecutorType
.
Activate
,
_CardId
.
VaylantzWorld_KonigWissen
,
DefaultVaylantzWorld_KonigWissen
);
AddExecutor
(
ExecutorType
.
Activate
,
_CardId
.
SantaClaws
);
AddExecutor
(
ExecutorType
.
Activate
,
DefaultGambleCard
);
}
/// <summary>
/// Decide which card should the attacker attack.
/// </summary>
/// <param name="attacker">Card that attack.</param>
/// <param name="defenders">Cards that defend.</param>
/// <returns>BattlePhaseAction including the target, or null (in this situation, GameAI will check the next attacker)</returns>
public
override
BattlePhaseAction
OnSelectAttackTarget
(
ClientCard
attacker
,
IList
<
ClientCard
>
defenders
)
{
foreach
(
ClientCard
defender
in
defenders
)
DealerMaidenModeAddCardExecutor
();
//发牌姬行为放到单独函数统一管理
}
void
DealerMaidenModeAddCardExecutor
()
{
SetFuncFilter
(
ExecutorType
.
Activate
,()=>
{
if
(
Card
.
IsCode
(
5990062
))
return
Bot
.
HasInSpellZone
(
9373534
);
//[大逆转谜题]只有在自己场上有手里剑覆盖的场合才发动
if
(
Card
.
IsCode
(
3493058
))
return
Bot
.
GetSpellCount
()
+
Enemy
.
GetSpellCount
()
>
0
;
//[骰子旋风]玩家场上有魔陷才发动
if
(
Card
.
IsCode
(
22802010
))
return
Bot
.
GetMonsterCount
()
<
Enemy
.
GetMonsterCount
();
//[无差别崩坏]自己场上怪兽少于对方才发动
return
false
;
});
SetFuncFilter
(
ExecutorType
.
SummonOrSet
,
()
=>
{
if
(
Card
.
IsCode
(
71625222
))
return
Enemy
.
GetMonsterCount
()
>
0
;
//[时间魔术师]对方场上有怪兽存在才召唤
int
[]
codes
=
new
[]
{
23434538
,
46502744
,
87170768
,
25137581
,
14558127
,
60643553
,
27204311
,
94145021
,
59438930
,
2830693
,
19665973
,
18964575
,
34267821
,
24508238
,
78661338
,
84192580
,
52038441
,
62015408
};
foreach
(
int
code
in
codes
)
if
(
Card
.
IsCode
(
code
))
return
false
;
//过滤手坑
return
true
;
});
SetFuncFilter
(
ExecutorType
.
SpSummon
,()
=>
{
if
(
Card
.
HasType
(
CardType
.
Link
))
//链接怪兽特殊召唤前过滤
{
List
<
ClientCard
>
cards
=
Bot
.
GetMonsters
();
List
<
ClientCard
>
noLinkCards
=
Bot
.
GetMonsters
().
Where
(
card
=>
card
==
null
||
card
.
IsFacedown
()
||
card
.
Level
>=
8
||
card
.
LinkCount
>=
4
||
card
.
Rank
>=
8
||
card
.
Attack
>=
3000
).
ToList
();
foreach
(
var
card
in
noLinkCards
)
cards
.
Remove
(
card
);
int
link_count
=
0
;
foreach
(
var
card
in
cards
)
{
link_count
+=
(
card
.
HasType
(
CardType
.
Link
))
?
card
.
LinkCount
:
1
;
if
(
link_count
>=
Card
.
LinkCount
)
return
true
;
}
}
return
false
;
});
AddExecutor
(
ExecutorType
.
Activate
,
DefaultGambleCard
);
//默认发动的赌博卡
AddExecutor
(
ExecutorType
.
SpellSet
,
9373534
);
//[封魔手里剑]始终盖放
}
BattlePhaseAction
DealerMaidenModeOnSelectAttackTarget
(
ClientCard
attacker
,
IList
<
ClientCard
>
defenders
)
{
if
(
attacker
.
IsCode
(
1102515
))
//暗黑之宝箱怪 LV3
{
List
<
ClientCard
>
attakposCards
=
defenders
.
Where
(
card
=>
card
!=
null
&&
card
.
IsAttack
()).
ToList
();
attakposCards
.
Sort
(
CardContainer
.
CompareCardAttack
);
if
(
attakposCards
.
Count
()
<=
0
)
return
null
;
foreach
(
ClientCard
defender
in
attakposCards
)
{
attacker
.
RealPower
=
attacker
.
Attack
;
defender
.
RealPower
=
defender
.
Attack
;
if
(!
OnPreBattleBetween
(
attacker
,
defender
))
continue
;
if
((
defender
.
RealPower
-
attacker
.
RealPower
>
Bot
.
LifePoints
)
||
attacker
.
RealPower
>
defender
.
RealPower
)
continue
;
return
AI
.
Attack
(
attacker
,
defender
);
}
}
return
null
;
}
/// <summary>
/// Decide which card should the attacker attack.
/// </summary>
/// <param name="attacker">Card that attack.</param>
/// <param name="defenders">Cards that defend.</param>
/// <returns>BattlePhaseAction including the target, or null (in this situation, GameAI will check the next attacker)</returns>
public
override
BattlePhaseAction
OnSelectAttackTarget
(
ClientCard
attacker
,
IList
<
ClientCard
>
defenders
)
{
var
action
=
DealerMaidenModeOnSelectAttackTarget
(
attacker
,
defenders
);
if
(
action
!=
null
)
return
action
;
foreach
(
ClientCard
defender
in
defenders
)
{
attacker
.
RealPower
=
attacker
.
Attack
;
defender
.
RealPower
=
defender
.
GetDefensePower
();
if
(!
OnPreBattleBetween
(
attacker
,
defender
))
if
(!
OnPreBattleBetween
(
attacker
,
defender
))
//对这个逻辑进行修改
continue
;
if
(
attacker
.
RealPower
>
defender
.
RealPower
||
(
attacker
.
RealPower
>=
defender
.
RealPower
&&
attacker
.
IsLastAttacker
&&
defender
.
IsAttack
()))
...
...
@@ -322,10 +385,10 @@ namespace WindBot.Game.AI
return
false
;
}
/// <summary>
/// Set when this card can't beat the enemies
/// </summary>
public
override
bool
OnSelectMonsterSummonOrSet
(
ClientCard
card
)
/// <summary>
/// Set when this card can't beat the enemies
/// </summary>
public
override
bool
OnSelectMonsterSummonOrSet
(
ClientCard
card
)
{
return
card
.
Level
<=
4
&&
Bot
.
GetMonsters
().
Count
(
m
=>
m
.
IsFaceup
())
==
0
&&
Util
.
IsAllEnemyBetterThanValue
(
card
.
Attack
,
true
);
}
...
...
@@ -360,6 +423,24 @@ namespace WindBot.Game.AI
return
Util
.
CheckSelectCount
(
extraDeck
,
cards
,
min
,
max
);
}
if
(
hint
==
HintMsg
.
LinkMaterial
)
{
if
(
AI
.
HaveSelectedCards
())
return
null
;
List
<
ClientCard
>
result
=
new
List
<
ClientCard
>(
cards
);
List
<
ClientCard
>
powerfulMonsters
=
new
List
<
ClientCard
>();
List
<
ClientCard
>
lowMonsters
=
new
List
<
ClientCard
>();
foreach
(
ClientCard
card
in
result
)
{
if
(
card
.
Level
>=
8
||
card
.
LinkCount
>=
4
||
card
.
Rank
>=
8
||
card
.
Attack
>=
3000
)
powerfulMonsters
.
Add
(
card
);
else
lowMonsters
.
Add
(
card
);
}
lowMonsters
.
Sort
(
CardContainer
.
CompareCardAttack
);
powerfulMonsters
.
Sort
(
CardContainer
.
CompareCardAttack
);
powerfulMonsters
.
Reverse
();
lowMonsters
.
AddRange
(
powerfulMonsters
);
return
Util
.
CheckSelectCount
(
lowMonsters
,
cards
,
min
,
max
);
}
return
null
;
}
...
...
@@ -1315,7 +1396,7 @@ namespace WindBot.Game.AI
int
[]
cardsname
=
new
[]
{
3280747
,
37812118
,
50470982
,
43061293
,
37313786
,
3493058
,
38299233
,
25173686
,
71625222
,
36562627
,
19162134
,
81172176
,
21598948
,
39537362
,
36378044
,
38143903
,
96012004
,
62784717
,
84290642
,
3549275
,
41139112
,
36708764
,
74137509
,
126218
,
93078761
,
76895648
,
22802010
,
83241722
,
84397023
,
31863912
,
39454112
,
59905358
,
5990062
,
9373534
,
58577036
};
foreach
(
int
cardname
in
cardsname
)
if
(
Card
.
I
d
==
cardname
)
return
true
;
if
(
Card
.
I
sCode
(
cardname
)
)
return
true
;
return
false
;
}
}
...
...
Game/AI/Executor.cs
View file @
53ab0e7a
...
...
@@ -13,7 +13,8 @@ namespace WindBot.Game.AI
public
string
Deck
{
get
;
set
;
}
public
Duel
Duel
{
get
;
private
set
;
}
public
IList
<
CardExecutor
>
Executors
{
get
;
private
set
;
}
public
GameAI
AI
{
get
;
private
set
;
}
public
Dictionary
<
ExecutorType
,
Func
<
bool
>>
FuncFilters
{
get
;
private
set
;
}
public
GameAI
AI
{
get
;
private
set
;
}
public
AIUtil
Util
{
get
;
private
set
;
}
protected
MainPhase
Main
{
get
;
private
set
;
}
...
...
@@ -33,8 +34,15 @@ namespace WindBot.Game.AI
AI
=
ai
;
Util
=
new
AIUtil
(
duel
);
Executors
=
new
List
<
CardExecutor
>();
Bot
=
Duel
.
Fields
[
0
];
FuncFilters
=
new
Dictionary
<
ExecutorType
,
Func
<
bool
>>();
FuncFilters
.
Add
(
ExecutorType
.
Summon
,
null
);
FuncFilters
.
Add
(
ExecutorType
.
SpSummon
,
null
);
FuncFilters
.
Add
(
ExecutorType
.
MonsterSet
,
null
);
FuncFilters
.
Add
(
ExecutorType
.
Repos
,
null
);
FuncFilters
.
Add
(
ExecutorType
.
SpellSet
,
null
);
FuncFilters
.
Add
(
ExecutorType
.
Activate
,
null
);
FuncFilters
.
Add
(
ExecutorType
.
SummonOrSet
,
null
);
Bot
=
Duel
.
Fields
[
0
];
Enemy
=
Duel
.
Fields
[
1
];
}
...
...
@@ -247,10 +255,15 @@ namespace WindBot.Game.AI
CurrentTiming
=
timing
;
}
/// <summary>
/// Do the action for the card if func return true.
/// </summary>
public
void
AddExecutor
(
ExecutorType
type
,
int
cardId
,
Func
<
bool
>
func
)
public
void
SetFuncFilter
(
ExecutorType
type
,
Func
<
bool
>
func
)
{
FuncFilters
[
type
]
=
func
;
}
/// <summary>
/// Do the action for the card if func return true.
/// </summary>
public
void
AddExecutor
(
ExecutorType
type
,
int
cardId
,
Func
<
bool
>
func
)
{
Executors
.
Add
(
new
CardExecutor
(
type
,
cardId
,
func
));
}
...
...
Game/GameAI.cs
View file @
53ab0e7a
...
...
@@ -2,6 +2,8 @@
using
System.Collections.Generic
;
using
WindBot.Game.AI
;
using
YGOSharp.OCGWrapper.Enums
;
using
System
;
using
System.Threading
;
namespace
WindBot.Game
{
...
...
@@ -203,10 +205,10 @@ namespace WindBot.Game
if
(
result
!=
null
)
return
result
;
if
(
attackers
.
Count
==
0
)
if
(
attackers
.
Count
==
0
)
//如果自己场上没有可以攻击的怪兽直接返回
return
ToMainPhase2
();
if
(
defenders
.
Count
==
0
)
if
(
defenders
.
Count
==
0
)
//如果对方场上没有怪兽则直接攻击
{
// Attack with the monster with the lowest attack first
ClientCard
attacker
=
attackers
[
attackers
.
Count
-
1
];
...
...
@@ -214,17 +216,17 @@ namespace WindBot.Game
}
else
{
for
(
int
k
=
0
;
k
<
attackers
.
Count
;
++
k
)
for
(
int
k
=
0
;
k
<
attackers
.
Count
;
++
k
)
//如果对方场上有怪兽
{
ClientCard
attacker
=
attackers
[
k
];
attacker
.
IsLastAttacker
=
(
k
==
attackers
.
Count
-
1
);
result
=
Executor
.
OnSelectAttackTarget
(
attacker
,
defenders
);
result
=
Executor
.
OnSelectAttackTarget
(
attacker
,
defenders
);
//这个函数决定是否要攻击
if
(
result
!=
null
)
return
result
;
}
}
if
(!
battle
.
CanMainPhaseTwo
)
if
(!
battle
.
CanMainPhaseTwo
)
//如果不能进战阶强制攻击
return
Attack
(
attackers
[
0
],
(
defenders
.
Count
==
0
)
?
null
:
defenders
[
0
]);
return
ToMainPhase2
();
...
...
@@ -719,7 +721,7 @@ namespace WindBot.Game
sorted
.
Sort
(
CardContainer
.
CompareCardAttack
);
IList
<
ClientCard
>
selected
=
new
List
<
ClientCard
>();
for
(
int
i
=
0
;
i
<
min
&&
i
<
sorted
.
Count
;
++
i
)
selected
.
Add
(
sorted
[
i
]);
...
...
@@ -1137,9 +1139,17 @@ namespace WindBot.Game
return
false
;
}
Executor
.
SetCard
(
type
,
card
,
desc
,
timing
);
bool
result
=
card
!=
null
&&
exec
.
Type
==
type
&&
Func
<
bool
>
Func
=
()
=>
{
bool
res
=
Executor
.
FuncFilters
.
ContainsKey
(
exec
.
Type
)
&&
Executor
.
FuncFilters
[
exec
.
Type
]
!=
null
;
if
(
Executor
.
FuncFilters
.
ContainsKey
(
exec
.
Type
)
&&
Executor
.
FuncFilters
[
exec
.
Type
]
!=
null
&&
!
Executor
.
FuncFilters
[
exec
.
Type
]())
return
false
;
return
exec
.
Func
==
null
||
exec
.
Func
();
};
bool
result
=
card
!=
null
&&
exec
.
Type
==
type
&&
(
exec
.
CardId
==
-
1
||
exec
.
CardId
==
card
.
Id
)
&&
(
exec
.
Func
==
null
||
exec
.
Func
()
);
Func
(
);
if
(
card
.
Id
!=
0
&&
type
==
ExecutorType
.
Activate
&&
result
)
{
int
count
=
card
.
IsDisabled
()
?
3
:
1
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment