Advertisement
Guest User

Untitled

a guest
Apr 19th, 2021
25
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.16 KB | None | 0 0
  1. OBSTACLE = "+"
  2. EMPTY = "."
  3. MINE = "M"
  4. BEACON = "B"
  5.  
  6. raw_board="""\
  7. ++++++++++++++++++++
  8. +++++++..+++++++++++
  9. +++++++...++++.+++++
  10. ++++++.+..+++.....++
  11. ++++++.....+......++
  12. +++++++..++.......++
  13. ++....+..+++.+.+..++
  14. ++........+........+
  15. ++..........++.+++++
  16. ++..........++.+++++
  17. +++++..+..........++
  18. ++++++++++++...++.++
  19. ++++++++++++......++
  20. +.++++...+++......++
  21. +..+++...+++++++++++
  22. ++++++...+++++++++++
  23. ++++++++++++++++++++"""
  24.  
  25. #all functions assume that: a board's outermost rows/columns are entirely obstacles
  26.  
  27. def copy(board):
  28. #could just use deepcopy, but meh
  29. return [row[:] for row in board]
  30.  
  31. def iter_neighbors(board, x,y):
  32. """yield the tile type of every adjacent tile"""
  33.  
  34. #todo: make this work for border tiles
  35. assert 0 < y < len(board) - 1
  36. assert 0 < x < len(board[0]) - 1
  37.  
  38. for dx in (-1,0,1):
  39. for dy in (-1, 0, 1):
  40. if dx == dy == 0: continue
  41. yield board[dy+y][dx+x]
  42.  
  43. def calculate_score(board):
  44. """Returns the total score of the board."""
  45. def _score(x,y):
  46. """the score of this one tile."""
  47. if board[y][x] == MINE:
  48. return 100 + sum(40 for tile in iter_neighbors(board, x, y) if tile == BEACON)
  49. else:
  50. return 0
  51. return sum(_score(x,y) for y, row in enumerate(board) for x, _ in enumerate(row))
  52.  
  53. def display(board):
  54. """print the board."""
  55. print("\n".join("".join(row) for row in board))
  56.  
  57.  
  58. #example optimizers. Each one may mutate board in-place in an attempt to improve its score.
  59. def literally_nothing(board):
  60. pass
  61.  
  62. def fill_empty_with_mines(board):
  63. for y, row in enumerate(board):
  64. for x, tile in enumerate(row):
  65. if board[y][x] == EMPTY:
  66. board[y][x] = MINE
  67.  
  68. def optimize_with_hill_climb(board):
  69. """Make only simple strict improvements. Very likely to get stuck in local optima."""
  70.  
  71. #pass 1: fill up empty tiles
  72. fill_empty_with_mines(board)
  73.  
  74. #pass 2: replace a mine with a beacon iff doing so increases score
  75. cur_score = calculate_score(board)
  76. for y, row in enumerate(board):
  77. for x, tile in enumerate(row):
  78. if board[y][x] == MINE:
  79. board[y][x] = BEACON
  80. new_score = calculate_score(board)
  81. if new_score > cur_score:
  82. #keep change
  83. cur_score = new_score
  84. else:
  85. #revert
  86. board[y][x] = MINE
  87.  
  88. def sample_showcase():
  89. """showcase the performance of the sample optimizers."""
  90. starting_board = [list(row) for row in raw_board.strip().split("\n")]
  91. optimizers = [literally_nothing, fill_empty_with_mines, optimize_with_hill_climb]
  92. print("Starting board:")
  93. display(starting_board)
  94. print("\n")
  95.  
  96. for i, optimize_func in enumerate(optimizers, 1):
  97. board = copy(starting_board)
  98. print(f"Candidate #{i}: {optimize_func.__name__}")
  99. optimize_func(board)
  100. display(board)
  101. print("Score:", calculate_score(board))
  102. print(f"End of report for candidate #{i}.\n\n")
  103.  
  104. if __name__ == "__main__":
  105. sample_showcase()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement