IPVGO: Improve favor gain from wins to balance around the rep value of favor (#2131)

This commit is contained in:
Michael Ficocelli
2025-05-17 05:36:58 -04:00
committed by GitHub
parent 2b8c008be1
commit 4749acdd4f
19 changed files with 79 additions and 51 deletions
+1 -1
View File
@@ -81,7 +81,7 @@ export function newOpponentStats(): OpponentStats {
winStreak: 0,
oldWinStreak: 0,
highestWinStreak: 0,
favor: 0,
rep: 0,
};
}
+3 -3
View File
@@ -152,10 +152,10 @@ function loadStats(stats: unknown): PartialRecord<GoOpponent, OpponentStats> | s
if (!getEnumHelper("GoOpponent").isMember(opponent)) return `Invalid opponent in Go.stats: ${opponent}`;
if (!opponentStats || typeof opponentStats !== "object") return "Non-object encountered for an opponent's stats";
assertLoadingType<OpponentStats>(opponentStats as object);
const { favor, highestWinStreak, losses, nodes, wins, oldWinStreak, winStreak, nodePower } =
const { rep, highestWinStreak, losses, nodes, wins, oldWinStreak, winStreak, nodePower } =
opponentStats as OpponentStats;
// Integers >= 0. Todo: make a better helper for this.
if (!isInteger(favor) || favor < 0) return "A favor entry in Go.stats was invalid";
if (!isInteger(rep) || rep < 0) return "A rep entry in Go.stats was invalid";
if (!isInteger(highestWinStreak) || highestWinStreak < 0) return "A highestWinStreak entry in Go.stats was invalid";
if (!isInteger(losses) || losses < 0) return "A losses entry in Go.stats was invalid";
if (!isInteger(nodes) || nodes < 0) return "A nodes entry in Go.stats was invalid";
@@ -167,7 +167,7 @@ function loadStats(stats: unknown): PartialRecord<GoOpponent, OpponentStats> | s
// Numbers >= 0
if (!isNumber(nodePower) || nodePower < 0) return "A nodePower entry in Go.stats was invalid";
finalStats[opponent] = { favor, highestWinStreak, losses, nodes, wins, oldWinStreak, winStreak, nodePower };
finalStats[opponent] = { rep, highestWinStreak, losses, nodes, wins, oldWinStreak, winStreak, nodePower };
}
return finalStats;
}
+2 -2
View File
@@ -98,7 +98,7 @@ export type OpponentStats = {
winStreak: number;
oldWinStreak: number;
highestWinStreak: number;
favor: number;
rep: number;
};
export type SimpleOpponentStats = {
@@ -106,7 +106,7 @@ export type SimpleOpponentStats = {
losses: number;
winStreak: number;
highestWinStreak: number;
favor: number;
rep: number;
bonusPercent: number;
bonusDescription: string;
};
+9 -5
View File
@@ -5,11 +5,12 @@ import { GoOpponent, GoColor } from "@enums";
import { newOpponentStats } from "../Constants";
import { getAllChains, getPlayerNeighbors } from "./boardAnalysis";
import { getKomi, resetAI } from "./goAI";
import { getDifficultyMultiplier, getMaxFavor, getWinstreakMultiplier } from "../effects/effect";
import { getDifficultyMultiplier, getMaxRep, getWinstreakMultiplier } from "../effects/effect";
import { isNotNullish } from "../boardState/boardState";
import { Factions } from "../../Faction/Factions";
import { getEnumHelper } from "../../utils/EnumHelper";
import { Go, GoEvents } from "../Go";
import { addRepToFavor } from "../../Faction/formulas/favor";
/**
* Returns the score of the current board.
@@ -49,7 +50,7 @@ export function endGoGame(boardState: BoardState) {
boardState.previousPlayer = null;
const statusToUpdate = getOpponentStats(boardState.ai);
statusToUpdate.favor = statusToUpdate.favor ?? 0;
statusToUpdate.rep = statusToUpdate.rep ?? 0;
const score = getScore(boardState);
if (score[GoColor.black].sum < score[GoColor.white].sum) {
@@ -68,10 +69,13 @@ export function endGoGame(boardState: BoardState) {
factionName &&
statusToUpdate.winStreak % 2 === 0 &&
Player.factions.includes(factionName) &&
statusToUpdate.favor < getMaxFavor()
statusToUpdate.rep < getMaxRep()
) {
Factions[factionName].setFavor(Factions[factionName].favor + 1);
statusToUpdate.favor++;
const currentFavor = Factions[factionName].favor;
const repToAdd = getMaxRep() / 200;
const newFavor = addRepToFavor(currentFavor, repToAdd);
Factions[factionName].setFavor(newFavor);
statusToUpdate.rep += repToAdd;
}
}
+8 -6
View File
@@ -23,22 +23,24 @@ export function CalculateEffect(nodes: number, faction: GoOpponent): number {
/**
* Get maximum favor that you can gain from IPvGO win streaks
* for factions you are a member of
* for factions you are a member of.
*
* This is added as converted rep to avoid making the equivalent value of the favor in rep very different as you approach 150 favor
*/
export function getMaxFavor() {
export function getMaxRep() {
const sourceFileLevel = Player.activeSourceFileLvl(14);
if (sourceFileLevel === 1) {
return 80;
return 200_000;
}
if (sourceFileLevel === 2) {
return 100;
return 300_000;
}
if (sourceFileLevel >= 3) {
return 120;
return 400_000;
}
return 40;
return 100_000;
}
/**
+1 -1
View File
@@ -378,7 +378,7 @@ export function getStats() {
losses: details.losses,
winStreak: details.winStreak,
highestWinStreak: details.highestWinStreak,
favor: details.favor,
rep: details.rep,
bonusPercent: effectPercent,
bonusDescription: effectDescription,
};
+7 -4
View File
@@ -7,7 +7,7 @@ import { getOpponentStats, getScore } from "../boardAnalysis/scoring";
import { GoGameboard } from "./GoGameboard";
import { boardStyles } from "../boardState/goStyles";
import { useRerender } from "../../ui/React/hooks";
import { getBonusText, getMaxFavor } from "../effects/effect";
import { getBonusText, getMaxRep } from "../effects/effect";
import { formatNumber } from "../../ui/formatNumber";
import { GoScoreSummaryTable } from "./GoScoreSummaryTable";
import { getNewBoardState } from "../boardState/boardState";
@@ -115,15 +115,18 @@ export const GoHistoryPage = (): React.ReactElement => {
<Tooltip
title={
<>
Two wins in a row against a faction will give you +1 favor to that faction <br />
(up to a max of {getMaxFavor()} favor), if you are a member of that faction <br />
Two wins in a row against an opponent will give you {getMaxRep() / 200} rep converted to favor
with that faction (up to a max of {getMaxRep()} favor), if you are a member of that faction.
<br />
The rep is immediately applied as favor, meaning it will increase reputation gain right away
without needing an install.
</>
}
>
<TableRow>
<TableCell className={classes.cellNone}>Favor from winstreaks:</TableCell>
<TableCell className={classes.cellNone}>
{data.favor ?? 0} {data.favor === getMaxFavor() ? "(max)" : ""}
{data.rep ?? 0} {data.rep === getMaxRep() ? "(max)" : ""}
</TableCell>
</TableRow>
</Tooltip>
+6 -3
View File
@@ -7,7 +7,7 @@ import { boardStateFromSimpleBoard } from "../boardAnalysis/boardAnalysis";
import { GoTutorialChallenge } from "./GoTutorialChallenge";
import { Router } from "../../ui/GameRoot";
import { Page } from "../../ui/Router";
import { getMaxFavor } from "../effects/effect";
import { getMaxRep } from "../effects/effect";
const captureChallenge = (
<GoTutorialChallenge
@@ -149,8 +149,11 @@ export const GoInstructionsPage = (): React.ReactElement => {
will increase the amount gained, but is not required.
<br />
<br />
Two wins in a row against a faction will give you +1 favor to that faction (up to a max of
{getMaxFavor()} favor), if you are a member of that faction.
Two wins in a row against an opponent will give you {getMaxRep() / 200} rep converted to favor with that
faction (up to a max of {getMaxRep()} favor), if you are a member of that faction.
<br />
The rep is immediately applied as favor, meaning it will increase reputation gain right away without
needing an install.
<br />
<br />
For experienced Go players: IPvGO uses the old traditional Go score rules, area scoring, rather than the
+9 -4
View File
@@ -6,7 +6,7 @@ import { Table, TableBody, TableCell, TableRow, Typography, Tooltip } from "@mui
import { Player } from "@player";
import { GoOpponent, GoColor } from "@enums";
import { Go } from "../Go";
import { getBonusText, getDifficultyMultiplier, getMaxFavor, getWinstreakMultiplier } from "../effects/effect";
import { getBonusText, getDifficultyMultiplier, getMaxRep, getWinstreakMultiplier } from "../effects/effect";
import { boardStyles } from "../boardState/goStyles";
import { formatNumber } from "../../ui/formatNumber";
import { getOpponentStats } from "../boardAnalysis/scoring";
@@ -99,14 +99,19 @@ export const GoScorePowerSummary = ({ finalScore, opponent }: Props) => {
<Tooltip
title={
<>
Two wins in a row against a faction will give you +1 favor to that faction <br />
(up to a max of {getMaxFavor()} favor), if you are a member of that faction
Two wins in a row against an opponent will give you {getMaxRep() / 200} rep converted to favor with that
faction (up to a max of {getMaxRep()} favor), if you are a member of that faction.
<br />
The rep is immediately applied as favor, meaning it will increase reputation gain right away without
needing an install.
</>
}
>
<Typography className={`${classes.inlineFlexBox} ${classes.keyText}`}>
<span>Winstreak Bonus: </span>
<span>+1 favor to {opponent}</span>
<span>
{getMaxRep() / 200} reputation converted to favor with {opponent}
</span>
</Typography>
</Tooltip>
) : (