# this is only needed for data visualization - can be safely removed

library(ggplot2)

#general functions

#engagementrange

range <- 1000

#fudge factor

errorsd <- 0.05

#the fudge factor should be a function of range (more error in position at greater range), but not a function of weapon firing angle, and be expressed in terms of pixels

error <- errorsd*range

#where does one shot hit within the weapon's arc of fire, in pixel difference from the target? get a random angle in degrees according to a uniform distribution,

#then consider that the circumference is 2 pi * range pixels, so the hit coordinates in pixels are

shotangle <- function(acc) return(runif(1,-acc/2,acc/2)/360*2*pi*range)

#now add a random positional error to the coordinates of the hit

hitlocation <- function(acc){

location <- shotangle(acc)

location <- location + rnorm(1,0,error)

return(location)

}

#so which box was hit?

cellhit <- function(angle){

if(angle < anglerangevector[1]) return(1)

if(angle > anglerangevector[ship[6]+1]) return(ship[6]+2)

for (i in 1:length(anglerangevector)) {

if ((angle > anglerangevector*) & (angle <= anglerangevector[i+1])) return(i+1)*

}

}

# this function generates the shot distribution per 1 shot with 100000 samples

#note: it is likely that a sample size of 1000 or 10000 would be acceptable in practice, reducing distribution computation time meaningfully, I just wanted to go big

createdistribution <- function(acc){

distributionvector <- vector(mode="double", length = ship[6]+2)

for (i in 1:100000){

wherehit <- cellhit(hitlocation(acc))

distributionvector[wherehit] <- distributionvector[wherehit] +1

}

return(distributionvector/sum(distributionvector))

}

# this is the default distribution of damage to armor cells

b <- matrix(0,nrow=5,ncol=5)

b[1:5,2:4] <- 1/30

b[2:4,1:5] <- 1/30

b[2:4,2:4] <- 1/15

b[1,1] <- 0

b[1,5] <- 0

b[5,1] <- 0

b[5,5] <- 0

#this function generates a sum of matrices multiplied by the distribution

createhitmatrix <- function(acc){

hitmatrix <- matrix(0,5,ship[6]+4)

distributionvector <- createdistribution(acc)

for (i in 1:ship[6]){

hitmatrix[,i:(i+4)] <- hitmatrix[,i:(i+4)]+b*(distributionvector[i+1])

}

return(hitmatrix)

}

hitchance <- function(acc){

hitchance <- 0

distributionvector <- createdistribution(acc)

hitchance <- (1-(distributionvector[1]+distributionvector[ship[6]]))

return(hitchance)

}

#for weapons with damage changing over time we need a sequence of matrices

createhitmatrixsequence <- function(accvector){

hitmatrixsequence <- list()

for (i in 1:length(accvector)){

hitmatrixsequence[*] <- createhitmatrix(accvector**)*

}

return(hitmatrixsequence)

}

# we do not actually use the armordamage function in practice

armordamage <- function(damage, armor, startingarmor) damage*(max(0.15,damage/(damage+max(0.05*startingarmor,armor))))

# this atrociously named function contains a logical switch which probably degrades performance, but also ensures we never divide by 0

armordamageselectivereduction <- function(damage, armor,startingarmor) {

useminarmor <- 0

if(armor < 0.05*startingarmor / 15) useminarmor <- 1

if(useminarmor == 0){

if(armor == 0) {return (damage)}

return(damage*(max(0.15,damage/(damage+armor))))

}

else{

return(damage*(max(0.15,damage/(damage+0.05*startingarmor/15))))

}

}

#ships -

#ship, hullhp, shieldregen, shieldmax, startingarmor, widthinpixels, armorcells, name

glimmer <- c(1500, 250/0.6, 2500/0.6, 200, 78, 5, "glimmer")

brawlerlp <- c(2000, 500/0.8, 3000/0.8, 450,110,floor(110/15), "brawlerlp")

vanguard <- c(3000, 150, 2000, 600, 104, floor(104/15),"vanguard")

tempest <- c(1250, 225/0.6, 2500/0.6, 200,64,floor(64/15), "tempest")

medusa <- c(3000,400/0.6,6000/0.6,300,134,floor(134/15), "medusa")

hammerhead <- c(5000,250/0.8,4200/0.8,500,108,floor(108/16.4), "hammerhead")

enforcer <- c(4000,200,4000,900,136,floor(136/15), "enforcer")

dominator <- c(14000, 500, 10000, 1500, 180, 12, "dominator")

fulgent <- c(5000,300/0.6,5000/0.6,450, 160, floor(160/15), "fulgent")

brilliant <- c(8000,600/0.6,10000/0.6,900,160,floor(160/20),"brilliant")

radiant <- c(20000,1500/0.6,25000/0.6,1500,316,floor(316/30),"radiant")

onslaught <- c(20000,600,17000,1750,288,floor(288/30),"onslaught")

aurora <- c(8000,800/0.8,11000/0.8,800,128,floor(128/28), "aurora")

paragon <- c(18000,1250/0.6,25000/0.6,1500,330,floor(330/30),"paragon")

conquest <- c(12000,1200/1.4,20000/1.4,1200,190,floor(190/30),"conquest")

champion <- c(10000,550/0.8,10000/0.8,1250, 180,floor(180/24),"champion")

ships <- list(glimmer,brawlerlp,vanguard,tempest,medusa,hammerhead,enforcer,dominator,fulgent,brilliant,radiant,onslaught,aurora,paragon,conquest,champion)

#ships <- list(glimmer,brawlerlp)

#WEAPON ACCURACY

#missiles do not have spread

squallacc <- c(0)

locustacc <- c(0)

hurricaneacc <- c(0)

harpoonacc <- c(0)

sabotacc <- c(0)

