Skip to content

Commit

Permalink
Merge pull request #599 from SibylLab/addMalwareCards-#534
Browse files Browse the repository at this point in the history
Add malware cards #534
  • Loading branch information
strinsberg authored Jun 30, 2020
2 parents 0e2092b + 82af70d commit 48541d7
Show file tree
Hide file tree
Showing 118 changed files with 2,138 additions and 798 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
.DS_Store
node_modules/
dist/
.firebase
npm-debug.log
test/unit/coverage
.idea
Expand Down
Binary file removed public/static/cardImages/BatteryBackup.png
Binary file not shown.
Binary file removed public/static/cardImages/Generator.png
Binary file not shown.
Binary file removed public/static/cardImages/Hacker.png
Binary file not shown.
Binary file removed public/static/cardImages/Malware.png
Binary file not shown.
Binary file removed public/static/cardImages/OverClock.png
Binary file not shown.
Binary file removed public/static/cardImages/PowerOutage.png
Binary file not shown.
File renamed without changes
Binary file removed public/static/cardImages/backOfCard.png.old
Binary file not shown.
Binary file modified public/static/cardImages/effects/ANTIVIRUS.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file removed public/static/cardImages/effects/BATTERYBACKUP.png
Binary file not shown.
Binary file added public/static/cardImages/effects/DISCARD.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified public/static/cardImages/effects/FIREWALL.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file removed public/static/cardImages/effects/GENERATOR.png
Binary file not shown.
Binary file added public/static/cardImages/effects/GROUP2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/static/cardImages/effects/GROUP3.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/static/cardImages/effects/GROUP4.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/static/cardImages/effects/GROUP5.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/static/cardImages/effects/GROUP6.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file removed public/static/cardImages/effects/HACK.png
Binary file not shown.
Binary file added public/static/cardImages/effects/INSTRUCTION1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/static/cardImages/effects/INSTRUCTION2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/static/cardImages/effects/INSTRUCTION3.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file removed public/static/cardImages/effects/OVERCLOCK.png
Binary file not shown.
Binary file removed public/static/cardImages/effects/POWEROUTAGE.png
Binary file not shown.
Binary file added public/static/cardImages/effects/RANSOM.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/static/cardImages/effects/REDRAW.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/static/cardImages/effects/REPEAT1.png
Binary file added public/static/cardImages/effects/REPEAT2.png
Binary file added public/static/cardImages/effects/REPEAT3.png
Binary file added public/static/cardImages/effects/REPEAT4.png
Binary file added public/static/cardImages/effects/SCAN.png
Binary file added public/static/cardImages/effects/SPYWARE.png
Binary file added public/static/cardImages/effects/TROJAN.png
Binary file added public/static/cardImages/effects/VARIABLE3.png
Binary file added public/static/cardImages/effects/VARIABLE4.png
Binary file added public/static/cardImages/effects/VARIABLE5.png
Binary file added public/static/cardImages/effects/VARIABLE6.png
Binary file modified public/static/cardImages/effects/VIRUS.png
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
Binary file added public/static/cardImages/ransom0.png
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
Binary file added public/static/cardImages/scan0.png
Binary file added public/static/cardImages/spyware0.png
Binary file added public/static/cardImages/trojan0.png
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
Binary file added public/static/cardImages/virus0.png
Binary file added public/static/miscIcons/arrow.png
Binary file added public/static/miscIcons/noIcon.png
Binary file added public/static/playerImages/player0.png
Binary file added public/static/playerImages/player1.png
Binary file added public/static/playerImages/player2.png
Binary file added public/static/playerImages/player3.png
Binary file added public/static/playerImages/player4.png
Binary file added public/static/playerImages/player5.png
Binary file added public/static/playerImages/player6.png
Binary file added public/static/playerImages/player7.png
Binary file removed public/static/playerImages/robo_0.jpg
Diff not rendered.
Binary file removed public/static/playerImages/robo_1.jpg
Diff not rendered.
Binary file removed public/static/playerImages/robo_2.jpg
Diff not rendered.
Binary file removed public/static/playerImages/robo_3.jpg
Diff not rendered.
13 changes: 10 additions & 3 deletions src/classes/ai/AiHandler.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,16 @@ export default class AiHandler {
chooseAction(hand, players, stacks, scores) {
// Try all the action handlers until one returns a turn object
for (let action of this.actionHandlers) {
let result = action.handle(hand, players, stacks, scores)
if (result) {
return result
try {
let result = action.handle(hand, players, stacks, scores)
if (result) {
return result
}

// Ensure that a component error does not stop the AI turn
} catch (err) {
console.log("AI handler error:", err) // eslint-disable-line
continue
}
}
// If no handler can handle this action use the default action
Expand Down
6 changes: 3 additions & 3 deletions src/classes/ai/AiHandlerFactory.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,15 @@ const CARD_ORDER = {
basic: ["VARIABLE", "REPEAT", "INSTRUCTION"],
standard: [
"GROUP", "VARIABLE", "REPEAT", "INSTRUCTION", "ANTIVIRUS", "FIREWALL",
"OVERCLOCK", "HACK", "VIRUS"
"OVERCLOCK", "RANSOM", "TROJAN", "VIRUS"
],
aggressive: [
"HACK", "VIRUS", "VARIABLE", "REPEAT", "INSTRUCTION", "GROUP",
"VIRUS", "RANSOM", "TROJAN", "VARIABLE", "REPEAT", "INSTRUCTION", "GROUP",
"FIREWALL", "ANTIVIRUS", "OVERCLOCK"
],
defensive: [
"FIREWALL", "ANTIVIRUS", "OVERCLOCK", "GROUP", "VARIABLE", "REPEAT",
"INSTRUCTION", "VIRUS", "HACK"
"INSTRUCTION", "TROJAN", "VIRUS", "RANSOM"
]
}

Expand Down
13 changes: 7 additions & 6 deletions src/classes/ai/PlayBestCardAction.js
Original file line number Diff line number Diff line change
Expand Up @@ -156,24 +156,24 @@ export default class PlayBestCardAction extends ActionHandler {
}

/**
* Hack another players stack under specific conditions.
* Will not hack single card stacks as this is a waste. Picks the biggest
* play a virus on another players stack under specific conditions.
* Will not attack single card stacks as this is a waste. Picks the biggest
* stack available that meets the criteria.
* @param card The card to attempt to play.
* @param state an object with all the state needed to make a decision
* @return a move object for hacking a stack, or undefined if
* no stack can be hacked.
* no stack can be attacked.
*/
hack (card, state) {
virus (card, state) {
let stack = state.stacks.filter((s) => {
return s.playerId !== this.player.id && s.cards.length > 1 && s.isHackable()
return s.playerId !== this.player.id && s.cards.length > 1
}).sort((a, b) => {
return b.getScore() - a.getScore()
}).shift()

if (stack) {
return {
playType: 'hackStack',
playType: 'playCardOnStack',
card: card,
player: this.player,
target: stack
Expand Down Expand Up @@ -238,6 +238,7 @@ export default class PlayBestCardAction extends ActionHandler {
let groupable = state.stacks.filter((s) => {
// don't group single group cards with the same value as card
return s.playerId === this.player.id && s.getScore() <= card.value
&& s.getTop().type !== 'VIRUS'
})
if (groupable.length == 0) { return undefined }

Expand Down
29 changes: 18 additions & 11 deletions src/classes/game/Card.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,42 +3,49 @@
* @author Steve modified on 2020-05-25
*/

// Function to create a unique object id
const uuidV1 = require('uuid/v1')

/**
* A Playing card.
*/
export default class Card {
/**
* Constructor for the Card class
* @constructor Card
* @param {int} id The ID of the card
* @param {int} value The value of the card
* @param {char} type The type of the card
* @param {char} image is a string pointing to the image of the card
*/
constructor (id, value, type, image) {
this.id = id
constructor (type, value) {
this.value = value
this.type = type
this.image = image
this.id = uuidV1()
this.image = 'static/cardImages/' + type.toLowerCase() + value + '.png'
this.isExtra = false
this.isMimic = false
}

/**
* Checks if this card is an attack card.
* Checks if this card is an attack card that is played with a popup and
* not placed.
*/
isAttack () {
return this.type === "VIRUS"
return this.type === "RANSOM" || this.type === "SPYWARE"
|| this.type === "TROJAN"
}

/**
* Checks if this card is a safety or remedy card
* Checks if this card is a safety or remedy card that is played with a
* popup and not placed.
*/
isSafety () {
return this.type === "OVERCLOCK"
|| this.type === "FIREWALL" || this.type === "ANTIVIRUS"
return this.type === "SCAN" || this.type === "FIREWALL"
|| this.type === "ANTIVIRUS"
}

/**
* Checks if this card is an attack or safety card.
* Checks if this card is an attack or safety card that is played with
* a popup and not placed.
*/
isSpecial () {
return this.isSafety() || this.isAttack()
Expand Down
42 changes: 42 additions & 0 deletions src/classes/game/CyberEffect.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/**
* @file CyberEffect.js file
* @author Steve on 2020-06-18
*/

// Function to create a unique object id
const uuidV1 = require('uuid/v1')

/**
* An effect for threat prevention or cyber attack on a player.
*/
export default class CyberEffect {
/**
* Constructor for the CyberEffect class.
* @constructor CyberEffect
*/
constructor (type, targetId, attackerId = undefined) {
this.id = uuidV1()
this.type = type
this.targetId = targetId
this.attackerId = attackerId
this.turnsLeft = undefined
if (type === "SPYWARE") {
this.turnsLeft = 2
}
this.image = 'static/cardImages/effects/' + type + '.png'
}

/**
* Decrements turnsLeft and returns the result
*/
takeTurn () {
if (this.turnsLeft === 0) {
return 0
} else if (this.turnsLeft === undefined) {
return 9999
}
this.turnsLeft -= 1
return this.turnsLeft
}
}

123 changes: 38 additions & 85 deletions src/classes/game/Deck.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,68 +5,28 @@

import Card from './Card'

// card types along with {value: numCard} pairs for each
const cardTypes = {
"INSTRUCTION": {1: 9, 2: 12, 3: 9},
"GROUP": {2: 1, 3: 2, 4: 3, 5: 2, 6: 1},
"REPEAT": {1: 5, 2: 3, 3: 5, 4: 3},
"VARIABLE": {3: 2, 4: 2, 5: 2, 6: 1},
"VIRUS": {0: 3},
"RANSOM": {0: 3},
"SPYWARE": {0: 3},
"TROJAN": {0: 3},
"ANTIVIRUS": {0: 1},
"FIREWALL": {0: 2},
"SCAN": {0: 5},
}

// Constants to determine how many of a card type and value to add to the deck

const instruction1 = 9
const instruction2 = 9
const instruction3 = 9

const group2 = 1
const group3 = 2
const group4 = 3
const group5 = 2
const group6 = 1

const repetition2 = 3
const repetition3 = 3
const repetition4 = 3
const repetitionX = 5

const variable3 = 2
const variable4 = 2
const variable5 = 2
const variable6 = 1

const hack = 3
const malware = 3

const overClock = 3

const antiVirus = 1
const firewall = 1

// A list of object of card information used to setup the deck.
const cardDeck = [
{type: 'INSTRUCTION', cardValue: 1, imgSrc: 'static/cardImages/Instruction1.png', howMany: instruction1},
{type: 'INSTRUCTION', cardValue: 2, imgSrc: 'static/cardImages/Instruction2.png', howMany: instruction2},
{type: 'INSTRUCTION', cardValue: 3, imgSrc: 'static/cardImages/Instruction3.png', howMany: instruction3},

{type: 'REPEAT', cardValue: 2, imgSrc: 'static/cardImages/Repetition2.png', howMany: repetition2},
{type: 'REPEAT', cardValue: 3, imgSrc: 'static/cardImages/Repetition3.png', howMany: repetition3},
{type: 'REPEAT', cardValue: 4, imgSrc: 'static/cardImages/Repetition4.png', howMany: repetition4},
{type: 'REPEAT', cardValue: 1, imgSrc: 'static/cardImages/RepetitionX.png', howMany: repetitionX},

{type: 'GROUP', cardValue: 2, imgSrc: 'static/cardImages/Group2.png', howMany: group2},
{type: 'GROUP', cardValue: 3, imgSrc: 'static/cardImages/Group3.png', howMany: group3},
{type: 'GROUP', cardValue: 4, imgSrc: 'static/cardImages/Group4.png', howMany: group4},
{type: 'GROUP', cardValue: 5, imgSrc: 'static/cardImages/Group5.png', howMany: group5},
{type: 'GROUP', cardValue: 6, imgSrc: 'static/cardImages/Group6.png', howMany: group6},

{type: 'VARIABLE', cardValue: 3, imgSrc: 'static/cardImages/Variable3.png', howMany: variable3},
{type: 'VARIABLE', cardValue: 4, imgSrc: 'static/cardImages/Variable4.png', howMany: variable4},
{type: 'VARIABLE', cardValue: 5, imgSrc: 'static/cardImages/Variable5.png', howMany: variable5},
{type: 'VARIABLE', cardValue: 6, imgSrc: 'static/cardImages/Variable6.png', howMany: variable6},

{type: 'HACK', cardValue: 0, imgSrc: 'static/cardImages/Hacker.png', howMany: hack},
{type: 'VIRUS', cardValue: 0, imgSrc: 'static/cardImages/Malware.png', howMany: malware},

{type: 'OVERCLOCK', cardValue: 0, imgSrc: 'static/cardImages/OverClock.png', howMany: overClock},

{type: 'FIREWALL', cardValue: 0, imgSrc: 'static/cardImages/Firewall.png', howMany: firewall},
{type: 'ANTIVIRUS', cardValue: 0, imgSrc: 'static/cardImages/AntiVirus.png', howMany: antiVirus}
// cards to add in when the deck is refreshed
const refreshCards = {
"GROUP": {4: 1, 5: 1, 6: 1},
"REPEAT": {1: 2, 3: 2, 4: 2},
"VARIABLE": {4: 1, 5: 1, 6: 1},
}

]

/**
* A deck for a program wars game.
Expand All @@ -76,42 +36,29 @@ const cardDeck = [
export default class Deck {
/**
* Constructor for the Deck class.
* @param {int} numPlayers The number of players using the deck.
*/
constructor (numPlayers) {
constructor () {
this.cards = []
this.discard = []
this.initDeck(numPlayers)
this.addCards(cardTypes, 4)
}

/**
* Initializes the deck with a pre determined number and type of cards.
* Shuffles the deck.
* @param {int} numPlayers The number of players using the deck.
*/
initDeck (numPlayers) {
let cardId = 0
for (let k = 0; k < numPlayers; k++) {
for (let i = 0; i < cardDeck.length; i++) {
for (let j = 0; j < cardDeck[i].howMany; j++) {
if (cardDeck[i].type === 'FIREWALL' && (k === 1 || k === 3)) {
this.cards.push(new Card(cardId, cardDeck[i].cardValue,
cardDeck[i].type, cardDeck[i].imgSrc))
cardId++
} else if (cardDeck[i].type === 'ANTIVIRUS' && (k === 1 || k === 3)) {
this.cards.push(new Card(cardId, cardDeck[i].cardValue,
cardDeck[i].type, cardDeck[i].imgSrc))
cardId++
} else if (cardDeck[i].type !== 'ANTIVIRUS'
&& cardDeck[i].type !== 'FIREWALL') {
this.cards.push(new Card(cardId, cardDeck[i].cardValue,
cardDeck[i].type, cardDeck[i].imgSrc))
cardId++
}
addCards (cardsToAdd, shuffles) {
for (let [type, values] of Object.entries(cardsToAdd)) {
for (let [value, number] of Object.entries(values)) {
for (let i = 0; i < number; i++) {
this.cards.push(new Card(type, parseInt(value)))
}
}
}
this.shuffle(this.cards)
// Shuffle a few times to try and get a good random order
for (let i = 0; i < shuffles; i++) {
this.shuffle(this.cards)
}
}

/**
Expand Down Expand Up @@ -140,10 +87,16 @@ export default class Deck {

/**
* Refreshes the deck by adding back the discard pile and shuffling.
* Also, adds some more group, variable, and repeat cards to keep the game
* moving. Especially in 4 player games these cards are moslty used up by
* the time the deck runs out, so we add some more in to ensure players
* can still play.
*/
refresh () {
this.cards = this.cards.concat(this.discard)
this.discard = []
this.shuffle(this.cards)
if (this.cards.length < 80) {
this.addCards(refreshCards)
}
}
}
Loading

0 comments on commit 48541d7

Please sign in to comment.