Files
rice-pk-xhs/web/lib/bracket.ts
T
codex-bot 9615add720
Verify mini program and deploy preview / verify-deploy (push) Successful in 3m57s
feat: redesign typed rice poster editor
2026-09-20 16:37:35 +08:00

6 lines
1.4 KiB
TypeScript

import type{BracketState,Candidate,ChoiceSide,Match}from'./types';
export function buildMatches(pool:Candidate[]):Match[]{const matches:Match[]=[];for(let index=0;index<pool.length;index+=2)matches.push({left:pool[index]!,right:pool[index+1]||null,winner:pool[index+1]?null:pool[index]!});return matches;}
export function createBracket(candidates:Candidate[]):BracketState{return{round:1,pool:[...candidates],matches:buildMatches(candidates),eliminated:[],decisions:[],offset:0};}
export function chooseMatch(state:BracketState,index:number,side:ChoiceSide):{state:BracketState;finished:boolean}{const match=state.matches[index];if(!match?.right||match.winner)return{state,finished:false};const winner=side==='right'?match.right:match.left,loser=side==='right'?match.left:match.right,matches=state.matches.map((item,i)=>i===index?{...item,winner}:item);let next:BracketState={...state,matches,eliminated:[loser,...state.eliminated],decisions:[...state.decisions,{round:state.round,left_id:match.left.id,right_id:match.right.id,winner_id:winner.id}]};if(matches.every(item=>item.winner)){const pool=matches.map(item=>item.winner).filter((item):item is Candidate=>Boolean(item));if(pool.length===1)return{state:{...next,pool},finished:true};next={...next,round:state.round+1,pool,matches:buildMatches(pool),offset:0};}return{state:next,finished:false};}
export function firstOpenMatch(state:BracketState):number{return state.matches.findIndex(match=>match.right&&!match.winner);}