@ -5,42 +5,22 @@ const { v4: uuidv4 } = require('uuid')
worldObj = require ( "../storageObjects/worldObj" )
creatureArr = require ( "../storageObjects/creatureArr" )
userObj = require ( "../storageObjects/userObj" )
function percentify ( lower , upper , input ) {
upper -= lower
input -= lower
return input * 100 / upper
}
function chooseOwner ( ) {
let playingUsers = [ ]
Object . keys ( userObj ) . forEach ( user => {
if ( userObj [ user ] [ "readyState" ] ) {
playingUsers . push ( user )
}
} )
let owner = playingUsers [ ( creatureArr . length % playingUsers . length ) ]
userObj [ owner ] . addCreature ( )
return owner
}
class Creature {
constructor ( parentName , surName , location , energy , maxEnergy , speed , brain , brainSize , brainComplexity , owner , activationValue , oscillatorFrequency , maxAge , generation , eatFoodLevel , colour ) {
this . _id = uuidv4 ( )
this . owner = owner || chooseOwner ( )
this . name = fName . choose ( )
this . parentName = parentName || this . name
this . surName = surName || lName . choose ( )
this . fullName = this . name + "." + this . parentName + "." + this . surName
this . maxEnergy = maxEnergy || config . creature . physical . maxEnergy
this . energy = energy || this . maxEnergy
this . facingDirection = Math . ceil ( Math . random ( ) * 4 )
this . location = location || this . placeSelf ( )
this . frontLoc = this . direction ( 1 )
this . rightLoc = this . direction ( 2 )
this . behindLoc = this . direction ( 3 )
this . leftLoc = this . direction ( 4 )
this . speed = speed || config . creature . physical . defaultSpeed
this . brain = brain || [ ]
this . brainSize = brainSize || config . creature . brain . size
@ -69,27 +49,6 @@ class Creature {
}
return x
} ,
blockedCheck : ( ) => {
if ( worldObj . checkBlocked ( this . frontLoc ) ) {
return 100
} else {
return 0
}
} ,
creatureCheck : ( ) => {
if ( worldObj . checkCreature ( this . frontLoc ) ) {
return 100
} else {
return 0
}
} ,
foodCheck : ( ) => {
if ( worldObj . checkTileFoodLevel ( this . frontLoc ) > this . eatFoodLevel ) {
return percentify ( 0 , config . world . tileMaxFood , worldObj . tiles [ JSON . stringify ( this . frontLoc ) ] . foodLevel )
} else {
return 0
}
} ,
energyCheck : ( ) => {
return percentify ( 0 , this . maxEnergy , this . energy )
} ,
@ -118,66 +77,12 @@ class Creature {
} ,
} ,
action : {
moveForward : ( input ) => {
if ( input > this . activationValue && this . alive ) {
if ( this . updateLocation ( this . frontLoc ) ) {
messageObj . add ( "MoveLog" , this . fullName + " Moved forward from " + this . location + " to " + this . frontLoc )
}
this . facingDirection = 1
return 100
}
return 0
} ,
moveRight : ( input ) => {
if ( input > this . activationValue && this . alive ) {
if ( this . updateLocation ( this . rightLoc ) ) {
messageObj . add ( "MoveLog" , this . fullName + " Moved right from " + this . location + " to " + this . rightLoc )
}
this . facingDirection = 2
return 100
}
return 0
} ,
moveBack : ( input ) => {
if ( input > this . activationValue && this . alive ) {
if ( this . updateLocation ( this . behindLoc ) ) {
messageObj . add ( "MoveLog" , this . fullName + " Moved backwards from " + this . location + " to " + this . behindLoc )
}
this . facingDirection = 3
return 100
}
return 0
} ,
moveLeft : ( input ) => {
if ( input > this . activationValue && this . alive ) {
if ( this . updateLocation ( this . leftLoc ) ) {
messageObj . add ( "MoveLog" , this . fullName + " Moved left from " + this . location + " to " + this . leftLoc )
}
this . facingDirection = 4
return 100
}
return 0
} ,
eat : ( input ) => {
worldObj . checkBlocked ( this . frontLoc )
if ( input > this . activationValue && worldObj . tiles [ JSON . stringify ( this . frontLoc ) ] . foodLevel > 0 && this . alive ) {
this . energy += config . world . foodReward
if ( this . energy > this . maxEnergy ) {
userObj [ this . owner ] . addEnergy ( this . energy - this . maxEnergy )
this . energy = this . maxEnergy
}
worldObj . tiles [ JSON . stringify ( this . frontLoc ) ] . foodLevel -= 1
return 100
}
return 0
} ,
mate : ( input ) => {
if ( input > this . activationValue && creatureArr . length < config . maxPop && this . alive && worldObj . checkBlocked ( this . location ) && this . energy > ( config . creature . physical . birthCost + 1 ) ) {
if ( input > this . activationValue && creatureArr . length < config . maxPop && this . alive && this . energy > ( config . creature . physical . birthCost + 1 ) ) {
// TODO: Figure out why colour Arr sometimes becomes a string.
if ( typeof this . colour == "string" ) {
this . die ( )
this . die ( this . colour )
return false
}
try {
@ -195,42 +100,28 @@ class Creature {
colour : this . colour
} ) ) )
if ( ! worldObj . checkBlocked ( this . behindLoc ) ) {
if ( true ) {
this . energy -= config . creature . physical . birthCost
this . births += 1
userObj [ this . owner ] . addCreature ( )
let baby = new Creature ( this . name , obj . surName , this . behindLoc , config . creature . physical . birthEnergy , obj . maxEnergy , obj . speed , obj . brain , obj . brainSize , obj . brainComplexity , this . owner , obj . activationValue , obj . oscillatorFrequency , obj . maxAge , this . generation + 1 , obj . eatFoodLevel , obj . colour )
messageObj . add ( "Birth" , this . fullName + " gave birth to " + baby . fullName )
creatureArr . push ( baby )
messageObj . add ( "Location" , this . fullName + " gave birth to " + baby . fullName + " at " + this . location + ", the child is at " + baby . location )
return 100
}
return 0
}
catch ( e ) {
this . die ( )
this . die ( e )
}
}
return 0
} ,
fight : ( input ) => {
if ( input > this . activationValue && worldObj . checkCreature ( this . frontLoc ) && this . alive ) {
this . kills += 1
userObj [ this . owner ] . addKill ( )
messageObj . add ( "Fight" , ( this . fullName + " Killed " + worldObj . tiles [ JSON . stringify ( this . frontLoc ) ] . creature . fullName ) + " they have killed " + this . kills + " creatures" )
worldObj . tiles [ JSON . stringify ( this . frontLoc ) ] . creature . die ( "they were killed by " + this . fullName )
return 100
}
return 0
}
}
}
mutate ( obj ) {
let mod = 0
if ( Math . random ( ) < config . creature . physical . mutateFraction ) {
userObj [ this . owner ] . addMutant ( )
obj . surName = ( this . name + "_" + this . surName )
if ( Math . random ( ) > 0.5 ) {
mod = 1
@ -265,96 +156,8 @@ class Creature {
}
return obj
}
updateLocation ( arr ) {
if ( arr [ 0 ] < 0 || arr [ 1 ] < 0 ) {
this . die ( )
return this . location
} else if ( arr [ 1 ] > config . boundry . right || arr [ 0 ] > config . boundry . top ) {
this . die ( )
return this . location
} else {
worldObj . checkBlocked ( arr )
if ( this . location !== undefined ) {
worldObj . checkBlocked ( this . location )
worldObj . tiles [ JSON . stringify ( this . location ) ] . creature = { }
worldObj . tiles [ JSON . stringify ( arr ) ] . creature = this
}
this . location = arr
this . frontLoc = this . direction ( 1 )
this . rightLoc = this . direction ( 2 )
this . behindLoc = this . direction ( 3 )
this . leftLoc = this . direction ( 4 )
return true
}
}
direction ( desiredLocation ) {
if ( desiredLocation [ 0 ] < 0 || desiredLocation [ 1 ] < 0 || desiredLocation [ 0 ] > config . boundry . top || desiredLocation [ 1 ] > config . boundry . right ) {
this . die ( )
return this . location
}
worldObj . checkBlocked ( [ this . location [ 0 ] + 1 , this . location [ 1 ] ] )
worldObj . checkBlocked ( [ this . location [ 0 ] - 1 , this . location [ 1 ] ] )
worldObj . checkBlocked ( [ this . location [ 0 ] , this . location [ 1 ] + 1 ] )
worldObj . checkBlocked ( [ this . location [ 0 ] , this . location [ 1 ] - 1 ] )
switch ( desiredLocation ) {
case 1 :
switch ( this . facingDirection ) {
case 1 :
return [ this . location [ 0 ] + 1 , this . location [ 1 ] ]
case 2 :
return [ this . location [ 0 ] , this . location [ 1 ] + 1 ]
case 3 :
return [ this . location [ 0 ] - 1 , this . location [ 1 ] ]
case 4 :
return [ this . location [ 0 ] , this . location [ 1 ] - 1 ]
}
case 2 :
switch ( this . facingDirection ) {
case 1 :
return [ this . location [ 0 ] , this . location [ 1 ] + 1 ]
case 2 :
return [ this . location [ 0 ] - 1 , this . location [ 1 ] ]
case 3 :
return [ this . location [ 0 ] , this . location [ 1 ] - 1 ]
case 4 :
return [ this . location [ 0 ] + 1 , this . location [ 1 ] ]
}
case 3 :
switch ( this . facingDirection ) {
case 1 :
return [ this . location [ 0 ] - 1 , this . location [ 1 ] ]
case 2 :
return [ this . location [ 0 ] , this . location [ 1 ] - 1 ]
case 3 :
return [ this . location [ 0 ] + 1 , this . location [ 1 ] ]
case 4 :
return [ this . location [ 0 ] , this . location [ 1 ] + 1 ]
}
case 4 :
switch ( this . facingDirection ) {
case 1 :
return [ this . location [ 0 ] , this . location [ 1 ] - 1 ]
case 2 :
return [ this . location [ 0 ] + 1 , this . location [ 1 ] ]
case 3 :
return [ this . location [ 0 ] , this . location [ 1 ] + 1 ]
case 4 :
return [ this . location [ 0 ] - 1 , this . location [ 1 ] ]
}
}
}
placeSelf ( ) {
let arr = [ Math . floor ( Math . random ( ) * config . boundry . top ) , Math . floor ( Math . random ( ) * config . boundry . right ) ]
worldObj . checkBlocked ( arr )
if ( ! worldObj . checkBlocked ( arr ) || worldObj . tiles [ JSON . stringify ( arr ) ] . creature . fullName == this . fullName ) {
this . updateLocation ( arr )
worldObj . tiles [ JSON . stringify ( arr ) ] . creature = this
messageObj . add ( "Location" , this . fullName + " Initially placed at " + this . location )
} else {
this . die ( "they were placed in tile " + arr + " which is occupied by " + worldObj . tiles [ JSON . stringify ( arr ) ] . creature . fullName )
}
return arr
}
randomBrain ( ) {
for ( let braindex = 0 ; braindex < this . brainSize ; braindex ++ ) {
let brainPath = [ ]
@ -403,17 +206,9 @@ class Creature {
}
die ( deathReason ) {
if ( this . alive ) {
userObj [ this . owner ] . takeCreature ( )
this . alive = false
// worldObj.checkBlocked(this.location)
if ( worldObj . checkCreature ( this . location ) ) {
worldObj . tiles [ JSON . stringify ( this . location ) ] . creature = { }
} else {
console . log ( this . fullName + " does not have a tile!" )
}
console . log ( this . fullName + " died: " + deathReason )
}
this . location = [ null , null ]
messageObj . add ( "Death" , ( this . fullName + " died because " + deathReason ) )
return 0
}
}