Skip to content

Commit 230483a

Browse files
committed
e
1 parent 39995fc commit 230483a

File tree

3 files changed

+67
-41
lines changed

3 files changed

+67
-41
lines changed

source/archipelago/APCategoryState.hx

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,14 @@ class APCategoryState extends states.CategoryState {
156156
archipelago.APGameState.instance = null;
157157
}
158158

159+
// AP Freeplay references
160+
if (managers.FreeplayManager.instance is APFreeplayManager) {
161+
managers.FreeplayManager.instance = null;
162+
managers.APFreeplayManager.cleanup();
163+
}
164+
165+
166+
159167
// Clean up local references in this state
160168
AP = null;
161169
gameState = null;
@@ -194,6 +202,8 @@ class APCategoryState extends states.CategoryState {
194202
archipelago.APGameState.instance = null;
195203
AP = null;
196204
gameState = null;
205+
managers.FreeplayManager.instance = null;
206+
managers.APFreeplayManager.cleanup();
197207

198208
// Clean up AP Items and data
199209
archipelago.APItem.cleanupAllAPData();
@@ -281,6 +291,8 @@ class APCategoryState extends states.CategoryState {
281291
archipelago.APStyledEntryState.apGame = null;
282292
archipelago.APStyledEntryState.ap = null;
283293
archipelago.APGameState.instance = null;
294+
managers.FreeplayManager.instance = null;
295+
managers.APFreeplayManager.cleanup();
284296

285297
// Clean up AP Items and data
286298
archipelago.APItem.cleanupAllAPData();

source/games/uno/backend/UnoCPU.hx

Lines changed: 43 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,23 @@
11
package games.uno.backend;
22

3-
using Math;
4-
5-
import games.uno.backend.UnoRules.UnoGameState;
63
import games.uno.backend.UnoCard.UnoColor;
4+
import games.uno.backend.UnoRules.UnoGameState;
5+
6+
using Math;
77

88
/**
99
* AI player implementation for UNO with different difficulty levels
1010
*/
1111
class UnoCPU extends UnoPlayer {
1212
public var difficulty:UnoDifficulty;
1313
public var thinkingTime:Float; // Delay to simulate thinking
14-
14+
1515
public function new(id:String, name:String, difficulty:UnoDifficulty = NORMAL) {
1616
super(id, name, false);
1717
this.difficulty = difficulty;
1818
this.thinkingTime = getDifficultyThinkingTime(difficulty);
1919
}
20-
20+
2121
/**
2222
* Get thinking time based on difficulty
2323
*/
@@ -29,33 +29,33 @@ class UnoCPU extends UnoPlayer {
2929
case EXPERT: 1.5;
3030
}
3131
}
32-
32+
3333
/**
3434
* CPU chooses a card to play
3535
*/
3636
public function chooseCard(topCard:UnoCard, gameState:UnoGameState):Int {
3737
var playableCards = getPlayableCards(topCard);
38-
38+
3939
if (playableCards.length == 0) {
4040
return -1; // No playable cardsdr
4141
}
42-
42+
4343
return switch(difficulty) {
4444
case EASY: chooseCardEasy(playableCards, topCard, gameState);
4545
case NORMAL: chooseCardNormal(playableCards, topCard, gameState);
4646
case HARD: chooseCardHard(playableCards, topCard, gameState);
4747
case EXPERT: chooseCardExpert(playableCards, topCard, gameState);
4848
}
4949
}
50-
50+
5151
/**
5252
* Easy AI - Random card selection
5353
*/
5454
private function chooseCardEasy(playableCards:Array<UnoCard>, topCard:UnoCard, gameState:UnoGameState):Int {
5555
var randomCard = playableCards[Math.floor(Math.random() * playableCards.length)];
5656
return hand.cards.indexOf(randomCard);
5757
}
58-
58+
5959
/**
6060
* Normal AI - Basic strategy
6161
*/
@@ -66,25 +66,25 @@ class UnoCPU extends UnoPlayer {
6666
return hand.cards.indexOf(card);
6767
}
6868
}
69-
69+
7070
// Then number cards
7171
for (card in playableCards) {
7272
if (card.type == NUMBER) {
7373
return hand.cards.indexOf(card);
7474
}
7575
}
76-
76+
7777
// Finally wild cards
7878
return hand.cards.indexOf(playableCards[0]);
7979
}
80-
80+
8181
/**
8282
* Hard AI - Strategic play
8383
*/
8484
private function chooseCardHard(playableCards:Array<UnoCard>, topCard:UnoCard, gameState:UnoGameState):Int {
8585
var nextPlayer = gameState.getNextPlayer();
8686
var isNextPlayerClose = nextPlayer.getHandSize() <= 3;
87-
87+
8888
// If next player is close to winning, try to disrupt them
8989
if (isNextPlayerClose) {
9090
// Use action cards to disrupt
@@ -94,7 +94,7 @@ class UnoCPU extends UnoPlayer {
9494
}
9595
}
9696
}
97-
97+
9898
// Save wild cards for later unless necessary
9999
var nonWildCards = [];
100100
for (card in playableCards) {
@@ -109,43 +109,43 @@ class UnoCPU extends UnoPlayer {
109109
return hand.cards.indexOf(card);
110110
}
111111
}
112-
112+
113113
// Then highest value number cards
114114
nonWildCards.sort(function(a, b) return b.value - a.value);
115115
return hand.cards.indexOf(nonWildCards[0]);
116116
}
117-
117+
118118
return hand.cards.indexOf(playableCards[0]);
119119
}
120-
120+
121121
/**
122122
* Expert AI - Advanced strategy
123123
*/
124124
private function chooseCardExpert(playableCards:Array<UnoCard>, topCard:UnoCard, gameState:UnoGameState):Int {
125125
var cardScores = [];
126-
126+
127127
for (card in playableCards) {
128128
var score = evaluateCardPlay(card, topCard, gameState);
129129
cardScores.push({card: card, score: score});
130130
}
131-
131+
132132
// Sort by score (highest first)
133133
cardScores.sort(function(a, b) return Math.round(b.score - a.score));
134-
134+
135135
return hand.cards.indexOf(cardScores[0].card);
136136
}
137-
137+
138138
/**
139139
* Evaluate the strategic value of playing a card
140140
*/
141141
private function evaluateCardPlay(card:UnoCard, topCard:UnoCard, gameState:UnoGameState):Float {
142142
var score = 0.0;
143143
var nextPlayer = gameState.getNextPlayer();
144144
var isNextPlayerClose = nextPlayer.getHandSize() <= 3;
145-
145+
146146
// Basic card value
147147
score += card.getPointValue() * 0.1;
148-
148+
149149
// Action card bonuses
150150
switch(card.type) {
151151
case SKIP:
@@ -165,37 +165,37 @@ class UnoCPU extends UnoPlayer {
165165
case CUSTOM(name, points, cpuImportance, action):
166166
score += cpuImportance;
167167
}
168-
168+
169169
// Color strategy (including custom colors)
170170
var colorCount = hand.getCardsByColor(card.color).length;
171171
if (!card.isWildCard()) {
172172
score += colorCount * 2; // Prefer playing colors we have more of
173173
}
174-
174+
175175
// Custom color bonus - slightly prefer custom colors if we have many
176176
switch(card.color) {
177177
case CUSTOM(color, name):
178178
score += colorCount > 2 ? 3 : 1; // Small bonus for custom colors
179179
case _: // Standard colors get no bonus
180180
}
181-
181+
182182
// End game strategy
183183
if (hand.getSize() <= 2) {
184184
// Prioritize getting rid of high-value cards
185185
score += card.getPointValue() * 0.5;
186186
}
187-
187+
188188
return score;
189189
}
190-
190+
191191
/**
192192
* CPU chooses a color for wild cards (including custom colors)
193193
*/
194194
public function chooseWildColor(?availableColors:Array<UnoColor>):UnoColor {
195195
// If no colors are specified, use standard colors plus any custom colors found in hand
196196
if (availableColors == null) {
197197
availableColors = UnoCard.getStandardColors();
198-
198+
199199
// Add any custom colors found in the hand
200200
for (card in hand.cards) {
201201
switch(card.color) {
@@ -214,7 +214,7 @@ class UnoCPU extends UnoPlayer {
214214
}
215215
}
216216
}
217-
217+
218218
var colorCounts = [];
219219
for (color in availableColors) {
220220
if (color != WILD) { // Don't count wild as a choosable color
@@ -224,45 +224,47 @@ class UnoCPU extends UnoPlayer {
224224
});
225225
}
226226
}
227-
227+
228228
// Sort by count (highest first)
229229
colorCounts.sort(function(a, b) return b.count - a.count);
230-
230+
231+
colorCounts = colorCounts.filter(function(c) return c.count > 0);
232+
231233
// Add some randomness for lower difficulties
232234
var randomFactor = switch(difficulty) {
233235
case EASY: Math.random() < 0.5;
234236
case NORMAL: Math.random() < 0.3;
235237
case HARD: Math.random() < 0.1;
236238
case EXPERT: false;
237239
}
238-
240+
239241
if (randomFactor && colorCounts.length > 1) {
240242
return colorCounts[1].color; // Choose second best sometimes
241243
}
242-
244+
243245
// Return the color with the most cards, or a random standard color if no cards
244246
return colorCounts.length > 0 ? colorCounts[0].color : UnoColor.RED;
245247
}
246-
248+
247249
/**
248250
* CPU decides whether to challenge a Wild Draw Four
249251
*/
250252
public function shouldChallenge(previousPlayer:UnoPlayer, topCard:UnoCard):Bool {
251253
if (difficulty == EASY) {
252254
return Math.random() < 0.1; // 10% chance
253255
}
254-
256+
255257
if (difficulty == NORMAL) {
256258
return Math.random() < 0.3; // 30% chance
257259
}
258-
260+
259261
// Hard and Expert: Strategic decision based on game state
260262
var handSize = previousPlayer.getHandSize();
261263
var challengeProbability = handSize <= 2 ? 0.7 : 0.4; // More likely to challenge if they're close to winning
262-
264+
263265
return Math.random() < challengeProbability;
264266
}
265-
267+
266268
/**
267269
* CPU automatically calls UNO when appropriate
268270
*/
@@ -274,7 +276,7 @@ class UnoCPU extends UnoPlayer {
274276
case HARD: 0.95;
275277
case EXPERT: 1.0; // Never forgets
276278
}
277-
279+
278280
if (Math.random() < callProbability) {
279281
callUno();
280282
}

source/managers/APFreeplayManager.hx

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,18 @@ class APFreeplayManager extends FreeplayManager {
190190
}
191191
}
192192

193+
194+
public static function cleanup() {
195+
curUnlocked = [];
196+
curMissing = [];
197+
curHinted = [];
198+
hintTable = new Map<String, String>();
199+
trueMissing = [];
200+
unplayedList = [];
201+
callVictory = false;
202+
trace("APFreeplayManager cleaned up.");
203+
}
204+
193205
public static function checkSongStatus() {
194206
trueMissing = [];
195207
unplayedList = [];

0 commit comments

Comments
 (0)