#gauss has a spread of 0 and no increase per shot

gaussacc <- c(0)

#hephaestus has a spread of 0 and it increases by 2 per shot to a max of 10

hephaestusacc <- c(seq(0,10,2))

#mark ix has a spread of 0 and it increases by 2 per shot to a max of 15

markixacc <- c(seq(0,15,2),15)

#mjolnir has a spread of 0 and it increases by 1 per shot to a max of 5

mjolniracc <- c(seq(0,5,1))

#hellbore has a spread of 10

hellboreacc <- c(10)

#storm needler has a spread of 10

stormneedleracc <- c(10)

#squall fires 2 missiles / sec for 10 secs, then recharges for 10 secs

squalltics <- c(2,2,2,2,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0,0)

#locust fires 10 missiles / sec for 4 secs, then recharges for 5 secs

locusttics <- c(10,10,10,10,0,0,0,0,0)

#hurricane fires 9 missiles every 15 seconds

hurricanetics <- c(9,0,0,0,0,0,0,0,0,0,0,0,0,0,0)

#harpoon pod fires 4 missiles in 1 second, then recharges for 8 seconds (in reality 8.25)

harpoontics <- c(4,0,0,0,0,0,0,0,0)

#sabot pod fires 2*5 missiles, then recharges for 8 seconds (in reality 8.75 seconds and firing time is .5 seconds)

sabottics <- c(10,0,0,0,0,0,0,0,0)

#gauss fires 1 shot, then charges for 1 second

gausstics <- c(1,0)

#hephaestus fires 4 shots / sec

hephaestustics <- c(4)

#mark ix fires 4 shots every 3 seconds, taking .4 seconds for the burst, so 20 shots / 17 seconds in bursts of 4

markixtics <- c(4,0,0,4,0,0,4,0,0,4,0,0,0,4,0,0,0)

#mjolnir fires 4 shots per 3 seconds

mjolnirtics <- c(1,1,2,1,2,1,2,1,1)

#hellbore fires 1 shot per 4 seconds

hellboretics <- c(1,0,0,0)

#storm needler fires 10 shots per second

stormneedlertics <- c(10)

#arbalest fires 1 shot every 1.2 seconds, so 5 shots / 6 seconds

arbalesttics <- c(1,1,1,0,1,1)

arbalestacc <- c(0,5,10,15)

arbalest <- list(200, 2, arbalesttics, "Arbalest",arbalestacc)

#heavy mauler fires a burst of 3, taking .9 seconds to do so, then recharges for 4.5 seconds. So total of 3 shots / 5.4 seconds, so total of 15 shots / 27 seconds in bursts of 3.

heavymaulertics <- c(3,0,0,0,0,0,3,0,0,0,0,3,0,0,0,0,3,0,0,0,0,3,0,0,0,0,0)

heavymauleracc <- c(seq(0,5,1))

heavymauler <- list(200,0.5,heavymaulertics, "Heavy Mauler", heavymauleracc)

#heavy autocannon takes .6 seconds to fire a burst, then recharges for 1 second. So 3 shots / 1.6 secs, so 15 shots / 8 secs in bursts

hactics <- c(3,0,3,3,0,3,3,0)

hacacc <- c(seq(0,18,3))

hac <- list(100, 2, hactics, "Heavy Autocannon", hacacc)

hvdtics <- c(1,0,0)

hvdacc <- c(0)

hvd <- list(275,2,hvdtics,"Hypervelocity Driver", hvdacc)

#heavy needler fires a burst of 30 needles with 0.05 sec intervals (1.5 sec) and then recharges for 4.55 sec (round to 4.5 sec)

needlertics <- c(20,10,0,0,0,0)

needleracc <- c(seq(1,10,0.5))

needler <- list(50,2,needlertics,"Heavy Needler",needleracc)

#heavy mortar fires a burst of 2 rounds, taking .6 seconds to do so, then recharges for .7 seconds. So a total of 2 rounds every 1.3 seconds, so 20 rounds / 13 seconds in bursts of 2.

mortartics <- c(2,2,0,2,2,2,2,0,2,2,2,0,2)

mortaracc <- c(seq(0,20,5))

mortar <- list(110,0.5,mortartics, "Heavy Mortar", mortaracc)

#damage per shot, damage type (2=kinetic, 0.5=he, 0.25=frag, 1=energy), tics, weapon name, weapon accuracy over time, hit chance

squall <- list(250, 2, squalltics, "Squall", squallacc)

locust <- list(200, 0.25, locusttics, "Locust", locustacc)

hurricane <- list(500, 0.5, hurricanetics, "Hurricane", hurricaneacc)

harpoon <- list(750, 0.5, harpoontics, "Harpoon", harpoonacc)

sabot <- list(200, 2, sabottics, "Sabot", sabotacc)

gauss <- list(700, 2, gausstics, "Gauss", gaussacc)

hephaestus <- list(120, 0.5, hephaestustics, "Hephaestus", hephaestusacc)

markix <- list(200, 2, markixtics, "Mark IX", markixacc)

mjolnir <- list(400, 1, mjolnirtics, "Mjolnir", mjolniracc)

hellbore <- list(750, 0.5, hellboretics, "Hellbore", hellboreacc)

stormneedler <- list(50, 2, stormneedlertics, "Storm Needler", stormneedleracc)

dummy <- list(0,0,c(0),"",c(0),c(0))

#which weapons are we studying?

weapon1choices <- list(squall, locust, hurricane)

weapon2choices <- list(squall, locust, hurricane)

weapon3choices <- list(harpoon, sabot)

weapon4choices <- list(harpoon, sabot)

weapon5choices <- list(gauss, markix, mjolnir, hellbore, hephaestus, stormneedler)

weapon6choices <- list(gauss, markix, mjolnir, hellbore, hephaestus, stormneedler)

