I am creating a Pokemon card game using Javascript but am not sure if I am going about it the right way

67
December 19, 2018, at 08:00 AM

player1 and player2 are both supposed to receive 3 random cards from the array. After the cards are drawn the cards should be discarded. I am not able to get 3 random cards into the players cards[] and also discard them. Is splice the best way to accomplish this?

let pokemonCards =  
[ 
  { name: "Bulbasaur", damage: 60 },  
  { name: "Caterpie", damage: 40 },  
  { name: "Charmander", damage: 60 },  
  { name: "Clefairy", damage: 50 },  
  { name: "Jigglypuff", damage: 60 },  
  { name: "Mankey", damage: 30 },  
  { name: "Meowth", damage: 60 },  
  { name: "Nidoran - female", damage: 60 },  
  { name: "Nidoran - male", damage: 50 },  
  { name: "Oddish", damage: 40 },  
  { name: "Pidgey", damage: 50 },  
  { name: "Pikachu", damage: 50 },  
  { name: "Poliwag", damage: 50 },  
  { name: "Psyduck", damage: 60 },  
  { name: "Rattata", damage: 30 },  
  { name: "Squirtle", damage: 60 },  
  { name: "Vulpix", damage: 50 },  
  { name: "Weedle",  damage: 40 } 
] 
 
 
 
 
 
 
 
// assign AI to player1 and player 2 
// They should each draw 3 cards 
 
 
let player1 = { 
	cards: [],  
	 
 } 
	 
let player2 = { 
	cards: [], 
	 
	 
 
 } 
 
 
 
//functions 
let randomCard = function(){ 
return randomCardValue = pokemonCards[Math.floor(Math.random()*pokemonCards.length)] 
}  
 
let drawCards = function(){ 
for(i = 0; i < 3; i++){ 
	 
	 player1.cards.push(randomCard()) 
	pokemonCards.splice(randomCard(),1) 
	 
	 
} 
	} 
 
drawCards() 
    
 
  

Answer 1

Try this. I store the random selected card and remove the card from the deck using splice() and push the card into the player's hand. It should work.

let pokemonCards =  
[ 
  { name: "Bulbasaur", damage: 60 },  
  { name: "Caterpie", damage: 40 },  
  { name: "Charmander", damage: 60 },  
  { name: "Clefairy", damage: 50 },  
  { name: "Jigglypuff", damage: 60 },  
  { name: "Mankey", damage: 30 },  
  { name: "Meowth", damage: 60 },  
  { name: "Nidoran - female", damage: 60 },  
  { name: "Nidoran - male", damage: 50 },  
  { name: "Oddish", damage: 40 },  
  { name: "Pidgey", damage: 50 },  
  { name: "Pikachu", damage: 50 },  
  { name: "Poliwag", damage: 50 },  
  { name: "Psyduck", damage: 60 },  
  { name: "Rattata", damage: 30 },  
  { name: "Squirtle", damage: 60 },  
  { name: "Vulpix", damage: 50 },  
  { name: "Weedle",  damage: 40 } 
] 
 
 
 
 
 
 
 
// assign AI to player1 and player 2 
// They should each draw 3 cards 
 
 
let player1 = { 
	cards: [],  
	 
 } 
	 
let player2 = { 
	cards: [], 
	 
	 
 
 } 
 
 
 
//functions 
let randomCard = function(){ 
return randomCardValue = pokemonCards[Math.floor(Math.random()*pokemonCards.length)] 
}  
 
let drawCards = function(){ 
for(i = 0; i < 3; i++){ 
	let selectedRandomCard = pokemonCards.splice(randomCard(),1)[0]; 
    console.log(selectedRandomCard); 
	player1.cards.push(selectedRandomCard); 
	 
} 
	} 
 
drawCards() 
    
 
  

Answer 2

I would suggest shuffling the deck. Then you don't need to worry about keeping track anything. You can just pop cards of like you would in a real deck.

Here's the standard Stack overflow answer about shuffling, which I've used (in spirit) below. You can pop() your cards off in a loop if you want. But below uses Array.from() which is a quick way to make an array without an explicit loop:

// shuffles the deck in place 
function shuffle(array) { 
    var currentIndex = array.length; 
    while (0 !== --currentIndex) { 
      let randomIndex = Math.floor(Math.random() * currentIndex); 
      [array[currentIndex], array[randomIndex]] = [array[randomIndex],  array[currentIndex]]; 
    }  
    return array; 
  } 
   
   
let pokemonCards =  
[ 
  { name: "Bulbasaur", damage: 60 },  
  { name: "Caterpie", damage: 40 },  
  { name: "Charmander", damage: 60 },  
  { name: "Clefairy", damage: 50 },  
  { name: "Jigglypuff", damage: 60 },  
  { name: "Mankey", damage: 30 },  
  { name: "Meowth", damage: 60 },  
  { name: "Nidoran - female", damage: 60 },  
  { name: "Nidoran - male", damage: 50 },  
  { name: "Oddish", damage: 40 },  
  { name: "Pidgey", damage: 50 },  
  { name: "Pikachu", damage: 50 },  
  { name: "Poliwag", damage: 50 },  
  { name: "Psyduck", damage: 60 },  
  { name: "Rattata", damage: 30 },  
  { name: "Squirtle", damage: 60 },  
  { name: "Vulpix", damage: 50 },  
  { name: "Weedle",  damage: 40 } 
] 
 
