Guest User

Untitled

a guest
Apr 24th, 2018
89
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.75 KB | None | 0 0
  1. // 2 entities, George and Phil will meet on this fateful night
  2. const e1 = {
  3. name: 'George',
  4. health: 400,
  5. target: null,
  6. }
  7.  
  8. const e2 = {
  9. name: 'Phil',
  10. health: 400,
  11. target: null,
  12. }
  13.  
  14.  
  15. e1.behave = agentBehaviour(e1)
  16. e2.behave = agentBehaviour(e2)
  17.  
  18. function *patrol(e) {
  19. console.log(e.name, 'patrolling for baddies...')
  20. while(true) {
  21. yield* wait(10)
  22. console.log(e.name, 'continues to patrol')
  23. }
  24. }
  25.  
  26. function *attack(e, target) {
  27. console.log(e.name, 'engages', target.name)
  28. yield* iwhile(() => target.health > 0, function *() {
  29. while (true) {
  30. if (Math.random() < 0.5) {
  31. // Cast fireball
  32. console.log(e.name, 'charges a fireball at', target.name)
  33. yield* wait(10)
  34. const damage = 100 + (Math.random() * 10)|0
  35. target.health -= damage
  36. console.log(`🔥 ${e.name}'s fireball hits ${target.name} for ${damage} damage, ${target.health} hp remaining`)
  37. } else {
  38. // Attack with sword
  39. const damage = 10 + (Math.random() * 10)|0
  40. target.health -= damage
  41. console.log(`⚔️ ${e.name}'s sword slices ${target.name} for ${damage} damage, ${target.health} hp remaining`)
  42. yield* wait(3)
  43. }
  44.  
  45. yield* wait(5)
  46. }
  47. })
  48. console.log(target.name, 'is dead!', e.name, 'cheers and hollers 🎉')
  49. e.target = null
  50. //while(true) yield
  51. }
  52.  
  53. function *agentBehaviour(e) {
  54. yield* iwhile(() => e.health > 0, function *() {
  55. while (true) {
  56. // If we have no target, just patrol around.
  57. yield* iwhile(() => e.target == null, patrol(e))
  58.  
  59. // ... Ok we have a target now. Attack!!
  60. yield* attack(e, e.target)
  61. }
  62. })
  63. console.log(e.name, 'is dead 👻')
  64. }
  65.  
  66.  
  67.  
  68.  
  69.  
  70.  
  71. // *** Plumbing.
  72.  
  73. // The state is a stack of iterators. Each tick we'll take the top of the stack
  74. // (the stack's last element) and iterate it.
  75.  
  76.  
  77. // Run iterator so long as predicate remains true
  78. function *iwhile(pred, iter) {
  79. if (typeof iter === 'function') iter = iter() // Avoids some awkward syntax
  80.  
  81. while (true) {
  82. if (!pred()) return
  83. const {value, done} = iter.next()
  84. if (done) return value // Wrap return value of iterator
  85. else yield value
  86. }
  87. }
  88.  
  89.  
  90. // Helper to wait X frames
  91. function *wait(framecount) {
  92. while(--framecount) yield // Each call to yield will wait 1 frame
  93. }
  94.  
  95.  
  96. // *** Actual runtime code
  97.  
  98. const timer = setInterval(tick, 100)
  99.  
  100. function updateEntity(e) {
  101. if (e.dead) return
  102.  
  103. const {done} = e.behave.next()
  104. if (done) {
  105. console.log('Cleanup', e.name)
  106. e.dead = true
  107. }
  108. }
  109.  
  110. let framecount = 0
  111.  
  112. function tick() {
  113. framecount++
  114.  
  115. if (e1.target == null && framecount === 10) {
  116. console.log('Oh no! They saw each other')
  117. e1.target = e2
  118. e2.target = e1
  119. }
  120.  
  121.  
  122. updateEntity(e1)
  123. updateEntity(e2)
  124.  
  125. // Done!
  126. if (e1.dead || e2.dead) clearInterval(timer)
  127. }
Add Comment
Please, Sign In to add comment