weapon7choices <- list(arbalest, hac, hvd, heavymauler, needler, mortar)

weapon8choices <- list(arbalest, hac, hvd, heavymauler, needler, mortar)

#how many unique weapon loadouts are there?

#get names of weapons from a choices list x

getweaponnames <- function(x){

vector <- vector(mode="character")

for (i in 1:length(x)){

vector <- cbind(vector, x[*][[4]])*

}

return(vector)

}

#convert the names back to numbers when we are done based on a weapon choices list y

convertweaponnames <- function(x, y){

vector <- vector(mode="integer")

for (j in 1:length(x)) {

for (i in 1:length(y)){

if(x[j] == y[*][[4]]) vector <- cbind(vector, i)*

}

}

return(vector)

}

#this section of code generates a table of all unique loadouts that we can create using the weapon choices available

generatepermutations <- 1

if (generatepermutations == 1){

#enumerate weapon choices as integers

perm1 <- seq(1,length(weapon1choices),1)

perm2 <- seq(1,length(weapon2choices),1)

perm3 <- seq(1,length(weapon3choices),1)

perm4 <- seq(1,length(weapon4choices),1)

perm5 <- seq(1,length(weapon5choices),1)

perm6 <- seq(1,length(weapon6choices),1)

perm7 <- seq(1,length(weapon7choices),1)

perm8 <- seq(1,length(weapon8choices),1)

#create a matrix of all combinations

perm1x2 <- expand.grid(perm1,perm2)

#sort, then only keep unique rows

perm1x2 <- unique(t(apply(perm1x2, 1, sort)))

perm3x4 <- expand.grid(perm3,perm4)

perm3x4 <- unique(t(apply(perm3x4, 1, sort)))

perm5x6 <- expand.grid(perm5,perm6)

perm5x6 <- unique(t(apply(perm5x6, 1, sort)))

perm7x8 <- expand.grid(perm7,perm8)

perm7x8 <- unique(t(apply(perm7x8, 1, sort)))

#now that we have all unique combinations of all two weapons, create a matrix containing all combinations of these unique combinations

allperms <- matrix(0,0,(length(perm1x2[1,])+length(perm3x4[1,])+length(perm5x6[1,])+length(perm7x8[1,])))

for(i in 1:length(perm1x2[,1])) for(j in 1:length(perm3x4[,1])) for(k in 1:length(perm5x6[,1])) for(l in 1:length(perm7x8[,1])) allperms <- rbind(allperms, c(perm1x2[i,],perm3x4[j,],perm5x6[k,],perm7x8[l,])

)

#this is just for testing, can remove

allperms

#we save this so we don't have to compute it again

saveRDS(allperms, file="allperms.RData")

} else {

allperms <- readRDS("lookuptable.RData")

}

#now compute a main lookuptable to save on computing time

#the lookuptable should be a list of lists, so that

#lookuptable[[ship]][[weapon]][[1]] returns hit chance vector and

#lookuptable[[ship]][[weapon]][[2]] returns hit probability matrix

#time for some black R magic

#note: the lookuptable will be formulated such that there is a running index of weapons rather than sub-lists, so all weapons will be indexed consecutively so we have lookuptable [[1]][[1]] = [[ship1]][[weaponchoices1_choice1]], etc. So that is what the below section does.

#read or generate lookuptable

generatelookuptable <- 0

