Bläddra i källkod

Added wire protocol and bot example

Alexey Dorokhov 3 år sedan
förälder
incheckning
3c0652b194

+ 44 - 0
bot_example.py

@@ -0,0 +1,44 @@
+#!/usr/bin/python3
+
+"""
+Competitive tetris bot example
+"""
+
+import time
+import random
+import zmq
+import flatbuffers
+
+import wire_protocol.Command
+import wire_protocol.CommandRequest
+import wire_protocol.CommandResponse
+import wire_protocol.CommandResponseError
+
+def main():
+    context = zmq.Context()
+    socket = context.socket(zmq.REQ)
+    res = socket.connect("tcp://localhost:5555")
+    print(f"connected: {res}")
+
+    while True:
+        builder = flatbuffers.Builder()
+        wire_protocol.CommandRequest.Start(builder)
+        wire_protocol.CommandRequest.AddCommand(
+                builder,
+                random.choice([
+                    wire_protocol.Command.Command.ShiftLeft,
+                    wire_protocol.Command.Command.ShiftRight,
+                    wire_protocol.Command.Command.Rotate,
+                    wire_protocol.Command.Command.Land,
+                    ]))
+        req = wire_protocol.CommandRequest.End(builder)
+        builder.Finish(req)
+        socket.send(builder.Output())
+
+        rsp_buf = socket.recv()
+        rsp = wire_protocol.CommandResponse.CommandResponse.GetRootAs(rsp_buf)
+        time.sleep(0.24)
+
+
+if __name__ == "__main__":
+    main()

+ 37 - 9
competitive_tetris.py

