Refactored gameflow to a static method, Updated All code. Refactored existing phases to seperate classes

master
j 2024-05-02 00:48:51 -04:00
parent 399fdfbe38
commit 8b630c45c9
7 changed files with 221 additions and 216 deletions

View File

@ -3,224 +3,88 @@ import { MessageService, MessageFileName } from '../utils/MessageService'
import { CommentPoster } from '../rdrama/services/CommentPoster';
import { RidersPhase } from '../phases/riders';
import { HuntPhase } from '../phases/hunt';
import { HandleSetup } from '../phases/setup';
import { HandleSetup as SetupPhase } from '../phases/setup';
import { travelPhase as TravelPhase } from '../phases/travel';
import { ActionPhase } from '../phases/action';
class GameFlow {
gameState: GameState;
constructor(gameState: GameState) {
this.gameState = gameState;
}
static async executeCurrentPhase(gameState: GameState, userInput?: string) {
GameFlow.cleanupGameState(gameState);
async executeCurrentPhase(userInput?: string) {
this.cleanupGameState();
switch (this.gameState.phase) {
switch (gameState.phase) {
case PHASE_ENUM.SETUP:
// Handle the setup phase, e.g., initial purchases
await HandleSetup.handleSetupPhase(this.gameState, this, userInput);
await SetupPhase.handleSetupPhase(gameState, userInput);
break;
case PHASE_ENUM.START_TURN:
await this.startTurn();
await GameFlow.startTurn(gameState);
break;
case PHASE_ENUM.ACTION_CHOICE:
await this.actionChoice(userInput)
await ActionPhase.actionChoice(gameState, userInput)
break;
case PHASE_ENUM.TRAVEL:
// Handle travel logic
await this.handleTravel();
await TravelPhase.handleTravel(gameState, userInput);
break;
case PHASE_ENUM.FORT:
// Handle interactions at the fort
await HandleSetup.handleSetupPhase(this.gameState, this, userInput);
await SetupPhase.handleSetupPhase(gameState, userInput);
break;
case PHASE_ENUM.HUNT:
// Handle hunting logic
await HuntPhase.handleHunt(this.gameState, this, userInput);
await HuntPhase.handleHunt(gameState, userInput);
break;
case PHASE_ENUM.RIDERS_ATTACK:
// Handle a riders attack phase
await RidersPhase.handleRidersAttack(this.gameState, this, userInput);
await RidersPhase.handleRidersAttack(gameState, userInput);
break;
case PHASE_ENUM.EVENT:
// Handle random events that can occur
await this.handleRandomEvent();
break;
case PHASE_ENUM.MOUNTAIN:
// Handle mountain traversal challenges
await this.handleMountain();
break;
case PHASE_ENUM.DEATH:
// Check if conditions leading to the player's death have been met
break;
default:
console.error("Unknown game phase:", this.gameState.phase);
console.error("Unknown game phase:", gameState.phase);
break;
}
}
private cleanupGameState(): void {
static cleanupGameState(gameState: GameState): void {
// Ensure all expenditures are non-negative
this.gameState.amountSpentOnFood = Math.max(0, this.gameState.amountSpentOnFood);
this.gameState.amountSpentOnAmmunition = Math.max(0, this.gameState.amountSpentOnAmmunition);
this.gameState.amountSpentOnClothing = Math.max(0, this.gameState.amountSpentOnClothing);
this.gameState.amountSpentOnMiscellaneousSupplies = Math.max(0, this.gameState.amountSpentOnMiscellaneousSupplies);
gameState.amountSpentOnFood = Math.max(0, gameState.amountSpentOnFood);
gameState.amountSpentOnAmmunition = Math.max(0, gameState.amountSpentOnAmmunition);
gameState.amountSpentOnClothing = Math.max(0, gameState.amountSpentOnClothing);
gameState.amountSpentOnMiscellaneousSupplies = Math.max(0, gameState.amountSpentOnMiscellaneousSupplies);
// Round expenditures and cash to integers
this.gameState.amountSpentOnFood = Math.floor(this.gameState.amountSpentOnFood);
this.gameState.amountSpentOnAmmunition = Math.floor(this.gameState.amountSpentOnAmmunition);
this.gameState.amountSpentOnClothing = Math.floor(this.gameState.amountSpentOnClothing);
this.gameState.amountSpentOnMiscellaneousSupplies = Math.floor(this.gameState.amountSpentOnMiscellaneousSupplies);
this.gameState.totalMileageWholeTrip = Math.floor(this.gameState.totalMileageWholeTrip);
gameState.amountSpentOnFood = Math.floor(gameState.amountSpentOnFood);
gameState.amountSpentOnAmmunition = Math.floor(gameState.amountSpentOnAmmunition);
gameState.amountSpentOnClothing = Math.floor(gameState.amountSpentOnClothing);
gameState.amountSpentOnMiscellaneousSupplies = Math.floor(gameState.amountSpentOnMiscellaneousSupplies);
gameState.totalMileageWholeTrip = Math.floor(gameState.totalMileageWholeTrip);
//Round Cash to two digits
this.gameState.cashLeftAfterInitialPurchases = Math.floor(this.gameState.cashLeftAfterInitialPurchases * 100) / 100;
gameState.cashLeftAfterInitialPurchases = Math.floor(gameState.cashLeftAfterInitialPurchases * 100) / 100;
}
private async startTurn(): Promise<void> {
static async startTurn(gameState: GameState): Promise<void> {
// Update total mileage up through the previous turn
this.gameState.totalMileageUpThroughPreviousTurn = this.gameState.totalMileageWholeTrip;
gameState.totalMileageUpThroughPreviousTurn = gameState.totalMileageWholeTrip;
// Toggle fort option flag
this.gameState.fortOptionFlag = !this.gameState.fortOptionFlag;
gameState.fortOptionFlag = !gameState.fortOptionFlag;
this.gameState.phase = PHASE_ENUM.ACTION_CHOICE;
await this.gameState.save()
gameState.phase = PHASE_ENUM.ACTION_CHOICE;
await gameState.save()
this.executeCurrentPhase()
}
private async actionChoice(userInput?: string): Promise<void> {
let responseMessage = "";
userInput = userInput?.toLowerCase()
console.log("userInput", userInput);
switch (userInput) {
case "1": // Hunt
if (this.gameState.amountSpentOnAmmunition < 40) {
responseMessage = `You do not have enough ammunition to hunt. Purchase more ammunition first.\n\n`;
if (this.gameState.fortOptionFlag) {
responseMessage += `Do you want to:\n2. Continue\n3. Stop at the Next Fort\n\n`
} else {
responseMessage += `Do you want to:\n2. Continue\n\n`
}
await MessageService.statusUpdate(this.gameState, responseMessage)
} else {
this.gameState.phase = PHASE_ENUM.HUNT;
this.gameState.totalMileageWholeTrip -= 45;
await this.gameState.save()
this.executeCurrentPhase()
}
return;
break;
case "2": // Continue
this.gameState.phase = PHASE_ENUM.TRAVEL;
await this.gameState.save()
this.executeCurrentPhase()
return;
break;
case "3": // Stop at the Next Fort (if applicable)
if (this.gameState.fortOptionFlag) {
this.gameState.subPhase = 2
this.gameState.totalMileageWholeTrip -= 45;
this.gameState.phase = PHASE_ENUM.FORT;
await this.gameState.save()
this.executeCurrentPhase()
return;
} else {
responseMessage += "⚠️ There is no fort option available at this time.\n\n"
responseMessage += `Do you want to:\n1. Hunt\n2. Continue\n\n`
await MessageService.statusUpdate(this.gameState, responseMessage)
return;
}
break;
default:
console.log("Starting turn...");
if (userInput !== undefined || userInput === "" || userInput === "start") {
responseMessage += "⚠️ Invalid Selection.\n\n"
}
//check for illness or injury
if (this.gameState.illnessFlag || this.gameState.injuryFlag) {
responseMessage += this.handleDoctor();
if (this.gameState.phase === PHASE_ENUM.DEATH) {
this.executeCurrentPhase()
return;
}
}
// Warn the player if food is low
if (this.gameState.amountSpentOnFood < 13) {
responseMessage += `You only have ${this.gameState.amountSpentOnFood} pounds of food.\n\n YOU'D BETTER DO SOME HUNTING OR BUY FOOD AND SOON!!!!\n\n`;
}
if (this.gameState.fortOptionFlag) {
responseMessage += `Do you want to:\n1. Hunt\n2. Continue\n3. Stop at the Next Fort\n\n`
} else {
responseMessage += `Do you want to:\n1. Hunt\n2. Continue\n\n`
}
await MessageService.statusUpdate(this.gameState, this.gameState.lastPrompt + responseMessage)
this.gameState.lastPrompt = responseMessage;
break;
}
return;
}
private async handleTravel(userInput?: string | number): Promise<void> {
let responseMessage = "";
if (!userInput || userInput?.toString().toLowerCase() === "start") {
responseMessage = "DO YOU WANT TO EAT\n(1) POORLY\n(2) MODERATELY\n(3) WELL: ";
await MessageService.statusUpdate(this.gameState, responseMessage);
return;
}
// Check if userInput is a number or can be converted to a valid number
if (isNaN(Number(userInput))) {
responseMessage = "Invalid input. Please enter a number.\n\n"
responseMessage += "DO YOU WANT TO EAT\n(1) POORLY\n(2) MODERATELY\n(3) WELL: ";
await MessageService.statusUpdate(this.gameState, responseMessage);
return; // Exit if input is not a valid number
}
let eatingChoice: number = parseInt(userInput.toString(), 10);
// Validate eating choice
if (eatingChoice < 1 || eatingChoice > 3) {
responseMessage = "Invalid choice.\n\n"
responseMessage += "DO YOU WANT TO EAT\n(1) POORLY\n(2) MODERATELY\n(3) WELL: ";
await MessageService.statusUpdate(this.gameState, responseMessage);
return;
}
// Calculate potential food consumption without updating the game state yet
let potentialAmountSpentOnFood = this.gameState.amountSpentOnFood - (8 + 5 * eatingChoice);
// Check if the potential amount spent on food is negative
if (potentialAmountSpentOnFood < 0) {
// If it would result in a negative value, inform the user they can't eat that well
responseMessage = "YOU CAN'T EAT THAT WELL\n\n";
responseMessage += "DO YOU WANT TO EAT\n(1) POORLY\n(2) MODERATELY\n(3) WELL: ";
await MessageService.statusUpdate(this.gameState, responseMessage);
return; // Exit the method to prevent further execution
} else {
// If the amount is sufficient, update the game state with the new amount
this.gameState.amountSpentOnFood = potentialAmountSpentOnFood;
}
// Calculate total mileage
this.gameState.totalMileageWholeTrip += 200 + (this.gameState.amountSpentOnAnimals - 220) / 5 + 10 * Math.random();
this.gameState.blizzardFlag = this.gameState.insufficientClothingFlag = false;
this.gameState.phase = PHASE_ENUM.RIDERS_ATTACK;
// Save the game state after making changes
await this.gameState.save();
// Continue with the game flow
this.executeCurrentPhase();
GameFlow.executeCurrentPhase(gameState)
}
private async handleEncounter(): Promise<void> {
@ -236,29 +100,29 @@ class GameFlow {
}
private handleDoctor(): string {
static handleDoctor(gameState: GameState): string {
let responseMessage: string = ""
// Handle illness and injury
if (this.gameState.illnessFlag && this.gameState.injuryFlag) {
if (gameState.illnessFlag && gameState.injuryFlag) {
responseMessage += `You were sick and and injured `
} else if (this.gameState.illnessFlag) {
} else if (gameState.illnessFlag) {
responseMessage += `You were sick and `
} else {
responseMessage += `You were injured and `
}
this.gameState.cashLeftAfterInitialPurchases -= 20;
if (this.gameState.cashLeftAfterInitialPurchases < 0) {
if (this.gameState.illnessFlag) this.gameState.death = DEATH_REASON_ENUM.ILLNESS
if (this.gameState.injuryFlag) this.gameState.death = DEATH_REASON_ENUM.INJURY
this.gameState.phase = PHASE_ENUM.DEATH
gameState.cashLeftAfterInitialPurchases -= 20;
if (gameState.cashLeftAfterInitialPurchases < 0) {
if (gameState.illnessFlag) gameState.death = DEATH_REASON_ENUM.ILLNESS
if (gameState.injuryFlag) gameState.death = DEATH_REASON_ENUM.INJURY
gameState.phase = PHASE_ENUM.DEATH
return "";
} else {
responseMessage += `The Doctors bill was $20\n\n`
}
this.gameState.injuryFlag = false;
this.gameState.illnessFlag = false;
gameState.injuryFlag = false;
gameState.illnessFlag = false;
return responseMessage;

View File

@ -0,0 +1,81 @@
import GameState, { PHASE_ENUM } from '../game/gameState';
import GameFlow from '../game/gameFlow';
import { MessageService } from '../utils/MessageService';
export class ActionPhase {
static async actionChoice(gameState: GameState, userInput?: string): Promise<void> {
let responseMessage = "";
userInput = userInput?.toLowerCase()
console.log("userInput", userInput);
switch (userInput) {
case "1": // Hunt
if (gameState.amountSpentOnAmmunition < 40) {
responseMessage = `You do not have enough ammunition to hunt. Purchase more ammunition first.\n\n`;
if (gameState.fortOptionFlag) {
responseMessage += `Do you want to:\n2. Continue\n3. Stop at the Next Fort\n\n`
} else {
responseMessage += `Do you want to:\n2. Continue\n\n`
}
await MessageService.statusUpdate(gameState, responseMessage)
} else {
gameState.phase = PHASE_ENUM.HUNT;
gameState.totalMileageWholeTrip -= 45;
await gameState.save()
GameFlow.executeCurrentPhase(gameState)
}
return;
break;
case "2": // Continue
gameState.phase = PHASE_ENUM.TRAVEL;
await gameState.save()
GameFlow.executeCurrentPhase(gameState)
return;
break;
case "3": // Stop at the Next Fort (if applicable)
if (gameState.fortOptionFlag) {
gameState.subPhase = 2
gameState.totalMileageWholeTrip -= 45;
gameState.phase = PHASE_ENUM.FORT;
await gameState.save()
GameFlow.executeCurrentPhase(gameState)
return;
} else {
responseMessage += "⚠️ There is no fort option available at this time.\n\n"
responseMessage += `Do you want to:\n1. Hunt\n2. Continue\n\n`
await MessageService.statusUpdate(gameState, responseMessage)
return;
}
break;
default:
console.log("Starting turn...");
if (userInput !== undefined || userInput === "" || userInput === "start") {
responseMessage += "⚠️ Invalid Selection.\n\n"
}
//check for illness or injury
if (gameState.illnessFlag || gameState.injuryFlag) {
responseMessage += GameFlow.handleDoctor(gameState);
if (gameState.phase === PHASE_ENUM.DEATH) {
GameFlow.executeCurrentPhase(gameState)
return;
}
}
// Warn the player if food is low
if (gameState.amountSpentOnFood < 13) {
responseMessage += `You only have ${gameState.amountSpentOnFood} pounds of food.\n\n YOU'D BETTER DO SOME HUNTING OR BUY FOOD AND SOON!!!!\n\n`;
}
if (gameState.fortOptionFlag) {
responseMessage += `Do you want to:\n1. Hunt\n2. Continue\n3. Stop at the Next Fort\n\n`
} else {
responseMessage += `Do you want to:\n1. Hunt\n2. Continue\n\n`
}
await MessageService.statusUpdate(gameState, gameState.lastPrompt + responseMessage)
gameState.lastPrompt = responseMessage;
break;
}
return;
}
}

View File

@ -4,16 +4,16 @@ import { HandleShooting } from './shooting';
import { MessageService } from '../utils/MessageService';
export class HuntPhase {
static async handleHunt(gameState: GameState, gameFlow: GameFlow, userInput?: string): Promise<void> {
static async handleHunt(gameState: GameState, userInput?: string): Promise<void> {
switch (gameState.subPhase) {
case 0: // Initial Logic
await HuntPhase.initialLogic(gameState, gameFlow);
await HuntPhase.initialLogic(gameState);
break;
case 1: // Shooting Logic
await HuntPhase.shootingLogic(gameState, gameFlow, userInput);
await HuntPhase.shootingLogic(gameState, userInput);
break;
case 2: // Outcome Logic
await HuntPhase.outcomeLogic(gameState, gameFlow);
await HuntPhase.outcomeLogic(gameState);
break;
default:
console.error("Unknown subphase in HuntPhase");
@ -22,7 +22,7 @@ export class HuntPhase {
}
static async initialLogic(gameState: GameState, gameFlow: GameFlow,): Promise<void> {
static async initialLogic(gameState: GameState): Promise<void> {
let responseMessage = '';
responseMessage += HandleShooting.handleShooting(gameState);
gameState.subPhase = 1;
@ -31,7 +31,7 @@ export class HuntPhase {
await gameState.save();
}
static async shootingLogic(gameState: GameState, gameFlow: GameFlow, userInput?: string): Promise<void> {
static async shootingLogic(gameState: GameState, userInput?: string): Promise<void> {
let responseMessage = '';
if (!userInput) {
responseMessage = "Invalid input.\n\n";
@ -48,11 +48,11 @@ export class HuntPhase {
gameState.lastPrompt = responseMessage;
gameState.subPhase = 2;
await gameState.save();
await gameFlow.executeCurrentPhase();
await GameFlow.executeCurrentPhase(gameState);
return;
}
static async outcomeLogic(gameState: GameState, gameFlow: GameFlow): Promise<void> {
static async outcomeLogic(gameState: GameState): Promise<void> {
let responseMessage = gameState.lastPrompt;
if (gameState.shootResponseTime <= 1) {
responseMessage += `RIGHT BETWEEN THE EYES---YOU GOT A BIG ONE!!!!\n\n`;
@ -71,7 +71,7 @@ export class HuntPhase {
gameState.phase = PHASE_ENUM.ACTION_CHOICE;
gameState.subPhase = 0;
await gameState.save();
await gameFlow.executeCurrentPhase();
await GameFlow.executeCurrentPhase(gameState);
return;
}
}

View File

@ -4,15 +4,15 @@ import { HandleShooting } from './shooting';
import { MessageService } from '../utils/MessageService';
export class RidersPhase {
static async handleRidersAttack(gameState: GameState, gameFlow: GameFlow, userInput?: string): Promise<void> {
static async handleRidersAttack(gameState: GameState, userInput?: string): Promise<void> {
let responseMessage = '';
gameState.lastPrompt = responseMessage;
switch (gameState.subPhase) {
case 0: // Initial Logic
await RidersPhase.initialLogic(gameState, gameFlow);
await RidersPhase.initialLogic(gameState);
break;
case 1: // Choice Logic
await RidersPhase.choiceLogic(gameState, gameFlow, userInput);
await RidersPhase.choiceLogic(gameState, userInput);
break;
case 2: //Fight Logic
responseMessage = gameState.lastPrompt
@ -43,7 +43,7 @@ export class RidersPhase {
gameState.phase = PHASE_ENUM.EVENT;
gameState.subPhase = 0
await gameState.save();
await gameFlow.executeCurrentPhase();
await GameFlow.executeCurrentPhase(gameState);
return;
case 4: // wagon fight logic
responseMessage = gameState.lastPrompt
@ -67,12 +67,12 @@ export class RidersPhase {
gameState.phase = PHASE_ENUM.EVENT;
gameState.subPhase = 0
await gameState.save();
await gameFlow.executeCurrentPhase();
await GameFlow.executeCurrentPhase(gameState);
return;
}
}
static async initialLogic(gameState: GameState, gameFlow: GameFlow): Promise<void> {
static async initialLogic(gameState: GameState): Promise<void> {
let responseMessage = '';
gameState.lastPrompt = responseMessage;
// Check for random encounter
@ -90,7 +90,7 @@ export class RidersPhase {
gameState.phase = PHASE_ENUM.EVENT;
gameState.subPhase = 0
gameState.save();
return gameFlow.executeCurrentPhase();
return GameFlow.executeCurrentPhase(gameState);
}
// If encounter occurs
gameState.hostileRiders = false;
@ -107,7 +107,7 @@ export class RidersPhase {
await MessageService.statusUpdate(gameState, responseMessage);
}
static async choiceLogic(gameState: GameState, gameFlow: GameFlow, userInput?: string): Promise<void> {
static async choiceLogic(gameState: GameState, userInput?: string): Promise<void> {
let responseMessage = '';
if (!userInput || isNaN(Number(userInput)) || +userInput < 1 && +userInput > 4) {
@ -121,12 +121,12 @@ export class RidersPhase {
// Random chance to flip hostility
if (Math.random() > 0.2) gameState.hostileRiders = !gameState.hostileRiders;
if (gameState.hostileRiders) RidersPhase.hostileRidersLogic(gameState, gameFlow)
else RidersPhase.friendlyRidersLogic(gameState, gameFlow);
if (gameState.hostileRiders) RidersPhase.hostileRidersLogic(gameState)
else RidersPhase.friendlyRidersLogic(gameState);
}
static async hostileRidersLogic(gameState: GameState, gameFlow: GameFlow): Promise<void> {
static async hostileRidersLogic(gameState: GameState): Promise<void> {
gameState.lastPrompt = "";
switch (gameState.tacticsChoiceWhenAttacked) {
case 1: // RUN away
@ -139,12 +139,12 @@ export class RidersPhase {
gameState.phase = PHASE_ENUM.EVENT;
gameState.subPhase = 0;
gameState.save();
return gameFlow.executeCurrentPhase();
return GameFlow.executeCurrentPhase(gameState);
case 2: // ATTACK
gameState.lastPrompt = "You decide to attack the hostile riders.\n\n";
gameState.subPhase = 2;
gameState.save()
return gameFlow.executeCurrentPhase()
return GameFlow.executeCurrentPhase(gameState)
case 3: // CONTINUE
//Penalize lost initiative if riders are hostile
gameState.lastPrompt = "You continue on cautiously, keeping your guard up. THE RIDERS ATTACK!\n\n";
@ -152,12 +152,12 @@ export class RidersPhase {
gameState.amountSpentOnAmmunition -= 100;
gameState.subPhase = 2;
gameState.save()
return gameFlow.executeCurrentPhase()
return GameFlow.executeCurrentPhase(gameState)
case 4: // CIRCLE WAGONS
gameState.subPhase = 4;
gameState.lastPrompt = "You formed a defensive circle with your wagons.THE RIDERS ATTACK!\n\n"
gameState.save()
return gameFlow.executeCurrentPhase()
return GameFlow.executeCurrentPhase(gameState)
default:
// Handle unexpected input (should be unreachable due to prior validation)
console.log("Unexpected tactics choice.");
@ -165,7 +165,7 @@ export class RidersPhase {
}
}
static async friendlyRidersLogic(gameState: GameState, gameFlow: GameFlow): Promise<void> {
static async friendlyRidersLogic(gameState: GameState): Promise<void> {
gameState.lastPrompt = "";
switch (gameState.tacticsChoiceWhenAttacked) {
case 1: // RUN Away
@ -178,25 +178,25 @@ export class RidersPhase {
gameState.phase = PHASE_ENUM.EVENT;
gameState.subPhase = 0;
gameState.save();
return gameFlow.executeCurrentPhase();
return GameFlow.executeCurrentPhase(gameState);
case 2: // ATTACK
gameState.lastPrompt = "You decide to attack the friendly riders. They flee in confusion\n\n";
gameState.subPhase = 2;
gameState.save()
return gameFlow.executeCurrentPhase()
return GameFlow.executeCurrentPhase(gameState)
case 3: // CONTINUE
gameState.lastPrompt = "The riders share news from up ahead and wish you safe travels. Your party continues on.\n\n";
gameState.phase = PHASE_ENUM.EVENT;
gameState.subPhase = 0;
gameState.save();
return gameFlow.executeCurrentPhase();
return GameFlow.executeCurrentPhase(gameState);
case 4: // CIRCLE WAGONS
gameState.totalMileageWholeTrip -= 20;
gameState.lastPrompt = "You formed a defensive circle with your wagons. The riders continue on their way without incident.\n\n";
gameState.phase = PHASE_ENUM.EVENT;
gameState.subPhase = 0;
gameState.save();
return gameFlow.executeCurrentPhase()
return GameFlow.executeCurrentPhase(gameState)
default:
// Handle unexpected input (should be unreachable due to prior validation)

View File

@ -3,7 +3,7 @@ import GameFlow from '../game/gameFlow';
import { MessageService, MessageFileName } from '../utils/MessageService'
export class HandleSetup {
static async handleSetupPhase(gameState: GameState, gameFlow: GameFlow, userInput?: string): Promise<void> {
static async handleSetupPhase(gameState: GameState, userInput?: string): Promise<void> {
userInput = userInput?.toLowerCase()
let responseMessage = "";
// Logic to handle initial setup
@ -23,7 +23,7 @@ export class HandleSetup {
if (purchaseResult.success) {
// If the purchase was successful, advance to the next subphase and recursively call handleSetupPhase without userInput to get the next set of instructions
gameState.subPhase++;
return HandleSetup.handleSetupPhase(gameState, gameFlow);
return HandleSetup.handleSetupPhase(gameState);
} else {
// If there was an error, include the error message in responseMessage
responseMessage = `${purchaseResult.errorMessage}`;
@ -46,7 +46,7 @@ export class HandleSetup {
const purchaseResult = HandleSetup.handleGenericPurchase(gameState, PurchaseOption.OXEN, userInput, 200, 300);
if (purchaseResult.success) {
gameState.subPhase++;
return HandleSetup.handleSetupPhase(gameState, gameFlow); // Call setup phase again for next subphase
return HandleSetup.handleSetupPhase(gameState); // Call setup phase again for next subphase
} else {
responseMessage = purchaseResult.errorMessage || '';
responseMessage += `\n\n${MessageService.getRandomMessage(
@ -67,7 +67,7 @@ export class HandleSetup {
const purchaseResult = HandleSetup.handleGenericPurchase(gameState, PurchaseOption.FOOD, userInput);
if (purchaseResult.success) {
gameState.subPhase++;
return HandleSetup.handleSetupPhase(gameState, gameFlow); // Call setup phase again for next subphase
return HandleSetup.handleSetupPhase(gameState); // Call setup phase again for next subphase
} else {
responseMessage = purchaseResult.errorMessage || '';
responseMessage += `\n\n${MessageService.getRandomMessage(
@ -88,7 +88,7 @@ export class HandleSetup {
const purchaseResult = HandleSetup.handleGenericPurchase(gameState, PurchaseOption.AMMO, userInput);
if (purchaseResult.success) {
gameState.subPhase++;
return HandleSetup.handleSetupPhase(gameState, gameFlow); // Call setup phase again for next subphase
return HandleSetup.handleSetupPhase(gameState); // Call setup phase again for next subphase
} else {
responseMessage = purchaseResult.errorMessage || '';
responseMessage += `\n\n${MessageService.getRandomMessage(
@ -109,7 +109,7 @@ export class HandleSetup {
const purchaseResult = HandleSetup.handleGenericPurchase(gameState, PurchaseOption.CLOTHING, userInput);
if (purchaseResult.success) {
gameState.subPhase++;
return HandleSetup.handleSetupPhase(gameState, gameFlow); // Call setup phase again for next subphase
return HandleSetup.handleSetupPhase(gameState); // Call setup phase again for next subphase
} else {
responseMessage = purchaseResult.errorMessage || '';
responseMessage += `\n\n${MessageService.getRandomMessage(
@ -130,7 +130,7 @@ export class HandleSetup {
const purchaseResult = HandleSetup.handleGenericPurchase(gameState, PurchaseOption.MISC, userInput);
if (purchaseResult.success) {
gameState.subPhase++;
return HandleSetup.handleSetupPhase(gameState, gameFlow); // Call setup phase again for next subphase
return HandleSetup.handleSetupPhase(gameState); // Call setup phase again for next subphase
} else {
responseMessage = purchaseResult.errorMessage || '';
responseMessage += `\n\n${MessageService.getRandomMessage(
@ -145,7 +145,7 @@ export class HandleSetup {
gameState.subPhase = 0;
gameState.phase === PHASE_ENUM.SETUP ? gameState.phase = PHASE_ENUM.START_TURN : gameState.phase = PHASE_ENUM.ACTION_CHOICE;
await gameState.save()
gameFlow.executeCurrentPhase()
GameFlow.executeCurrentPhase(gameState)
break;
default:
responseMessage = `@J something went wrong come and fix it.\n\n ${JSON.stringify(gameState, null, 4)}`

View File

@ -0,0 +1,61 @@
import GameState, { PHASE_ENUM } from '../game/gameState';
import GameFlow from '../game/gameFlow';
import { MessageService } from '../utils/MessageService';
export class travelPhase {
static async handleTravel(gameState: GameState, userInput?: string | number): Promise<void> {
let responseMessage = "";
if (!userInput || userInput?.toString().toLowerCase() === "start") {
responseMessage = "DO YOU WANT TO EAT\n(1) POORLY\n(2) MODERATELY\n(3) WELL: ";
await MessageService.statusUpdate(gameState, responseMessage);
return;
}
// Check if userInput is a number or can be converted to a valid number
if (isNaN(Number(userInput))) {
responseMessage = "Invalid input. Please enter a number.\n\n"
responseMessage += "DO YOU WANT TO EAT\n(1) POORLY\n(2) MODERATELY\n(3) WELL: ";
await MessageService.statusUpdate(gameState, responseMessage);
return; // Exit if input is not a valid number
}
let eatingChoice: number = parseInt(userInput.toString(), 10);
// Validate eating choice
if (eatingChoice < 1 || eatingChoice > 3) {
responseMessage = "Invalid choice.\n\n"
responseMessage += "DO YOU WANT TO EAT\n(1) POORLY\n(2) MODERATELY\n(3) WELL: ";
await MessageService.statusUpdate(gameState, responseMessage);
return;
}
// Calculate potential food consumption without updating the game state yet
let potentialAmountSpentOnFood = gameState.amountSpentOnFood - (8 + 5 * eatingChoice);
// Check if the potential amount spent on food is negative
if (potentialAmountSpentOnFood < 0) {
// If it would result in a negative value, inform the user they can't eat that well
responseMessage = "YOU CAN'T EAT THAT WELL\n\n";
responseMessage += "DO YOU WANT TO EAT\n(1) POORLY\n(2) MODERATELY\n(3) WELL: ";
await MessageService.statusUpdate(gameState, responseMessage);
return; // Exit the method to prevent further execution
} else {
// If the amount is sufficient, update the game state with the new amount
gameState.amountSpentOnFood = potentialAmountSpentOnFood;
}
// Calculate total mileage
gameState.totalMileageWholeTrip += 200 + (gameState.amountSpentOnAnimals - 220) / 5 + 10 * Math.random();
gameState.blizzardFlag = gameState.insufficientClothingFlag = false;
gameState.phase = PHASE_ENUM.RIDERS_ATTACK;
// Save the game state after making changes
await gameState.save();
// Continue with the game flow
GameFlow.executeCurrentPhase(gameState);
}
}

View File

@ -18,8 +18,7 @@ class WorkflowOrchestrator {
let gameState = await GameState.load(comment)
if (parsedComment.command === 'restart') gameState = await gameState.reset();
const gameFlow = new GameFlow(gameState)
await gameFlow.executeCurrentPhase(parsedComment.command)
await GameFlow.executeCurrentPhase(gameState, parsedComment.command)
await gameState.save()
} catch (error) {