Skip to content

Commit

Permalink
Merge pull request #65 from frostburn/params
Browse files Browse the repository at this point in the history
Make more rules and mechanics customizable
  • Loading branch information
frostburn authored Nov 12, 2023
2 parents 11635a4 + a3c3e14 commit a54d5a7
Show file tree
Hide file tree
Showing 16 changed files with 473 additions and 529 deletions.
77 changes: 30 additions & 47 deletions src/__tests__/ai.test.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,22 @@
import {expect, test} from 'bun:test';
import {RED, SimplePuyoScreen} from '../screen';
import {RED} from '../screen';
import {
DEFAULT_TARGET_POINTS,
MOVES,
MultiplayerGame,
MultiplayerParams,
PASS,
SimpleGame,
randomBag,
randomColorSelection,
defaultRules,
randomMultiplayer,
} from '../game';
import {effectiveLockout, flexDropletStrategy1} from '../ai';
import {randomSeed} from '../jkiss';
import {puyosEqual} from '../bitboard';
import {TimeWarpingGame, TimeWarpingMirror} from '../realtime';
import {simpleFromLines} from './utils';

test('Effective lockout', () => {
const screen = SimplePuyoScreen.fromLines([
const screen = simpleFromLines([
'',
'',
'',
Expand All @@ -42,14 +43,15 @@ test('Effective lockout', () => {
0,
0,
[0, 1, 2, 3],
[RED, RED]
[RED, RED],
defaultRules()
);
const heuristic = effectiveLockout(game);
expect(heuristic).toBeLessThan(0);
});

test('Ineffective lockout', () => {
const screen = SimplePuyoScreen.fromLines([
const screen = simpleFromLines([
'',
'',
'',
Expand All @@ -76,14 +78,15 @@ test('Ineffective lockout', () => {
0,
0,
[0, 1, 2, 3],
[RED, RED]
[RED, RED],
defaultRules()
);
const heuristic = effectiveLockout(game);
expect(heuristic).toBe(0);
});

test('Ineffective lockout (no bag)', () => {
const screen = SimplePuyoScreen.fromLines([
const screen = simpleFromLines([
'',
'',
'',
Expand All @@ -110,35 +113,26 @@ test('Ineffective lockout (no bag)', () => {
0,
0,
[0, 1, 2, 3],
[]
[],
defaultRules()
);
const heuristic = effectiveLockout(game);
expect(heuristic).toBe(0);
});

test('Server/client pausing game simulation', () => {
const maxConsecutiveRerolls = 10;
const gameSeeds = [randomSeed(), randomSeed()];
const screenSeeds = [randomSeed(), randomSeed()];
const colorSelection = randomColorSelection();
const colorSelections = [colorSelection, colorSelection];
const initialBag = randomBag(colorSelection);
const initialBags = [initialBag, initialBag];
const main = new MultiplayerGame(
gameSeeds,
screenSeeds,
colorSelections,
initialBags
);
const params = randomMultiplayer();
const main = new MultiplayerGame(params);

// In practice this would be two mirrors for each client
const knownBags = main.initialBags;
const mirror = new MultiplayerGame(
null,
screenSeeds,
colorSelections,
knownBags
);
const mirrorParams: MultiplayerParams = {
...params,
bagSeeds: null,
initialBags: knownBags,
};
const mirror = new MultiplayerGame(mirrorParams);
for (let i = 0; i < mirror.games.length; ++i) {
// Send initial bag and prompt moves with next pieces
mirror.games[i].bag = main.games[i].initialBag.concat(
Expand Down Expand Up @@ -224,29 +218,18 @@ test('Server/client pausing game simulation', () => {

test('Server/client realtime game simulation', () => {
const maxConsecutiveRerolls = 10;
const gameSeeds = [randomSeed(), randomSeed()];
const screenSeeds = [randomSeed(), randomSeed()];
const colorSelection = randomColorSelection();
const colorSelections = [colorSelection, colorSelection];
const initialBag = randomBag(colorSelection);
const initialBags = [initialBag, initialBag];
const origin = new MultiplayerGame(
gameSeeds,
screenSeeds,
colorSelections,
initialBags
);

const params = randomMultiplayer();
const origin = new MultiplayerGame(params);
// Server
const main = new TimeWarpingGame(origin);

const knownBags = origin.initialBags;
const mirrorOrigin = new MultiplayerGame(
null,
screenSeeds,
colorSelections,
knownBags
);
const mirrorParams: MultiplayerParams = {
...params,
bagSeeds: null,
initialBags: knownBags,
};
const mirrorOrigin = new MultiplayerGame(mirrorParams);
// Two dueling clients
const mirrors = [
new TimeWarpingMirror(mirrorOrigin),
Expand Down
3 changes: 1 addition & 2 deletions src/__tests__/algebraic.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
import {expect, test} from 'bun:test';
import {SimplePuyoScreen, isEmpty, puyosEqual} from '..';
import {
algebraicToGameStates,
applyAlgebraic,
joinTokens,
// replayToAlgebraic,
Expand All @@ -11,6 +10,7 @@ import {
} from '../algebraic';
import {LUMI_VS_FLEX2, fixedRandomGame} from './archive';

/*
test('Documentation example', () => {
const apn = [
'[Event "Documentation"]',
Expand Down Expand Up @@ -85,7 +85,6 @@ test('Utter multilines', () => {
expect(utterAlgebraic('5Lr')).toBe('rock right.');
});
/*
test('Known game', () => {
const replay = fixedRandomGame();
// TODO: Figure out why it says '2Nbcdef 3Lr' instead of '5Lr'
Expand Down
52 changes: 18 additions & 34 deletions src/__tests__/archive.ts
Original file line number Diff line number Diff line change
@@ -1,40 +1,24 @@
import {WIDTH} from '../bitboard';
import {
DEFAULT_MARGIN_FRAMES,
DEFAULT_MERCY_FRAMES,
MultiplayerGame,
} from '../game';
import {MultiplayerGame, ReplayParams, defaultRules} from '../game';
import {JKISS32} from '../jkiss';
import {Replay} from '../replay';

export function fixedRandomGame() {
const gameSeeds = [7, 7];
const colorSelection = [1, 2, 3, 4];
const colorSelections = [colorSelection, colorSelection];
const initialBags = [[], []];
const screenSeeds = [11, 11];
const targetPoints = [70, 70];
const marginFrames = DEFAULT_MARGIN_FRAMES;
const mercyFrames = DEFAULT_MERCY_FRAMES;
const game = new MultiplayerGame(
gameSeeds,
screenSeeds,
const params: ReplayParams = {
bagSeeds: [7, 7],
garbageSeeds: [11, 11],
colorSelections,
initialBags,
targetPoints,
marginFrames,
mercyFrames
);
rules: defaultRules(),
};
const game = new MultiplayerGame(params);
const rng = new JKISS32(8);

const replay: Replay = {
gameSeeds,
screenSeeds,
colorSelections,
initialBags,
targetPoints,
marginFrames,
mercyFrames,
params,
moves: [],
metadata: {
event: 'Fixed Random Match',
Expand Down Expand Up @@ -72,16 +56,16 @@ export function fixedRandomGame() {
}

export const LUMI_VS_FLEX2: Replay = {
gameSeeds: [3864657304, 3864657304],
screenSeeds: [2580717322, 2580717322],
colorSelections: [
[3, 1, 0, 2],
[3, 1, 0, 2],
],
initialBags: [[], []],
targetPoints: [70, 70],
marginFrames: DEFAULT_MARGIN_FRAMES,
mercyFrames: Infinity,
params: {
bagSeeds: [3864657304, 3864657304],
garbageSeeds: [2580717322, 2580717322],
colorSelections: [
[3, 1, 0, 2],
[3, 1, 0, 2],
],
initialBags: [[], []],
rules: defaultRules(),
},
metadata: {
event:
'First human vs. machine game to be captured in algebraic notation for Puyo',
Expand Down
Loading

0 comments on commit a54d5a7

Please sign in to comment.