@@ -5,9 +5,15 @@ Competitive tetris server
 """
 import random
 import pygame
+import zmq
+import flatbuffers
 
 import tetrominos
 import game
+import wire_protocol.Command
+import wire_protocol.CommandRequest
+import wire_protocol.CommandResponse
+import wire_protocol.CommandResponseError
 
 pygame.font.init()
 
@@ -102,6 +108,12 @@ def main(win):
     frame_time = 0
     clock = pygame.time.Clock()
 
+    zmq_context = zmq.Context()
+    socket = zmq_context.socket(zmq.REP)
+    socket.bind("tcp://*:5555")
+    poller = zmq.Poller()
+    poller.register(socket, zmq.POLLIN)
+
     def _next_piece_func():
         return random.choice(range(len(tetrominos.SHAPES)))
     game_state = game.initial_game_state(_next_piece_func(),
@@ -117,15 +129,31 @@ def main(win):
                 run = False
                 pygame.display.quit()
 
-            if event.type == pygame.KEYDOWN:
-                if event.key == pygame.K_LEFT:
-                    game_state = game.game_state_shift(game_state, -1)
-                if event.key == pygame.K_RIGHT:
-                    game_state = game.game_state_shift(game_state, 1)
-                if event.key == pygame.K_UP:
-                    game_state = game.game_state_rotate(game_state)
-                if event.key == pygame.K_DOWN:
-                    game_state = game.game_state_land(game_state)
+        for sock, _ in poller.poll(timeout=0):
+            req_buf = sock.recv()
+            req = wire_protocol.CommandRequest.CommandRequest.GetRootAs(req_buf)
+
+            error_code = wire_protocol.CommandResponseError.CommandResponseError.OK
+
+            if req.Command() == wire_protocol.Command.Command.ShiftLeft:
+                game_state = game.game_state_shift(game_state, -1)
+            elif req.Command() == wire_protocol.Command.Command.ShiftRight:
+                game_state = game.game_state_shift(game_state, 1)
+            elif req.Command() == wire_protocol.Command.Command.Rotate:
+                game_state = game.game_state_rotate(game_state)
+            elif req.Command() == wire_protocol.Command.Command.Land:
+                game_state = game.game_state_land(game_state)
+            else:
+                error_code = wire_protocol.CommandResponseError.CommandResponseError.UNKNOWN_COMMAND
+
+            builder = flatbuffers.Builder()
+            wire_protocol.CommandResponse.Start(builder)
+            wire_protocol.CommandResponse.AddError(builder, error_code)
+            rsp = wire_protocol.CommandResponse.End(builder)
+            builder.Finish(rsp)
+            socket.send(builder.Output())
+
+
 
         is_game_running = True
         if frame_time >= 500:

+ 24 - 0
wire_protocol.fbs

@@ -0,0 +1,24 @@
+namespace wire_protocol;
+
+enum Command : short {
+  ShiftLeft = 0,
+  ShiftRight = 1,
+  Rotate = 2,
+  Land = 3,
+}
+
+enum CommandResponseError : short {
+  OK = 0,
+  UNKNOWN_COMMAND = 1,
+}
+
+table CommandRequest {
+  command:Command;
+}
+
+table CommandResponse {
+  error:CommandResponseError;
+}
+
+root_type CommandRequest;
+root_type CommandResponse;

+ 9 - 0
wire_protocol/Command.py

@@ -0,0 +1,9 @@
+# automatically generated by the FlatBuffers compiler, do not modify
+
+# namespace: wire_protocol
+
+class Command(object):
+    ShiftLeft = 0
+    ShiftRight = 1
+    Rotate = 2
+    Land = 3

+ 42 - 0
wire_protocol/CommandRequest.py

@@ -0,0 +1,42 @@
+# automatically generated by the FlatBuffers compiler, do not modify
+
+# namespace: wire_protocol
+
+import flatbuffers
+from flatbuffers.compat import import_numpy
+np = import_numpy()
+
+class CommandRequest(object):
+    __slots__ = ['_tab']
+
+    @classmethod
+    def GetRootAs(cls, buf, offset=0):
+        n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, offset)
+        x = CommandRequest()
+        x.Init(buf, n + offset)
+        return x
+
+    @classmethod
+    def GetRootAsCommandRequest(cls, buf, offset=0):
+        """This method is deprecated. Please switch to GetRootAs."""
+        return cls.GetRootAs(buf, offset)
+    # CommandRequest
+    def Init(self, buf, pos):
+        self._tab = flatbuffers.table.Table(buf, pos)
+
+    # CommandRequest
+    def Command(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(4))
+        if o != 0:
+            return self._tab.Get(flatbuffers.number_types.Int16Flags, o + self._tab.Pos)
+        return 0
+
+def CommandRequestStart(builder): builder.StartObject(1)
+def Start(builder):
+    return CommandRequestStart(builder)
+def CommandRequestAddCommand(builder, command): builder.PrependInt16Slot(0, command, 0)
+def AddCommand(builder, command):
+    return CommandRequestAddCommand(builder, command)
+def CommandRequestEnd(builder): return builder.EndObject()
+def End(builder):
+    return CommandRequestEnd(builder)

+ 42 - 0
wire_protocol/CommandResponse.py

@@ -0,0 +1,42 @@
+# automatically generated by the FlatBuffers compiler, do not modify
+
+# namespace: wire_protocol
+
+import flatbuffers
+from flatbuffers.compat import import_numpy
+np = import_numpy()
+
+class CommandResponse(object):
+    __slots__ = ['_tab']
+
+    @classmethod
+    def GetRootAs(cls, buf, offset=0):
+        n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, offset)
+        x = CommandResponse()
+        x.Init(buf, n + offset)
+        return x
+
+    @classmethod
+    def GetRootAsCommandResponse(cls, buf, offset=0):
+        """This method is deprecated. Please switch to GetRootAs."""
+        return cls.GetRootAs(buf, offset)
+    # CommandResponse
+    def Init(self, buf, pos):
+        self._tab = flatbuffers.table.Table(buf, pos)
+
+    # CommandResponse
+    def Error(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(4))
+        if o != 0:
+            return self._tab.Get(flatbuffers.number_types.Int16Flags, o + self._tab.Pos)
+        return 0
+
+def CommandResponseStart(builder): builder.StartObject(1)
+def Start(builder):
+    return CommandResponseStart(builder)
+def CommandResponseAddError(builder, error): builder.PrependInt16Slot(0, error, 0)
+def AddError(builder, error):
+    return CommandResponseAddError(builder, error)
+def CommandResponseEnd(builder): return builder.EndObject()
+def End(builder):
+    return CommandResponseEnd(builder)

+ 7 - 0
wire_protocol/CommandResponseError.py

@@ -0,0 +1,7 @@
+# automatically generated by the FlatBuffers compiler, do not modify
+
+# namespace: wire_protocol
+
+class CommandResponseError(object):
+    OK = 0
+    UNKNOWN_COMMAND = 1

+ 0 - 0
wire_protocol/__init__.py