Functionality for a Pokemon fight in R: how to loop over attacks until one faints?

Viewed 52

I am trying to create the functionality for a fight between Mewtwo and Rayquaza in R for a programming project. I am using "The Complete Pokemon Dataset" from Kaggle. I have successfully coded "round 1", but my problem is that when i attempt to loop over it until one Pokemon faints it just starts over. I want it to "remember" the HP of the Pokemon after it has suffered an attack. My code looks like this:

round1 <- function(){
  M<- sample(c("Psystrike", "Aura Sphere", "Ice Punch",
               "Solar Beam"))
  R <- sample(c("Outrage", "Dragon Ascent", "Crunch",
                "Brutal Swing"))
  
  for (i in c("Ready", "Set", "Go!")){
    
    print(i)
    Sys.sleep(1.2)
    
  } 
  
  if (speedM>speedR && M == "Ice Punch"){
    print(Rextremedamage(75))
    print("Ice Punch is hyper effective!")
  }
    
  if (speedM>speedR && M== "Psystrike"){
    print(Rdamage(100))
    print("Psystrike has normal efficiency.")
    }
  if (speedM>speedR && M== "Aura Sphere"){
    print(Rlowdamage(80))
    print("Aura Sphere is not very effective...")
  }
  if (speedM>speedR && M== "Solar Beam"){
    print(Rlowdamage(100))
    print("Solar Beam is not very effective...")
  }
  
  
    Sys.sleep(1.4)
  
  
  for (a in c("Rayquaza is angry...", "Go!")){
    
    print(a)
    Sys.sleep(1.2)
    
  }
  
  if (hpRayquaza >0 && R == "Outrage"){
    print(Mdamage(120))
    print("Outrage has normal efficiency.")
  }
  if (hpRayquaza >0 && R == "Dragon Ascent"){
    print(Mdamage(120))
    print("Dragon Ascent has normal efficiency.")
  }
  if (hpRayquaza >0 && R == "Crunch"){
    print(Mhighdamage(80))
    print("Crunch is super effective!")
  }
  if (hpRayquaza >0 && R == "Brutal Swing"){
    print(Mhighdamage(60))
    print("Brutal swing is super effective!")
  }
    
}

Fyi, the "damage" functions are coded like this:

Mhighdamage <- function(x){
  pain=hpMewTwo-x/1.8
  return(pain)
}

...where "hpMewTwo" is the HP for mewtwo given in the dataset(106). My output looks like this:

> round1()
[1] "Ready"
[1] "Set"
[1] "Go!"
        hp
1 87.97872
[1] "Aura Sphere is not very effective..."
[1] "Rayquaza is angry..."
[1] "Go!"
        hp
1 61.55556
[1] "Crunch is super effective!"

I attempted to put round 1 in a while loop, but it just kept on running through the code and then starting from the top with full HP forever. Does anyone have a clue on how i can run a loop that "remembers" the HP and runs until one hits zero?

1 Answers

i guess you could do this using while. In general if you want to make an ABM i would suggest to you to use some sort of agent struct ( like a setClass(Class="Pokemon") or simply a list or vecor) )of type pokemon.The pokemon can have different fields (id, name, lvl, hp, attacks, type) then bulid a fight function that is general for all agents (pokemon) and takes inputs poke1 , poke2 instead of hpMewtown... Then you can run a multiple fights by using something like listapply or even build a tournament by sampling pokemons to duos. tipp Try to keep Functions as general and reusable as possible.

## Damage system
highdamage <- function(x){
  dmg=-x/0.8
  return(dmg)
}

extremedamage <- function(x){
  dmg=-x/0.5
  return(dmg)
}

lowdamage<- function(x){
  dmg=-x/2
  return(dmg)
}


damage<- function(x){
  dmg=-x/1
  return(dmg)
}
####

round1 <- function(hpRayquaza,hpMewtwo){

# START
  for (i in c("Ready", "Set", "Go!")){
    print(i)
    Sys.sleep(1)
  } 
# ALIVE
  while (hpRayquaza>0 && hpMewtwo>0){
# WHO ATTACKS FASTER
    speedM<-rnorm(1,mean = speedM_v,3)
    speedR<-rnorm(1,mean = speedR_v,3)
    M<- sample(c("Psystrike", "Aura Sphere", "Ice Punch",
                 "Solar Beam"),1)
    R <- sample(c("Outrage", "Dragon Ascent", "Crunch",
                  "Brutal Swing"),1)
    Sys.sleep(0.5)
    if(speedM > speedR ){  
      for(a in c("Mewtwo attacks...", "Go!")){
        print(a)
        Sys.sleep(1)
      }
      if(M == "Ice Punch"){
        dmg<-extremedamage(75)
        print("Ice Punch is hyper effective!")
      }
      if(M== "Psystrike"){
        dmg<-damage(100)
        print("Psystrike has normal efficiency.")
      }
      if(M== "Aura Sphere"){
        dmg<-lowdamage(80)
      print("Aura Sphere is not very effective...")
      }
      if(M== "Solar Beam"){
      dmg<-lowdamage(100)
      print("Solar Beam is not very effective...")
      }
    hpRayquaza <- (hpRayquaza + dmg)
    print(paste("hpRayquaza:", hpRayquaza))
    }
    if(speedM<speedR){  
  for(a in c("Rayquaza is angry...", "Go!")){
      print(a)
      Sys.sleep(1)
    }
     if(R == "Outrage"){
      dmg<-damage(120)
      print("Outrage has normal efficiency.")
    }
     if(R == "Dragon Ascent"){
      dmg<-damage(120)
      print("Dragon Ascent has normal efficiency.")
    }
     if(R == "Crunch"){
      dmg<-highdamage(80)
      print("Crunch is super effective!")
      }
     if(R == "Brutal Swing"){
      dmg<-highdamage(60)
      print("Brutal swing is super effective!")
       }
    hpMewtwo <- (hpMewtwo + dmg)
    print(paste("hpMewtwo:",hpMewtwo))
    }
    res<-c(hpMewtwo,hpRayquaza)
  }
  
  return(res)
}

## Some values

hpMewtwo = 300
hpRayquaza = 600
speedM_v = 10
speedR_v = 8

## safe as a result
result_round1<-round1(hpRayquaza=hpRayquaza,hpMewtwo = hpMewtwo)
result_round1[1]

if you want to analyze the steps during a fight i would create a dataframe at the beginning of the round function with the columns hp_pke1, hp_pke2, akk, dmg

Related