function deal(num_of_cards){ 
  // return an array of n cards 
  return Array.from({length:num_of_cards}, () => pokemonCards.pop()) 
} 
 
// randomize the deck order: 
shuffle(pokemonCards) 
console.log("deck length: ", pokemonCards.length) 
 
// players should be in a datastructure of some sort 
// not individual variables 
let players = [] 
players.push({name: "player 1", cards: deal(3)}) 
players.push({name: "player 2", cards: deal(3)}) 
 
console.log(players[0]) 
console.log(players[1]) 
  
// double check deck length 
console.log("deck length: ", pokemonCards.length)

Answer 3

I can see two issues:

  1. You are calling splice() wrong (the first argument needs to be the index you'll start splicing and the second should be the delete count: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/splice ) Thus, you need to know the index of the card you are randomly choosing. You can modify your randomCards() function to achieve that.

  2. You are calling randomCards twice in the drawCards function, both of which returns a different result. For consistency call it once in every loop, assign the result to a variable and use that variable when pushing and splicing.

I believe the following snippet does what you want your code to do:

//functions
let randomCard = function() {
    let randomCardIndex = Math.floor(Math.random() * pokemonCards.length)
    let randomCardValue = pokemonCards[randomCardIndex]
    return [randomCardIndex, randomCardValue]
} 
let drawCards = function() {
    for(i = 0; i < 3; i++){
        let card = randomCard();
        player1.cards.push(card[1])
        pokemonCards.splice(card[0], 1)
    }
}
Answer 4

With this solution, not everything is global, with something like a game, that matters... But that stuff aside, I'd say that using splice is probably the best approach, it's simple, easy to read, etc...

I've also taken the time to create a config object for you, I mean you may like it, dislike it, that's your shout, I just did it because I like to see it that way.

const PokemonApp = function(myNameSpace) { 
  const publicProps = {}; 
  const config = { 
    cards: [ 
      { name: "Bulbasaur", damage: 60 },  
      { name: "Caterpie", damage: 40 },  
      { name: "Charmander", damage: 60 },  
      { name: "Clefairy", damage: 50 },  
      { name: "Jigglypuff", damage: 60 },  
      { name: "Mankey", damage: 30 },  
      { name: "Meowth", damage: 60 },  
      { name: "Nidoran - female", damage: 60 },  
      { name: "Nidoran - male", damage: 50 },  
      { name: "Oddish", damage: 40 },  
      { name: "Pidgey", damage: 50 },  
      { name: "Pikachu", damage: 50 },  
      { name: "Poliwag", damage: 50 },  
      { name: "Psyduck", damage: 60 },  
      { name: "Rattata", damage: 30 },  
      { name: "Squirtle", damage: 60 },  
      { name: "Vulpix", damage: 50 },  
      { name: "Weedle",  damage: 40 } 
    ], 
    cardLimit: 3, 
    players: [{ cards: [] }, { cards: [] }] 
  }; 
   
   
  publicProps.getPlayer1 = () => { return {...config.players[0]} }; 
  publicProps.getPlayer2 = () => { return {...config.players[1]} }; 
  publicProps.getCards = () => { return [...config.cards] }; 
   
   
  const randomCard = () => { 
    const index = Math.floor(Math.random() * config.cards.length); 
    return { 
      index: index,  
      card: config.cards[index] 
    } 
  }; 
 
 
  publicProps.drawCards = () => config.players.map(p =>  
    Array.from({length: config.cardLimit}, () => {  
      const cardObject = randomCard(); 
      p.cards.push(cardObject.card); 
      config.cards.splice(cardObject.index, 1); 
  }));   
   
   
  myNameSpace.launch = () => { 
    console.log('Launching App...'); 
    return publicProps; 
  }; 
   
   
  return myNameSpace; 
}({}); 
 
 
const app = PokemonApp.launch(); 
console.log(app.getCards()); // before. 
app.drawCards(); 
console.log(app.getCards()); // after. 
console.log(app.getPlayer1()); 
console.log(app.getPlayer2());

READ ALSO
Extract text in Regular Expression in Javascript

Extract text in Regular Expression in Javascript

In Javascript, I want to extract array from a stringThe string is

50
Uploading image using mobile image get flipped

Uploading image using mobile image get flipped

I have used 3rd party jquery plugin for cropping imagesIt has been implemented successfully, but when I upload an image from a mobile device after getting cropped it will just rotate 45 degree right or left

50
Storing HTML templates with variables

Storing HTML templates with variables

I'm working on a platform that enables you to use templates provided by the platform and you can change few things in the choosen template (title, text, imageetc)

9
Node.js got limit response size

Node.js got limit response size

I am using the got module in order to make web requestsSometimes, the requested urls serve really large files, but I just need the first 10kB of content, so I want to optimize my network usage

26