bot_example.py 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. #!/usr/bin/python3
  2. """
  3. Competitive tetris bot example
  4. """
  5. import time
  6. import random
  7. import zmq
  8. import flatbuffers
  9. import numpy as np
  10. import wire_protocol.Command
  11. import wire_protocol.CommandRequest
  12. import wire_protocol.CommandResponse
  13. import wire_protocol.CommandResponseError
  14. import game_state
  15. def dummy_next_piece_func():
  16. return 0
  17. def cell_strength(field, row, col):
  18. neighbour_count = 0
  19. for r in range(row-1, row+2):
  20. for c in range(col-1, col+2):
  21. if (r < 0 or r >= field.shape[0] or
  22. c < 0 or c >= field.shape[1]):
  23. # walls are neighbours
  24. neighbour_count += 1
  25. elif field[r][c] > 0:
  26. neighbour_count += 1
  27. if field[row][col]:
  28. return neighbour_count * row
  29. else:
  30. return -neighbour_count * row
  31. def field_heuristic(field):
  32. result = 0.0
  33. for r in range(field.shape[0]):
  34. for c in range(field.shape[1]):
  35. result += cell_strength(field, r, c)
  36. return result
  37. class ShiftAndRotate:
  38. def __init__(self, rotate_count, col_offset, value, state):
  39. self.rotate_count = rotate_count
  40. self.col_offset = col_offset
  41. self.value = value
  42. self.state = state
  43. def create_shifts_and_rotates(state):
  44. shift_and_rotates = []
  45. for rotate_count in range(5):
  46. rotate_state = state
  47. for _ in range(rotate_count):
  48. rotate_state = rotate_state.rotate()
  49. if rotate_state is None:
  50. break
  51. if rotate_state is None:
  52. continue
  53. for col_offset in range(-game_state.FIELD_WIDTH, game_state.FIELD_HEIGHT+1):
  54. next_state = rotate_state.shift(col_offset)
  55. if next_state is not None:
  56. final_state, is_running = next_state.land().advance()
  57. if is_running:
  58. value = (field_heuristic(final_state.data.grid) +
  59. final_state.data.score*10000.0)
  60. shift_and_rotates.append(ShiftAndRotate(
  61. rotate_count,
  62. col_offset,
  63. value,
  64. final_state))
  65. return shift_and_rotates
  66. def main():
  67. context = zmq.Context()
  68. socket = context.socket(zmq.REQ)
  69. socket.connect("tcp://localhost:5555")
  70. while True:
  71. builder = flatbuffers.Builder()
  72. wire_protocol.CommandRequest.Start(builder)
  73. wire_protocol.CommandRequest.AddCommand(
  74. builder,
  75. wire_protocol.Command.Command.GetGameState)
  76. req = wire_protocol.CommandRequest.End(builder)
  77. builder.Finish(req)
  78. socket.send(builder.Output())
  79. rsp_buf = socket.recv()
  80. rsp = wire_protocol.CommandResponse.CommandResponse.GetRootAs(rsp_buf)
  81. grid = rsp.GameState().GridAsNumpy()
  82. grid = grid.reshape((rsp.GameState().Rows(), rsp.GameState().Cols()))
  83. state = game_state.GameState()
  84. state.data = game_state.GameStateData(
  85. grid = grid,
  86. current_piece = rsp.GameState().CurrentPiece(),
  87. next_piece = rsp.GameState().NextPiece(),
  88. rotation = rsp.GameState().PieceRotation(),
  89. row = rsp.GameState().PieceRow(),
  90. col = rsp.GameState().PieceCol(),
  91. score = rsp.GameState().Score())
  92. state.next_piece_func = dummy_next_piece_func
  93. next_moves = create_shifts_and_rotates(state)
  94. if len(next_moves) > 0:
  95. best_moves = sorted(next_moves, key=lambda x: x.value, reverse=True)
  96. best_move = best_moves[0]
  97. command = wire_protocol.Command.Command.Rotate
  98. for _ in range(best_move.rotate_count):
  99. builder = flatbuffers.Builder()
  100. wire_protocol.CommandRequest.Start(builder)
  101. wire_protocol.CommandRequest.AddCommand(builder, command)
  102. req = wire_protocol.CommandRequest.End(builder)
  103. builder.Finish(req)
  104. socket.send(builder.Output())
  105. rsp_buf = socket.recv()
  106. rsp = wire_protocol.CommandResponse.CommandResponse.GetRootAs(rsp_buf)
  107. command = wire_protocol.Command.Command.ShiftRight
  108. if best_move.col_offset < 0:
  109. command = wire_protocol.Command.Command.ShiftLeft
  110. for _ in range(abs(best_move.col_offset)):
  111. builder = flatbuffers.Builder()
  112. wire_protocol.CommandRequest.Start(builder)
  113. wire_protocol.CommandRequest.AddCommand(builder, command)
  114. req = wire_protocol.CommandRequest.End(builder)
  115. builder.Finish(req)
  116. socket.send(builder.Output())
  117. rsp_buf = socket.recv()
  118. rsp = wire_protocol.CommandResponse.CommandResponse.GetRootAs(rsp_buf)
  119. builder = flatbuffers.Builder()
  120. wire_protocol.CommandRequest.Start(builder)
  121. wire_protocol.CommandRequest.AddCommand(
  122. builder, wire_protocol.Command.Command.Land)
  123. req = wire_protocol.CommandRequest.End(builder)
  124. builder.Finish(req)
  125. socket.send(builder.Output())
  126. rsp_buf = socket.recv()
  127. rsp = wire_protocol.CommandResponse.CommandResponse.GetRootAs(rsp_buf)
  128. if __name__ == "__main__":
  129. main()