AO code common to all AO projects (ao-server, ao-svelt, ao-3, ao-cli), included on both client and server
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

100 lines
3.2 KiB

import { getTask } from './cards.js'
// DUPLICATED function from client/cardActions.ts
// Returns the number of vouches a member has. Member card must exist for each voucher. Members do not have to be active to vouch.
// This function can be used either on the client or the server. If on the server, server state must be passed as the second arg.
export function countVouches(memberId, state): number | null {
let card
card = getTask(state.tasks, memberId)
if (!card || !card.hasOwnProperty('deck')) return null
let count = 0
const memberCards = card.deck
.map(memberId => state.members.find(m => m.memberId === memberId))
.forEach(memberCard => {
if (memberCard !== undefined) {
count++
}
})
return count
}
// Returns true if the senpai memberId is ahead of the kohai memberId in the members list order
export function isAheadOf(senpaiId, kohaiId, state, errRes?) {
if (errRes === undefined) {
errRes = []
}
let senpaiRank = state.members.findIndex(m => m.memberId === senpaiId)
let kohaiRank = state.members.findIndex(m => m.memberId === kohaiId)
if (senpaiRank < kohaiRank) {
return 1
} else if (kohaiRank < senpaiRank) {
return -1
}
errRes.push('member is not ahead of other member in order of member list')
return 0
}
// Returns true if the senpai has more attack than the kohai has defense
// A member's defense is their number of vouches, or the highest attack score out of anyone who vouches for them (whichever is greater)
// This method does not check if vouchers exist, therefore it depends on the mutations being perfect
// and there not being any invalid members leftover in the .deck / vouchers list of the other member
export function isDecidedlyMorePopularThan(senpaiId, kohaiId, state, errRes?) {
if (errRes === undefined) {
errRes = []
}
const senpaiCard = state.tasks.find(t => t.taskId === senpaiId)
if (!senpaiCard) {
errRes.push('invalid member detected')
return null
}
const kohaiCard = state.tasks.find(t => t.taskId === kohaiId)
if (!kohaiCard) {
errRes.push('invalid member detected')
return null
}
const senpaiVouches = countVouches(senpaiId, state)
let kohaiVouchCards = state.tasks.filter(
t => kohaiCard.deck.indexOf(t.taskId) >= 0
)
let kohaiVouches = kohaiVouchCards.length
kohaiVouchCards.forEach(card => {
if (card.taskId !== senpaiCard.taskId) {
kohaiVouches = Math.max(kohaiVouches, countVouches(card.taskId, state))
}
})
if (senpaiVouches > kohaiVouches) {
return 1
} else if (kohaiVouches > senpaiVouches) {
return -1
}
errRes.push('member does not have more vouches than other member')
return 0
}
// Returns true if the senpaiId member is both isAheadOf and isDecidedlyMorePopularThan the kohaiId member
export function isSenpaiOf(senpaiId, kohaiId, state, errRes?) {
if (errRes === undefined) {
errRes = []
}
const rank = isAheadOf(senpaiId, kohaiId, state, errRes)
const vouches = isDecidedlyMorePopularThan(senpaiId, kohaiId, state, errRes)
if (rank === 1 && vouches === 1) {
return 1
} else if (rank === -1 && vouches === -1) {
return -1
}
errRes.push('member is not a senpai of the other member')
return 0
}