forest_fire.sf 1.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364
  1. #!/usr/bin/ruby
  2. define w = `tput cols`.to_i
  3. define h = `tput lines`.to_i
  4. define r = "\033[H"
  5. define red = "\033[31m"
  6. define green = "\033[32m"
  7. define yellow = "\033[33m"
  8. define chars = [' ', green+'*', yellow+'&', red+'&']
  9. define tree_prob = 0.05
  10. define burn_prob = 0.0002
  11. enum |Empty, Tree, Heating, Burning|
  12. define dirs = [
  13. %n(-1 -1), %n(-1 0), %n(-1 1), %n(0 -1),
  14. %n(0 1), %n(1 -1), %n(1 0), %n(1 1),
  15. ]
  16. var forest = h.of { w.of { 1.rand < tree_prob ? Tree : Empty } }
  17. var range_h = h.range
  18. var range_w = w.range
  19. func iterate {
  20. var new = h.of{ w.of(0) }
  21. for i in range_h {
  22. for j in range_w {
  23. given (new[i][j] = forest[i][j]) {
  24. when (Tree) {
  25. 1.rand < burn_prob && (new[i][j] = Heating; next)
  26. dirs.each { |pair|
  27. var y = pair[0]+i
  28. range_h.contains(y) || next
  29. var x = pair[1]+j
  30. range_w.contains(x) || next
  31. forest[y][x] == Heating && (new[i][j] = Heating; break)
  32. }
  33. }
  34. when (Heating) { new[i][j] = Burning }
  35. when (Burning) { new[i][j] = Empty }
  36. case (1.rand < tree_prob) { new[i][j] = Tree }
  37. }
  38. }
  39. }
  40. forest = new
  41. }
  42. STDOUT.autoflush(true)
  43. func init_forest {
  44. print r
  45. forest.each { |row|
  46. print chars[row]
  47. print "\033[E\033[1G"
  48. }
  49. iterate()
  50. }
  51. loop { init_forest() }