be carefullercarefull with the file type
be carefuller with the file type
be carefull with the file type
this is the 1st2nd version not finished yet (and it is a big mess now)
import fs from 'fs'
import { promisify } from 'util'
const appendFile = promisify(fs.appendFile)
const writeFile = promisify(fs.writeFile)
const readFile = promisify(fs.readFile)
const delay = ms => new Promise(_ => setTimeout(_, ms));
let [filename, othercoins, mycoins, mycards ] = process.argv.slice(2)
othercoins = +othercoins
mycoins = +mycoins
const move = async (m) => await appendFile(filename, m)
const message = m => process.stdout.write(m)
const endTurn = async _ => await move(`\n`)
const stateFileName = `./state.json`
const defaultState = {
usedCardsinTheDeck: [],
oponentCards: [],
oponentMissingTempCard: "",
oponentMissingCards: [],
oponentDropedCards: [],
oponentCardModifier: 0
}
const CardTypes = Object.freeze({
Ambassador : `Ambassador`,
Assassin : `Assassin`,
Captain : `Captain`,
Contessa : `Contessa`,
Duke : `Duke`,
})
const revealTable = Object.freeze({
[CardTypes.Ambassador]: `~`,
[CardTypes.Assassin]: `^`,
[CardTypes.Captain]: `*`,
[CardTypes.Contessa]: `!`,
[CardTypes.Duke]: `$`,
})
const giveUpTable = Object.freeze({
[CardTypes.Ambassador]: `_`,
[CardTypes.Assassin]: `'`,
[CardTypes.Captain]: `<`,
[CardTypes.Contessa]: `=`,
[CardTypes.Duke]: `0`,
})
function GetRevealCardChar(cardType) {
return revealTable[cardType]
}
function GetRevealCardType(char) {
return Object.keys(revealTable).find(key => revealTable[key] === char)
}
function GetGiveUpCardChar(cardType) {
return giveUpTable[cardType]
}
function GetGiveUpCardType(char) {
return Object.keys(giveUpTable).find(key => giveUpTable[key] === char)
}
async function GiveUpCard(cardType, endTurn = false) {
return await move(
GetGiveUpCardChar(cardType) + `${endTurn?`\n`:``}`
);
}
function OponentCanHave(cardType) {
// it has it
if (!!~state.oponentCards.indexOf(cardType)) return true
if (state.oponentCards.length + state.oponentDropedCards.length >= 2) return false
return true
}
function GiveCard(getOrder = false) {
// TODO: Tactic
const giveAwayOrder = [
CardTypes.Captain,
CardTypes.Ambassador,
CardTypes.Contessa,
CardTypes.Assassin,
CardTypes.Duke,
]
returnconst GetGiveUpCardChar(tmp = mycards
.split('')
.map(GetRevealCardType)
let [unique, duplicate] = tmp.reduce(([unique, duplicate], item) => {
return unique.includes(item) ?
[unique, [...duplicate, item]] :
[[...unique, item], duplicate]
}
, [[],[]])
unique.sort(
(a, b) => {giveAwayOrder.indexOf(a) - giveAwayOrder.indexOf(b));
duplicate.sort(
(a, b) => giveAwayOrder.indexOf(a) - giveAwayOrder.indexOf(b))
const out = [...duplicate, }...unique]
)[0]return getOrder? out: GetGiveUpCardChar(out[0]);
}
const iHaveAmbassador = !!~mycards.indexOf(`~`)
const iHaveAssassin = !!~mycards.indexOf(`^`)
const iHaveCaptain = !!~mycards.indexOf(`*`)
const iHaveContessa = !!~mycards.indexOf(`!`)
const iHaveDuke = !!~mycards.indexOf(`$`)
let state = defaultState
;(async ()=>{
const data = (await readFile(filename, `utf8`)).replace(/\r/g, ``)
const isNewGame = data === "" && mycoins === 1 && othercoins === 1
if (isNewGame) {
await writeFile(stateFileName, JSON.stringify(state))
} else {
state = JSON.parse(await readFile(stateFileName, `utf8`))
}
//console.error(state);
let line = data.split(/\n/g).pop()
// I am in the exchnage
if (mycards.length >= 3) {
const [c1, c2] = GiveCard(true).reverse()
if (mycards.length === 3) {
state.inTheDeck.push(c1)
message(GetRevealCardChar(c1))
}
if (mycards.length === 4) {
state.inTheDeck.push(c1, c2)
message(`${GetRevealCardChar(c1)}${GetRevealCardChar(c2)}`)
}
return await move(`\n`)
}
const newTurn = line === ``
if (newTurn) {
if (mycoins >= 7) {
return await move(`C`)
}
if (othercoins >= 6) {
if (iHaveCaptain)
return await move(`S`)
if (mycoins <= 6 && mycards.length <= 1) {
// TODO: bluff
}
}
if (
!iHaveDuke &&
!iHaveContessa &&
iHaveAmbassador
) {
return await move(`E`)
}
// Assasinate if oponent has no Contessa
if (
mycoins >= 3 &&
iHaveAssassin &&
!~state.oponentCards.indexOf(CardTypes.Contessa)
) {
return await move(`A`)
}
if (iHaveDuke) {
return await move(`T`)
}
return await move(`I\n`)
}
// Exchange
if (line === `Eq`) {
if (iHaveAmbassador)
return await move(GetRevealCardChar(CardTypes.Ambassador))
return await GiveUpCard(GiveCard(true)[0])
}
// Tax Challenge
if(line === `Tq`) {
if (iHaveDuke)
return await move(GetRevealCardChar(CardTypes.Duke))
return await moveGiveUpCard(GiveCard(true)[0])
}
if (line === `Sa`) {
if (!~state.oponentCards.indexOf(CardTypes.Ambassador)) {
state.oponentMissingTempCard = CardTypes.Ambassador
return await move(`\n``q`)
}
return await endTurn()
}
if (line === `Sc`) {
if (!~state.oponentCards.indexOf(CardTypes.Captain)) {
state.oponentMissingTempCard = CardTypes.Captain
return await move(`\n``q`)
}
return await endTurn()
}
if (line=== `Saq${GetRevealCardChar(CardTypes.Ambassador)}`) {
state.oponentMissingTempCard = ``
state.oponentCards.push(
CardTypes.Ambassador
);
return await GiveUpCard(GiveCard(true)[0], true)
}
if (line=== `Scq${GetRevealCardChar(CardTypes.Captain)}`) {
state.oponentMissingTempCard = ``
state.oponentCards.push(
CardTypes.Captain
);
return await GiveUpCard(GiveCard(true)[0], true)
}
if (line === `Sq`) {
if (iHaveCaptain)
return await move(GetRevealCardChar(CardTypes.Captain))
return await moveGiveUpCard(GiveCard(true)[0])
}
// Assassinate Block and Chalange it
if (line === `As`) {
state.oponentMissingTempCard = CardTypes.Contessa
return await move(`q`)
}
// Assasint blocked by Contessa
if (line === `Asq!`Asq${GetRevealCardChar(CardTypes.Contessa)}`) {
state.oponentMissingTempCard = ``
state.oponentCards.push(
CardTypes.Contessa
)
// Assassin useless here lets give it up
return await move( GetGiveUpCardCharGiveUpCard(CardTypes.Assassin) +, `\n`true)
}
// Assassinate challenge
if (line === `Aq`) {
if (iHaveAssassin)
return await move(GetRevealCardChar(CardTypes.Assassin))
return await moveGiveUpCard(GiveCard(true)[0])
}
// Defense Moves
if (line === `C`) {
return await moveGiveUpCard(GiveCard(true)[0])
}
if (line === `A`) {
if (iHaveContessa)
return await move(`s`)
if (!!~state.oponentCards.indexOf(CardTypes.Assassin)) {
// If oponent has an Assasin card lets bluff
return await move(GiveCard(`s`)
} else {
state.oponentMissingTempCard = CardTypes.Assassin
return await move(`q`)
}
}
if (line === `Aq${GetRevealCardChar(CardTypes.Assassin)}`) {
state.oponentMissingTempCard = ``
state.oponentCards.push(
CardTypes.Assassin
);
return await GiveUpCard(GiveCard(true)[0], true)
}
if (line === `Asq`) {
if (iHaveContessa)
return await move(GetRevealCardChar(CardTypes.Contessa))
return await moveGiveUpCard(GiveCard(true)[0])
}
if (line === `S`) {
if (iHaveAmbassador)
return await move(`a`)
if (iHaveCaptain)
return await move(`c`)
return await move(`p`)
}
if (line === `Saq`) {
if (iHaveAmbassador)
return await move(GetRevealCardChar(CardTypes.Ambassador))
return await moveGiveUpCard(GiveCard(true)[0])
}
if (line === `Scq`) {
if (iHaveCaptain)
return await move(GetRevealCardChar(CardTypes.Captain))
return await moveGiveUpCard(GiveCard(true)[0])
}
if (line === `F`) {
if (iHaveDuke)
return await move(`d`)
return await move(`p`)
}
if (line === `Fdq`) {
if (iHaveDuke)
return await move(GetRevealCardChar(CardTypes.Duke))
return await moveGiveUpCard(GiveCard(true)[0])
}
if (line === `E`) {
if (!OponentCanHave(CardTypes.Ambassador)) {
return await move(`q`)
}
// pass state.oponentCards = []
state.oponentMissingCards = []
state.oponentMissingTempCard = ''
return await move(`p`)
}
if (!!~[`E`,line `T`]=== `Eq${GetRevealCardChar(CardTypes.indexOfAmbassador)}`) {
console.error(111, `THIS SHOULD NEVER HAPPEN`)
return await GiveUpCard(GiveCard(true)[0])
}
if (line === `T`) {
if (!OponentCanHave(CardTypes.Duke)) {
return await move(`q`)
}
return await move(`p`)
}
if (line === `Tq${GetRevealCardChar(CardTypes.Duke)}`) {
console.error(111, `THIS SHOULD NEVER HAPPEN`)
return await moveGiveUpCard(`\n`GiveCard(true)[0])
}
// remove oponents drop card from the state
// can't detect if oponent has the same card twice
if (!!~Object.values(giveUpTable).indexOf(line.substr(-1))) {
// Catch the bluff
if (state.oponentMissingTempCard !== "") {
state.oponentMissingCards.push(state.oponentMissingTempCard)
state.oponentMissingTempCard = ""
}
// maybe we should asume user doeas not has the same card?
const cardType = GetGiveUpCardType(line.substr(-1))
state.oponentCards.filter(c => c !== cardType)
state.inTheDeck.push(cardType)
state.oponentDropedCards.push(cardType)
}
return await endTurn()
})()
.then(async () => {
await writeFile(stateFileName, JSON.stringify(state))
})
.catch(console.error.bind(console))
```
this is the 1st version not finished yet
import fs from 'fs'
import { promisify } from 'util'
const appendFile = promisify(fs.appendFile)
const writeFile = promisify(fs.writeFile)
const readFile = promisify(fs.readFile)
const delay = ms => new Promise(_ => setTimeout(_, ms));
let [filename, othercoins, mycoins, mycards ] = process.argv.slice(2)
othercoins = +othercoins
mycoins = +mycoins
const move = async (m) => await appendFile(filename, m)
const stateFileName = `./state.json`
const defaultState = {
usedCards: [],
oponentCards: [],
oponentCardModifier: 0
}
const CardTypes = Object.freeze({
Ambassador : `Ambassador`,
Assassin : `Assassin`,
Captain : `Captain`,
Contessa : `Contessa`,
Duke : `Duke`,
})
const revealTable = Object.freeze({
[CardTypes.Ambassador]: `~`,
[CardTypes.Assassin]: `^`,
[CardTypes.Captain]: `*`,
[CardTypes.Contessa]: `!`,
[CardTypes.Duke]: `$`,
})
const giveUpTable = Object.freeze({
[CardTypes.Ambassador]: `_`,
[CardTypes.Assassin]: `'`,
[CardTypes.Captain]: `<`,
[CardTypes.Contessa]: `=`,
[CardTypes.Duke]: `0`,
})
function GetRevealCardChar(cardType) {
return revealTable[cardType]
}
function GetRevealCardType(char) {
return Object.keys(revealTable).find(key => revealTable[key] === char)
}
function GetGiveUpCardChar(cardType) {
return giveUpTable[cardType]
}
function GiveCard() {
// TODO: Tactic
const giveAwayOrder = [
CardTypes.Captain,
CardTypes.Ambassador,
CardTypes.Contessa,
CardTypes.Assassin,
CardTypes.Duke,
]
return GetGiveUpCardChar(mycards
.split('')
.map(GetRevealCardType)
.sort(
(a, b) => {
giveAwayOrder.indexOf(a) - giveAwayOrder.indexOf(b)
}
)[0])
}
const iHaveAmbassador = !!~mycards.indexOf(`~`)
const iHaveAssassin = !!~mycards.indexOf(`^`)
const iHaveCaptain = !!~mycards.indexOf(`*`)
const iHaveContessa = !!~mycards.indexOf(`!`)
const iHaveDuke = !!~mycards.indexOf(`$`)
let state = defaultState
;(async ()=>{
const data = (await readFile(filename, `utf8`)).replace(/\r/g, ``)
const isNewGame = data === "" && mycoins === 1 && othercoins === 1
if (isNewGame) {
await writeFile(stateFileName, JSON.stringify(state))
} else {
state = JSON.parse(await readFile(stateFileName, `utf8`))
}
let line = data.split(/\n/g).pop()
const newTurn = line === ``
if (newTurn) {
if (mycoins >= 7) {
return await move(`C`)
}
if (othercoins >= 6) {
if (iHaveCaptain)
return await move(`S`)
if (mycoins <= 6 && mycards.length <= 1) {
// TODO: bluff
}
}
// Assasinate if oponent has no Contessa
if (
mycoins >= 3 &&
iHaveAssassin &&
!~state.oponentCards.indexOf(CardTypes.Contessa)
) {
return await move(`A`)
}
if (iHaveDuke) {
return await move(`T`)
}
return await move(`I\n`)
}
// Tax Challenge
if(line === `Tq`) {
if (iHaveDuke)
return await move(GetRevealCardChar(CardTypes.Duke))
return await move(GiveCard())
}
if (line === `Sa`) {
return await move(`\n`)
}
if (line === `Sc`) {
return await move(`\n`)
}
if (line === `Sq`) {
if (iHaveCaptain)
return await move(GetRevealCardChar(CardTypes.Captain))
return await move(GiveCard())
}
// Assassinate Block and Chalange it
if (line === `As`) {
return await move(`q`)
}
// Assasint blocked by Contessa
if (line === `Asq!`) {
state.oponentCards.push(
CardTypes.Contessa
)
// Assassin useless here lets give it up
return await move( GetGiveUpCardChar(CardTypes.Assassin) + `\n`)
}
// Assassinate challenge
if (line === `Aq`) {
if (iHaveAssassin)
return await move(GetRevealCardChar(CardTypes.Assassin))
return await move(GiveCard())
}
// Defense Moves
if (line === `C`) {
return await move(GiveCard())
}
if (line === `A`) {
if (iHaveContessa)
return await move(`s`)
return await move(GiveCard())
}
if (line === `Asq`) {
if (iHaveContessa)
return await move(GetRevealCardChar(CardTypes.Contessa))
return await move(GiveCard())
}
if (line === `S`) {
if (iHaveAmbassador)
return await move(`a`)
if (iHaveCaptain)
return await move(`c`)
return await move(`p`)
}
if (line === `Saq`) {
if (iHaveAmbassador)
return await move(GetRevealCardChar(CardTypes.Ambassador))
return await move(GiveCard())
}
if (line === `Scq`) {
if (iHaveCaptain)
return await move(GetRevealCardChar(CardTypes.Captain))
return await move(GiveCard())
}
if (line === `F`) {
if (iHaveDuke)
return await move(`d`)
return await move(`p`)
}
if (line === `Fdq`) {
if (iHaveDuke)
return await move(GetRevealCardChar(CardTypes.Duke))
return await move(GiveCard())
}
// pass
if (!!~[`E`, `T`].indexOf(line)) {
return await move(`p`)
}
return await move(`\n`)
})()
.then(async () => {
await writeFile(stateFileName, JSON.stringify(state))
})
.catch(console.error.bind(console))
```
this is the 2nd version not finished yet (and it is a big mess now)
import fs from 'fs'
import { promisify } from 'util'
const appendFile = promisify(fs.appendFile)
const writeFile = promisify(fs.writeFile)
const readFile = promisify(fs.readFile)
const delay = ms => new Promise(_ => setTimeout(_, ms));
let [filename, othercoins, mycoins, mycards ] = process.argv.slice(2)
othercoins = +othercoins
mycoins = +mycoins
const move = async m => await appendFile(filename, m)
const message = m => process.stdout.write(m)
const endTurn = async _ => await move(`\n`)
const stateFileName = `./state.json`
const defaultState = {
inTheDeck: [],
oponentCards: [],
oponentMissingTempCard: "",
oponentMissingCards: [],
oponentDropedCards: [],
oponentCardModifier: 0
}
const CardTypes = Object.freeze({
Ambassador : `Ambassador`,
Assassin : `Assassin`,
Captain : `Captain`,
Contessa : `Contessa`,
Duke : `Duke`,
})
const revealTable = Object.freeze({
[CardTypes.Ambassador]: `~`,
[CardTypes.Assassin]: `^`,
[CardTypes.Captain]: `*`,
[CardTypes.Contessa]: `!`,
[CardTypes.Duke]: `$`,
})
const giveUpTable = Object.freeze({
[CardTypes.Ambassador]: `_`,
[CardTypes.Assassin]: `'`,
[CardTypes.Captain]: `<`,
[CardTypes.Contessa]: `=`,
[CardTypes.Duke]: `0`,
})
function GetRevealCardChar(cardType) {
return revealTable[cardType]
}
function GetRevealCardType(char) {
return Object.keys(revealTable).find(key => revealTable[key] === char)
}
function GetGiveUpCardChar(cardType) {
return giveUpTable[cardType]
}
function GetGiveUpCardType(char) {
return Object.keys(giveUpTable).find(key => giveUpTable[key] === char)
}
async function GiveUpCard(cardType, endTurn = false) {
return await move(
GetGiveUpCardChar(cardType) + `${endTurn?`\n`:``}`
);
}
function OponentCanHave(cardType) {
// it has it
if (!!~state.oponentCards.indexOf(cardType)) return true
if (state.oponentCards.length + state.oponentDropedCards.length >= 2) return false
return true
}
function GiveCard(getOrder = false) {
// TODO: Tactic
const giveAwayOrder = [
CardTypes.Captain,
CardTypes.Ambassador,
CardTypes.Contessa,
CardTypes.Assassin,
CardTypes.Duke,
]
const tmp = mycards
.split('')
.map(GetRevealCardType)
let [unique, duplicate] = tmp.reduce(([unique, duplicate], item) => {
return unique.includes(item) ?
[unique, [...duplicate, item]] :
[[...unique, item], duplicate]
}
, [[],[]])
unique.sort(
(a, b) => giveAwayOrder.indexOf(a) - giveAwayOrder.indexOf(b));
duplicate.sort(
(a, b) => giveAwayOrder.indexOf(a) - giveAwayOrder.indexOf(b))
const out = [...duplicate, ...unique]
return getOrder? out: GetGiveUpCardChar(out[0]);
}
const iHaveAmbassador = !!~mycards.indexOf(`~`)
const iHaveAssassin = !!~mycards.indexOf(`^`)
const iHaveCaptain = !!~mycards.indexOf(`*`)
const iHaveContessa = !!~mycards.indexOf(`!`)
const iHaveDuke = !!~mycards.indexOf(`$`)
let state = defaultState
;(async ()=>{
const data = (await readFile(filename, `utf8`)).replace(/\r/g, ``)
const isNewGame = data === "" && mycoins === 1 && othercoins === 1
if (isNewGame) {
await writeFile(stateFileName, JSON.stringify(state))
} else {
state = JSON.parse(await readFile(stateFileName, `utf8`))
}
//console.error(state);
let line = data.split(/\n/g).pop()
// I am in the exchnage
if (mycards.length >= 3) {
const [c1, c2] = GiveCard(true).reverse()
if (mycards.length === 3) {
state.inTheDeck.push(c1)
message(GetRevealCardChar(c1))
}
if (mycards.length === 4) {
state.inTheDeck.push(c1, c2)
message(`${GetRevealCardChar(c1)}${GetRevealCardChar(c2)}`)
}
return await move(`\n`)
}
const newTurn = line === ``
if (newTurn) {
if (mycoins >= 7) {
return await move(`C`)
}
if (othercoins >= 6) {
if (iHaveCaptain)
return await move(`S`)
if (mycoins <= 6 && mycards.length <= 1) {
// TODO: bluff
}
}
if (
!iHaveDuke &&
!iHaveContessa &&
iHaveAmbassador
) {
return await move(`E`)
}
// Assasinate if oponent has no Contessa
if (
mycoins >= 3 &&
iHaveAssassin &&
!~state.oponentCards.indexOf(CardTypes.Contessa)
) {
return await move(`A`)
}
if (iHaveDuke) {
return await move(`T`)
}
return await move(`I\n`)
}
// Exchange
if (line === `Eq`) {
if (iHaveAmbassador)
return await move(GetRevealCardChar(CardTypes.Ambassador))
return await GiveUpCard(GiveCard(true)[0])
}
// Tax Challenge
if(line === `Tq`) {
if (iHaveDuke)
return await move(GetRevealCardChar(CardTypes.Duke))
return await GiveUpCard(GiveCard(true)[0])
}
if (line === `Sa`) {
if (!~state.oponentCards.indexOf(CardTypes.Ambassador)) {
state.oponentMissingTempCard = CardTypes.Ambassador
return await move(`q`)
}
return await endTurn()
}
if (line === `Sc`) {
if (!~state.oponentCards.indexOf(CardTypes.Captain)) {
state.oponentMissingTempCard = CardTypes.Captain
return await move(`q`)
}
return await endTurn()
}
if (line=== `Saq${GetRevealCardChar(CardTypes.Ambassador)}`) {
state.oponentMissingTempCard = ``
state.oponentCards.push(
CardTypes.Ambassador
);
return await GiveUpCard(GiveCard(true)[0], true)
}
if (line=== `Scq${GetRevealCardChar(CardTypes.Captain)}`) {
state.oponentMissingTempCard = ``
state.oponentCards.push(
CardTypes.Captain
);
return await GiveUpCard(GiveCard(true)[0], true)
}
if (line === `Sq`) {
if (iHaveCaptain)
return await move(GetRevealCardChar(CardTypes.Captain))
return await GiveUpCard(GiveCard(true)[0])
}
// Assassinate Block and Chalange it
if (line === `As`) {
state.oponentMissingTempCard = CardTypes.Contessa
return await move(`q`)
}
// Assasint blocked by Contessa
if (line === `Asq${GetRevealCardChar(CardTypes.Contessa)}`) {
state.oponentMissingTempCard = ``
state.oponentCards.push(
CardTypes.Contessa
)
// Assassin useless here lets give it up
return await GiveUpCard(CardTypes.Assassin, true)
}
// Assassinate challenge
if (line === `Aq`) {
if (iHaveAssassin)
return await move(GetRevealCardChar(CardTypes.Assassin))
return await GiveUpCard(GiveCard(true)[0])
}
// Defense Moves
if (line === `C`) {
return await GiveUpCard(GiveCard(true)[0])
}
if (line === `A`) {
if (iHaveContessa)
return await move(`s`)
if (!!~state.oponentCards.indexOf(CardTypes.Assassin)) {
// If oponent has an Assasin card lets bluff
return await move(`s`)
} else {
state.oponentMissingTempCard = CardTypes.Assassin
return await move(`q`)
}
}
if (line === `Aq${GetRevealCardChar(CardTypes.Assassin)}`) {
state.oponentMissingTempCard = ``
state.oponentCards.push(
CardTypes.Assassin
);
return await GiveUpCard(GiveCard(true)[0], true)
}
if (line === `Asq`) {
if (iHaveContessa)
return await move(GetRevealCardChar(CardTypes.Contessa))
return await GiveUpCard(GiveCard(true)[0])
}
if (line === `S`) {
if (iHaveAmbassador)
return await move(`a`)
if (iHaveCaptain)
return await move(`c`)
return await move(`p`)
}
if (line === `Saq`) {
if (iHaveAmbassador)
return await move(GetRevealCardChar(CardTypes.Ambassador))
return await GiveUpCard(GiveCard(true)[0])
}
if (line === `Scq`) {
if (iHaveCaptain)
return await move(GetRevealCardChar(CardTypes.Captain))
return await GiveUpCard(GiveCard(true)[0])
}
if (line === `F`) {
if (iHaveDuke)
return await move(`d`)
return await move(`p`)
}
if (line === `Fdq`) {
if (iHaveDuke)
return await move(GetRevealCardChar(CardTypes.Duke))
return await GiveUpCard(GiveCard(true)[0])
}
if (line === `E`) {
if (!OponentCanHave(CardTypes.Ambassador)) {
return await move(`q`)
}
state.oponentCards = []
state.oponentMissingCards = []
state.oponentMissingTempCard = ''
return await move(`p`)
}
if (line === `Eq${GetRevealCardChar(CardTypes.Ambassador)}`) {
console.error(111, `THIS SHOULD NEVER HAPPEN`)
return await GiveUpCard(GiveCard(true)[0])
}
if (line === `T`) {
if (!OponentCanHave(CardTypes.Duke)) {
return await move(`q`)
}
return await move(`p`)
}
if (line === `Tq${GetRevealCardChar(CardTypes.Duke)}`) {
console.error(111, `THIS SHOULD NEVER HAPPEN`)
return await GiveUpCard(GiveCard(true)[0])
}
// remove oponents drop card from the state
// can't detect if oponent has the same card twice
if (!!~Object.values(giveUpTable).indexOf(line.substr(-1))) {
// Catch the bluff
if (state.oponentMissingTempCard !== "") {
state.oponentMissingCards.push(state.oponentMissingTempCard)
state.oponentMissingTempCard = ""
}
// maybe we should asume user doeas not has the same card?
const cardType = GetGiveUpCardType(line.substr(-1))
state.oponentCards.filter(c => c !== cardType)
state.inTheDeck.push(cardType)
state.oponentDropedCards.push(cardType)
}
return await endTurn()
})()
.then(async () => {
await writeFile(stateFileName, JSON.stringify(state))
})
.catch(console.error.bind(console))
```
import fs from 'fs'
import { promisify } from 'util'
const appendFile = promisify(fs.appendFile)
const writeFile = promisify(fs.writeFile)
const readFile = promisify(fs.readFile)
const delay = ms => new Promise(_ => setTimeout(_, ms));
let [filename, othercoins, mycoins, mycards ] = process.argv.slice(2)
othercoins = +othercoins
mycoins = +mycoins
const move = async (m) => await appendFile(filename, m)
const stateFileName = `./state.json`
const defaultState = {
usedCards: [],
oponentCards: [],
oponentCardModifier: 0
}
const CardTypes = Object.freeze({
Ambassador : `Ambassador`,
Assassin : `Assassin`,
Captain : `Captain`,
Contessa : `Contessa`,
Duke : `Duke`,
})
const revealTable = Object.freeze({
[CardTypes.Ambassador]: `~`,
[CardTypes.Assassin]: `^`,
[CardTypes.Captain]: `*`,
[CardTypes.Contessa]: `!`,
[CardTypes.Duke]: `$`,
})
const giveUpTable = Object.freeze({
[CardTypes.Ambassador]: `_`,
[CardTypes.Assassin]: `'`,
[CardTypes.Captain]: `<`,
[CardTypes.Contessa]: `=`,
[CardTypes.Duke]: `0`,
})
function GetRevealCardChar(cardType) {
return revealTable[cardType]
}
function GetRevealCardType(char) {
return Object.keys(revealTable).find(key => revealTable[key] === char)
}
function GetGiveUpCardChar(cardType) {
return giveUpTable[cardType]
}
function GiveCard() {
// TODO: Tactic
const giveAwayOrder = [
CardTypes.Captain,
CardTypes.Ambassador,
CardTypes.Contessa,
CardTypes.Assassin,
CardTypes.Duke,
]
return GetGiveUpCardChar(mycards
.split('')
.map(GetRevealCardType)
.sort(
(a, b) => {
giveAwayOrder.indexOf(a) - giveAwayOrder.indexOf(b)
}
)[0])
}
const iHaveAmbassador = !!~mycards.indexOf(`~`)
const iHaveAssassin = !!~mycards.indexOf(`^`)
const iHaveCaptain = !!~mycards.indexOf(`*`)
const iHaveContessa = !!~mycards.indexOf(`!`)
const iHaveDuke = !!~mycards.indexOf(`$`)
let state = defaultState
;(async ()=>{
const data = (await readFile(filename, `utf8`)).replace(/\r/g, ``)
const isNewGame = data === "" && mycoins === 1 && othercoins === 1
if (isNewGame) {
await writeFile(stateFileName, JSON.stringify(state))
} else {
state = JSON.parse(await readFile(stateFileName, `utf8`))
}
let line = data.split(/\n/g).pop()
const newTurn = line === ``
if (newTurn) {
if (mycoins >= 7) {
return await move(`C`)
}
if (othercoins >= 6) {
if (iHaveCaptain)
return await move(`S`)
if (mycoins <= 6 && mycards.length <= 1) {
// TODO: bluff
}
}
// Assasinate if oponent has no Contessa
if (
mycoins >= 3 &&
iHaveAssassin &&
!~state.oponentCards.indexOf(CardTypes.Contessa)
) {
return await move(`A`)
}
if (iHaveDuke) {
return await move(`T`)
}
return await move(`I\n`)
}
// Tax Challenge
if(line === `Tq`) {
if (iHaveDuke)
return await move(GetRevealCardChar(CardTypes.Duke))
return await move(GiveCard())
}
if (line === `Sa`) {
return await move(`\n`)
}
if (line === `Sc`) {
return await move(`\n`)
}
if (line === `Sq`) {
if (iHaveCaptain)
return await move(GetRevealCardChar(CardTypes.Captain))
return await move(GiveCard())
}
// Assassinate Block and Chalange it
if (line === `As`) {
return await move(`q`)
}
// Assasint blocked by Contessa
if (line === `Asq!`) {
state.oponentCards.push(
CardTypes.Contessa
)
// Assassin useless here lets give it up
return await move( GetGiveUpCardChar(CardTypes.Assassin) + `\n`)
}
// Assassinate challenge
if (line === `Aq`) {
if (iHaveAssassin)
return await move(GetRevealCardChar(CardTypes.Assassin))
return await move(GiveCard())
}
// Defense Moves
if (line === `C`) {
return await move(GiveCard())
}
if (line === `A`) {
if (iHaveContessa)
return await move(`s`)
return await move(`p`GiveCard())
}
if (line === `Asq`) {
if (iHaveContessa)
return await move(GetRevealCardChar(CardTypes.Contessa))
return await move(GiveCard())
}
if (line === `S`) {
if (iHaveAmbassador)
return await move(`a`)
if (iHaveCaptain)
return await move(`c`)
return await move(`p`)
}
if (line === `Saq`) {
if (iHaveAmbassador)
return await move(GetRevealCardChar(CardTypes.Ambassador))
return await move(GiveCard())
}
if (line === `Scq`) {
if (iHaveCaptain)
return await move(GetRevealCardChar(CardTypes.Captain))
return await move(GiveCard())
}
if (line === `F`) {
if (iHaveDuke)
return await move(`d`)
return await move(`p`)
}
if (line === `Fdq`) {
if (iHaveDuke)
return await move(GetRevealCardChar(CardTypes.Duke))
return await move(GiveCard())
}
// pass
if (!!~[`E`, `T`].indexOf(line)) {
return await move(`p`)
}
return await move(`\n`)
})()
.then(async () => {
await writeFile(stateFileName, JSON.stringify(state))
})
.catch(console.error.bind(console))
```
import fs from 'fs'
import { promisify } from 'util'
const appendFile = promisify(fs.appendFile)
const writeFile = promisify(fs.writeFile)
const readFile = promisify(fs.readFile)
const delay = ms => new Promise(_ => setTimeout(_, ms));
let [filename, othercoins, mycoins, mycards ] = process.argv.slice(2)
othercoins = +othercoins
mycoins = +mycoins
const move = async (m) => await appendFile(filename, m)
const stateFileName = `./state.json`
const defaultState = {
usedCards: [],
oponentCards: [],
oponentCardModifier: 0
}
const CardTypes = Object.freeze({
Ambassador : `Ambassador`,
Assassin : `Assassin`,
Captain : `Captain`,
Contessa : `Contessa`,
Duke : `Duke`,
})
const revealTable = Object.freeze({
[CardTypes.Ambassador]: `~`,
[CardTypes.Assassin]: `^`,
[CardTypes.Captain]: `*`,
[CardTypes.Contessa]: `!`,
[CardTypes.Duke]: `$`,
})
const giveUpTable = Object.freeze({
[CardTypes.Ambassador]: `_`,
[CardTypes.Assassin]: `'`,
[CardTypes.Captain]: `<`,
[CardTypes.Contessa]: `=`,
[CardTypes.Duke]: `0`,
})
function GetRevealCardChar(cardType) {
return revealTable[cardType]
}
function GetRevealCardType(char) {
return Object.keys(revealTable).find(key => revealTable[key] === char)
}
function GetGiveUpCardChar(cardType) {
return giveUpTable[cardType]
}
function GiveCard() {
// TODO: Tactic
const giveAwayOrder = [
CardTypes.Captain,
CardTypes.Ambassador,
CardTypes.Contessa,
CardTypes.Assassin,
CardTypes.Duke,
]
return GetGiveUpCardChar(mycards
.split('')
.map(GetRevealCardType)
.sort(
(a, b) => {
giveAwayOrder.indexOf(a) - giveAwayOrder.indexOf(b)
}
)[0])
}
const iHaveAmbassador = !!~mycards.indexOf(`~`)
const iHaveAssassin = !!~mycards.indexOf(`^`)
const iHaveCaptain = !!~mycards.indexOf(`*`)
const iHaveContessa = !!~mycards.indexOf(`!`)
const iHaveDuke = !!~mycards.indexOf(`$`)
let state = defaultState
;(async ()=>{
const data = (await readFile(filename, `utf8`)).replace(/\r/g, ``)
const isNewGame = data === "" && mycoins === 1 && othercoins === 1
if (isNewGame) {
await writeFile(stateFileName, JSON.stringify(state))
} else {
state = JSON.parse(await readFile(stateFileName, `utf8`))
}
let line = data.split(/\n/g).pop()
const newTurn = line === ``
if (newTurn) {
if (mycoins >= 7) {
return await move(`C`)
}
if (othercoins >= 6) {
if (iHaveCaptain)
return await move(`S`)
if (mycoins <= 6 && mycards.length <= 1) {
// TODO: bluff
}
}
// Assasinate if oponent has no Contessa
if (
mycoins >= 3 &&
iHaveAssassin &&
!~state.oponentCards.indexOf(CardTypes.Contessa)
) {
return await move(`A`)
}
if (iHaveDuke) {
return await move(`T`)
}
return await move(`I\n`)
}
// Tax Challenge
if(line === `Tq`) {
if (iHaveDuke)
return await move(GetRevealCardChar(CardTypes.Duke))
return await move(GiveCard())
}
if (line === `Sa`) {
return await move(`\n`)
}
if (line === `Sc`) {
return await move(`\n`)
}
if (line === `Sq`) {
if (iHaveCaptain)
return await move(GetRevealCardChar(CardTypes.Captain))
return await move(GiveCard())
}
// Assassinate Block and Chalange it
if (line === `As`) {
return await move(`q`)
}
// Assasint blocked by Contessa
if (line === `Asq!`) {
state.oponentCards.push(
CardTypes.Contessa
)
// Assassin useless here lets give it up
return await move( GetGiveUpCardChar(CardTypes.Assassin) + `\n`)
}
// Assassinate challenge
if (line === `Aq`) {
if (iHaveAssassin)
return await move(GetRevealCardChar(CardTypes.Assassin))
return await move(GiveCard())
}
// Defense Moves
if (line === `C`) {
return await move(GiveCard())
}
if (line === `A`) {
if (iHaveContessa)
return await move(`s`)
return await move(`p`)
}
if (line === `Asq`) {
if (iHaveContessa)
return await move(GetRevealCardChar(CardTypes.Contessa))
return await move(GiveCard())
}
if (line === `S`) {
if (iHaveAmbassador)
return await move(`a`)
if (iHaveCaptain)
return await move(`c`)
return await move(`p`)
}
if (line === `Saq`) {
if (iHaveAmbassador)
return await move(GetRevealCardChar(CardTypes.Ambassador))
return await move(GiveCard())
}
if (line === `Scq`) {
if (iHaveCaptain)
return await move(GetRevealCardChar(CardTypes.Captain))
return await move(GiveCard())
}
if (line === `F`) {
if (iHaveDuke)
return await move(`d`)
return await move(`p`)
}
if (line === `Fdq`) {
if (iHaveDuke)
return await move(GetRevealCardChar(CardTypes.Duke))
return await move(GiveCard())
}
// pass
if (!!~[`E`, `T`].indexOf(line)) {
return await move(`p`)
}
return await move(`\n`)
})()
.then(async () => {
await writeFile(stateFileName, JSON.stringify(state))
})
.catch(console.error.bind(console))
```
import fs from 'fs'
import { promisify } from 'util'
const appendFile = promisify(fs.appendFile)
const writeFile = promisify(fs.writeFile)
const readFile = promisify(fs.readFile)
const delay = ms => new Promise(_ => setTimeout(_, ms));
let [filename, othercoins, mycoins, mycards ] = process.argv.slice(2)
othercoins = +othercoins
mycoins = +mycoins
const move = async (m) => await appendFile(filename, m)
const stateFileName = `./state.json`
const defaultState = {
usedCards: [],
oponentCards: [],
oponentCardModifier: 0
}
const CardTypes = Object.freeze({
Ambassador : `Ambassador`,
Assassin : `Assassin`,
Captain : `Captain`,
Contessa : `Contessa`,
Duke : `Duke`,
})
const revealTable = Object.freeze({
[CardTypes.Ambassador]: `~`,
[CardTypes.Assassin]: `^`,
[CardTypes.Captain]: `*`,
[CardTypes.Contessa]: `!`,
[CardTypes.Duke]: `$`,
})
const giveUpTable = Object.freeze({
[CardTypes.Ambassador]: `_`,
[CardTypes.Assassin]: `'`,
[CardTypes.Captain]: `<`,
[CardTypes.Contessa]: `=`,
[CardTypes.Duke]: `0`,
})
function GetRevealCardChar(cardType) {
return revealTable[cardType]
}
function GetRevealCardType(char) {
return Object.keys(revealTable).find(key => revealTable[key] === char)
}
function GetGiveUpCardChar(cardType) {
return giveUpTable[cardType]
}
function GiveCard() {
// TODO: Tactic
const giveAwayOrder = [
CardTypes.Captain,
CardTypes.Ambassador,
CardTypes.Contessa,
CardTypes.Assassin,
CardTypes.Duke,
]
return GetGiveUpCardChar(mycards
.split('')
.map(GetRevealCardType)
.sort(
(a, b) => {
giveAwayOrder.indexOf(a) - giveAwayOrder.indexOf(b)
}
)[0])
}
const iHaveAmbassador = !!~mycards.indexOf(`~`)
const iHaveAssassin = !!~mycards.indexOf(`^`)
const iHaveCaptain = !!~mycards.indexOf(`*`)
const iHaveContessa = !!~mycards.indexOf(`!`)
const iHaveDuke = !!~mycards.indexOf(`$`)
let state = defaultState
;(async ()=>{
const data = (await readFile(filename, `utf8`)).replace(/\r/g, ``)
const isNewGame = data === "" && mycoins === 1 && othercoins === 1
if (isNewGame) {
await writeFile(stateFileName, JSON.stringify(state))
} else {
state = JSON.parse(await readFile(stateFileName, `utf8`))
}
let line = data.split(/\n/g).pop()
const newTurn = line === ``
if (newTurn) {
if (mycoins >= 7) {
return await move(`C`)
}
if (othercoins >= 6) {
if (iHaveCaptain)
return await move(`S`)
if (mycoins <= 6 && mycards.length <= 1) {
// TODO: bluff
}
}
// Assasinate if oponent has no Contessa
if (
mycoins >= 3 &&
iHaveAssassin &&
!~state.oponentCards.indexOf(CardTypes.Contessa)
) {
return await move(`A`)
}
if (iHaveDuke) {
return await move(`T`)
}
return await move(`I\n`)
}
// Tax Challenge
if(line === `Tq`) {
if (iHaveDuke)
return await move(GetRevealCardChar(CardTypes.Duke))
return await move(GiveCard())
}
if (line === `Sa`) {
return await move(`\n`)
}
if (line === `Sc`) {
return await move(`\n`)
}
if (line === `Sq`) {
if (iHaveCaptain)
return await move(GetRevealCardChar(CardTypes.Captain))
return await move(GiveCard())
}
// Assassinate Block and Chalange it
if (line === `As`) {
return await move(`q`)
}
// Assasint blocked by Contessa
if (line === `Asq!`) {
state.oponentCards.push(
CardTypes.Contessa
)
// Assassin useless here lets give it up
return await move( GetGiveUpCardChar(CardTypes.Assassin) + `\n`)
}
// Assassinate challenge
if (line === `Aq`) {
if (iHaveAssassin)
return await move(GetRevealCardChar(CardTypes.Assassin))
return await move(GiveCard())
}
// Defense Moves
if (line === `C`) {
return await move(GiveCard())
}
if (line === `A`) {
if (iHaveContessa)
return await move(`s`)
return await move(GiveCard())
}
if (line === `Asq`) {
if (iHaveContessa)
return await move(GetRevealCardChar(CardTypes.Contessa))
return await move(GiveCard())
}
if (line === `S`) {
if (iHaveAmbassador)
return await move(`a`)
if (iHaveCaptain)
return await move(`c`)
return await move(`p`)
}
if (line === `Saq`) {
if (iHaveAmbassador)
return await move(GetRevealCardChar(CardTypes.Ambassador))
return await move(GiveCard())
}
if (line === `Scq`) {
if (iHaveCaptain)
return await move(GetRevealCardChar(CardTypes.Captain))
return await move(GiveCard())
}
if (line === `F`) {
if (iHaveDuke)
return await move(`d`)
return await move(`p`)
}
if (line === `Fdq`) {
if (iHaveDuke)
return await move(GetRevealCardChar(CardTypes.Duke))
return await move(GiveCard())
}
// pass
if (!!~[`E`, `T`].indexOf(line)) {
return await move(`p`)
}
return await move(`\n`)
})()
.then(async () => {
await writeFile(stateFileName, JSON.stringify(state))
})
.catch(console.error.bind(console))
```