Esempio n. 1
0
func fightN(f1, f2 Factory, n int) []MatchResult {
	aiA := &aiAdapter{factory: f1, games: make(map[string]gameState)}
	aiB := &aiAdapter{factory: f2, games: make(map[string]gameState)}

	a1, a2 := net.Pipe()
	b1, b2 := net.Pipe()

	ca1, ca2 := rpc.StreamTransport(a1), rpc.StreamTransport(a2)
	cb1, cb2 := rpc.StreamTransport(b1), rpc.StreamTransport(b2)

	// Server-side
	srvA := botapi.Ai_ServerToClient(aiA)
	srvB := botapi.Ai_ServerToClient(aiB)
	serverConnA := rpc.NewConn(ca1, rpc.MainInterface(srvA.Client))
	serverConnB := rpc.NewConn(cb1, rpc.MainInterface(srvB.Client))
	defer serverConnA.Wait()
	defer serverConnB.Wait()

	// Client-side
	ctx := context.Background()

	clientConnA := rpc.NewConn(ca2)
	clientConnB := rpc.NewConn(cb2)
	defer clientConnA.Close()
	defer clientConnB.Close()

	clientA := localAI{botapi.Ai{Client: clientConnA.Bootstrap(ctx)}}
	clientB := localAI{botapi.Ai{Client: clientConnB.Bootstrap(ctx)}}

	matchRes := make([]MatchResult, n)
	// Run the game
	for i := 0; i < n; i++ {
		b := engine.EmptyBoard(engine.DefaultConfig)
		b.InitBoard(engine.DefaultConfig)

		for !b.IsFinished() {
			turnCtx, _ := context.WithTimeout(ctx, 30*time.Second)
			resA, _ := clientA.takeTurn(turnCtx, strconv.Itoa(i), b, engine.P1Faction)
			resB, _ := clientB.takeTurn(turnCtx, strconv.Itoa(i), b, engine.P2Faction)
			b.Update(resA, resB)
		}
		matchRes[i] = MatchResult{
			P1Score: b.BotCount(1),
			P2Score: b.BotCount(2),
		}
	}
	return matchRes
}
Esempio n. 2
0
func client(ctx context.Context, c net.Conn) error {
	// Create a connection that we can use to get the HashFactory.
	conn := rpc.NewConn(rpc.StreamTransport(c))
	defer conn.Close()
	// Get the "bootstrap" interface.  This is the capability set with
	// rpc.MainInterface on the remote side.
	hf := hashes.HashFactory{Client: conn.Bootstrap(ctx)}

	// Now we can call methods on hf, and they will be sent over c.
	s := hf.NewSha1(ctx, nil).Hash()
	// s refers to a remote Hash.  Method calls are delivered in order.
	s.Write(ctx, func(p hashes.Hash_write_Params) error {
		err := p.SetData([]byte("Hello, "))
		return err
	})
	s.Write(ctx, func(p hashes.Hash_write_Params) error {
		err := p.SetData([]byte("World!"))
		return err
	})
	result, err := s.Sum(ctx, nil).Struct()
	if err != nil {
		return err
	}
	sha1Val, err := result.Hash()
	if err != nil {
		return err
	}
	fmt.Printf("sha1: %x\n", sha1Val)
	return nil
}
Esempio n. 3
0
func server(c net.Conn) error {
	// Create a new locally implemented HashFactory.
	main := hashes.HashFactory_ServerToClient(hashFactory{})
	// Listen for calls, using the HashFactory as the bootstrap interface.
	conn := rpc.NewConn(rpc.StreamTransport(c), rpc.MainInterface(main.Client))
	// Wait for connection to abort.
	err := conn.Wait()
	return err
}
Esempio n. 4
0
func Example() {
	// Create an in-memory transport.  In a real application, you would probably
	// use a net.TCPConn (for RPC) or an os.Pipe (for IPC).
	p1, p2 := net.Pipe()
	t1, t2 := rpc.StreamTransport(p1), rpc.StreamTransport(p2)

	// Server-side
	srv := testcapnp.Adder_ServerToClient(AdderServer{})
	serverConn := rpc.NewConn(t1, rpc.MainInterface(srv.Client))
	defer serverConn.Wait()

	// Client-side
	ctx := context.Background()
	clientConn := rpc.NewConn(t2)
	defer clientConn.Close()
	adderClient := testcapnp.Adder{Client: clientConn.Bootstrap(ctx)}
	// Every client call returns a promise.  You can make multiple calls
	// concurrently.
	call1 := adderClient.Add(ctx, func(p testcapnp.Adder_add_Params) error {
		p.SetA(5)
		p.SetB(2)
		return nil
	})
	call2 := adderClient.Add(ctx, func(p testcapnp.Adder_add_Params) error {
		p.SetA(10)
		p.SetB(20)
		return nil
	})
	// Calling Struct() on a promise waits until it returns.
	result1, err := call1.Struct()
	if err != nil {
		fmt.Println("Add #1 failed:", err)
		return
	}
	result2, err := call2.Struct()
	if err != nil {
		fmt.Println("Add #2 failed:", err)
		return
	}

	fmt.Println("Results:", result1.Result(), result2.Result())
	// Output:
	// Results: 7 30
}
Esempio n. 5
0
// Dial connects to a server at the given TCP address.
func Dial(addr string) (*Client, error) {
	c, err := net.Dial("tcp", addr)
	if err != nil {
		return nil, err
	}
	conn := rpc.NewConn(rpc.StreamTransport(c))
	return &Client{
		conn:      conn,
		connector: botapi.AiConnector{Client: conn.Bootstrap(context.TODO())},
	}, nil
}
Esempio n. 6
0
// handleConn runs in its own goroutine, started by listen.
func (e *aiEndpoint) handleConn(c net.Conn) {
	aic := &aiConnector{e: e}
	rc := rpc.NewConn(rpc.StreamTransport(c), rpc.MainInterface(botapi.AiConnector_ServerToClient(aic).Client))
	rc.Wait()
	aic.drop()
}