if(generatelookuptable == 1){

lookuptable <- list()

for (f in 1:length(ships)){

lookuptable[[f]] <- list()

ship <- ships[[f]]

ship <- as.double(ship[1:6])

#how much is the visual arc of the ship in rad?

shipangle <- ship[5]/(2* pi *range)

#how much is the visual arc of a single cell of armor in rad?

cellangle <- shipangle/ship[6]

#now assume the weapon is targeting the center of the ship's visual arc and that the ship is in the center of the weapon's firing arc

#which cell will the shot hit, or will it miss?

#call the cells (MISS, cell1, cell2, ... ,celli, MISS) and get a vector giving the (maximum for negative / minimum for positive) angles for hitting each

anglerangevector <- vector(mode="double", length = ship[6]+1)

anglerangevector[1] <- -shipangle/2

for (i in 1:(length(anglerangevector)-1)) anglerangevector[i+1] <- anglerangevector*+cellangle*

#now convert it to pixels

anglerangevector <- anglerangevector*2*pi*range

weaponindexmax <- length(weapon1choices)+length(weapon2choices)+length(weapon3choices)+length(weapon4choices)+length(weapon5choices)+length(weapon6choices)+length(weapon7choices)+length(weapon8choices)

for (x in 1:weaponindexmax) {

print(x)

if(x <= length(weapon1choices)){

weapon1<-weapon1choices[

if(weapon1[4] != ""){

hitchancevector <- vector(mode = "double", length = length(weapon1[[5]]))

for (i in 1:length(weapon1[[5]])){

hitchancevector* <- hitchance(weapon1[[5]]**)*

}

lookuptable[[f]][

lookuptable[[f]][- ][[1]] <- hitchancevector

lookuptable[[f]][- ][[2]] <- createhitmatrixsequence(weapon1[[5]])

}

}

if((x > length(weapon1choices)) & (x <= length(weapon1choices) + length(weapon2choices))){

weapon2<-weapon2choices[[x-length(weapon1choices)]]

if(weapon2[4] != ""){

hitchancevector <- vector(mode = "double", length = length(weapon2[[5]]))

for (i in 1:length(weapon2[[5]])){

hitchancevector* <- hitchance(weapon2[[5]]**)*

}

lookuptable[[f]][

lookuptable[[f]][- ][[1]] <- hitchancevector

lookuptable[[f]][- ][[2]] <- createhitmatrixsequence(weapon2[[5]])

}

}

if((x > length(weapon1choices) + length(weapon2choices)) & (x <= length(weapon2choices) + length(weapon1choices) + length(weapon3choices))){

weapon3<-weapon3choices[[x-length(weapon2choices)-length(weapon1choices)]]

if(weapon3[4] != ""){

hitchancevector <- vector(mode = "double", length = length(weapon3[[5]]))

for (i in 1:length(weapon3[[5]])){

hitchancevector* <- hitchance(weapon3[[5]]**)*

}

lookuptable[[f]][

lookuptable[[f]][- ][[1]] <- hitchancevector

lookuptable[[f]][- ][[2]] <- createhitmatrixsequence(weapon3[[5]])

}

}

if((x > length(weapon2choices) + length(weapon1choices) + length(weapon3choices)) & (x <= length(weapon3choices) + length(weapon2choices) + length(weapon1choices) + length(weapon4choices))){

weapon4<-weapon4choices[[x-length(weapon3choices)-length(weapon2choices)-length(weapon1choices)]]

if(weapon4[4] != ""){

hitchancevector <- vector(mode = "double", length = length(weapon4[[5]]))

for (i in 1:length(weapon4[[5]])){

hitchancevector* <- hitchance(weapon4[[5]]**)*

}

lookuptable[[f]][

lookuptable[[f]][- ][[1]] <- hitchancevector

lookuptable[[f]][- ][[2]] <- createhitmatrixsequence(weapon4[[5]])

}

}

if((x > length(weapon3choices) + length(weapon2choices) + length(weapon1choices) + length(weapon4choices)) & (x <= length(weapon4choices) + length(weapon3choices) + length(weapon2choices) + length(weapon1choices) + length(weapon5choices))){

weapon5<-weapon5choices[[x-length(weapon4choices)-length(weapon3choices)-length(weapon2choices)-length(weapon1choices)]]

if(weapon5[4] != ""){

hitchancevector <- vector(mode = "double", length = length(weapon5[[5]]))

for (i in 1:length(weapon5[[5]])){

hitchancevector* <- hitchance(weapon5[[5]]**)*

}

lookuptable[[f]][

lookuptable[[f]][- ][[1]] <- hitchancevector

lookuptable[[f]][- ][[2]] <- createhitmatrixsequence(weapon5[[5]])

}

}

if((x > length(weapon4choices) + length(weapon3choices) + length(weapon2choices) + length(weapon1choices) + length(weapon5choices)) & (x <= length(weapon5choices) + length(weapon4choices) + length(weapon3choices) + length(weapon2choices) + length(weapon1choices) + length(weapon6choices))){

weapon6<-weapon6choices[[x-length(weapon5choices)-length(weapon4choices)-length(weapon3choices)-length(weapon2choices)-length(weapon1choices)]]

if(weapon6[4] != ""){

hitchancevector <- vector(mode = "double", length = length(weapon6[[5]]))

for (i in 1:length(weapon6[[5]])){

hitchancevector* <- hitchance(weapon6[[5]]**)*

}

lookuptable[[f]][

lookuptable[[f]][- ][[1]] <- hitchancevector

lookuptable[[f]][- ][[2]] <- createhitmatrixsequence(weapon6[[5]])

}

}

if((x > length(weapon5choices) + length(weapon4choices) + length(weapon3choices) + length(weapon2choices) + length(weapon1choices) + length(weapon6choices)) & (x <= length(weapon6choices) + length(weapon5choices) + length(weapon4choices) + length(weapon3choices) + length(weapon2choices) + length(weapon1choices) + length(weapon7choices))){

weapon7<-weapon7choices[[x-length(weapon6choices)-length(weapon5choices)-length(weapon4choices)-length(weapon3choices)-length(weapon2choices)-length(weapon1choices)]]

if(weapon7[4] != ""){

hitchancevector <- vector(mode = "double", length = length(weapon7[[5]]))

for (i in 1:length(weapon7[[5]])){

hitchancevector* <- hitchance(weapon7[[5]]**)*

}

lookuptable[[f]][

lookuptable[[f]][- ][[1]] <- hitchancevector

lookuptable[[f]][- ][[2]] <- createhitmatrixsequence(weapon7[[5]])

}

}

if((x > length(weapon6choices) + length(weapon5choices) + length(weapon4choices) + length(weapon3choices) + length(weapon2choices) + length(weapon1choices) + length(weapon7choices)) & (x <= length(weapon7choices) + length(weapon6choices) + length(weapon5choices) + length(weapon4choices) + length(weapon3choices) + length(weapon2choices) + length(weapon1choices) + length(weapon8choices))){

weapon8<-weapon8choices[[x-length(weapon7choices)-length(weapon6choices)-length(weapon5choices)-length(weapon4choices)-length(weapon3choices)-length(weapon2choices)-length(weapon1choices)]]

if(weapon8[4] != ""){

hitchancevector <- vector(mode = "double", length = length(weapon8[[5]]))

for (i in 1:length(weapon8[[5]])){

hitchancevector* <- hitchance(weapon8[[5]]**)*

}

lookuptable[[f]][

lookuptable[[f]][- ][[1]] <- hitchancevector

lookuptable[[f]][- ][[2]] <- createhitmatrixsequence(weapon8[[5]])

}

}

}

}

# save this so we don't have to re-compute it

saveRDS(lookuptable, file="lookuptable.RData")

} else {

lookuptable <- readRDS("lookuptable.RData")

}

lookup <- function(ship, weapon, var) return(lookuptable[[ship]][[weapon]][[var]])

#this generates a heatmap for visualization, remove

geom_tile(lookup(8,15,2)[[2]])

#go through all ships

for (f in 1:length(ships)){

ship <- ships[[f]]

#format ship data types appropriately

shipname <- ship[[7]]

ship <- as.double(ship[1:6])

timeseriesarray <- data.frame(matrix(ncol = 7,nrow=0))

timetokill=0

shieldblock <- 0

#calculate shield damage

#timepoint %% length ... etc. section returns how many shots that weapon will fire at that point of it's cycle (ie. vector index = timepoint modulo vector index maximum)

shielddamageattimepoint <- function(weapon, timepoint){

nohits <- weapon[[3]][(timepoint %% (length(weapon[[3]])))+1]

if (nohits == 0) {return(0)} else {

return(weapon[[1]]*nohits)

}

}

#hitmatrix[hitx,hity] returns the damage allocation to that cell

damageattimepoint <- function(weapon, timepoint, armor, startingarmor, hitx, hity, shots){

# vectors in R are indexed starting from 1

hitmatrix <- weapon[[7]][[min(shots,length(weapon[[7]]))]]

nohits <- weapon[[3]][(timepoint %% (length(weapon[[3]])))+1]

if (nohits == 0) {return(0)} else {

damagesum <- 0

for (i in 1:nohits) {

# damagesum <- damagesum + as.double(weapon[[1]]*hitmatrix[hitx,hity])

damagesum <- damagesum + armordamageselectivereduction(as.double(weapon[[1]]*hitmatrix[hitx,hity]),armor,startingarmor)

shots <- shots + 1

hitmatrix <- weapon[[7]][[min(shots,length(weapon[[7]]))]]

}

return(damagesum)

}

}

timeseries <- function(timepoint, shieldhp, armorhp, hullhp, shieldregen, shieldmax, startingarmor,armormatrix){

weaponacc <- 0

#are we using shield to block?

shieldblock <- 0

hulldamage <- 0

if(hullhp > 0){} else {shieldhp <- 0}

#1. shields. if shieldhp is sufficient, use shield to block

if (weapon1[[4]] !=""){

weapon1mult <- unlist(weapon1[2])

if (shieldhp > shielddamageattimepoint(weapon1, timepoint)*weapon1mult){

shieldhp <- shieldhp - shielddamageattimepoint(weapon1, timepoint)*weapon1mult*weapon1[[6]][min(weapon1shots,length(weapon1[[6]]))]

shieldhp <- max(shieldhp, 0)

if(shielddamageattimepoint(weapon1,timepoint) > 0) {shieldblock <- 1}

} else {

#if you did not use shield to block, regenerate flux <- applied later

#2. armor and hull

if(unlist(weapon1[2])==0.25){weapon1mult = 0.25} else {weapon1mult= 1 / unlist(weapon1[2])}

#2.1. damage armor and hull

hulldamage <- 0

#damageattimepoint <- function(weapon, timepoint, armor, startingarmor, hitx, hity, shots){

for (j in 1:length(armormatrix[1,])){

for (i in 1:length(armormatrix[,1])){

#this monster of a line does the following:

#hull damage is maximum of: 0, or (weapon damage to armor cell, with multiplier - armor cell hp)/weapon multiplier

hulldamage <- hulldamage+max(0,weapon1mult*damageattimepoint(weapon1, timepoint,armormatrix[i,j],startingarmor,i,j,weapon1shots)-armormatrix[i,j])/weapon1mult

#new armor hp at cell [i,j] is maximum of: 0, or (armor cell health - weapon damage to that section of armor at that timepoint, multiplied by overall hit probability to hit ship --- note: the damage distribution matrix is calculated such that it is NOT inclusive of hit chance, but hit chance is added separately here

armormatrix[i,j] <- max(0,armormatrix[i,j]-weapon1mult*damageattimepoint(weapon1, timepoint,armormatrix[i,j],startingarmor,i,j,weapon1shots)*weapon1[[6]][min(weapon1shots,length(weapon1[[6]]))])

}}

# now reduce hullhp by hull damage times probability to hit ship

hullhp <- hullhp - hulldamage*weapon1[[6]][min(weapon1shots,length(weapon1[[6]]))]

hullhp <- max(hullhp, 0)

}

}

weapon1shots <- weapon1shots + weapon1[[3]][(timepoint %% (length(weapon1[[3]])+1))]

#repeat for other weapons

#1. shields. if shieldhp is sufficient, use shield to block

if (weapon2[[4]] !=""){

weapon2mult <- unlist(weapon2[2])

if (shieldhp > shielddamageattimepoint(weapon2, timepoint)*weapon2mult){

shieldhp <- shieldhp - shielddamageattimepoint(weapon2, timepoint)*weapon2mult*weapon2[[6]][min(weapon2shots,length(weapon2[[6]]))]

shieldhp <- max(shieldhp, 0)

if(shielddamageattimepoint(weapon2,timepoint) > 0) {shieldblock <- 1}

} else {

#if you did not use shield to block, regenerate flux

#2. armor and hull

if(unlist(weapon2[2])==0.25){weapon2mult = 0.25} else {weapon2mult= 1 / unlist(weapon2[2])}

#2.1. damage armor and hull

hulldamage <- 0

#damageattimepoint <- function(weapon, timepoint, armor, startingarmor, hitx, hity, shots){

for (j in 1:length(armormatrix[1,])){

for (i in 1:length(armormatrix[,1])){

hulldamage <- hulldamage+max(0,weapon2mult*damageattimepoint(weapon2, timepoint,armormatrix[i,j],startingarmor,i,j,weapon2shots)-armormatrix[i,j])/weapon2mult

armormatrix[i,j] <- max(0,armormatrix[i,j]-weapon2mult*damageattimepoint(weapon2, timepoint,armormatrix[i,j],startingarmor,i,j,weapon2shots)*weapon2[[6]][min(weapon2shots,length(weapon2[[6]]))])

}}

hullhp <- hullhp - hulldamage*weapon2[[6]][min(weapon2shots,length(weapon2[[6]]))]

hullhp <- max(hullhp, 0)

}

}

weapon2shots <- weapon2shots + weapon2[[3]][(timepoint %% (length(weapon2[[3]])+1))]

#1. shields. if shieldhp is sufficient, use shield to block

if (weapon3[[4]] !=""){

weapon3mult <- unlist(weapon3[2])

if (shieldhp > shielddamageattimepoint(weapon3, timepoint)*weapon3mult){

shieldhp <- shieldhp - shielddamageattimepoint(weapon3, timepoint)*weapon3mult*weapon3[[6]][min(weapon3shots,length(weapon3[[6]]))]

shieldhp <- max(shieldhp, 0)

if(shielddamageattimepoint(weapon3,timepoint) > 0) {shieldblock <- 1}

} else {

#if you did not use shield to block, regenerate flux

#2. armor and hull

if(unlist(weapon3[2])==0.25){weapon3mult = 0.25} else {weapon3mult= 1 / unlist(weapon3[2])}

#2.1. damage armor and hull

hulldamage <- 0

#damageattimepoint <- function(weapon, timepoint, armor, startingarmor, hitx, hity, shots){

for (j in 1:length(armormatrix[1,])){

for (i in 1:length(armormatrix[,1])){

hulldamage <- hulldamage+max(0,weapon3mult*damageattimepoint(weapon3, timepoint,armormatrix[i,j],startingarmor,i,j,weapon3shots)-armormatrix[i,j])/weapon3mult

armormatrix[i,j] <- max(0,armormatrix[i,j]-weapon3mult*damageattimepoint(weapon3, timepoint,armormatrix[i,j],startingarmor,i,j,weapon3shots)*weapon3[[6]][min(weapon3shots,length(weapon3[[6]]))])

}}

hullhp <- hullhp - hulldamage*weapon3[[6]][min(weapon3shots,length(weapon3[[6]]))]

hullhp <- max(hullhp, 0)

}

}

weapon3shots <- weapon3shots + weapon3[[3]][(timepoint %% (length(weapon3[[3]])+1))]

#1. shields. if shieldhp is sufficient, use shield to block

if (weapon4[[4]] !=""){

weapon4mult <- unlist(weapon4[2])

if (shieldhp > shielddamageattimepoint(weapon4, timepoint)*weapon4mult){

shieldhp <- shieldhp - shielddamageattimepoint(weapon4, timepoint)*weapon4mult*weapon4[[6]][min(weapon4shots,length(weapon4[[6]]))]

shieldhp <- max(shieldhp, 0)

if(shielddamageattimepoint(weapon4,timepoint) > 0) {shieldblock <- 1}

} else {

#if you did not use shield to block, regenerate flux

#2. armor and hull

if(unlist(weapon4[2])==0.25){weapon4mult = 0.25} else {weapon4mult= 1 / unlist(weapon4[2])}

#2.1. damage armor and hull

hulldamage <- 0

#damageattimepoint <- function(weapon, timepoint, armor, startingarmor, hitx, hity, shots){

for (j in 1:length(armormatrix[1,])){

for (i in 1:length(armormatrix[,1])){

hulldamage <- hulldamage+max(0,weapon4mult*damageattimepoint(weapon4, timepoint,armormatrix[i,j],startingarmor,i,j,weapon4shots)-armormatrix[i,j])/weapon4mult

armormatrix[i,j] <- max(0,armormatrix[i,j]-weapon4mult*damageattimepoint(weapon4, timepoint,armormatrix[i,j],startingarmor,i,j,weapon4shots)*weapon4[[6]][min(weapon4shots,length(weapon4[[6]]))])

}}

hullhp <- hullhp - hulldamage*weapon4[[6]][min(weapon4shots,length(weapon4[[6]]))]

hullhp <- max(hullhp, 0)

}

}

weapon4shots <- weapon4shots + weapon4[[3]][(timepoint %% (length(weapon4[[3]])+1))]

#1. shields. if shieldhp is sufficient, use shield to block

if (weapon5[[4]] !=""){

weapon5mult <- unlist(weapon5[2])

if (shieldhp > shielddamageattimepoint(weapon5, timepoint)*weapon5mult){

shieldhp <- shieldhp - shielddamageattimepoint(weapon5, timepoint)*weapon5mult*weapon5[[6]][min(weapon5shots,length(weapon5[[6]]))]

shieldhp <- max(shieldhp, 0)

if(shielddamageattimepoint(weapon5,timepoint) > 0) {shieldblock <- 1}

} else {

#if you did not use shield to block, regenerate flux

#2. armor and hull

if(unlist(weapon5[2])==0.25){weapon5mult = 0.25} else {weapon5mult= 1 / unlist(weapon5[2])}

#2.1. damage armor and hull

hulldamage <- 0

#damageattimepoint <- function(weapon, timepoint, armor, startingarmor, hitx, hity, shots){

for (j in 1:length(armormatrix[1,])){

for (i in 1:length(armormatrix[,1])){

hulldamage <- hulldamage+max(0,weapon5mult*damageattimepoint(weapon5, timepoint,armormatrix[i,j],startingarmor,i,j,weapon5shots)-armormatrix[i,j])/weapon5mult

armormatrix[i,j] <- max(0,armormatrix[i,j]-weapon5mult*damageattimepoint(weapon5, timepoint,armormatrix[i,j],startingarmor,i,j,weapon5shots)*weapon5[[6]][min(weapon5shots,length(weapon5[[6]]))])

}}

hullhp <- hullhp - hulldamage*weapon5[[6]][min(weapon5shots,length(weapon5[[6]]))]

hullhp <- max(hullhp, 0)

}

}

weapon5shots <- weapon5shots + weapon5[[3]][(timepoint %% (length(weapon5[[3]])+1))]

#1. shields. if shieldhp is sufficient, use shield to block

if (weapon6[[4]] !=""){

weapon6mult <- unlist(weapon6[2])

if (shieldhp > shielddamageattimepoint(weapon6, timepoint)*weapon6mult){

shieldhp <- shieldhp - shielddamageattimepoint(weapon6, timepoint)*weapon6mult*weapon6[[6]][min(weapon6shots,length(weapon6[[6]]))]

shieldhp <- max(shieldhp, 0)

if(shielddamageattimepoint(weapon6,timepoint) > 0) {shieldblock <- 1}

} else {

#if you did not use shield to block, regenerate flux

#2. armor and hull

if(unlist(weapon6[2])==0.25){weapon6mult = 0.25} else {weapon6mult= 1 / unlist(weapon6[2])}

#2.1. damage armor and hull

hulldamage <- 0

#damageattimepoint <- function(weapon, timepoint, armor, startingarmor, hitx, hity, shots){

for (j in 1:length(armormatrix[1,])){

for (i in 1:length(armormatrix[,1])){

hulldamage <- hulldamage+max(0,weapon6mult*damageattimepoint(weapon6, timepoint,armormatrix[i,j],startingarmor,i,j,weapon6shots)-armormatrix[i,j])/weapon6mult

armormatrix[i,j] <- max(0,armormatrix[i,j]-weapon6mult*damageattimepoint(weapon6, timepoint,armormatrix[i,j],startingarmor,i,j,weapon6shots)*weapon6[[6]][min(weapon6shots,length(weapon6[[6]]))])

}}

hullhp <- hullhp - hulldamage*weapon6[[6]][min(weapon6shots,length(weapon6[[6]]))]

hullhp <- max(hullhp, 0)

}

}

weapon6shots <- weapon6shots + weapon6[[3]][(timepoint %% (length(weapon6[[3]])+1))]

#1. shields. if shieldhp is sufficient, use shield to block

if (weapon7[[4]] !=""){

weapon7mult <- unlist(weapon7[2])

if (shieldhp > shielddamageattimepoint(weapon7, timepoint)*weapon7mult){

shieldhp <- shieldhp - shielddamageattimepoint(weapon7, timepoint)*weapon7mult*weapon7[[6]][min(weapon7shots,length(weapon7[[6]]))]

shieldhp <- max(shieldhp, 0)

if(shielddamageattimepoint(weapon7,timepoint) > 0) {shieldblock <- 1}

} else {

#if you did not use shield to block, regenerate flux

#2. armor and hull

if(unlist(weapon7[2])==0.25){weapon7mult = 0.25} else {weapon7mult= 1 / unlist(weapon7[2])}

#2.1. damage armor and hull

hulldamage <- 0

#damageattimepoint <- function(weapon, timepoint, armor, startingarmor, hitx, hity, shots){

for (j in 1:length(armormatrix[1,])){

for (i in 1:length(armormatrix[,1])){

hulldamage <- hulldamage+max(0,weapon7mult*damageattimepoint(weapon7, timepoint,armormatrix[i,j],startingarmor,i,j,weapon7shots)-armormatrix[i,j])/weapon7mult

armormatrix[i,j] <- max(0,armormatrix[i,j]-weapon7mult*damageattimepoint(weapon7, timepoint,armormatrix[i,j],startingarmor,i,j,weapon7shots)*weapon7[[6]][min(weapon7shots,length(weapon7[[6]]))])

}}

hullhp <- hullhp - hulldamage*weapon7[[6]][min(weapon7shots,length(weapon7[[6]]))]

hullhp <- max(hullhp, 0)

}

}

weapon7shots <- weapon7shots + weapon7[[3]][(timepoint %% (length(weapon7[[3]])+1))]

#1. shields. if shieldhp is sufficient, use shield to block

if (weapon8[[4]] !=""){

weapon8mult <- unlist(weapon8[2])

if (shieldhp > shielddamageattimepoint(weapon8, timepoint)*weapon8mult){

shieldhp <- shieldhp - shielddamageattimepoint(weapon8, timepoint)*weapon8mult*weapon8[[6]][min(weapon8shots,length(weapon8[[6]]))]

shieldhp <- max(shieldhp, 0)

if(shielddamageattimepoint(weapon8,timepoint) > 0) {shieldblock <- 1}

} else {

#if you did not use shield to block, regenerate flux

#2. armor and hull

if(unlist(weapon8[2])==0.25){weapon8mult = 0.25} else {weapon8mult= 1 / unlist(weapon8[2])}

#2.1. damage armor and hull

hulldamage <- 0

#damageattimepoint <- function(weapon, timepoint, armor, startingarmor, hitx, hity, shots){

for (j in 1:length(armormatrix[1,])){

for (i in 1:length(armormatrix[,1])){

hulldamage <- hulldamage+max(0,weapon8mult*damageattimepoint(weapon8, timepoint,armormatrix[i,j],startingarmor,i,j,weapon8shots)-armormatrix[i,j])/weapon8mult

armormatrix[i,j] <- max(0,armormatrix[i,j]-weapon8mult*damageattimepoint(weapon8, timepoint,armormatrix[i,j],startingarmor,i,j,weapon8shots)*weapon8[[6]][min(weapon8shots,length(weapon8[[6]]))])

}}

hullhp <- hullhp - hulldamage*weapon8[[6]][min(weapon8shots,length(weapon8[[6]]))]

hullhp <- max(hullhp, 0)

}

}

weapon8shots <- weapon8shots + weapon8[[3]][(timepoint %% (length(weapon8[[3]])+1))]

hullhp <- hullhp - hulldamage

hullhp <- max(hullhp, 0)

if(hullhp==0) armorhp <- 0

armorhp <- sum(armormatrix)*15/((ship[[6]]+4)*5)

if(hullhp==0) armorhp <- 0

if (shieldblock==0){shieldhp <- min(shieldmax,shieldhp+shieldregen)}

return(list(timepoint, shieldhp, armorhp, hullhp, shieldregen, shieldmax, startingarmor,armormatrix))

}

totaltime = 500

armorhp <- ship[4]

shieldhp <- ship[3]

hullhp <- ship[1]

shieldregen <- ship[2]

shieldmax <- ship[3]

armorhp <- ship[4]

startingarmor <- ship[4]

weapon1shots <- 1

weapon2shots <- 1

weapon3shots <- 1

weapon4shots <- 1

weapon5shots <- 1

weapon6shots <- 1

weapon7shots <- 1

weapon8shots <- 1

armormatrix <- matrix(ship[4]/15,5,ship[6]+4)

startingarmormatrixsum <- sum(armormatrix)

#now what we do here is we go through all the permutations using the running index, which is i+j+k+l+m+n+o+p for weapons 8

for (z in 1:length(allperms[,1])) {

i <- allperms[z,1]

j <- allperms[z,2]

k <- allperms[z,3]

l <- allperms[z,4]

m <- allperms[z,5]

n <- allperms[z,6]

o <- allperms[z,7]

p <- allperms[z,8]

#for (i in 1:length(weapon1choices)) {

weapon1<-weapon1choices[*]*

# for (j in 1:length(weapon2choices)) {

weapon2<-weapon2choices[[j]]

# for (k in 1:length(weapon3choices)) {

weapon3<-weapon3choices[[k]]

# for (l in 1:length(weapon4choices)) {

weapon4<-weapon4choices[[l]]

# for (m in 1:length(weapon5choices)) {

weapon5<-weapon5choices[[m]]

# for (n in 1:length(weapon6choices)) {

weapon6<-weapon6choices[[n]]

# for (o in 1:length(weapon7choices)) {

weapon7<-weapon7choices[

# for (p in 1:length(weapon8choices)) {

weapon8<-weapon8choices[[p]]

#lookup <- function(ship, weapon, var) return(lookuptable[[ship]][[weapon]][[var]])

if(weapon1[4] != ""){

weapon1[[6]] <- lookup(f,i,1)

weapon1[[7]] <- lookup(f,i,2)

}

if(weapon2[4] != ""){

weapon2[[6]] <- lookup(f,i+j,1)

weapon2[[7]] <- lookup(f,i+j,2)

}

if(weapon3[4] != ""){

weapon3[[6]] <- lookup(f,i+j+k,1)

weapon3[[7]] <- lookup(f,i+j+k,2)

}

if(weapon4[4] != ""){

weapon4[[6]] <- lookup(f,i+j+k+l,1)

weapon4[[7]] <- lookup(f,i+j+k+l,2)

}

if(weapon5[4] != ""){

weapon5[[6]] <- lookup(f,i+j+k+l+m,1)

weapon5[[7]] <- lookup(f,i+j+k+l+m,2)

}

if(weapon6[4] != ""){

weapon6[[6]] <- lookup(f,i+j+k+l+m+n,1)

weapon6[[7]] <- lookup(f,i+j+k+l+m+n,2)

}

if(weapon7[4] != ""){

weapon7[[6]] <- lookup(f,i+j+k+l+m+n+o,1)

weapon7[[7]] <- lookup(f,i+j+k+l+m+n+o,2)

}

if(weapon8[4] != ""){

weapon8[[6]] <- lookup(f,i+j+k+l+m+n+o+p,1)

weapon8[[7]] <- lookup(f,i+j+k+l+m+n+o+p,2)

}

#time series - run time series at point t, save it to state, update values according to state, re-run time series, break if ship dies

for (t in 1:totaltime){

state <- timeseries(t,shieldhp,armorhp,hullhp,shieldregen,shieldmax,startingarmor,armormatrix)

shieldhp <- state[[2]]

armorhp <- state[[3]]

hullhp <- state[[4]]

flux <- shieldmax - shieldhp

armormatrix <- state[[8]]

if(hullhp == 0){flux <- 0

if (timetokill == 0){timetokill <- t

break}

}

}

if (timetokill ==0){timetokill <- NA}

tobind <- c(timetokill,unlist(weapon1[4]),unlist(weapon2[4]),unlist(weapon3[4]),unlist(weapon4[4]),unlist(weapon5[4]),unlist(weapon6[4]),unlist(weapon7[4]),unlist(weapon8[4]))

timeseriesarray <- rbind(timeseriesarray,tobind)

armorhp <- ship[4]

shieldhp <- ship[3]

hullhp <- ship[1]

shieldregen <- ship[2]

shieldmax <- ship[3]

armorhp <- ship[4]

startingarmor <- ship[4]

weapon1shots <- 1

weapon2shots <- 1

weapon3shots <- 1

weapon4shots <- 1

weapon5shots <- 1

weapon6shots <- 1

weapon7shots <- 1

weapon8shots <- 1

armormatrix <- matrix(ship[4]/15,5,ship[6]+4)

startingarmormatrixsum <- sum(armormatrix)

timetokill <- 0

# }

# }

# }

# }

# }

#}

# }

}

#}

colnames(timeseriesarray) <- c("Timetokill", "Weapon1", "Weapon2", "Weapon3", "Weapon4", "Weapon5", "Weapon6", "Weapon7", "Weapon8")

sortbytime <- timeseriesarray[order(as.integer(timeseriesarray$Timetokill)),]

write.table(sortbytime, file = paste("optimizeweaponsbytime",shipname,"allweaponswithacc.txt", sep=""), row.names=FALSE, sep="\t")

}